Skip to content

Commit 66fc4d5

Browse files
authored
Merge pull request #333 from dzikowski/dev-mode
Dev mode support for chaincodes
2 parents 7c7eb61 + 45d7d99 commit 66fc4d5

File tree

37 files changed

+1881
-520
lines changed

37 files changed

+1881
-520
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Attach `fabric-ca-server-config.yaml` as a volume [#168](https://github.com/hyperledger-labs/fablo/issues/168)
77
* Support tls for CA [#229](https://github.com/hyperledger-labs/fablo/issues/229)
88
* Use nvm to switch node version for chaincode build
9+
* Allow to run peers in dev mode [#126](https://github.com/hyperledger-labs/fablo/issues/126)
10+
* Allow to install each chaincode manually
911

1012
### Fixes
1113
* Support Apple M1 / arm64 architecture

README.md

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,22 @@ In this case, however, you should use generated `fablo-docker.sh` instead of `fa
7070
### init
7171

7272
```bash
73-
fablo init [node]
73+
fablo init [node] [rest] [dev]
7474
```
7575

7676
Creates simple network config file in current dir.
7777
Good step to start your adventure with Fablo or set up a fast prototype.
7878

79-
Option `node` makes Fablo to generate a sample Node.js chaincode as well.
79+
Fablo `init` command takes three parameters (the order does not matter):
80+
* Option `node` makes Fablo to generate a sample Node.js chaincode as well.
81+
* Option `rest` enables simple REST API with [Fablo REST](https://github.com/softwaremill/fablo-rest) as standalone Docker container.
82+
* Option `dev` enables running peers in dev mode (so the hot reload for chaincode is possible).
83+
84+
Sample command:
85+
86+
```bash
87+
fablo init node dev
88+
```
8089

8190
Generated `fablo-config.json` file uses single node Solo consensus and no TLS support.
8291
This is the simplest way to start with Hyperledger Fabric, since Raft consensus requires TLS and TLS itself adds a lot of complexity to the blockchain network and integration with it.
@@ -178,16 +187,69 @@ If you want to use Fablo for network configuration setup only, then the `fabric-
178187
179188
## Managing chaincodes
180189
190+
### chaincode(s) install
191+
192+
```bash
193+
fablo chaincodes install
194+
```
195+
Install all chaincodes. Might be useful if for some reason, Fablo won't manage to do it by itself.
196+
197+
If you want to install a single chaincode defined in Fablo config file, execute:
198+
199+
```bash
200+
fablo chaincode install <chaincode-name> <version>
201+
```
202+
181203
### chaincode upgrade
182204
183205
```bash
184-
fablo chaincode upgrade chaincode-name version
206+
fablo chaincode upgrade <chaincode-name> <version>
185207
```
186208
187-
Upgrades and instantiates chaincode with given name on all relevant peers.
209+
Upgrades chaincode with given name on all relevant peers.
188210
Chaincode directory is specified in Fablo config file.
189211
190-
## Chaincode scripts
212+
### Running chaincodes in dev mode
213+
214+
Hyperledger Fabric allows to run peers in [dev mode](https://hyperledger-fabric.readthedocs.io/en/release-2.4/peer-chaincode-devmode.html) in order to allow simple develop of chaincodes.
215+
In this case chaincodes do not need to be upgraded each time, but they are run locally.
216+
This feature allows hot reload of chaincode code and speeds up the development a lot.
217+
218+
Fablo will run peers in dev mode when `global.peerDevMode` is set to `true`.
219+
Note: in this case TLS has to be disabled, otherwise config validation fails.
220+
221+
The simplest way of trying Fablo with dev mode is as follows:
222+
223+
1. Execute `fablo init node dev`.
224+
It will initialize Fablo config file with sample node chaincode and dev mode enabled.
225+
In this case Fablo config file has `global.peerDevMode` set to `true`, and the `package.json` file for sample Node.js chaincode has a script for running chaincode in dev mode (`start:dev`).
226+
2. Start the network with `fablo up`.
227+
Because dev mode is enabled, chaincode containers don't start.
228+
Instead, Fablo approves and commits chaincode definitions from Fablo config file.
229+
3. Npm install and start the sample chaincode with:
230+
```bash
231+
(cd chaincodes/chaincode-kv-node && nvm use && npm i && npm run start:watch)
232+
```
233+
Now, when you update the chaincode source code, it will be automatically refreshed on Hyperledger Fabric Network.
234+
235+
Our sample chaincode definition contains some scripts for running chaincode in dev mode:
236+
237+
```json
238+
"scripts": {
239+
...
240+
"start:dev": "fabric-chaincode-node start --peer.address \"127.0.0.1:8541\" --chaincode-id-name \"chaincode1:0.0.1\" --tls.enabled false",
241+
"start:watch": "nodemon --exec \"npm run start:dev\"",
242+
...
243+
},
244+
```
245+
246+
Worth considering:
247+
* If you want chaincode to be running on multiple peers, you need to start it multiple times, specifying different `--peer.address`
248+
* In case of errors ensure you have the same `--chaincode-id-name` as `CC_PACKAGE_ID` in Fablo output.
249+
250+
Feel free to update this scripts to adjust it to your chaincode definition.
251+
252+
## Channel scripts
191253
192254
### channel help
193255
@@ -279,6 +341,7 @@ Example:
279341
"global": {
280342
"fabricVersion": "2.3.0",
281343
"tls": false,
344+
"peerDevMode": false,
282345
"monitoring": {
283346
"loglevel": "debug"
284347
},

docs/sample.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
2-
"$schema": "https://github.com/softwaremill/fablo/releases/download/1.0.3-unstable/schema.json",
2+
"$schema": "https://github.com/softwaremill/fablo/releases/download/1.1.0-unstable/schema.json",
33
"global": {
44
"fabricVersion": "2.3.2",
5-
"tls": false
5+
"tls": false,
6+
"peerDevMode": false
67
},
78
"orgs": [
89
{

docs/schema.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
],
1313
"properties": {
1414
"$schema": {
15-
"const": "https://github.com/softwaremill/fablo/releases/download/1.0.3-unstable/schema.json"
15+
"const": "https://github.com/softwaremill/fablo/releases/download/1.1.0-unstable/schema.json"
1616
},
1717
"global": {
1818
"$id": "#/properties/global",
@@ -68,6 +68,12 @@
6868
"type": "boolean",
6969
"default": true
7070
},
71+
"peerDevMode": {
72+
"$id": "#/properties/global/properties/peerDevMode",
73+
"title": "Start all peers in dev mode",
74+
"type": "boolean",
75+
"default": false
76+
},
7177
"monitoring": {
7278
"$id": "#/properties/monitoring",
7379
"title": "Monitoring settings",

e2e/__snapshots__/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json.test.ts.snap

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,10 +2052,14 @@ elif [ \\"$1\\" = \\"start\\" ]; then
20522052
startNetwork
20532053
elif [ \\"$1\\" = \\"stop\\" ]; then
20542054
stopNetwork
2055-
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
2055+
elif [ \\"$1\\" = \\"chaincodes\\" ] && [ \\"$2\\" = \\"install\\" ]; then
20562056
installChaincodes
2057+
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
2058+
installChaincode \\"$3\\" \\"$4\\"
20572059
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"upgrade\\" ]; then
20582060
upgradeChaincode \\"$3\\" \\"$4\\"
2061+
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"dev\\" ]; then
2062+
runDevModeChaincode \\"$3\\" \\"$4\\"
20592063
elif [ \\"$1\\" = \\"channel\\" ]; then
20602064
channelQuery \\"\${@:2}\\"
20612065
elif [ \\"$1\\" = \\"snapshot\\" ]; then
@@ -2077,7 +2081,7 @@ fi
20772081
`;
20782082
20792083
exports[`samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json should create proper e2e/__tmp__/samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json.tmpdir/fablo-target/fabric-docker/.env from samples/fablo-config-hlf1.3-2orgs-1chaincode-private-data.json 1`] = `
2080-
"FABLO_VERSION=1.0.3-unstable
2084+
"FABLO_VERSION=1.1.0-unstable
20812085
FABLO_BUILD=<date with git hash>
20822086
FABLO_REST_VERSION=0.1.0
20832087
HYPERLEDGER_EXPLORER_VERSION=1.1.8
@@ -2316,18 +2320,41 @@ installChaincodes() {
23162320
23172321
}
23182322
2319-
notifyOrgsAboutChannels() {
2320-
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
2321-
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
2322-
createNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
2323+
installChaincode() {
2324+
local chaincodeName=\\"$1\\"
2325+
if [ -z \\"$chaincodeName\\" ]; then
2326+
echo \\"Error: chaincode name is not provided\\"
2327+
exit 1
2328+
fi
23232329
2324-
printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
2325-
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
2326-
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\" \\"peer0.org2.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
2330+
local version=\\"$2\\"
2331+
if [ -z \\"$version\\" ]; then
2332+
echo \\"Error: chaincode version is not provided\\"
2333+
exit 1
2334+
fi
23272335
2328-
printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
2329-
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
2330-
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\"
2336+
if [ \\"$chaincodeName\\" = \\"chaincode1\\" ]; then
2337+
if [ -n \\"$(ls \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\")\\" ]; then
2338+
chaincodeBuild \\"chaincode1\\" \\"node\\" \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\" \\"12\\"
2339+
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer0\\" \\"U1F60E\\"
2340+
chaincodeInstall \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
2341+
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer1\\" \\"U1F60E\\"
2342+
chaincodeInstall \\"cli.org1.example.com\\" \\"peer1.org1.example.com:7042\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
2343+
printHeadline \\"Installing 'chaincode1' on my-channel1/Org2/peer0\\" \\"U1F60E\\"
2344+
chaincodeInstall \\"cli.org2.example.com\\" \\"peer0.org2.example.com:7061\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"\\"
2345+
printItalics \\"Instantiating chaincode 'chaincode1' on channel 'my-channel1' as 'Org1'\\" \\"U1F618\\"
2346+
chaincodeInstantiate \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" '{\\"Args\\":[]}' \\"OR('Org1MSP.member', 'Org2MSP.member')\\" \\"\\" \\"collections/chaincode1.json\\"
2347+
2348+
else
2349+
echo \\"Warning! Skipping chaincode 'chaincode1' install. Chaincode directory is empty.\\"
2350+
echo \\"Looked in dir: '$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4'\\"
2351+
fi
2352+
fi
2353+
}
2354+
2355+
runDevModeChaincode() {
2356+
echo \\"Running chaincode in dev mode is supported by Fablo only for V2 channel capabilities\\"
2357+
exit 1
23312358
}
23322359
23332360
upgradeChaincode() {
@@ -2365,6 +2392,20 @@ upgradeChaincode() {
23652392
fi
23662393
}
23672394
2395+
notifyOrgsAboutChannels() {
2396+
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
2397+
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
2398+
createNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
2399+
2400+
printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
2401+
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
2402+
notifyOrgAboutNewChannel \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\" \\"peer0.org2.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\"
2403+
2404+
printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
2405+
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
2406+
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org2MSP\\" \\"cli.org2.example.com\\"
2407+
}
2408+
23682409
stopNetwork() {
23692410
printHeadline \\"Stopping network\\" \\"U1F68F\\"
23702411
(cd \\"$FABLO_NETWORK_ROOT\\"/fabric-docker && docker-compose stop)

e2e/__snapshots__/fablo-config-hlf1.4-1org-1chaincode-raft.json.test.ts.snap

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,10 +1463,14 @@ elif [ \\"$1\\" = \\"start\\" ]; then
14631463
startNetwork
14641464
elif [ \\"$1\\" = \\"stop\\" ]; then
14651465
stopNetwork
1466-
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
1466+
elif [ \\"$1\\" = \\"chaincodes\\" ] && [ \\"$2\\" = \\"install\\" ]; then
14671467
installChaincodes
1468+
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"install\\" ]; then
1469+
installChaincode \\"$3\\" \\"$4\\"
14681470
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"upgrade\\" ]; then
14691471
upgradeChaincode \\"$3\\" \\"$4\\"
1472+
elif [ \\"$1\\" = \\"chaincode\\" ] && [ \\"$2\\" = \\"dev\\" ]; then
1473+
runDevModeChaincode \\"$3\\" \\"$4\\"
14701474
elif [ \\"$1\\" = \\"channel\\" ]; then
14711475
channelQuery \\"\${@:2}\\"
14721476
elif [ \\"$1\\" = \\"snapshot\\" ]; then
@@ -1488,7 +1492,7 @@ fi
14881492
`;
14891493
14901494
exports[`samples/fablo-config-hlf1.4-1org-1chaincode-raft.json should create proper e2e/__tmp__/samples/fablo-config-hlf1.4-1org-1chaincode-raft.json.tmpdir/fablo-target/fabric-docker/.env from samples/fablo-config-hlf1.4-1org-1chaincode-raft.json 1`] = `
1491-
"FABLO_VERSION=1.0.3-unstable
1495+
"FABLO_VERSION=1.1.0-unstable
14921496
FABLO_BUILD=<date with git hash>
14931497
FABLO_REST_VERSION=0.1.0
14941498
HYPERLEDGER_EXPLORER_VERSION=1.1.8
@@ -1680,15 +1684,39 @@ installChaincodes() {
16801684
16811685
}
16821686
1683-
notifyOrgsAboutChannels() {
1684-
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
1685-
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
1687+
installChaincode() {
1688+
local chaincodeName=\\"$1\\"
1689+
if [ -z \\"$chaincodeName\\" ]; then
1690+
echo \\"Error: chaincode name is not provided\\"
1691+
exit 1
1692+
fi
16861693
1687-
printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
1688-
notifyOrgAboutNewChannelTls \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
1694+
local version=\\"$2\\"
1695+
if [ -z \\"$version\\" ]; then
1696+
echo \\"Error: chaincode version is not provided\\"
1697+
exit 1
1698+
fi
16891699
1690-
printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
1691-
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
1700+
if [ \\"$chaincodeName\\" = \\"chaincode1\\" ]; then
1701+
if [ -n \\"$(ls \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\")\\" ]; then
1702+
chaincodeBuild \\"chaincode1\\" \\"node\\" \\"$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4\\" \\"12\\"
1703+
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer0\\" \\"U1F60E\\"
1704+
chaincodeInstall \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
1705+
printHeadline \\"Installing 'chaincode1' on my-channel1/Org1/peer1\\" \\"U1F60E\\"
1706+
chaincodeInstall \\"cli.org1.example.com\\" \\"peer1.org1.example.com:7042\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
1707+
printItalics \\"Instantiating chaincode 'chaincode1' on channel 'my-channel1' as 'Org1'\\" \\"U1F618\\"
1708+
chaincodeInstantiate \\"cli.org1.example.com\\" \\"peer0.org1.example.com:7041\\" \\"my-channel1\\" \\"chaincode1\\" \\"0.0.1\\" \\"node\\" \\"orderer0.group1.orderer.example.com:7030\\" '{\\"Args\\":[]}' \\"AND ('Org1MSP.member')\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\" \\"\\"
1709+
1710+
else
1711+
echo \\"Warning! Skipping chaincode 'chaincode1' install. Chaincode directory is empty.\\"
1712+
echo \\"Looked in dir: '$CHAINCODES_BASE_DIR/./chaincodes/chaincode-kv-node-1.4'\\"
1713+
fi
1714+
fi
1715+
}
1716+
1717+
runDevModeChaincode() {
1718+
echo \\"Running chaincode in dev mode is supported by Fablo only for V2 channel capabilities\\"
1719+
exit 1
16921720
}
16931721
16941722
upgradeChaincode() {
@@ -1723,6 +1751,17 @@ upgradeChaincode() {
17231751
fi
17241752
}
17251753
1754+
notifyOrgsAboutChannels() {
1755+
printHeadline \\"Creating new channel config blocks\\" \\"U1F537\\"
1756+
createNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"MyChannel1\\" \\"$FABLO_NETWORK_ROOT/fabric-config\\" \\"$FABLO_NETWORK_ROOT/fabric-config/config\\"
1757+
1758+
printHeadline \\"Notyfing orgs about channels\\" \\"U1F4E2\\"
1759+
notifyOrgAboutNewChannelTls \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\" \\"peer0.org1.example.com\\" \\"orderer0.group1.orderer.example.com:7030\\" \\"crypto-orderer/tlsca.orderer.example.com-cert.pem\\"
1760+
1761+
printHeadline \\"Deleting new channel config blocks\\" \\"U1F52A\\"
1762+
deleteNewChannelUpdateTx \\"my-channel1\\" \\"Org1MSP\\" \\"cli.org1.example.com\\"
1763+
}
1764+
17261765
stopNetwork() {
17271766
printHeadline \\"Stopping network\\" \\"U1F68F\\"
17281767
(cd \\"$FABLO_NETWORK_ROOT\\"/fabric-docker && docker-compose stop)

0 commit comments

Comments
 (0)