github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/examples/configtxupdate/README.md (about) 1 # Reconfiguring with configtxlator 2 3 ## Overview 4 5 The `configtxlator` tool was created to support reconfiguration independent of SDKs. Channel configuration is stored as a transaction in configuration blocks of a channel and may be manipulated directly, such as in the bdd behave tests. However, at the time of this writing, no SDK natively supports manipulating the configuration directly, so the `configtxlator` tool is designed to provide an API which consumers of any SDK may interact with to assist with configuration updates. 6 7 The tool name is a portmanteau of *configtx* and *translator* and is intended to convey that the tool simply converts between different equivalent data representations. It does not generate configuration, it does not submit or retrieve configuration, it does not modify configuration itself, it simply provides some bijective operations between different views of the configtx format. 8 9 The standard usage is expected to be: 10 1. SDK retrieves latest config 11 2. `configtxlator` produces human readable version of config 12 3. User or application edits the config 13 4. `configtxlator` used to compute config update representation of changes to the config 14 5. SDK submits signs and submits config 15 16 The `configtxlator` tool exposes a truly stateless REST API for interacting with configuration elements. These REST components support converting the native configuration format to/from a human readable JSON representation, as well as computing computing configuration updates based on the difference between two configurations. 17 18 Because the `configtxlator` service deliberately does not contain any crypto material, or otherwise secret information, it does not include any authorization or access control. The anticipated typical deployment would be to operate as a sandboxed container, locally with the application, so that there is a dedicated configtxlator process for each consumer of it. 19 20 ## Buliding and running the configtxlator 21 22 The `configtxlator` binary may be produced by executing `make configtxlator`. 23 24 To execute the `configtxlator` simply execute the binary, optionally with the `-serverPort` option to specify a listen port, or accept the default listen port, `7059`. 25 26 The binary will start an http server listening on the designated port and is now ready to process requests. 27 28 ## Proto translation 29 30 For extensibility, and because certain fields must be signed over, many proto fields are stored as bytes. This makes the natural proto to JSON translation using the `jsonpb` package ineffective for producing a human readable version of the protobufs. Instead, the `configtxlator` exposes a REST component to do a more sophisticated translation. 31 32 To convert a proto to its human readable JSON equivalent, simply post the binary proto to the rest target `http://$SERVER:$PORT/protolator/decode/<message.Name>` where `<message.Name>` is the fully qualified proto name of the message. 33 34 For instance, to decode a configuration block saved as `configuration_block.pb`, run the command: 35 36 ``` 37 curl -X POST --data-binary @configuration_block.pb http://127.0.0.1:7059/protolator/decode/common.Block 38 ``` 39 40 To convert the human readable JSON version of the proto message, simply post the JSON version to `http://$SERVER:$PORT/protolator/encode/<message.Name` where `<message.Name>` is again the fully qualified proto name of the message. 41 42 For instance, re-encode the block saved as `configuration_block.json`, run the command: 43 44 ``` 45 curl -X POST --data-binary @configuration_block.json http://127.0.0.1:7059/protolator/encode/common.Block 46 ``` 47 48 Any of the configuration related protos, including `common.Block`, `common.Envelope`, `common.ConfigEnvelope`, `common.ConfigUpdateEnvelope`, `common.Configuration`, and `common.ConfigUpdate` are valid targets for these URLs. In the future, other proto decoding types may be added, such as for endorser transactions. 49 50 ## Config update computation 51 52 Given two different configurations, it is possible to compute the config update which transitions between them. Simply POST the two `common.Config` proto encoded configurations as `multipart/formdata`, with the original as field `original` and the updated as field `updated`, to `http://$SERVER:$PORT/configtxlator/compute/update-from-configs`. 53 54 For example, given the original config as the file `original_config.pb` and the updated config as the file `updated_config.pb` for the channel `desiredchannel`: 55 56 ``` 57 curl -X POST -F channel=desiredchannel -F original=@original_config.pb -F updated=@updated_config.pb http://127.0.0.1:7059/configtxlator/compute/update-from-configs 58 ``` 59 60 ## Bootstraping example 61 62 First build and start the `configtxlator`. 63 64 ``` 65 $ make configtxlator 66 build/bin/configtxlator 67 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-42434e60f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/common/tools/configtxlator 68 Binary available as build/bin/configtxlator 69 ``` 70 ``` 71 $ configtxlator start 72 2017-05-31 12:57:22.499 EDT [configtxlator] main -> INFO 001 Serving HTTP requests on port: 7059 73 ``` 74 75 Then, in another window, build the `configtxgen` tool. 76 77 ``` 78 $ make configtxgen 79 build/bin/configtxgen 80 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "nopkcs11" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/common/configtx/tool/configtxgen 81 Binary available as build/bin/configtxgen 82 ``` 83 84 It is recommended to run the example by invoking the script `fabric/example/configtxupdate/bootstrap_batchsize/script.sh` as follows: 85 86 ``` 87 INTERACTIVE=true ./script.sh 88 ``` 89 90 This will write out what is happening at each step, pause, and allow you to inspect the artifacts generated before proceeding. Alternatively, you may run the steps below manually. 91 92 ---- 93 First produce a genesis block for the ordering system channel. 94 95 ``` 96 $ configtxgen -outputBlock genesis_block.pb 97 2017-05-31 14:15:16.634 EDT [common/configtx/tool] main -> INFO 001 Loading configuration 98 2017-05-31 14:15:16.646 EDT [common/configtx/tool] doOutputBlock -> INFO 002 Generating genesis block 99 2017-05-31 14:15:16.646 EDT [common/configtx/tool] doOutputBlock -> INFO 003 Writing genesis block 100 ``` 101 Decode the genesis block into a human editable form. 102 ``` 103 curl -X POST --data-binary @genesis_block.pb http://127.0.0.1:7059/protolator/decode/common.Block > genesis_block.json 104 ``` 105 Edit the `genesis_block.json` file in your favorite JSON editor, or manipulate it programatically, here, we use the JSON CLI tool `jq`. For simplicity, we are editing the batch size for the channel, because it is a single numeric field, but any edits, including policy and MSP edits may be made here. 106 ``` 107 $ export MAXBATCHSIZEPATH=".data.data[0].payload.data.config.channel_group.groups.Orderer.values.BatchSize.value.max_message_count" 108 # Display the old batch size 109 $ jq "$MAXBATCHSIZEPATH" genesis_block.json 110 10 111 112 # Set the new batch size 113 $ jq "$MAXBATCHSIZEPATH = 20" genesis_block.json > updated_genesis_block.json 114 115 # Display the new batch size 116 $ jq "$MAXBATCHSIZEPATH" updated_genesis_block.json 117 20 118 ``` 119 The genesis block is now ready to be re-encoded into the native proto form to be used for bootstrapping. 120 ``` 121 curl -X POST --data-binary @updated_genesis_block.json http://127.0.0.1:7059/protolator/encode/common.Block > updated_genesis_block.pb 122 ``` 123 The `updated_genesis_block.pb` file may now be used as the genesis block for bootstrapping an ordering system channel. 124 125 ## Reconfiguration example 126 127 First build and start the `configtxlator`. 128 129 ``` 130 $ make configtxlator 131 build/bin/configtxlator 132 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-42434e60f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/common/tools/configtxlator 133 Binary available as build/bin/configtxlator 134 ``` 135 ``` 136 $ configtxlator start 137 2017-05-31 12:57:22.499 EDT [configtxlator] main -> INFO 001 Serving HTTP requests on port: 7059 138 ``` 139 140 Then, in another window, build the orderer and peer. 141 142 ``` 143 $ make peer 144 Installing chaintool 145 curl -L https://github.com/hyperledger/fabric-chaintool/releases/download/v0.10.3/chaintool > build/bin/chaintool 146 ... 147 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/peer 148 Binary available as build/bin/peer 149 150 $ make orderer 151 build/bin/orderer 152 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/orderer 153 Binary available as build/bin/orderer 154 ``` 155 Start the orderer using the default options, including the provisional bootstrapper which will create a `testchainid` ordering system channel. 156 157 ``` 158 ORDERER_GENERAL_LOGLEVEL=debug orderer 159 ``` 160 161 Reconfiguring a channel can be performed in a very similar way to modifying a genesis config. 162 163 The recommended path to proceed with this example is to run the script located at `fabric/example/configtxupdate/reconfigure_batchsize/script.sh` by invoking 164 165 ``` 166 INTERACTIVE=true ./script.sh 167 ``` 168 169 This will write out what is happening at each step, pause, and allow you to inspect the artifacts generated before proceeding. Alternatively, you may run the steps below manually. 170 171 ---- 172 173 At this point, executing `examples/reconfig/script.sh` in another window will increase the batch size of the ordering system channel by 1, or, you may follow the steps below to do the process interactively. 174 175 ``` 176 $ peer channel fetch config config_block.pb -o 127.0.0.1:7050 -c testchainid 177 2017-05-31 15:11:37.617 EDT [msp] getMspConfig -> INFO 001 intermediate certs folder not found at [/home/yellickj/go/src/github.com/hyperledger/fabric/sampleconfig/msp/intermediatecerts]. Skipping.: [stat /home/yellickj/go/src/github.com/hyperledger/fabric/sampleconfig/msp/intermediatecerts: no such file or directory] 178 2017-05-31 15:11:37.617 EDT [msp] getMspConfig -> INFO 002 crls folder not found at [/home/yellickj/go/src/github.com/hyperledger/fabric/sampleconfig/msp/intermediatecerts]. Skipping.: [stat /home/yellickj/go/src/github.com/hyperledger/fabric/sampleconfig/msp/crls: no such file or directory] 179 Received block: 1 180 Received block: 1 181 2017-05-31 15:11:37.635 EDT [main] main -> INFO 003 Exiting..... 182 ``` 183 184 Send the config block to the `configtxlator` service for decoding: 185 186 ``` 187 curl -X POST --data-binary @config_block.pb http://127.0.0.1:7059/protolator/decode/common.Block > config_block.json 188 ``` 189 190 Extract the config section from the block: 191 192 ``` 193 jq .data.data[0].payload.data.config config_block.json > config.json 194 ``` 195 196 Edit the config, saving it as a new `updated_config.json`. Here, we set the batch size to 30. 197 198 ``` 199 jq ".channel_group.groups.Orderer.values.BatchSize.value.max_message_count = 30" config.json > updated_config.json 200 ``` 201 202 Re-encode both the original config, and the updated config into proto. 203 204 ``` 205 curl -X POST --data-binary @config.json http://127.0.0.1:7059/protolator/encode/common.Config > config.pb 206 ``` 207 208 ``` 209 curl -X POST --data-binary @updated_config.json http://127.0.0.1:7059/protolator/encode/common.Config > updated_config.pb 210 ``` 211 212 Now, with both configs properly encoded, send them to the `configtxlator` service to compute the config update which transitions between the two. 213 214 ``` 215 curl -X POST -F original=@config.pb -F updated=@updated_config.pb http://127.0.0.1:7059/configtxlator/compute/update-from-configs -F channel=testchainid > config_update.pb 216 ``` 217 218 At this point, the computed config update is now prepared, and traditionally, an SDK would be used to sign and wrap this message, but in the interest of using only the peer cli, the `configtxlator` can also be used for this task. 219 220 First, we decode the ConfigUpdate so that we may work with it as text. 221 222 ``` 223 $ curl -X POST --data-binary @config_update.pb http://127.0.0.1:7059/protolator/decode/common.ConfigUpdate > config_update.json 224 ``` 225 226 Then, we wrap it in an envelope message. 227 228 ``` 229 echo '{"payload":{"header":{"channel_header":{"channel_id":"testchainid", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' > config_update_as_envelope.json 230 ``` 231 232 And finally, convert it back into the proto form of a full fledged config transaction. 233 234 ``` 235 curl -X POST --data-binary @config_update_as_envelope.json http://127.0.0.1:7059/protolator/encode/common.Envelope > config_update_as_envelope.pb 236 ``` 237 238 Finally, submit the config update transaction to ordering to perform a config update. 239 240 ``` 241 peer channel update -f config_update_as_envelope.pb -c testchainid -o 127.0.0.1:7050 242 ``` 243 244 ## Adding an organization 245 246 First build and start the `configtxlator`. 247 248 ``` 249 $ make configtxlator 250 build/bin/configtxlator 251 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-42434e60f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/common/tools/configtxlator 252 Binary available as build/bin/configtxlator 253 ``` 254 ``` 255 $ configtxlator start 256 2017-05-31 12:57:22.499 EDT [configtxlator] main -> INFO 001 Serving HTTP requests on port: 7059 257 ``` 258 259 Then, in another window, build the `configtxgen` tool. 260 261 ``` 262 $ make configtxgen 263 build/bin/configtxgen 264 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "nopkcs11" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/common/configtx/tool/configtxgen 265 Binary available as build/bin/configtxgen 266 ``` 267 268 Then, build the orderer and peer. 269 270 ``` 271 $ make peer 272 Installing chaintool 273 curl -L https://github.com/hyperledger/fabric-chaintool/releases/download/v0.10.3/chaintool > build/bin/chaintool 274 ... 275 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/peer 276 Binary available as build/bin/peer 277 278 $ make orderer 279 build/bin/orderer 280 CGO_CFLAGS=" " GOBIN=/home/yellickj/go/src/github.com/hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-alpha3-snapshot-63e0dc80f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.1 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger" github.com/hyperledger/fabric/orderer 281 Binary available as build/bin/orderer 282 ``` 283 284 Start the orderer using the `SampleDevModSolo` profile option. 285 286 ``` 287 ORDERER_GENERAL_LOGLEVEL=debug ORDERER_GENERAL_GENESISPROFILE=SampleDevModeSolo orderer 288 ``` 289 290 The process to add an organization then follows exactly like the batch size example, but, instead of setting the batch size, a new org is defined at the application level. Adding an organization is slightly more involved, because we must first create a channel, then modify its membership set. 291 292 To see this example run the script `fabric/examples/configtxupdate/reconfig_membership/script.sh` by: 293 294 ``` 295 INTERACTIVE=true ./script.sh 296 ``` 297 298 Running the script interactively (as above), you may inspect the artifacts produced as they appear in the `example_output` directory.