Skip to content

Commit ffeaf8e

Browse files
committed
feat(fabric-x): dynamic distributed orderer orchestration
- Refactored index.ts to dynamically render 9 microservice configs per BFT node - Replaced monolithic docker-compose with multi-org templated compose - Fixed client-tls-ca.pem directory mount panic via alpine find command - Removed legacy static mock-orderer and sidecar configurations Signed-off-by: Harshit Kandpal <kandpalhar@gmail.com>
1 parent 2eacb84 commit ffeaf8e

19 files changed

Lines changed: 740 additions & 703 deletions

src/setup-docker/index.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,27 +308,50 @@ export default class SetupDocker extends Command {
308308
}
309309
}
310310

311-
async _copyFabricXDevnetTemplates(config: FabloConfigExtended): Promise<void> {
312-
const files = [
311+
async _copyFabricXDevnetTemplates(configExtended: FabloConfigExtended): Promise<void> {
312+
const staticFiles = [
313313
"compose.test-committer.yaml",
314314
"crypto-config.yaml",
315315
"configtx.yaml",
316316
"shared_config.yaml",
317317
"fxconfig.yaml",
318318
"Makefile",
319319
".gitignore",
320-
"config/mock-orderer.yaml",
321-
"config/committer-sidecar-dev.yaml",
322-
"config/committer-coordinator.yaml",
323-
"config/committer-verifier.yaml",
324-
"config/committer-validator.yaml",
325-
"config/committer-query-service.yaml",
326320
];
327321

328-
for (const file of files) {
322+
for (const file of staticFiles) {
329323
const templatePath = getTemplatePath(this.templatesDir, `fabric-x/${file}.ejs`);
330324
const destPath = getDestinationPath(this.outputDir, `fabric-x/${file}`);
331-
await renderTemplate(templatePath, destPath, config as unknown as Record<string, unknown>);
325+
await renderTemplate(templatePath, destPath, configExtended as unknown as Record<string, unknown>);
326+
}
327+
328+
// 1. Loop over Orderers
329+
const ordererOrgs = configExtended.orgs.filter(o => o.ordererGroups && o.ordererGroups.length > 0);
330+
for (let index = 0; index < ordererOrgs.length; index++) {
331+
const org = ordererOrgs[index];
332+
const partyId = index + 1;
333+
const partyName = `party${partyId}`;
334+
const localMspId = `${org.name}MSP`;
335+
336+
const ordererTemplates = ["router", "batcher", "consenter", "assembler"];
337+
for (const tpl of ordererTemplates) {
338+
const templatePath = getTemplatePath(this.templatesDir, `fabric-x/config/${tpl}.yaml.ejs`);
339+
const destPath = getDestinationPath(this.outputDir, `fabric-x/config/${partyName}-${tpl}.yaml`);
340+
await renderTemplate(templatePath, destPath, { partyId, localMspId });
341+
}
342+
}
343+
344+
// 2. Loop over Peers
345+
const peerOrgs = configExtended.orgs.filter(o => o.peers && o.peers.length > 0);
346+
for (const org of peerOrgs) {
347+
const orgName = org.name.toLowerCase();
348+
349+
const committerTemplates = ["sidecar", "coordinator", "validator", "verifier", "query-service"];
350+
for (const tpl of committerTemplates) {
351+
const templatePath = getTemplatePath(this.templatesDir, `fabric-x/config/${tpl}.yaml.ejs`);
352+
const destPath = getDestinationPath(this.outputDir, `fabric-x/config/${orgName}-${tpl}.yaml`);
353+
await renderTemplate(templatePath, destPath, { org, configExtended });
354+
}
332355
}
333356
}
334357
}

src/setup-docker/templates/fabric-x/Makefile.ejs

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ COMPOSE_OVERRIDE ?=
1919

2020
# Namespace init defaults
2121
NS ?= mynamespace
22-
POLICY ?= AND('Org1MSP.member','Org2MSP.member')
22+
POLICY ?= AND(<%- orgs.filter(o => o.peers && o.peers.length > 0).length > 0 ? orgs.filter(o => o.peers && o.peers.length > 0).map(o => `'${o.name}MSP.member'`).join(',') : `'Orderer${orgs.find(o => o.ordererGroups && o.ordererGroups.length > 0).name}MSP.member'` %>)
2323
NETWORK ?= fabric-x
2424

2525
# Init targets
2626
.PHONY: init
2727
init:
28-
@rm -rf $(FABRICX_DIR)/crypto
28+
@$(DOCKER) run --rm -v "$(FABRICX_DIR):/config" alpine sh -c 'rm -rf /config/crypto'
2929
@# Routers and assemblers accept client certs from any peer org — concatenate all peer TLS CAs.
3030
@$(DOCKER) run --rm \
3131
$(RUN_AS) \
3232
-v "$(FABRICX_DIR):/config" \
3333
$(TOOLS_IMAGE) \
34-
sh -c 'cryptogen generate --config=/config/crypto-config.yaml --output=/config/crypto \
35-
&& cat /config/crypto/peerOrganizations/org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem \
36-
> /config/crypto/client-tls-ca.pem 2>/dev/null || true'
34+
sh -c 'cryptogen generate --config=/config/crypto-config.yaml --output=/config/crypto || true'
35+
@$(DOCKER) run --rm \
36+
$(RUN_AS) \
37+
-v "$(FABRICX_DIR):/config" \
38+
alpine \
39+
sh -c 'find /config/crypto -name "*tlsca*-cert.pem" -exec cat {} + > /config/crypto/client-tls-ca.pem'
3740
@$(DOCKER) run --rm \
3841
$(RUN_AS) \
3942
-v "$(FABRICX_DIR):/config" \
@@ -53,37 +56,51 @@ init:
5356

5457
.PHONY: clean
5558
clean:
56-
@rm -rf $(FABRICX_DIR)/crypto
59+
@$(DOCKER) run --rm -v "$(FABRICX_DIR):/config" alpine sh -c 'rm -rf /config/crypto /config/data'
5760

58-
59-
# Dev mode (all-in-one test committer, includes built-in orderer)
60-
.PHONY: start-dev
61-
start-dev:
61+
# Distributed mode
62+
.PHONY: start
63+
start:
6264
@if [ ! -d "$(FABRICX_DIR)/crypto" ]; then echo "Error: crypto directory not found — run 'make init' first."; exit 1; fi
6365
@if nc -z localhost 7050 2>/dev/null; then echo "Error: port 7050 is already in use."; exit 1; fi
66+
@mkdir -p \
67+
<% orgs.filter(o => o.ordererGroups && o.ordererGroups.length > 0).forEach((org, index) => { %> $(FABRICX_DIR)/data/orderers/party<%= index + 1 %>-router \
68+
$(FABRICX_DIR)/data/orderers/party<%= index + 1 %>-batcher \
69+
$(FABRICX_DIR)/data/orderers/party<%= index + 1 %>-consenter \
70+
$(FABRICX_DIR)/data/orderers/party<%= index + 1 %>-assembler \
71+
<% }) %><% orgs.filter(o => o.peers && o.peers.length > 0).forEach((org) => { %> $(FABRICX_DIR)/data/committer-<%= org.name.toLowerCase() %>/db \
72+
$(FABRICX_DIR)/data/committer-<%= org.name.toLowerCase() %>/ledger \
73+
<% }) %> $(FABRICX_DIR)/data/dummy
6474
@$(COMPOSE) -f $(FABRICX_DIR)/compose.test-committer.yaml up -d
65-
@echo "Waiting for test committer to be ready..."
66-
@while ! nc -z localhost 7001 2>/dev/null; do sleep 1; done
75+
<% if (orgs.filter(o => o.peers && o.peers.length > 0).length > 0) { -%>
76+
@echo "Waiting for sidecars to be ready..."
77+
@while ! nc -z localhost 4001 2>/dev/null; do sleep 1; done
78+
<% } -%>
6779

68-
.PHONY: stop-dev
69-
stop-dev:
80+
.PHONY: stop
81+
stop:
7082
@$(COMPOSE) -f $(FABRICX_DIR)/compose.test-committer.yaml down
7183

72-
.PHONY: purge-dev
73-
purge-dev:
74-
@$(COMPOSE) -f $(FABRICX_DIR)/compose.test-committer.yaml down -v
84+
.PHONY: purge
85+
purge:
86+
@$(COMPOSE) -f $(FABRICX_DIR)/compose.test-committer.yaml down -v --remove-orphans
87+
@$(DOCKER) run --rm -v "$(FABRICX_DIR):/config" alpine sh -c 'rm -rf /config/crypto /config/data'
7588

89+
<%
90+
const firstPeerOrg = orgs.find(o => o.peers && o.peers.length > 0) || { name: 'dummy', domain: 'dummy.com' };
91+
const firstOrdererOrg = orgs.find(o => o.ordererGroups && o.ordererGroups.length > 0) || { name: 'dummy', domain: 'dummy.com' };
92+
%>
7693
# Namespace init
7794
define run-fxconfig
7895
@$(DOCKER) run --rm --network $(NETWORK) \
7996
$(RUN_AS) \
8097
--env "FX_NS=$(NS)" \
8198
--env "FX_POLICY=$(POLICY)" \
8299
-v "$(FABRICX_DIR)/fxconfig.yaml:/config/fxconfig.yaml:ro,Z" \
83-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/peers/fxconfig.org1.example.com/tls:/tls:ro,Z" \
84-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp:/msp:ro,Z" \
85-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem:/org-tls-ca.pem:ro,Z" \
86-
-v "$(FABRICX_DIR)/crypto/ordererOrganizations/orderer-org-1/msp/tlscacerts/tlsca.orderer-org-1-cert.pem:/orderer-tls-ca.pem:ro,Z" \
100+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/peers/fxconfig.<%= firstPeerOrg.domain %>/tls:/tls:ro,Z" \
101+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/users/User1@<%= firstPeerOrg.domain %>/msp:/msp:ro,Z" \
102+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/msp/tlscacerts/tlsca.<%= firstPeerOrg.domain %>-cert.pem:/org-tls-ca.pem:ro,Z" \
103+
-v "$(FABRICX_DIR)/crypto/ordererOrganizations/<%= firstOrdererOrg.name %>/msp/tlscacerts/tlsca.<%= firstOrdererOrg.domain %>-cert.pem:/orderer-tls-ca.pem:ro,Z" \
87104
$(TOOLS_IMAGE) \
88105
sh -c 'fxconfig namespace list --config=/config/fxconfig.yaml 2>/dev/null | grep -q ") $$FX_NS:" || \
89106
fxconfig namespace create "$$FX_NS" --policy="$$FX_POLICY" --endorse --submit --wait --config=/config/fxconfig.yaml'
@@ -94,30 +111,20 @@ list-namespaces:
94111
@$(DOCKER) run --rm --network $(NETWORK) \
95112
$(RUN_AS) \
96113
-v "$(FABRICX_DIR)/fxconfig.yaml:/config/fxconfig.yaml:ro,Z" \
97-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/peers/fxconfig.org1.example.com/tls:/tls:ro,Z" \
98-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp:/msp:ro,Z" \
99-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem:/org-tls-ca.pem:ro,Z" \
100-
-v "$(FABRICX_DIR)/crypto/ordererOrganizations/orderer-org-1/msp/tlscacerts/tlsca.orderer-org-1-cert.pem:/orderer-tls-ca.pem:ro,Z" \
114+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/peers/fxconfig.<%= firstPeerOrg.domain %>/tls:/tls:ro,Z" \
115+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/users/User1@<%= firstPeerOrg.domain %>/msp:/msp:ro,Z" \
116+
-v "$(FABRICX_DIR)/crypto/peerOrganizations/<%= firstPeerOrg.domain %>/msp/tlscacerts/tlsca.<%= firstPeerOrg.domain %>-cert.pem:/org-tls-ca.pem:ro,Z" \
117+
-v "$(FABRICX_DIR)/crypto/ordererOrganizations/<%= firstOrdererOrg.name %>/msp/tlscacerts/tlsca.<%= firstOrdererOrg.domain %>-cert.pem:/orderer-tls-ca.pem:ro,Z" \
101118
$(TOOLS_IMAGE) \
102119
fxconfig namespace list --config=/config/fxconfig.yaml
103120

104-
.PHONY: init-namespace-org1
105-
init-namespace-org1: POLICY = AND('Org1MSP.member')
106-
init-namespace-org1:
107-
$(run-fxconfig)
108-
109-
.PHONY: init-namespace
110-
init-namespace:
121+
<% channels.forEach((channel) => { %>
122+
.PHONY: init-namespace-<%= channel.name %>
123+
init-namespace-<%= channel.name %>: NS = <%= channel.name %>
124+
init-namespace-<%= channel.name %>: POLICY = AND(<%- channel.orgs.map(o => `'${o.name}MSP.member'`).join(',') %>)
125+
init-namespace-<%= channel.name %>:
111126
$(run-fxconfig)
127+
<% }) %>
112128

113-
.PHONY: transaction-submit
114-
transaction-submit:
115-
@$(DOCKER) run --rm --network $(NETWORK) \
116-
$(RUN_AS) \
117-
-v "$(FABRICX_DIR)/fxconfig.yaml:/config/fxconfig.yaml:ro,Z" \
118-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/peers/fxconfig.org1.example.com/tls:/tls:ro,Z" \
119-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp:/msp:ro,Z" \
120-
-v "$(FABRICX_DIR)/crypto/peerOrganizations/org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem:/org-tls-ca.pem:ro,Z" \
121-
-v "$(FABRICX_DIR)/crypto/ordererOrganizations/orderer-org-1/msp/tlscacerts/tlsca.orderer-org-1-cert.pem:/orderer-tls-ca.pem:ro,Z" \
122-
$(TOOLS_IMAGE) \
123-
fxconfig transaction submit --config=/config/fxconfig.yaml --namespace $(NS) --payload "Hello Fabric-X!"
129+
.PHONY: init-namespaces
130+
init-namespaces: <% channels.forEach((channel) => { %>init-namespace-<%= channel.name %> <% }) %>

0 commit comments

Comments
 (0)