diff --git a/README.md b/README.md index 21160ed..6c8a07c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,10 @@ to set it to an explicit majority endorsement policy (TODO: Is there are way to return it to an implicit majority policy ?) +## Update orderer address + +- ./scripts/updateOrdererAddress.sh + ## bring up the client Make sure you are using Node 14 or higher LTS release In client diff --git a/fabric-network/docker-based-syschannel/.gitignore b/fabric-network/docker-based-syschannel/.gitignore old mode 100644 new mode 100755 index 790fd1d..2de8c72 --- a/fabric-network/docker-based-syschannel/.gitignore +++ b/fabric-network/docker-based-syschannel/.gitignore @@ -2,3 +2,10 @@ log.txt *.tar.gz *.block *.tx + +*.json +*.pb + + + + diff --git a/fabric-network/docker-based-syschannel/docker/docker-compose-test-net.yaml b/fabric-network/docker-based-syschannel/docker/docker-compose-test-net.yaml index 69145f2..807bb0d 100644 --- a/fabric-network/docker-based-syschannel/docker/docker-compose-test-net.yaml +++ b/fabric-network/docker-based-syschannel/docker/docker-compose-test-net.yaml @@ -432,6 +432,7 @@ services: - /var/run/:/host/var/run/ - ../organizations:/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations - ../scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ + - ../channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts depends_on: - peer0.org1.example.com - peer0.org2.example.com diff --git a/fabric-network/docker-based-syschannel/docker/ordererUpdate.yaml b/fabric-network/docker-based-syschannel/docker/ordererUpdate.yaml new file mode 100755 index 0000000..20d5700 --- /dev/null +++ b/fabric-network/docker-based-syschannel/docker/ordererUpdate.yaml @@ -0,0 +1,50 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '2' + +volumes: + orderer2.example.com: + + +networks: + test: + name: fabric_test + +services: + + orderer2.example.com: + container_name: orderer2.example.com + image: hyperledger-fabric.jfrog.io/fabric-orderer:amd64-latest + environment: + - FABRIC_LOGGING_SPEC=DEBUG + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7057 + - ORDERER_GENERAL_GENESISMETHOD=file + - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block + - ORDERER_GENERAL_LOCALMSPID=OrdererMSP + - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp + + # enabled TLS + - ORDERER_GENERAL_TLS_ENABLED=true + - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:17057 + working_dir: /opt/gopath/src/github.com/hyperledger/fabric + command: orderer + volumes: + - ../channel-artifacts/latest_config.block:/var/hyperledger/orderer/orderer.genesis.block + - ../organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/msp:/var/hyperledger/orderer/msp + - ../organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/:/var/hyperledger/orderer/tls + - orderer2.example.com:/var/hyperledger/production/orderer + ports: + - 7057:7057 + - 17057:17057 + networks: + - test \ No newline at end of file diff --git a/fabric-network/docker-based-syschannel/organizations/cryptogen/crypto-config-update-orderer.yaml b/fabric-network/docker-based-syschannel/organizations/cryptogen/crypto-config-update-orderer.yaml new file mode 100644 index 0000000..e203a93 --- /dev/null +++ b/fabric-network/docker-based-syschannel/organizations/cryptogen/crypto-config-update-orderer.yaml @@ -0,0 +1,25 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# --------------------------------------------------------------------------- +# "OrdererOrgs" - Definition of organizations managing orderer nodes +# --------------------------------------------------------------------------- +OrdererOrgs: + # --------------------------------------------------------------------------- + # Orderer + # --------------------------------------------------------------------------- + - Name: Orderer + Domain: example.com + EnableNodeOUs: true + # --------------------------------------------------------------------------- + # "Specs" - See PeerOrgs for complete description + # --------------------------------------------------------------------------- + Specs: + - Hostname: orderer + SANS: + - localhost + - Hostname: orderer2 + SANS: + - localhost \ No newline at end of file diff --git a/fabric-network/docker-based-syschannel/scripts/changeCCEndosementPolicy.sh b/fabric-network/docker-based-syschannel/scripts/changeCCEndosementPolicy.sh index 8faaa53..1af3adf 100755 --- a/fabric-network/docker-based-syschannel/scripts/changeCCEndosementPolicy.sh +++ b/fabric-network/docker-based-syschannel/scripts/changeCCEndosementPolicy.sh @@ -17,6 +17,19 @@ DELAY=${8:-"3"} MAX_RETRY=${9:-"5"} VERBOSE=${10:-"false"} +println "executing with the following" +println "- CHANNEL_NAME: ${C_GREEN}${CHANNEL_NAME}${C_RESET}" +println "- CC_NAME: ${C_GREEN}${CC_NAME}${C_RESET}" + +println "- CC_VERSION: ${C_GREEN}${CC_VERSION}${C_RESET}" +println "- CC_SEQUENCE: ${C_GREEN}${CC_SEQUENCE}${C_RESET}" +println "- CC_END_POLICY: ${C_GREEN}${CC_END_POLICY}${C_RESET}" +println "- CC_COLL_CONFIG: ${C_GREEN}${CC_COLL_CONFIG}${C_RESET}" +println "- CC_INIT_FCN: ${C_GREEN}${CC_INIT_FCN}${C_RESET}" +println "- DELAY: ${C_GREEN}${DELAY}${C_RESET}" +println "- MAX_RETRY: ${C_GREEN}${MAX_RETRY}${C_RESET}" +println "- VERBOSE: ${C_GREEN}${VERBOSE}${C_RESET}" + FABRIC_CFG_PATH=$PWD/../config/ #User has not provided a name diff --git a/fabric-network/docker-based-syschannel/scripts/envVar.sh b/fabric-network/docker-based-syschannel/scripts/envVar.sh index f082473..78360c0 100755 --- a/fabric-network/docker-based-syschannel/scripts/envVar.sh +++ b/fabric-network/docker-based-syschannel/scripts/envVar.sh @@ -12,13 +12,17 @@ export CORE_PEER_TLS_ENABLED=true export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export ORDERER2_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export ORDERER3_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export ORDERER4_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +export ORDERER5_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem + export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt export PEER0_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt export PEER0_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt export PEER1_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt export PEER1_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt export PEER1_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt - # Set environment variables for the peer0 org setGlobals() { local USING_ORG="" @@ -53,6 +57,8 @@ setGlobals() { fi } + + # Set environment variables for the peer org setGlobalsPeer1() { local USING_ORG="" @@ -136,3 +142,43 @@ verifyResult() { fatalln "$2" fi } + +# Set environment variables for the orderer +setOrderer(){ + if [ -z "$OVERRIDE_ORG" ]; then + USING_ORG=$1 + else + USING_ORG="${OVERRIDE_ORG}" + fi + infoln "Using orderer organization ${USING_ORG}" + if [ $USING_ORG -eq 1 ]; then + export CORE_PEER_LOCALMSPID="OrdererMSP" + export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA + export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp + export CORE_PEER_ADDRESS=orderer1.example.com:7050 + elif [ $USING_ORG -eq 2 ]; then + export CORE_PEER_LOCALMSPID="OrdererMSP" + export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER2_CA + export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp + export CORE_PEER_ADDRESS=orderer2.example.com:7051 + + elif [ $USING_ORG -eq 3 ]; then + export CORE_PEER_LOCALMSPID="OrdererMSP" + export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER3_CA + export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp + export CORE_PEER_ADDRESS=orderer3.example.com:7052 + elif [ $USING_ORG -eq 4 ]; then + export CORE_PEER_LOCALMSPID="OrdererMSP" + export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER4_CA + export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp + export CORE_PEER_ADDRESS=orderer4.example.com:7053 + elif [ $USING_ORG -eq 5 ]; then + export CORE_PEER_LOCALMSPID="OrdererMSP" + export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER5_CA + export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp + export CORE_PEER_ADDRESS=orderer4.example.com:7054 + else + errorln "ORG Unknown" + fi +} + diff --git a/fabric-network/docker-based-syschannel/scripts/updateOrdererAddress.sh b/fabric-network/docker-based-syschannel/scripts/updateOrdererAddress.sh new file mode 100755 index 0000000..017bfa9 --- /dev/null +++ b/fabric-network/docker-based-syschannel/scripts/updateOrdererAddress.sh @@ -0,0 +1,255 @@ +#!/bin/bash +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# import utils +. scripts/envVar.sh + +# fetchChannelConfig +# Writes the current channel config for a given channel to a JSON file +# NOTE: this must be run in a CLI container since it requires configtxlator +FABRIC_CFG_PATH=$PWD/../config/ +COMPOSE_FILE_ORDERER_UPDATE='ordererUpdate.yaml' + + +generateOrdererCrypto() { + # Create crypto material using cryptogen + + which cryptogen + if [ "$?" -ne 0 ]; then + fatalln "cryptogen tool not found. exiting" + fi + infoln "Generating certificates using cryptogen tool" + + infoln "Creating orderer Identities" + + set -x + cryptogen extend --config=./organizations/cryptogen/crypto-config-update-orderer.yaml --input="${PWD}/organizations" + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate certificates..." + fi +} + +verifyChannelConfig() { + timestamp + ORG=$1 + CHANNEL=$2 + OUTPUT=$3 + + + if [ $CHANNEL == 'system-channel' ] + then + echo "setting orderer env variables" + setOrderer $ORG + else + echo "setting peer env variables" + setGlobals $ORG + fi + + export FABRIC_CFG_PATH=$PWD/../config/ + infoln "Fetching the most recent configuration block for the channel" + set -x + peer channel fetch config config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer1.example.com -c $CHANNEL --tls --cafile $ORDERER_CA + { set +x; } 2>/dev/null + + infoln "Decoding config block to JSON and isolating config to ${OUTPUT}" + set -x + configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json + + # filter requird data + jq .data.data[0].payload.data.config config_block.json > "${OUTPUT}" + + + { set +x; } 2>/dev/null +} +fetchChannelConfig() { + timestamp + ORG=$1 + CHANNEL=$2 + OUTPUT=$3 + MODIFIED=$4 + + + + + TLS_FILE=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt + + if [ $CHANNEL == 'system-channel' ] + then + echo "setting orderer env variables" + setOrderer $ORG + else + echo "setting peer env variables" + setGlobals $ORG + fi + + export FABRIC_CFG_PATH=$PWD/../config/ + infoln "$(timestamp) Fetching the most recent configuration block for the channel" + set -x + peer channel fetch config config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer1.example.com -c $CHANNEL --tls --cafile $ORDERER_CA + { set +x; } 2>/dev/null + + infoln "Decoding config block to JSON and isolating config to ${OUTPUT}" + set -x + configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json + + # filter requird data + jq .data.data[0].payload.data.config config_block.json > "${OUTPUT}" + + + # edit orderer address and tls cert + tmp=$(mktemp) + jq '.channel_group.groups.Orderer.groups.OrdererOrg.values.Endpoints.value.addresses[1] = "orderer2.example.com:7057"' ${OUTPUT} > ${MODIFIED} + echo "{\"client_tls_cert\":\"$(cat $TLS_FILE | base64)\",\"host\":\"orderer2.example.com\",\"port\":7057,\"server_tls_cert\":\"$(cat $TLS_FILE | base64)\"}" > $PWD/ordererconsenter.json + + + + + ordererconsenter=`cat $PWD/ordererconsenter.json` + tmp=$(mktemp) + jq '.channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters[1] = '$ordererconsenter'' ${MODIFIED} > "$tmp" && mv "$tmp" ${MODIFIED} + + { set +x; } 2>/dev/null +} + +# createConfigUpdate +# Takes an original and modified config, and produces the config update tx +# which transitions between the two +# NOTE: this must be run in a CLI container since it requires configtxlator +createConfigUpdate() { + infoln "$(timestamp) Creating config update" + CHANNEL=$1 + ORIGINAL=$2 + MODIFIED=$3 + OUTPUT=$4 + + set -x + configtxlator proto_encode --input "${ORIGINAL}" --type common.Config --output config.pb + configtxlator proto_encode --input "${MODIFIED}" --type common.Config --output modified_config.pb + configtxlator compute_update --channel_id $CHANNEL --original config.pb --updated modified_config.pb --output config_update.pb + configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json + echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json + configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output "${OUTPUT}" + + { set +x; } 2>/dev/null + infoln " $(timestamp) Completed creating config update " +} + + +# signConfigtxAsPeerOrg +# Set the peerOrg admin of an org and sign the config update +signConfigtxAsPeerOrg() { + infoln "Signing config update transaction" + + ORG=$1 + CONFIGTXFILE=$2 + setOrderer $ORG + set -x + + peer channel signconfigtx -f "${CONFIGTXFILE}" + { set +x; } 2>/dev/null + infoln " $(timestamp) Completed signing the config update process" + +} +# Submit the config update transaction +submitConfigUpdateTransaction(){ + infoln "$(timestamp) Submitting config update transaction" + ORG=$1 + CHANNEL=$2 + CONFIGTXFILE=$3 + if [ $CHANNEL == 'system-channel' ] + then + echo "setting orderer env variables" + setOrderer $ORG + else + echo "setting peer env variables" + setGlobals $ORG + fi + + set -x + peer channel update -f $CONFIGTXFILE -c $CHANNEL -o localhost:7050 --tls --cafile $ORDERER_CA + { set +x; } 2>/dev/null + infoln " $(timestamp) Submit config update process done" +} +startOrderer(){ + infoln " $(timestamp) Recreating orderer container at new port" + docker-compose -f docker/${COMPOSE_FILE_ORDERER_UPDATE} up -d + docker ps +} +stopOrderer(){ + infoln " $(timestamp) stopping orderer container at old port" + docker stop orderer2.example.com + docker ps +} +fetchConfigBlock(){ + + infoln "Fetch latest block from channel ${2}" + ORG=$1 + CHANNEL=$2 + setOrderer $ORG + peer channel fetch config channel-artifacts/latest_config.block -o localhost:7050 --ordererTLSHostnameOverride orderer1.example.com -c ${CHANNEL} --tls --cafile $ORDERER_CA + docker cp cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/latest_config.block ./channel-artifacts/latest_config.block +} + + +# # stop orderer at old port +# stopOrderer + +# #remove old cypto +# rm -r organizations/ordererOrganizations/example.com/orderers/orderer2.example.com + + + +# Update crypto for orderer +generateOrdererCrypto + +# Update system channel + +# fetch latest channel config +fetchChannelConfig 1 'system-channel' 'sys-config.json' 'sys-modified_config.json' + +# create update config +createConfigUpdate 'system-channel' 'sys-config.json' 'sys-modified_config.json' 'sys-config_update_in_envelope.pb' + +# sign by org1 admin +signConfigtxAsPeerOrg 1 'sys-config_update_in_envelope.pb' + +# submit update by org1 +submitConfigUpdateTransaction 1 'system-channel' 'sys-config_update_in_envelope.pb' + +# check for updation +verifyChannelConfig 1 'system-channel' 'sys-confignew.json' + + + +# # Update application channel + +# fetch latest channel config +fetchChannelConfig 1 'mychannel' 'config.json' 'modified_config.json' + +# create update config +createConfigUpdate 'mychannel' 'config.json' 'modified_config.json' 'config_update_in_envelope.pb' + +# sign by org1 admin +signConfigtxAsPeerOrg 1 'config_update_in_envelope.pb' + + + +# submit update by org1 +submitConfigUpdateTransaction 1 'mychannel' 'config_update_in_envelope.pb' + +# check for updation +verifyChannelConfig 1 'mychannel' 'confignew.json' + + + +fetchConfigBlock 1 'system-channel' + + +#start orderer at new port +startOrderer \ No newline at end of file