Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new orderer to channel #72

Merged
merged 10 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
orderer6.example.com:


networks:
test:
name: fabric_test

services:

orderer6.example.com:
container_name: orderer6.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=7056
- 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:17056
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/orderer6.example.com/msp:/var/hyperledger/orderer/msp
- ../organizations/ordererOrganizations/example.com/orderers/orderer6.example.com/tls/:/var/hyperledger/orderer/tls
- orderer6.example.com:/var/hyperledger/production/orderer
ports:
- 7056:7056
- 17056:17056
networks:
- test
Original file line number Diff line number Diff line change
@@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we want to generate the crypto only for orderer6, then we can remove this entry Hostname: orderer

SANS:
- localhost
- Hostname: orderer6
SANS:
- localhost
225 changes: 225 additions & 0 deletions fabric-network/docker-based-syschannel/scripts/addNewOrderer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# import utils
. scripts/envVar.sh

# fetchChannelConfig <org> <channel_id> <output_json>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment needs to go down closer to function definition.

# 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

COMPOSE_FILES=docker-compose-new-orderer.yaml
FABRIC_CFG_PATH=$PWD/../config/
export CH_NAME='mychannel'

startNewOrderer(){

docker-compose -f docker/${COMPOSE_FILES} up -d

docker ps -a
if [ $? -ne 0 ]; then
fatalln "Unable to start network"
fi

}
# Create Organziation crypto material using cryptogen or CAs
function 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-orderer-new.yaml --input="${PWD}/organizations"
res=$?
{ set +x; } 2>/dev/null
if [ $res -ne 0 ]; then
fatalln "Failed to generate certificates..."
fi
}


fetchChannelConfig() {
timestamp
ORG=$1
CHANNEL=$2
OUTPUT=$3
setOrderer $ORG
export FABRIC_CFG_PATH=$PWD/../config/

infoln "$(timestamp) Fetching the most recent configuration block for the channel ${CHANNEL}"
set -x
peer channel fetch config config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer1.example.com --tls --cafile $ORDERER_CA -c ${CHANNEL}
{ 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 ${OUTPUT}
{ set +x; } 2>/dev/null


}


# createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb>
# 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
createConfigUpdateTLS() {
infoln "$(timestamp) Creating config update"
CHANNEL=$1
ORIGINAL=$2
MODIFIED=$3
OUTPUT=$4

TLS_FILE=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer6.example.com/tls/server.crt


set -x
# filter requird data
jq .data.data[0].payload.data.config config_block.json > "${ORIGINAL}"

# edit orderer address
echo "{\"client_tls_cert\":\"$(cat $TLS_FILE | base64)\",\"host\":\"orderer6.example.com\",\"port\":7056,\"server_tls_cert\":\"$(cat $TLS_FILE | base64)\"}" > $PWD/org6consenter.json
jq ".channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters += [$(cat org6consenter.json)]" ${ORIGINAL} > ${MODIFIED}

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 "
}

createConfigUpdateEndpoint() {
infoln "$(timestamp) Creating config update"
CHANNEL=$1
ORIGINAL=$2
MODIFIED=$3
OUTPUT=$4

set -x
# filter requird data
jq .data.data[0].payload.data.config config_block.json > "${ORIGINAL}"

# edit orderer address

jq ".channel_group.groups.Orderer.groups.OrdererOrg.values.Endpoints.value.addresses += [\"orderer6.example.com:7056\"]" config.json > modified_config.json
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 <org> <configtx.pb>
# 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 "Submitting config update transaction"
ORG=$1
CHANNEL=$2
CONFIGTXFILE=$3
setOrderer $ORG
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"
}


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


}




# generate crypto for new orderer
generateOrdererCrypto

# fetch latest config block from sysytem channel
fetchChannelConfig 1 'system-channel ' 'config_block.json'
# create config update for system channel
createConfigUpdateTLS 'system-channel' 'config.json' 'modified_config.json' 'config_update_in_envelope.pb'
# sign the config update
signConfigtxAsPeerOrg 1 'config_update_in_envelope.pb'

# submit update in system channel
submitConfigUpdateTransaction 1 'system-channel' 'config_update_in_envelope.pb'

# fetch latest config and move the config block to channel artifacts
fetchConfigBlock 1 'system-channel'

# start new orderer container
startNewOrderer


# fetch latest config block from sysytem channel
fetchChannelConfig 1 'system-channel ' 'config_block'
# update endpoint info in sysytem channel
createConfigUpdateEndpoint 'system-channel' 'config.json' 'modified_config.json' 'config_update_in_envelope.pb'
# sign the update
# signConfigtxAsPeerOrg 1 'config_update_in_envelope.pb'
# submit update in system channel
submitConfigUpdateTransaction 1 'system-channel' 'config_update_in_envelope.pb'

# Application channel updates

fetchChannelConfig 1 'mychannel ' 'config_block'
createConfigUpdateTLS 'mychannel' 'config.json' 'modified_config.json' 'config_update_in_envelope.pb'
# signConfigtxAsPeerOrg 1 'config_update_in_envelope.pb'
submitConfigUpdateTransaction 1 'mychannel' 'config_update_in_envelope.pb'
fetchChannelConfig 1 'mychannel ' 'config_block'


createConfigUpdateEndpoint
createConfigUpdateEndpoint 'mychannel' 'config.json' 'modified_config.json' 'config_update_in_envelope.pb'
# signConfigtxAsPeerOrg 1 'config_update_in_envelope.pb'
submitConfigUpdateTransaction 1 'mychannel' 'config_update_in_envelope.pb'

#verify latest block
fetchChannelConfig 1 'mychannel ' 'latest.json'
15 changes: 8 additions & 7 deletions fabric-network/docker-based-syschannel/scripts/configUpdate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ fetchChannelConfig() {

infoln "Decoding config block to JSON and isolating config to ${OUTPUT}"
set -x
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > "${OUTPUT}"
{ set +x; } 2>/dev/null
}

Expand All @@ -38,12 +39,12 @@ createConfigUpdate() {
OUTPUT=$4

set -x
configtxlator proto_encode --input "${ORIGINAL}" --type common.Config >original_config.pb
configtxlator proto_encode --input "${MODIFIED}" --type common.Config >modified_config.pb
configtxlator compute_update --channel_id "${CHANNEL}" --original original_config.pb --updated modified_config.pb >config_update.pb
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >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}"
configtxlator proto_encode --input "${ORIGINAL}" --type common.Config --output original_config.pb
configtxlator proto_encode --input "${MODIFIED}" --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id "${CHANNEL}" --original 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
}

Expand Down
2 changes: 1 addition & 1 deletion fabric-network/docker-based-syschannel/scripts/envVar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ setOrderer(){
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER5_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=orderer4.example.com:7054
export CORE_PEER_ADDRESS=orderer5.example.com:7054
else
errorln "ORG Unknown"
fi
Expand Down