docker-compose-files/hyperledger_fabric/fabric-ca/scripts/run-fabric.sh

292 lines
9.3 KiB
Bash
Raw Normal View History

#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
set -e
source $(dirname "$0")/env.sh
function main {
done=false
# Wait for setup to complete and then wait another 10 seconds for the orderer and peers to start
awaitSetup
sleep 10
trap finish EXIT
mkdir -p $LOGPATH
logr "The docker 'run' container has started"
# Set ORDERER_PORT_ARGS to the args needed to communicate with the 1st orderer
IFS=', ' read -r -a OORGS <<< "$ORDERER_ORGS"
initOrdererVars ${OORGS[0]}
export ORDERER_PORT_ARGS="-o $ORDERER_HOST:7050 --tls --cafile $CA_CHAINFILE --clientauth"
# Convert PEER_ORGS to an array named PORGS
IFS=', ' read -r -a PORGS <<< "$PEER_ORGS"
# Create the channel
createChannel
# All peers join the channel
for ORG in $PEER_ORGS; do
local COUNT=1
while [[ "$COUNT" -le $NUM_PEERS ]]; do
initPeerVars $ORG $((COUNT-1))
joinChannel
COUNT=$((COUNT+1))
done
done
# Update the anchor peers
for ORG in $PEER_ORGS; do
initPeerVars $ORG 0
switchToAdminIdentity
logr "Updating anchor peers for $PEER_HOST ..."
peer channel update -c $CHANNEL_NAME -f $ANCHOR_TX_FILE $ORDERER_CONN_ARGS
done
# Install chaincode on the 1st peer in each org
for ORG in $PEER_ORGS; do
initPeerVars $ORG 0
installChaincode
done
# Instantiate chaincode on the 1st peer of the 2nd org
makePolicy
initPeerVars ${PORGS[1]} 0
switchToAdminIdentity
logr "Instantiating chaincode on $PEER_HOST ..."
peer chaincode instantiate -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "$POLICY" $ORDERER_CONN_ARGS
# Query chaincode from the 1st peer of the 1st org
initPeerVars ${PORGS[0]} 0
switchToUserIdentity
chaincodeQuery 100
# Invoke chaincode on the 1st peer of the 1st org
initPeerVars ${PORGS[0]} 0
switchToUserIdentity
logr "Sending invoke transaction to $PEER_HOST ..."
peer chaincode invoke -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' $ORDERER_CONN_ARGS
## Install chaincode on 2nd peer of 2nd org
initPeerVars ${PORGS[1]} 1
installChaincode
# Query chaincode on 2nd peer of 2nd org
sleep 10
initPeerVars ${PORGS[1]} 1
switchToUserIdentity
chaincodeQuery 90
initPeerVars ${PORGS[0]} 0
switchToUserIdentity
# Revoke the user and generate CRL using admin's credentials
revokeFabricUserAndGenerateCRL
# Fetch config block
fetchConfigBlock
# Create config update envelope with CRL and update the config block of the channel
createConfigUpdatePayloadWithCRL
updateConfigBlock
# querying the chaincode should fail as the user is revoked
switchToUserIdentity
queryAsRevokedUser
if [ "$?" -ne 0 ]; then
logr "The revoked user $USER_NAME should have failed to query the chaincode in the channel '$CHANNEL_NAME'"
exit 1
fi
logr "Congratulations! The tests ran successfully."
done=true
}
# Enroll as a peer admin and create the channel
function createChannel {
initPeerVars ${PORGS[0]} 0
switchToAdminIdentity
logr "Creating channel '$CHANNEL_NAME' on $ORDERER_HOST ..."
peer channel create --logging-level=DEBUG -c $CHANNEL_NAME -f $CHANNEL_TX_FILE $ORDERER_CONN_ARGS
}
# Enroll as a fabric admin and join the channel
function joinChannel {
switchToAdminIdentity
set +e
local COUNT=1
MAX_RETRY=10
while true; do
logr "Peer $PEER_HOST is attempting to join channel '$CHANNEL_NAME' (attempt #${COUNT}) ..."
peer channel join -b $CHANNEL_NAME.block
if [ $? -eq 0 ]; then
set -e
logr "Peer $PEER_HOST successfully joined channel '$CHANNEL_NAME'"
return
fi
if [ $COUNT -gt $MAX_RETRY ]; then
fatalr "Peer $PEER_HOST failed to join channel '$CHANNEL_NAME' in $MAX_RETRY retries"
fi
COUNT=$((COUNT+1))
sleep 1
done
}
function chaincodeQuery {
if [ $# -ne 1 ]; then
fatalr "Usage: chaincodeQuery <expected-value>"
fi
set +e
logr "Querying chaincode in the channel '$CHANNEL_NAME' on the peer '$PEER_HOST' ..."
local rc=1
local starttime=$(date +%s)
# Continue to poll until we get a successful response or reach QUERY_TIMEOUT
while test "$(($(date +%s)-starttime))" -lt "$QUERY_TIMEOUT"; do
sleep 1
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >& log.txt
VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')
if [ $? -eq 0 -a "$VALUE" = "$1" ]; then
logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful"
set -e
return 0
else
# removed the string "Query Result" from peer chaincode query command result, as a result, have to support both options until the change is merged.
VALUE=$(cat log.txt | egrep '^[0-9]+$')
if [ $? -eq 0 -a "$VALUE" = "$1" ]; then
logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful"
set -e
return 0
fi
fi
echo -n "."
done
cat log.txt
cat log.txt >> $RUN_SUMFILE
fatalr "Failed to query channel '$CHANNEL_NAME' on peer '$PEER_HOST'; expected value was $1 and found $VALUE"
}
function queryAsRevokedUser {
set +e
logr "Querying the chaincode in the channel '$CHANNEL_NAME' on the peer '$PEER_HOST' as revoked user '$USER_NAME' ..."
local starttime=$(date +%s)
# Continue to poll until we get an expected response or reach QUERY_TIMEOUT
while test "$(($(date +%s)-starttime))" -lt "$QUERY_TIMEOUT"; do
sleep 1
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >& log.txt
if [ $? -ne 0 ]; then
err=$(cat log.txt | grep "access denied")
if [ "$err" != "" ]; then
logr "Expected error occurred when the revoked user '$USER_NAME' queried the chaincode in the channel '$CHANNEL_NAME'"
set -e
return 0
fi
fi
echo -n "."
done
set -e
cat log.txt
cat log.txt >> $RUN_SUMFILE
return 1
}
function makePolicy {
POLICY="OR("
local COUNT=0
for ORG in $PEER_ORGS; do
if [ $COUNT -ne 0 ]; then
POLICY="${POLICY},"
fi
initOrgVars $ORG
POLICY="${POLICY}'${ORG_MSP_ID}.member'"
COUNT=$((COUNT+1))
done
POLICY="${POLICY})"
log "policy: $POLICY"
}
function installChaincode {
switchToAdminIdentity
logr "Installing chaincode on $PEER_HOST ..."
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric-samples/chaincode/abac/go
}
function fetchConfigBlock {
logr "Fetching the configuration block of the channel '$CHANNEL_NAME'"
peer channel fetch config $CONFIG_BLOCK_FILE -c $CHANNEL_NAME $ORDERER_CONN_ARGS
}
function updateConfigBlock {
logr "Updating the configuration block of the channel '$CHANNEL_NAME'"
peer channel update -f $CONFIG_UPDATE_ENVELOPE_FILE -c $CHANNEL_NAME $ORDERER_CONN_ARGS
}
function createConfigUpdatePayloadWithCRL {
logr "Creating config update payload with the generated CRL for the organization '$ORG'"
# Start the configtxlator
configtxlator start &
configtxlator_pid=$!
log "configtxlator_pid:$configtxlator_pid"
logr "Sleeping 5 seconds for configtxlator to start..."
sleep 5
pushd /tmp
CTLURL=http://127.0.0.1:7059
# Convert the config block protobuf to JSON
curl -X POST --data-binary @$CONFIG_BLOCK_FILE $CTLURL/protolator/decode/common.Block > config_block.json
# Extract the config from the config block
jq .data.data[0].payload.data.config config_block.json > config.json
# Update crl in the config json
CRL=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n')
cat config.json | jq --arg org "$ORG" --arg crl "$CRL" '.channel_group.groups.Application.groups[$org].values.MSP.value.config.revocation_list = [$crl]' > updated_config.json
# Create the config diff protobuf
curl -X POST --data-binary @config.json $CTLURL/protolator/encode/common.Config > config.pb
curl -X POST --data-binary @updated_config.json $CTLURL/protolator/encode/common.Config > updated_config.pb
curl -X POST -F original=@config.pb -F updated=@updated_config.pb $CTLURL/configtxlator/compute/update-from-configs -F channel=$CHANNEL_NAME > config_update.pb
# Convert the config diff protobuf to JSON
curl -X POST --data-binary @config_update.pb $CTLURL/protolator/decode/common.ConfigUpdate > config_update.json
# Create envelope protobuf container config diff to be used in the "peer channel update" command to update the channel configuration block
echo '{"payload":{"header":{"channel_header":{"channel_id":"'"${CHANNEL_NAME}"'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' > config_update_as_envelope.json
curl -X POST --data-binary @config_update_as_envelope.json $CTLURL/protolator/encode/common.Envelope > $CONFIG_UPDATE_ENVELOPE_FILE
# Stop configtxlator
kill $configtxlator_pid
popd
}
function finish {
if [ "$done" = true ]; then
logr "See $RUN_LOGFILE for more details"
touch /$RUN_SUCCESS_FILE
else
logr "Tests did not complete successfully; see $RUN_LOGFILE for more details"
touch /$RUN_FAIL_FILE
exit 1
fi
}
function logr {
log $*
log $* >> $RUN_SUMPATH
}
function fatalr {
logr "FATAL: $*"
exit 1
}
main