diff --git a/varion/.gitignore b/varion/.gitignore new file mode 100644 index 00000000..ed5913d7 --- /dev/null +++ b/varion/.gitignore @@ -0,0 +1,15 @@ +/channel-artifacts/*.tx +/channel-artifacts/*.block +/ledgers +/ledgers-backup +/channel-artifacts/*.json +/channel-artifacts/*.pb +/org3-artifacts/crypto-config/* +organizations/fabric-ca/ordererOrg/* +organizations/fabric-ca/org1/* +organizations/fabric-ca/org2/* +organizations/ordererOrganizations/* +organizations/peerOrganizations/* +system-genesis-block/* +*.tar.gz +log.txt diff --git a/varion/CHAINCODE_AS_A_SERVICE_TUTORIAL.md b/varion/CHAINCODE_AS_A_SERVICE_TUTORIAL.md new file mode 100644 index 00000000..6482a64b --- /dev/null +++ b/varion/CHAINCODE_AS_A_SERVICE_TUTORIAL.md @@ -0,0 +1,206 @@ +# Running Chaincode as Service with the Test Network + +The chaincode-as-a-service feature is a very useful and practical way to run 'Smart Contracts'. Traditionally the Fabric Peer has taken on the role of orchestrating the complete lifecycle of the chaincode. It required access to the Docker Daemon to create images, and start containers. Java, Node.js and Go chaincode frameworks were explicitly known to the peer including how they should be built and started. + +As a result this makes it very hard to deploy into Kubernetes (K8S) style environments, or to run in any form of debug mode. Additionally, the code is being rebuilt by the peer therefore there is some degree of uncertainty about what dependencies have been pulled in. + +Chaincode-as-service requires you to orchestrate the build and deployment phase yourself. Whilst this is an additional step, it gives control back. The Peer still requires a 'chaincode package' to be installed. In this case this doesn't contain code, but the information about where the chaincode is hosted. (Hostname,Port,TLS config etc) + +## Fabric v2.4.1 Improvements + +We need to use the latest 2.4.1 release as this contains some improvements to make this process easier. The core functionality is available in earlier releases but requires more configuration. + +- The docker image for the peer contains a builder for chaincode-as-a-service preconfigured. This is named 'ccaasbuilder'. This removes the need to build your own external builder and repackage and configure the peer +- The `ccaasbuilder` applications are included in the binary tgz archive download for use in other circumstances. The `sampleconfig/core.yaml` is updated as well to refer to 'ccaasbuilder' +- The 2.4.1 Java Chaincode release has been updated to remove the need to write a custom bootstrap main class, similar to the Node.js Chaincode. It is intended that this will be added to the go chaincode as well. + +## End-to-end with the the test-network + +The `test-network` and some of the chaincodes have been updated to support running chaincode-as-a-service. The commands below assume that you've got the latest fabric-samples cloned, along with the latest Fabric docker images. + +It's useful to have two terminal windows open, one for starting the Fabric Network, and a second for monitoring all the docker containers. + +In your 'monitoring' window, run this to watch all activity from the all the docker containers on the `fabric_test` network; this will monitor all the docker containers that are added to the `fabric-test` network. The network is usually created by the `./network.sh up` command, so remember to delay running this until at least the network is created. It is possible to precreate the network with `docker network create fabric-test` if you wish. + +```bash +# from the fabric-samples repo +./test-network/monitordocker.sh +``` + +In the 'Fabric Network' window, start the test network + +```bash +cd test-network +./network.sh up createChannel -ca +``` + +You can run other variants of this command, eg to use CouchDB or CAs, without affecting the '-as-a-service' feature. The three keys steps are: + +- Build a docker image of the contract. Both `/asset-transfer-basic/chaincode-typescript` and `/asset-transfer-basic/chaincode-java` have been updated with Dockerfiles +- Install, Approve, and Commit a chaincode definition. This is unchanged, but the chaincode package contains connection information (hostname,port,tls certificates etc.), not code +- Start the docker container(s) containing the contract + +Note that the order listed isn't mandatory. The key thing is that the containers are running before the first transaction is set by the peer. Remember that this could be on the `commit` if the `initRequired` flag is set. + +This sequence can be run as follows + +```bash +./network.sh deployCCAAS -ccn basicts -ccp ../asset-transfer-basic/chaincode-typescript +``` + +This is very similar to the `deployCC` command, it needs the name, and path. But also needs to have the port the chaincode container is going to use. As each container is on the `fabric-test` network, you might wish to alter this so there are no collisions with other chaincode containers. + +You should be able to see the contract starting in the monitoring window. There will be two containers running, one for org1 and one for org2. The container names contain the organization/peer and the name of the chaincode. + +To test things are working you can invoke the 'Contract Metadata' function. For information on how to work as different organizations see [Interacting with the network](https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html#interacting-with-the-network) + +```bash +# Environment variables for Org1 + +export CORE_PEER_TLS_ENABLED=true +export CORE_PEER_LOCALMSPID=Org1MSP +export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem +export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp +export CORE_PEER_ADDRESS=localhost:7051 +export PATH=${PWD}/../bin:$PATH +export FABRIC_CFG_PATH=${PWD}/../config + +# invoke the function +peer chaincode query -C mychannel -n basicts -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq +``` + +If you don't have `jq` installed omit `| jq`. The metadata shows the details of the deployed contract and is JSON, so jq makes it easier to read. You can repeat the above commands for org2 to confirm that is working. + +To run the Java example, change the `deployCCAAS` command as follows. This will create two new containers. + +```bash +./network.sh deployCCAAS -ccn basicj -ccp ../asset-transfer-basic/chaincode-java +``` + +Note that all the asset-transfer-basic application samples use 'basic' as the chaincode name and need to be adjusted to use the name 'basicts' or 'basicj' accordingly, or you need to use the name 'basic' in the commands above. + +### Troubleshooting + +If the JSON structure passed in is badly formatted JSON this error will be in the peer log: + +``` +::Error: Failed to unmarshal json: cannot unmarshal string into Go value of type map[string]interface {} command=build +``` + +## How to configure each language + +Each language can work in the '-as-a-service' mode. Note that the approaches here are based on the very latest libraries. +When starting the image you can also specify any of the TLS options or additional logging options for the respective chaincode libraries. + +### Java + +With the v2.4.1 Java Chaincode libraries, there are no code changes to make or build changes. The '-as-a-service' mode will be used if the environment variable `CHAINCODE_SERVER_ADDRESS` is set. + +A sample docker run command could be as follows. The two key variables that are needed are the `CHAINCODE_SERVER_ADDRESS` and `CORE_CHAICODE_ID_NAME` + +```bash + docker run --rm -d --name peer0org1_assettx_ccaas \ + --network fabric_test \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 \ + -e CORE_CHAINCODE_ID_NAME= \ + assettx_ccaas_image:latest +``` + +### Node.js + +For Node.js (JavaScript or TypeScript) chaincode, typically the `package.json` has `fabric-chaincode-node start` as the main start command. To run in the '-as-a-service' mode change this to `fabric-chaincode-node server --chaincode-address=$CHAINCODE_SERVER_ADDRESS --chaincode-id=$CHAINCODE_ID` + +## Debugging the Chaincode + +Running in the '-as-a-service' mode offers options, similar to how the Fabric 'dev' mode works on debugging code. The restrictions of the 'dev' mode don't apply. + +There is an option `-ccaasdocker false` that can be provided on the `deployCCAAS` command. This will _not_ build the docker image or start a docker container. It does output the commands it would have run. + +Run this command, and you'll see similar output + +```bash +./network.sh deployCCAAS -ccn basicj -ccp ../asset-transfer-basic/chaincode-java -ccaasdocker false +#.... +Not building docker image; this the command we would have run +docker build -f ../asset-transfer-basic/chaincode-java/Dockerfile -t basicj_ccaas_image:latest --build-arg CC_SERVER_PORT=9999 ../asset-transfer-basic/chaincode-java +#.... +Not starting docker containers; these are the commands we would have run + docker run --rm -d --name peer0org1_basicj_ccaas --network fabric_test -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -e CHAINCODE_ID=basicj_1.0:59dcd73a14e2db8eab7f7683343ce27ac242b93b4e8075605a460d63a0438405 -e CORE_CHAINCODE_ID_NAME=basicj_1.0:59dcd73a14e2db8eab7f7683343ce27ac242b93b4e8075605a460d63a0438405 basicj_ccaas_image:latest +``` + +Depending on your directory, and what you need to debug you might need to adjust these commands. + +### Building the docker image + +The first thing needed is to build the docker image. Remember that so long as the peer can connect to the hostname:port given in the `connection.json` the actual packaging of the chaincode is not important to the peer. You are at liberty to adjust the dockerfiles given hgere. + +To manually build the docker image for the `asset-transfer-basic/chaincode-java` + +```bash +docker build -f ../asset-transfer-basic/chaincode-java/Dockerfile -t basicj_ccaas_image:latest --build-arg CC_SERVER_PORT=9999 ../asset-transfer-basic/chaincode-java +``` + +### Starting the docker container + +You need to start the docker container. + +NodeJs for example, could be started like this + +```bash + docker run --rm -it -p 9229:9229 --name peer0org2_basic_ccaas --network fabric_test -e DEBUG=true -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -e CHAINCODE_ID=basic_1.0:7c7dff5cdc43c77ccea028c422b3348c3c1fb5a26ace0077cf3cc627bd355ef0 -e CORE_CHAINCODE_ID_NAME=basic_1.0:7c7dff5cdc43c77ccea028c422b3348c3c1fb5a26ace0077cf3cc627bd355ef0 basic_ccaas_image:latest +``` + +Java for example, could be started like this + +```bash + docker run --rm -it --name peer0org1_basicj_ccaas -p 8000:8000 --network fabric_test -e DEBUG=true -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -e CHAINCODE_ID=basicj_1.0:b014a03d8eb1898535e25b4dfeeb3f8244c9f07d91a06aec03e2d19174c45e4f -e CORE_CHAINCODE_ID_NAME=basicj_1.0:b014a03d8e +b1898535e25b4dfeeb3f8244c9f07d91a06aec03e2d19174c45e4f basicj_ccaas_image:latest +``` + +For all languages please note: + +- the name of the container needs to match what the peer has in the `connection.json` +- the peer is connecting to the chaincode container via the docker network. Therefore port 9999 does not need to be forwarded to the host +- If you are going to single step in a debugger, then you are likely to hit the Fabric transaction timeout value. By default this is 30 seconds, meaning the chaincode has to complete transactions in 30 seconds or less. In the `test-network/docker/docker-composer-test-net.yml` add `CORE_CHAINCODE_EXECUTETIMEOUT=300s` to the environment options of each peer. +- In the command above, the `-d` option has been removed from the command the test-network would have used, and has been replaced with `-it`. This means that docker container will not run in detached mode, and will run in the foreground. + +For Node.js please note: + +- Port 9229 is forwarded however - this is the debug port used by Node.js +- `-e DEBUG=true` will trigger the node runtime to be started in debug mode. This is encoded in the `docker/docker-entrypoint.sh` script - this is an example and you may wish to remove this in production images for security +- If you are using typescript, ensure that the typescript has been compiled with sourcemaps, otherwise a debugger will struggle matching up the source code. + +For Java please note: + +- Port 800 is forwarded, the debug port for the JVM +- `-e DEBUG=true` will trigger the node runtime to be started in debug mode. This is encoded in the `docker/docker-entrypoint.sh` script - this is an example and you may wish to remove this in production images for security +- In the java command with the option to start the debugger is `java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000 -jar /chaincode.jar` Note the `0.0.0.0` as the debug port needs to be bound to all network adapters so the debugger can be attached from outside the container + +## Running with multiple peers + +In the traditional approach, each peer that the chaincode is approved on will have a container running the chaincode. With the '-as-a-service' approach we need to achieve the same architecture. + +As the `connection.json` contains the address of the running chaincode container, it can be updated to ensure that each peer connects to a different container. However the as the `connection.json` in the chaincode package, Fabric mandates that the package id is consistent amongst all peers in an organization. To achieve that +the the external builder supports a template capability. The context from this template is taken from an environment variable set on each Peer. `CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG` + +We can define the address to be a template in the `connection.json` + +```json +{ + "address": "{{.peername}}_assettransfer_ccaas:9999", + "dial_timeout": "10s", + "tls_required": false +} +``` + +In the peer's environment configuration we then set for org1's peer1 + +```bash +CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG="{\"peername\":\"org1peer1\"}" +``` + +The external builder will then resolve this address to be `org1peer1_assettransfer_ccaas:9999` for the peer to use. + +Each peer can have their own separate configuration, and therefore different addresses. The JSON string that is set can have any structure, so long as the templates (in golang template syntax) match. + +Any value in the `connection.json` can be templated - but only the values and not the keys. diff --git a/varion/README.md b/varion/README.md new file mode 100644 index 00000000..31578af1 --- /dev/null +++ b/varion/README.md @@ -0,0 +1,68 @@ +# Running the test network + +You can use the `./network.sh` script to stand up a simple Fabric test network. The test network has two peer organizations with one peer each and a single node raft ordering service. You can also use the `./network.sh` script to create channels and deploy chaincode. For more information, see [Using the Fabric test network](https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html). The test network is being introduced in Fabric v2.0 as the long term replacement for the `first-network` sample. + +If you are planning to run the test network with consensus type BFT then please pass `-bft` flag as input to the `network.sh` script when creating the channel. Note that currently this sample does not yet support the use of consensus type BFT and CA together. +That is to create a network use: +```bash +./network.sh up -bft +``` + +To create a channel use: + +```bash +./network.sh createChannel -bft +``` + +To restart a running network use: + +```bash +./network.sh restart -bft +``` + +Note that running the createChannel command will start the network, if it is not already running. + +Before you can deploy the test network, you need to follow the instructions to [Install the Samples, Binaries and Docker Images](https://hyperledger-fabric.readthedocs.io/en/latest/install.html) in the Hyperledger Fabric documentation. + +## Using the Peer commands + +The `setOrgEnv.sh` script can be used to set up the environment variables for the organizations, this will help to be able to use the `peer` commands directly. + +First, ensure that the peer binaries are on your path, and the Fabric Config path is set assuming that you're in the `test-network` directory. + +```bash + export PATH=$PATH:$(realpath ../bin) + export FABRIC_CFG_PATH=$(realpath ../config) +``` + +You can then set up the environment variables for each organization. The `./setOrgEnv.sh` command is designed to be run as follows. + +```bash +export $(./setOrgEnv.sh Org2 | xargs) +``` + +(Note bash v4 is required for the scripts.) + +You will now be able to run the `peer` commands in the context of Org2. If a different command prompt, you can run the same command with Org1 instead. +The `setOrgEnv` script outputs a series of `=` strings. These can then be fed into the export command for your current shell. + +## Chaincode-as-a-service + +To learn more about how to use the improvements to the Chaincode-as-a-service please see this [tutorial](./test-network/../CHAINCODE_AS_A_SERVICE_TUTORIAL.md). It is expected that this will move to augment the tutorial in the [Hyperledger Fabric ReadTheDocs](https://hyperledger-fabric.readthedocs.io/en/release-2.4/cc_service.html) + + +## Podman + +*Note - podman support should be considered experimental but the following has been reported to work with podman 4.1.1 on Mac. If you wish to use podman a LinuxVM is recommended.* + +Fabric's `install-fabric.sh` script has been enhanced to support using `podman` to pull down images and tag them rather than docker. The images are the same, just pulled differently. Simply specify the 'podman' argument when running the `install-fabric.sh` script. + +Similarly, the `network.sh` script has been enhanced so that it can use `podman` and `podman-compose` instead of docker. Just set the environment variable `CONTAINER_CLI` to `podman` before running the `network.sh` script: + +```bash +CONTAINER_CLI=podman ./network.sh up +```` + +As there is no Docker-Daemon when using podman, only the `./network.sh deployCCAAS` command will work. Following the Chaincode-as-a-service Tutorial above should work. + + diff --git a/varion/addOrg3/README.md b/varion/addOrg3/README.md new file mode 100644 index 00000000..82b1e8ac --- /dev/null +++ b/varion/addOrg3/README.md @@ -0,0 +1,28 @@ +## Adding Org3 to the test network + +You can use the `addOrg3.sh` script to add another organization to the Fabric test network. The `addOrg3.sh` script generates the Org3 crypto material, creates an Org3 organization definition, and adds Org3 to a channel on the test network. + +You first need to run `./network.sh up createChannel` in the `test-network` directory before you can run the `addOrg3.sh` script. + +``` +./network.sh up createChannel +cd addOrg3 +./addOrg3.sh up +``` + +If you used `network.sh` to create a channel other than the default `mychannel`, you need pass that name to the `addorg3.sh` script. +``` +./network.sh up createChannel -c channel1 +cd addOrg3 +./addOrg3.sh up -c channel1 +``` + +You can also re-run the `addOrg3.sh` script to add Org3 to additional channels. +``` +cd .. +./network.sh createChannel -c channel2 +cd addOrg3 +./addOrg3.sh up -c channel2 +``` + +For more information, use `./addOrg3.sh -h` to see the `addOrg3.sh` help text. diff --git a/varion/addOrg3/addOrg3.sh b/varion/addOrg3/addOrg3.sh new file mode 100755 index 00000000..2d14c817 --- /dev/null +++ b/varion/addOrg3/addOrg3.sh @@ -0,0 +1,284 @@ +#!/bin/bash +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This script extends the Hyperledger Fabric test network by adding +# adding a third organization to the network +# + +# prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries +# this may be commented out to resolve installed version of tools if desired +export PATH=${PWD}/../../bin:${PWD}:$PATH +export FABRIC_CFG_PATH=${PWD}/../../config +export VERBOSE=false + +. ../scripts/utils.sh + +: ${CONTAINER_CLI:="docker"} +if command -v ${CONTAINER_CLI}-compose > /dev/null 2>&1; then + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} +else + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI} compose"} +fi +infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" + + +# Print the usage message +function printHelp () { + echo "Usage: " + echo " addOrg3.sh up|down|generate [-c ] [-t ] [-d ] [-f ] [-s ]" + echo " addOrg3.sh -h|--help (print this message)" + echo " - one of 'up', 'down', or 'generate'" + echo " - 'up' - add org3 to the sample network. You need to bring up the test network and create a channel first." + echo " - 'down' - bring down the test network and org3 nodes" + echo " - 'generate' - generate required certificates and org definition" + echo " -c - test network channel name (defaults to \"mychannel\")" + echo " -ca - Use a CA to generate the crypto material" + echo " -t - CLI timeout duration in seconds (defaults to 10)" + echo " -d - delay duration in seconds (defaults to 3)" + echo " -s - the database backend to use: goleveldb (default) or couchdb" + echo " -verbose - verbose mode" + echo + echo "Typically, one would first generate the required certificates and " + echo "genesis block, then bring up the network. e.g.:" + echo + echo " addOrg3.sh generate" + echo " addOrg3.sh up" + echo " addOrg3.sh up -c mychannel -s couchdb" + echo " addOrg3.sh down" + echo + echo "Taking all defaults:" + echo " addOrg3.sh up" + echo " addOrg3.sh down" +} + +# We use the cryptogen tool to generate the cryptographic material +# (x509 certs) for the new org. After we run the tool, the certs will +# be put in the organizations folder with org1 and org2 + +# Create Organziation crypto material using cryptogen or CAs +function generateOrg3() { + # Create crypto material using cryptogen + if [ "$CRYPTO" == "cryptogen" ]; then + which cryptogen + if [ "$?" -ne 0 ]; then + fatalln "cryptogen tool not found. exiting" + fi + infoln "Generating certificates using cryptogen tool" + + infoln "Creating Org3 Identities" + + set -x + cryptogen generate --config=org3-crypto.yaml --output="../organizations" + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate certificates..." + fi + + fi + + # Create crypto material using Fabric CA + if [ "$CRYPTO" == "Certificate Authorities" ]; then + fabric-ca-client version > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + echo "ERROR! fabric-ca-client binary not found.." + echo + echo "Follow the instructions in the Fabric docs to install the Fabric Binaries:" + echo "https://hyperledger-fabric.readthedocs.io/en/latest/install.html" + exit 1 + fi + + infoln "Generating certificates using Fabric CA" + ${CONTAINER_CLI_COMPOSE} -f ${COMPOSE_FILE_CA_BASE} -f $COMPOSE_FILE_CA_ORG3 up -d 2>&1 + + . fabric-ca/registerEnroll.sh + + sleep 10 + + infoln "Creating Org3 Identities" + createOrg3 + + fi + + infoln "Generating CCP files for Org3" + ./ccp-generate.sh +} + +# Generate channel configuration transaction +function generateOrg3Definition() { + which configtxgen + if [ "$?" -ne 0 ]; then + fatalln "configtxgen tool not found. exiting" + fi + infoln "Generating Org3 organization definition" + export FABRIC_CFG_PATH=$PWD + set -x + configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate Org3 organization definition..." + fi +} + +function Org3Up () { + # start org3 nodes + + if [ "$CONTAINER_CLI" == "podman" ]; then + cp ../podman/core.yaml ../../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/ + fi + + if [ "${DATABASE}" == "couchdb" ]; then + DOCKER_SOCK=${DOCKER_SOCK} ${CONTAINER_CLI_COMPOSE} -f ${COMPOSE_FILE_BASE} -f $COMPOSE_FILE_ORG3 -f ${COMPOSE_FILE_COUCH_BASE} -f $COMPOSE_FILE_COUCH_ORG3 up -d 2>&1 + else + DOCKER_SOCK=${DOCKER_SOCK} ${CONTAINER_CLI_COMPOSE} -f ${COMPOSE_FILE_BASE} -f $COMPOSE_FILE_ORG3 up -d 2>&1 + fi + if [ $? -ne 0 ]; then + fatalln "ERROR !!!! Unable to start Org3 network" + fi +} + +# Generate the needed certificates, the genesis block and start the network. +function addOrg3 () { + # If the test network is not up, abort + if [ ! -d ../organizations/ordererOrganizations ]; then + fatalln "ERROR: Please, run ./network.sh up createChannel first." + fi + + # generate artifacts if they don't exist + if [ ! -d "../organizations/peerOrganizations/org3.example.com" ]; then + generateOrg3 + generateOrg3Definition + fi + + infoln "Bringing up Org3 peer" + Org3Up + + # Create the configuration transaction needed to add + # Org3 to the network + infoln "Generating and submitting config tx to add Org3" + export FABRIC_CFG_PATH=${PWD}/../../config + . ../scripts/org3-scripts/updateChannelConfig.sh $CHANNEL_NAME $CLI_DELAY $CLI_TIMEOUT $VERBOSE + if [ $? -ne 0 ]; then + fatalln "ERROR !!!! Unable to create config tx" + fi + + infoln "Joining Org3 peers to network" + . ../scripts/org3-scripts/joinChannel.sh $CHANNEL_NAME $CLI_DELAY $CLI_TIMEOUT $VERBOSE + if [ $? -ne 0 ]; then + fatalln "ERROR !!!! Unable to join Org3 peers to network" + fi +} + +# Tear down running network +function networkDown () { + cd .. + ./network.sh down +} + +# Using crpto vs CA. default is cryptogen +CRYPTO="cryptogen" +# timeout duration - the duration the CLI should wait for a response from +# another container before giving up +CLI_TIMEOUT=10 +#default for delay +CLI_DELAY=3 +# channel name defaults to "mychannel" +CHANNEL_NAME="mychannel" +# use this as the docker compose couch file +COMPOSE_FILE_COUCH_BASE=compose/compose-couch-org3.yaml +COMPOSE_FILE_COUCH_ORG3=compose/${CONTAINER_CLI}/docker-compose-couch-org3.yaml +# use this as the default docker-compose yaml definition +COMPOSE_FILE_BASE=compose/compose-org3.yaml +COMPOSE_FILE_ORG3=compose/${CONTAINER_CLI}/docker-compose-org3.yaml +# certificate authorities compose file +COMPOSE_FILE_CA_BASE=compose/compose-ca-org3.yaml +COMPOSE_FILE_CA_ORG3=compose/${CONTAINER_CLI}/docker-compose-ca-org3.yaml +# database +DATABASE="leveldb" + +# Get docker sock path from environment variable +SOCK="${DOCKER_HOST:-/var/run/docker.sock}" +DOCKER_SOCK="${SOCK##unix://}" + +# Parse commandline args + +## Parse mode +if [[ $# -lt 1 ]] ; then + printHelp + exit 0 +else + MODE=$1 + shift +fi + +# parse flags + +while [[ $# -ge 1 ]] ; do + key="$1" + case $key in + -h ) + printHelp + exit 0 + ;; + -c ) + CHANNEL_NAME="$2" + shift + ;; + -ca ) + CRYPTO="Certificate Authorities" + ;; + -t ) + CLI_TIMEOUT="$2" + shift + ;; + -d ) + CLI_DELAY="$2" + shift + ;; + -s ) + DATABASE="$2" + shift + ;; + -verbose ) + VERBOSE=true + ;; + * ) + errorln "Unknown flag: $key" + printHelp + exit 1 + ;; + esac + shift +done + + +# Determine whether starting, stopping, restarting or generating for announce +if [ "$MODE" == "up" ]; then + infoln "Adding org3 to channel '${CHANNEL_NAME}' with '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE}'" + echo +elif [ "$MODE" == "down" ]; then + EXPMODE="Stopping network" +elif [ "$MODE" == "generate" ]; then + EXPMODE="Generating certs and organization definition for Org3" +else + printHelp + exit 1 +fi + +#Create the network using docker compose +if [ "${MODE}" == "up" ]; then + addOrg3 +elif [ "${MODE}" == "down" ]; then ## Clear the network + networkDown +elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts + generateOrg3 + generateOrg3Definition +else + printHelp + exit 1 +fi diff --git a/varion/addOrg3/ccp-generate.sh b/varion/addOrg3/ccp-generate.sh new file mode 100755 index 00000000..a361a9d4 --- /dev/null +++ b/varion/addOrg3/ccp-generate.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +function one_line_pem { + echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" +} + +function json_ccp { + local PP=$(one_line_pem $4) + local CP=$(one_line_pem $5) + sed -e "s/\${ORG}/$1/" \ + -e "s/\${P0PORT}/$2/" \ + -e "s/\${CAPORT}/$3/" \ + -e "s#\${PEERPEM}#$PP#" \ + -e "s#\${CAPEM}#$CP#" \ + ccp-template.json +} + +function yaml_ccp { + local PP=$(one_line_pem $4) + local CP=$(one_line_pem $5) + sed -e "s/\${ORG}/$1/" \ + -e "s/\${P0PORT}/$2/" \ + -e "s/\${CAPORT}/$3/" \ + -e "s#\${PEERPEM}#$PP#" \ + -e "s#\${CAPEM}#$CP#" \ + ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g' +} + +ORG=3 +P0PORT=11051 +CAPORT=11054 +PEERPEM=../organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem +CAPEM=../organizations/peerOrganizations/org3.example.com/ca/ca.org3.example.com-cert.pem + +echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > ../organizations/peerOrganizations/org3.example.com/connection-org3.json +echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > ../organizations/peerOrganizations/org3.example.com/connection-org3.yaml diff --git a/varion/addOrg3/ccp-template.json b/varion/addOrg3/ccp-template.json new file mode 100644 index 00000000..2b19d1b9 --- /dev/null +++ b/varion/addOrg3/ccp-template.json @@ -0,0 +1,49 @@ +{ + "name": "test-network-org${ORG}", + "version": "1.0.0", + "client": { + "organization": "Org${ORG}", + "connection": { + "timeout": { + "peer": { + "endorser": "300" + } + } + } + }, + "organizations": { + "Org${ORG}": { + "mspid": "Org${ORG}MSP", + "peers": [ + "peer0.org${ORG}.example.com" + ], + "certificateAuthorities": [ + "ca.org${ORG}.example.com" + ] + } + }, + "peers": { + "peer0.org${ORG}.example.com": { + "url": "grpcs://localhost:${P0PORT}", + "tlsCACerts": { + "pem": "${PEERPEM}" + }, + "grpcOptions": { + "ssl-target-name-override": "peer0.org${ORG}.example.com", + "hostnameOverride": "peer0.org${ORG}.example.com" + } + } + }, + "certificateAuthorities": { + "ca.org${ORG}.example.com": { + "url": "https://localhost:${CAPORT}", + "caName": "ca-org${ORG}", + "tlsCACerts": { + "pem": "${CAPEM}" + }, + "httpOptions": { + "verify": false + } + } + } +} diff --git a/varion/addOrg3/ccp-template.yaml b/varion/addOrg3/ccp-template.yaml new file mode 100644 index 00000000..b675c186 --- /dev/null +++ b/varion/addOrg3/ccp-template.yaml @@ -0,0 +1,35 @@ +--- +name: test-network-org${ORG} +version: 1.0.0 +client: + organization: Org${ORG} + connection: + timeout: + peer: + endorser: '300' +organizations: + Org${ORG}: + mspid: Org${ORG}MSP + peers: + - peer0.org${ORG}.example.com + certificateAuthorities: + - ca.org${ORG}.example.com +peers: + peer0.org${ORG}.example.com: + url: grpcs://localhost:${P0PORT} + tlsCACerts: + pem: | + ${PEERPEM} + grpcOptions: + ssl-target-name-override: peer0.org${ORG}.example.com + hostnameOverride: peer0.org${ORG}.example.com +certificateAuthorities: + ca.org${ORG}.example.com: + url: https://localhost:${CAPORT} + caName: ca-org${ORG} + tlsCACerts: + pem: + - | + ${CAPEM} + httpOptions: + verify: false diff --git a/varion/addOrg3/compose/compose-ca-org3.yaml b/varion/addOrg3/compose/compose-ca-org3.yaml new file mode 100644 index 00000000..74dbf4d6 --- /dev/null +++ b/varion/addOrg3/compose/compose-ca-org3.yaml @@ -0,0 +1,27 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + ca_org3: + image: hyperledger/fabric-ca:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org3 + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_PORT=11054 + ports: + - "11054:11054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../fabric-ca/org3:/etc/hyperledger/fabric-ca-server + container_name: ca_org3 diff --git a/varion/addOrg3/compose/compose-couch-org3.yaml b/varion/addOrg3/compose/compose-couch-org3.yaml new file mode 100644 index 00000000..76971c48 --- /dev/null +++ b/varion/addOrg3/compose/compose-couch-org3.yaml @@ -0,0 +1,42 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + couchdb4: + container_name: couchdb4 + image: couchdb:3.3.3 + labels: + service: hyperledger-fabric + # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password + # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. + environment: + - COUCHDB_USER=admin + - COUCHDB_PASSWORD=adminpw + # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, + # for example map it to utilize Fauxton User Interface in dev environments. + ports: + - "9984:5984" + networks: + - test + + peer0.org3.example.com: + environment: + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb4:5984 + # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD + # provide the credentials for ledger to connect to CouchDB. The username and password must + # match the username and password set for the associated CouchDB. + - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin + - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw + depends_on: + - couchdb4 + networks: + - test diff --git a/varion/addOrg3/compose/compose-org3.yaml b/varion/addOrg3/compose/compose-org3.yaml new file mode 100644 index 00000000..f6e1ca1b --- /dev/null +++ b/varion/addOrg3/compose/compose-org3.yaml @@ -0,0 +1,53 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +volumes: + peer0.org3.example.com: + +networks: + test: + name: fabric_test + +services: + + peer0.org3.example.com: + container_name: peer0.org3.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + #Generic peer variables + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=true + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org3.example.com + - CORE_PEER_ADDRESS=peer0.org3.example.com:11051 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_PEER_LISTENADDRESS=0.0.0.0:11051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org3.example.com:11052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:11052 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:11051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org3.example.com:11051 + - CORE_PEER_LOCALMSPID=Org3MSP + - CORE_METRICS_PROVIDER=prometheus + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org1"} + - CORE_CHAINCODE_EXECUTETIMEOUT=300s + volumes: + - ../../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com:/etc/hyperledger/fabric + - peer0.org3.example.com:/var/hyperledger/production + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + command: peer node start + ports: + - 11051:11051 + networks: + - test diff --git a/varion/addOrg3/compose/docker/docker-compose-ca-org3.yaml b/varion/addOrg3/compose/docker/docker-compose-ca-org3.yaml new file mode 100644 index 00000000..16732f0c --- /dev/null +++ b/varion/addOrg3/compose/docker/docker-compose-ca-org3.yaml @@ -0,0 +1,7 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + diff --git a/varion/addOrg3/compose/docker/docker-compose-couch-org3.yaml b/varion/addOrg3/compose/docker/docker-compose-couch-org3.yaml new file mode 100644 index 00000000..16732f0c --- /dev/null +++ b/varion/addOrg3/compose/docker/docker-compose-couch-org3.yaml @@ -0,0 +1,7 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + diff --git a/varion/addOrg3/compose/docker/docker-compose-org3.yaml b/varion/addOrg3/compose/docker/docker-compose-org3.yaml new file mode 100644 index 00000000..12c9ea71 --- /dev/null +++ b/varion/addOrg3/compose/docker/docker-compose-org3.yaml @@ -0,0 +1,25 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + + peer0.org3.example.com: + container_name: peer0.org3.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + #Generic peer variables + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test + volumes: + - ./docker/peercfg:/etc/hyperledger/peercfg + - ${DOCKER_SOCK}:/host/var/run/docker.sock diff --git a/varion/addOrg3/compose/docker/peercfg/core.yaml b/varion/addOrg3/compose/docker/peercfg/core.yaml new file mode 100644 index 00000000..b20e421c --- /dev/null +++ b/varion/addOrg3/compose/docker/peercfg/core.yaml @@ -0,0 +1,777 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Settings for the Peer's gateway server. + gateway: + # Whether the gateway is enabled for this Peer. + enabled: true + # endorsementTimeout is the duration the gateway waits for a response + # from other endorsing peers before returning a timeout error to the client. + endorsementTimeout: 30s + # dialTimeout is the duration the gateway waits for a connection + # to other network nodes. + dialTimeout: 2m + + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is false, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: false + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + + # Path on the file system where peer will find MSP local configurations + mspConfigPath: msp + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: SampleOrg + + # CLI common client config options + client: + # connection timeout + connTimeout: 3s + + # Delivery service related config + deliveryclient: + # Enables this peer to disseminate blocks it pulled from the ordering service + # via gossip. + # Note that 'gossip.state.enabled' controls point to point block replication + # of blocks committed in the past. + blockGossipEnabled: true + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 3s + + # It sets the delivery service maximal delay between consecutive retries + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes GRPC server and client can receive + maxRecvMsgSize: 104857600 + # Max message size in bytes GRPC server and client can send + maxSendMsgSize: 104857600 + +############################################################################### +# +# VM section +# +############################################################################### +vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # If you utilize external chaincode builders and don't need the default Docker chaincode builder, + # the endpoint should be unconfigured so that the peer's Docker health checker doesn't get registered. + endpoint: unix:///var/run/docker.sock + + # settings for docker vms + docker: + tls: + enabled: false + ca: + file: docker/ca.crt + cert: + file: docker/tls.crt + key: + file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + hostConfig: + NetworkMode: host + Dns: + # - 192.168.0.1 + LogConfig: + Type: json-file + Config: + max-size: "50m" + max-file: "5" + Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. + # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/ccaas_builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + + snapshots: + # Path on the file system where peer will store ledger snapshots + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/varion/addOrg3/compose/podman/peercfg/core.yaml b/varion/addOrg3/compose/podman/peercfg/core.yaml new file mode 100644 index 00000000..b5000333 --- /dev/null +++ b/varion/addOrg3/compose/podman/peercfg/core.yaml @@ -0,0 +1,777 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Settings for the Peer's gateway server. + gateway: + # Whether the gateway is enabled for this Peer. + enabled: true + # endorsementTimeout is the duration the gateway waits for a response + # from other endorsing peers before returning a timeout error to the client. + endorsementTimeout: 30s + # dialTimeout is the duration the gateway waits for a connection + # to other network nodes. + dialTimeout: 2m + + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is false, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: false + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + + # Path on the file system where peer will find MSP local configurations + mspConfigPath: msp + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: SampleOrg + + # CLI common client config options + client: + # connection timeout + connTimeout: 3s + + # Delivery service related config + deliveryclient: + # Enables this peer to disseminate blocks it pulled from the ordering service + # via gossip. + # Note that 'gossip.state.enabled' controls point to point block replication + # of blocks committed in the past. + blockGossipEnabled: true + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 3s + + # It sets the delivery service maximal delay between consecutive retries + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes GRPC server and client can receive + maxRecvMsgSize: 104857600 + # Max message size in bytes GRPC server and client can send + maxSendMsgSize: 104857600 + +############################################################################### +# +# VM section +# +############################################################################### +#vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # If you utilize external chaincode builders and don't need the default Docker chaincode builder, + # the endpoint should be unconfigured so that the peer's Docker health checker doesn't get registered. +# endpoint: unix:///var/run/docker.sock + + # settings for docker vms + # docker: + # tls: + # enabled: false + # ca: + # file: docker/ca.crt + # cert: + # file: docker/tls.crt + # key: + # file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + # attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + # hostConfig: + # NetworkMode: host + # Dns: + # # - 192.168.0.1 + # LogConfig: + # Type: json-file + # Config: + # max-size: "50m" + # max-file: "5" + # Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. + # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/ccaas_builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + + snapshots: + # Path on the file system where peer will store ledger snapshots + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/varion/addOrg3/compose/podman/podman-compose-ca-org3.yaml b/varion/addOrg3/compose/podman/podman-compose-ca-org3.yaml new file mode 100644 index 00000000..74dbf4d6 --- /dev/null +++ b/varion/addOrg3/compose/podman/podman-compose-ca-org3.yaml @@ -0,0 +1,27 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + ca_org3: + image: hyperledger/fabric-ca:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org3 + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_PORT=11054 + ports: + - "11054:11054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../fabric-ca/org3:/etc/hyperledger/fabric-ca-server + container_name: ca_org3 diff --git a/varion/addOrg3/compose/podman/podman-compose-couch-org3.yaml b/varion/addOrg3/compose/podman/podman-compose-couch-org3.yaml new file mode 100644 index 00000000..76971c48 --- /dev/null +++ b/varion/addOrg3/compose/podman/podman-compose-couch-org3.yaml @@ -0,0 +1,42 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + couchdb4: + container_name: couchdb4 + image: couchdb:3.3.3 + labels: + service: hyperledger-fabric + # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password + # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. + environment: + - COUCHDB_USER=admin + - COUCHDB_PASSWORD=adminpw + # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, + # for example map it to utilize Fauxton User Interface in dev environments. + ports: + - "9984:5984" + networks: + - test + + peer0.org3.example.com: + environment: + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb4:5984 + # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD + # provide the credentials for ledger to connect to CouchDB. The username and password must + # match the username and password set for the associated CouchDB. + - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin + - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw + depends_on: + - couchdb4 + networks: + - test diff --git a/varion/addOrg3/compose/podman/podman-compose-org3.yaml b/varion/addOrg3/compose/podman/podman-compose-org3.yaml new file mode 100644 index 00000000..208f6d04 --- /dev/null +++ b/varion/addOrg3/compose/podman/podman-compose-org3.yaml @@ -0,0 +1,51 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +volumes: + peer0.org3.example.com: + +networks: + test: + name: fabric_test + +services: + + peer0.org3.example.com: + container_name: peer0.org3.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + #Generic peer variables + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=true + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org3.example.com + - CORE_PEER_ADDRESS=peer0.org3.example.com:11051 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_PEER_LISTENADDRESS=0.0.0.0:11051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org3.example.com:11052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:11052 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:11051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org3.example.com:11051 + - CORE_PEER_LOCALMSPID=Org3MSP + volumes: + - ../peercfg:/etc/hyperledger/peercfg + - ../../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com:/etc/hyperledger/fabric + - peer0.org3.example.com:/var/hyperledger/production + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + command: peer node start + ports: + - 11051:11051 + networks: + - test diff --git a/varion/addOrg3/configtx.yaml b/varion/addOrg3/configtx.yaml new file mode 100644 index 00000000..93502f02 --- /dev/null +++ b/varion/addOrg3/configtx.yaml @@ -0,0 +1,38 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + - &Org3 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org3MSP + + # ID to load the MSP definition as + ID: Org3MSP + + MSPDir: ../organizations/peerOrganizations/org3.example.com/msp + + Policies: + Readers: + Type: Signature + Rule: "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org3MSP.admin', 'Org3MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org3MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org3MSP.peer')" diff --git a/varion/addOrg3/fabric-ca/org3/fabric-ca-server-config.yaml b/varion/addOrg3/fabric-ca/org3/fabric-ca-server-config.yaml new file mode 100644 index 00000000..903106e7 --- /dev/null +++ b/varion/addOrg3/fabric-ca/org3/fabric-ca-server-config.yaml @@ -0,0 +1,408 @@ +############################################################################# +# This is a configuration file for the fabric-ca-server command. +# +# COMMAND LINE ARGUMENTS AND ENVIRONMENT VARIABLES +# ------------------------------------------------ +# Each configuration element can be overridden via command line +# arguments or environment variables. The precedence for determining +# the value of each element is as follows: +# 1) command line argument +# Examples: +# a) --port 443 +# To set the listening port +# b) --ca.keyfile ../mykey.pem +# To set the "keyfile" element in the "ca" section below; +# note the '.' separator character. +# 2) environment variable +# Examples: +# a) FABRIC_CA_SERVER_PORT=443 +# To set the listening port +# b) FABRIC_CA_SERVER_CA_KEYFILE="../mykey.pem" +# To set the "keyfile" element in the "ca" section below; +# note the '_' separator character. +# 3) configuration file +# 4) default value (if there is one) +# All default values are shown beside each element below. +# +# FILE NAME ELEMENTS +# ------------------ +# The value of all fields whose name ends with "file" or "files" are +# name or names of other files. +# For example, see "tls.certfile" and "tls.clientauth.certfiles". +# The value of each of these fields can be a simple filename, a +# relative path, or an absolute path. If the value is not an +# absolute path, it is interpretted as being relative to the location +# of this configuration file. +# +############################################################################# + +# Version of config file +version: 1.2.0 + +# Server's listening port (default: 7054) +port: 11054 + +# Enables debug logging (default: false) +debug: false + +# Size limit of an acceptable CRL in bytes (default: 512000) +crlsizelimit: 512000 + +############################################################################# +# TLS section for the server's listening port +# +# The following types are supported for client authentication: NoClientCert, +# RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, +# and RequireAndVerifyClientCert. +# +# Certfiles is a list of root certificate authorities that the server uses +# when verifying client certificates. +############################################################################# +tls: + # Enable TLS (default: false) + enabled: true + # TLS for the server's listening port + certfile: + keyfile: + clientauth: + type: noclientcert + certfiles: + +############################################################################# +# The CA section contains information related to the Certificate Authority +# including the name of the CA, which should be unique for all members +# of a blockchain network. It also includes the key and certificate files +# used when issuing enrollment certificates (ECerts) and transaction +# certificates (TCerts). +# The chainfile (if it exists) contains the certificate chain which +# should be trusted for this CA, where the 1st in the chain is always the +# root CA certificate. +############################################################################# +ca: + # Name of this CA + name: Org3CA + # Key file (is only used to import a private key into BCCSP) + keyfile: + # Certificate file (default: ca-cert.pem) + certfile: + # Chain file + chainfile: + +############################################################################# +# The gencrl REST endpoint is used to generate a CRL that contains revoked +# certificates. This section contains configuration options that are used +# during gencrl request processing. +############################################################################# +crl: + # Specifies expiration for the generated CRL. The number of hours + # specified by this property is added to the UTC time, the resulting time + # is used to set the 'Next Update' date of the CRL. + expiry: 24h + +############################################################################# +# The registry section controls how the fabric-ca-server does two things: +# 1) authenticates enrollment requests which contain a username and password +# (also known as an enrollment ID and secret). +# 2) once authenticated, retrieves the identity's attribute names and +# values which the fabric-ca-server optionally puts into TCerts +# which it issues for transacting on the Hyperledger Fabric blockchain. +# These attributes are useful for making access control decisions in +# chaincode. +# There are two main configuration options: +# 1) The fabric-ca-server is the registry. +# This is true if "ldap.enabled" in the ldap section below is false. +# 2) An LDAP server is the registry, in which case the fabric-ca-server +# calls the LDAP server to perform these tasks. +# This is true if "ldap.enabled" in the ldap section below is true, +# which means this "registry" section is ignored. +############################################################################# +registry: + # Maximum number of times a password/secret can be reused for enrollment + # (default: -1, which means there is no limit) + maxenrollments: -1 + + # Contains identity information which is used when LDAP is disabled + identities: + - name: admin + pass: adminpw + type: client + affiliation: "" + attrs: + hf.Registrar.Roles: "*" + hf.Registrar.DelegateRoles: "*" + hf.Revoker: true + hf.IntermediateCA: true + hf.GenCRL: true + hf.Registrar.Attributes: "*" + hf.AffiliationMgr: true + +############################################################################# +# Database section +# Supported types are: "sqlite3", "postgres", and "mysql". +# The datasource value depends on the type. +# If the type is "sqlite3", the datasource value is a file name to use +# as the database store. Since "sqlite3" is an embedded database, it +# may not be used if you want to run the fabric-ca-server in a cluster. +# To run the fabric-ca-server in a cluster, you must choose "postgres" +# or "mysql". +############################################################################# +db: + type: sqlite3 + datasource: fabric-ca-server.db + tls: + enabled: false + certfiles: + client: + certfile: + keyfile: + +############################################################################# +# LDAP section +# If LDAP is enabled, the fabric-ca-server calls LDAP to: +# 1) authenticate enrollment ID and secret (i.e. username and password) +# for enrollment requests; +# 2) To retrieve identity attributes +############################################################################# +ldap: + # Enables or disables the LDAP client (default: false) + # If this is set to true, the "registry" section is ignored. + enabled: false + # The URL of the LDAP server + url: ldap://:@:/ + # TLS configuration for the client connection to the LDAP server + tls: + certfiles: + client: + certfile: + keyfile: + # Attribute related configuration for mapping from LDAP entries to Fabric CA attributes + attribute: + # 'names' is an array of strings containing the LDAP attribute names which are + # requested from the LDAP server for an LDAP identity's entry + names: ['uid','member'] + # The 'converters' section is used to convert an LDAP entry to the value of + # a fabric CA attribute. + # For example, the following converts an LDAP 'uid' attribute + # whose value begins with 'revoker' to a fabric CA attribute + # named "hf.Revoker" with a value of "true" (because the boolean expression + # evaluates to true). + # converters: + # - name: hf.Revoker + # value: attr("uid") =~ "revoker*" + converters: + - name: + value: + # The 'maps' section contains named maps which may be referenced by the 'map' + # function in the 'converters' section to map LDAP responses to arbitrary values. + # For example, assume a user has an LDAP attribute named 'member' which has multiple + # values which are each a distinguished name (i.e. a DN). For simplicity, assume the + # values of the 'member' attribute are 'dn1', 'dn2', and 'dn3'. + # Further assume the following configuration. + # converters: + # - name: hf.Registrar.Roles + # value: map(attr("member"),"groups") + # maps: + # groups: + # - name: dn1 + # value: peer + # - name: dn2 + # value: client + # The value of the user's 'hf.Registrar.Roles' attribute is then computed to be + # "peer,client,dn3". This is because the value of 'attr("member")' is + # "dn1,dn2,dn3", and the call to 'map' with a 2nd argument of + # "group" replaces "dn1" with "peer" and "dn2" with "client". + maps: + groups: + - name: + value: + +############################################################################# +# Affiliations section. Fabric CA server can be bootstrapped with the +# affiliations specified in this section. Affiliations are specified as maps. +# For example: +# businessunit1: +# department1: +# - team1 +# businessunit2: +# - department2 +# - department3 +# +# Affiliations are hierarchical in nature. In the above example, +# department1 (used as businessunit1.department1) is the child of businessunit1. +# team1 (used as businessunit1.department1.team1) is the child of department1. +# department2 (used as businessunit2.department2) and department3 (businessunit2.department3) +# are children of businessunit2. +# Note: Affiliations are case sensitive except for the non-leaf affiliations +# (like businessunit1, department1, businessunit2) that are specified in the configuration file, +# which are always stored in lower case. +############################################################################# +affiliations: + org1: + - department1 + - department2 + org2: + - department1 + org3: + - department1 + +############################################################################# +# Signing section +# +# The "default" subsection is used to sign enrollment certificates; +# the default expiration ("expiry" field) is "8760h", which is 1 year in hours. +# +# The "ca" profile subsection is used to sign intermediate CA certificates; +# the default expiration ("expiry" field) is "43800h" which is 5 years in hours. +# Note that "isca" is true, meaning that it issues a CA certificate. +# A maxpathlen of 0 means that the intermediate CA cannot issue other +# intermediate CA certificates, though it can still issue end entity certificates. +# (See RFC 5280, section 4.2.1.9) +# +# The "tls" profile subsection is used to sign TLS certificate requests; +# the default expiration ("expiry" field) is "8760h", which is 1 year in hours. +############################################################################# +signing: + default: + usage: + - digital signature + expiry: 8760h + profiles: + ca: + usage: + - cert sign + - crl sign + expiry: 43800h + caconstraint: + isca: true + maxpathlen: 0 + tls: + usage: + - signing + - key encipherment + - server auth + - client auth + - key agreement + expiry: 8760h + +########################################################################### +# Certificate Signing Request (CSR) section. +# This controls the creation of the root CA certificate. +# The expiration for the root CA certificate is configured with the +# "ca.expiry" field below, whose default value is "131400h" which is +# 15 years in hours. +# The pathlength field is used to limit CA certificate hierarchy as described +# in section 4.2.1.9 of RFC 5280. +# Examples: +# 1) No pathlength value means no limit is requested. +# 2) pathlength == 1 means a limit of 1 is requested which is the default for +# a root CA. This means the root CA can issue intermediate CA certificates, +# but these intermediate CAs may not in turn issue other CA certificates +# though they can still issue end entity certificates. +# 3) pathlength == 0 means a limit of 0 is requested; +# this is the default for an intermediate CA, which means it can not issue +# CA certificates though it can still issue end entity certificates. +########################################################################### +csr: + cn: ca.org3.example.com + names: + - C: US + ST: "North Carolina" + L: "Raleigh" + O: org3.example.com + OU: + hosts: + - localhost + - org3.example.com + ca: + expiry: 131400h + pathlength: 1 + +############################################################################# +# BCCSP (BlockChain Crypto Service Provider) section is used to select which +# crypto library implementation to use +############################################################################# +bccsp: + default: SW + sw: + hash: SHA2 + security: 256 + filekeystore: + # The directory used for the software file-based keystore + keystore: msp/keystore + +############################################################################# +# Multi CA section +# +# Each Fabric CA server contains one CA by default. This section is used +# to configure multiple CAs in a single server. +# +# 1) --cacount +# Automatically generate non-default CAs. The names of these +# additional CAs are "ca1", "ca2", ... "caN", where "N" is +# This is particularly useful in a development environment to quickly set up +# multiple CAs. Note that, this config option is not applicable to intermediate CA server +# i.e., Fabric CA server that is started with intermediate.parentserver.url config +# option (-u command line option) +# +# 2) --cafiles +# For each CA config file in the list, generate a separate signing CA. Each CA +# config file in this list MAY contain all of the same elements as are found in +# the server config file except port, debug, and tls sections. +# +# Examples: +# fabric-ca-server start -b admin:adminpw --cacount 2 +# +# fabric-ca-server start -b admin:adminpw --cafiles ca/ca1/fabric-ca-server-config.yaml +# --cafiles ca/ca2/fabric-ca-server-config.yaml +# +############################################################################# + +cacount: + +cafiles: + +############################################################################# +# Intermediate CA section +# +# The relationship between servers and CAs is as follows: +# 1) A single server process may contain or function as one or more CAs. +# This is configured by the "Multi CA section" above. +# 2) Each CA is either a root CA or an intermediate CA. +# 3) Each intermediate CA has a parent CA which is either a root CA or another intermediate CA. +# +# This section pertains to configuration of #2 and #3. +# If the "intermediate.parentserver.url" property is set, +# then this is an intermediate CA with the specified parent +# CA. +# +# parentserver section +# url - The URL of the parent server +# caname - Name of the CA to enroll within the server +# +# enrollment section used to enroll intermediate CA with parent CA +# profile - Name of the signing profile to use in issuing the certificate +# label - Label to use in HSM operations +# +# tls section for secure socket connection +# certfiles - PEM-encoded list of trusted root certificate files +# client: +# certfile - PEM-encoded certificate file for when client authentication +# is enabled on server +# keyfile - PEM-encoded key file for when client authentication +# is enabled on server +############################################################################# +intermediate: + parentserver: + url: + caname: + + enrollment: + hosts: + profile: + label: + + tls: + certfiles: + client: + certfile: + keyfile: diff --git a/varion/addOrg3/fabric-ca/registerEnroll.sh b/varion/addOrg3/fabric-ca/registerEnroll.sh new file mode 100644 index 00000000..0c43aaf5 --- /dev/null +++ b/varion/addOrg3/fabric-ca/registerEnroll.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + +function createOrg3 { + infoln "Enrolling the CA admin" + mkdir -p ../organizations/peerOrganizations/org3.example.com/ + + export FABRIC_CA_CLIENT_HOME=${PWD}/../organizations/peerOrganizations/org3.example.com/ + + set -x + fabric-ca-client enroll -u https://admin:adminpw@localhost:11054 --caname ca-org3 --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/localhost-11054-ca-org3.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/localhost-11054-ca-org3.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/localhost-11054-ca-org3.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/localhost-11054-ca-org3.pem + OrganizationalUnitIdentifier: orderer' > "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml" + + infoln "Registering peer0" + set -x + fabric-ca-client register --caname ca-org3 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering user" + set -x + fabric-ca-client register --caname ca-org3 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering the org admin" + set -x + fabric-ca-client register --caname ca-org3 --id.name org3admin --id.secret org3adminpw --id.type admin --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + infoln "Generating the peer0 msp" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp" --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml" "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/config.yaml" + + infoln "Generating the peer0-tls certificates, use --csr.hosts to specify Subject Alternative Names" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:11054 --caname ca-org3 -M "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls" --enrollment.profile tls --csr.hosts peer0.org3.example.com --csr.hosts localhost --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/tlscacerts/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt" + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/signcerts/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.crt" + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/keystore/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.key" + + mkdir "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/tlscacerts" + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/tlscacerts/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/tlscacerts/ca.crt" + + mkdir "${PWD}/../organizations/peerOrganizations/org3.example.com/tlsca" + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/tlscacerts/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem" + + mkdir "${PWD}/../organizations/peerOrganizations/org3.example.com/ca" + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/cacerts/"* "${PWD}/../organizations/peerOrganizations/org3.example.com/ca/ca.org3.example.com-cert.pem" + + infoln "Generating the user msp" + set -x + fabric-ca-client enroll -u https://user1:user1pw@localhost:11054 --caname ca-org3 -M "${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp" --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml" "${PWD}/../organizations/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp/config.yaml" + + infoln "Generating the org admin msp" + set -x + fabric-ca-client enroll -u https://org3admin:org3adminpw@localhost:11054 --caname ca-org3 -M "${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp" --tls.certfiles "${PWD}/fabric-ca/org3/tls-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/../organizations/peerOrganizations/org3.example.com/msp/config.yaml" "${PWD}/../organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp/config.yaml" +} diff --git a/varion/addOrg3/org3-crypto.yaml b/varion/addOrg3/org3-crypto.yaml new file mode 100644 index 00000000..73ae7333 --- /dev/null +++ b/varion/addOrg3/org3-crypto.yaml @@ -0,0 +1,21 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# --------------------------------------------------------------------------- +# "PeerOrgs" - Definition of organizations managing peer nodes +# --------------------------------------------------------------------------- +PeerOrgs: + # --------------------------------------------------------------------------- + # Org3 + # --------------------------------------------------------------------------- + - Name: Org3 + Domain: org3.example.com + EnableNodeOUs: true + Template: + Count: 1 + SANS: + - localhost + Users: + Count: 1 diff --git a/varion/bft-config/configtx.yaml b/varion/bft-config/configtx.yaml new file mode 100644 index 00000000..39b6f0f3 --- /dev/null +++ b/varion/bft-config/configtx.yaml @@ -0,0 +1,312 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + - &OrdererOrg + # SampleOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: OrdererOrg + # ID to load the MSP definition as + ID: OrdererMSP + # MSPDir is the filesystem path which contains the MSP configuration + MSPDir: ../organizations/ordererOrganizations/example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Writers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Admins: + Type: Signature + Rule: "OR('OrdererMSP.admin')" + OrdererEndpoints: + - orderer.example.com:7050 + - orderer2.example.com:7052 + - orderer3.example.com:7056 + - orderer4.example.com:7058 + - &Org1 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org1MSP + # ID to load the MSP definition as + ID: Org1MSP + MSPDir: ../organizations/peerOrganizations/org1.example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org1MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org1MSP.peer')" + - &Org2 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org2MSP + # ID to load the MSP definition as + ID: Org2MSP + MSPDir: ../organizations/peerOrganizations/org2.example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org2MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org2MSP.peer')" +################################################################################ +# +# SECTION: Capabilities +# +# - This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. +# +################################################################################ +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. + # Set the value of the capability to true to require it. + Channel: &ChannelCapabilities + # V3.0 for Channel is a catchall flag for behavior which has been + # determined to be desired for all orderers and peers running at the v3.0.0 + # level, but which would be incompatible with orderers and peers from + # prior releases. + # Prior to enabling V3.0 channel capabilities, ensure that all + # orderers and peers on a channel are at v3.0.0 or later. + V3_0: true + # Orderer capabilities apply only to the orderers, and may be safely + # used with prior release peers. + # Set the value of the capability to true to require it. + Orderer: &OrdererCapabilities + # V2_0 orderer capability ensures that orderers behave according + # to v2.0 orderer capabilities. Orderers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 orderer capability. + # Prior to enabling V2.0 orderer capabilities, ensure that all + # orderers on channel are at v2.0.0 or later. + V2_0: true + # Application capabilities apply only to the peer network, and may be safely + # used with prior release orderers. + # Set the value of the capability to true to require it. + Application: &ApplicationCapabilities + # V2.5 for Application enables the new non-backwards compatible + # features of fabric v2.5, namely the ability to purge private data. + # Prior to enabling V2.5 application capabilities, ensure that all + # peers on a channel are at v2.5.0 or later. + V2_5: true +################################################################################ +# +# SECTION: Application +# +# - This section defines the values to encode into a config transaction or +# genesis block for application related parameters +# +################################################################################ +Application: &ApplicationDefaults + # Organizations is the list of orgs which are defined as participants on + # the application side of the network + Organizations: + # Policies defines the set of policies at this level of the config tree + # For Application policies, their canonical path is + # /Channel/Application/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + LifecycleEndorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Endorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Capabilities: + <<: *ApplicationCapabilities +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + # Batch Size: Controls the number of messages batched into a block + BatchSize: + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 99 MB + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: + # Policies defines the set of policies at this level of the config tree + # For Orderer policies, their canonical path is + # /Channel/Orderer/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # BlockValidation specifies what signatures must be included in the block + # from the orderer for the peer to validate it. + BlockValidation: + Type: ImplicitMeta + Rule: "ANY Writers" +################################################################################ +# +# CHANNEL +# +# This section defines the values to encode into a config transaction or +# genesis block for channel related parameters. +# +################################################################################ +Channel: &ChannelDefaults + # Policies defines the set of policies at this level of the config tree + # For Channel policies, their canonical path is + # /Channel/ + Policies: + # Who may invoke the 'Deliver' API + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + # Who may invoke the 'Broadcast' API + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + # By default, who may modify elements at this config level + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # Capabilities describes the channel level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *ChannelCapabilities +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + ChannelUsingBFT: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Capabilities: *OrdererCapabilities + OrdererType: BFT + SmartBFT: + RequestBatchMaxCount: 100 + RequestBatchMaxInterval: 50ms + RequestForwardTimeout: 2s + RequestComplainTimeout: 20s + RequestAutoRemoveTimeout: 3m0s + ViewChangeResendInterval: 5s + ViewChangeTimeout: 20s + LeaderHeartbeatTimeout: 1m0s + CollectTimeout: 1s + RequestBatchMaxBytes: 10485760 + IncomingMessageBufferSize: 200 + RequestPoolSize: 100000 + LeaderHeartbeatCount: 10 + ConsenterMapping: + - ID: 1 + Host: orderer.example.com + Port: 7050 + MSPID: OrdererMSP + Identity: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/signcerts/orderer.example.com-cert.pem + ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt + ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt + - ID: 2 + Host: orderer2.example.com + Port: 7052 + MSPID: OrdererMSP + Identity: ../organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/msp/signcerts/orderer2.example.com-cert.pem + ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt + ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt + - ID: 3 + Host: orderer3.example.com + Port: 7056 + MSPID: OrdererMSP + Identity: ../organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/msp/signcerts/orderer3.example.com-cert.pem + ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt + ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt + - ID: 4 + Host: orderer4.example.com + Port: 7058 + MSPID: OrdererMSP + Identity: ../organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/msp/signcerts/orderer4.example.com-cert.pem + ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt + ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: *ApplicationCapabilities \ No newline at end of file diff --git a/varion/compose/compose-bft-test-net.yaml b/varion/compose/compose-bft-test-net.yaml new file mode 100644 index 00000000..4ab83059 --- /dev/null +++ b/varion/compose/compose-bft-test-net.yaml @@ -0,0 +1,264 @@ +version: '3.7' + +volumes: + orderer.example.com: + orderer2.example.com: + orderer3.example.com: + orderer4.example.com: + peer0.org1.example.com: + peer0.org2.example.com: + +networks: + test: + name: fabric_test + +services: + + orderer.example.com: + container_name: orderer.example.com + image: hyperledger/fabric-orderer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_LOGGING_SPEC=INFO + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7050 + - 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_GENERAL_BOOTSTRAPMETHOD=none + - ORDERER_CHANNELPARTICIPATION_ENABLED=true + - ORDERER_ADMIN_TLS_ENABLED=true + - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7053 + - ORDERER_OPERATIONS_LISTENADDRESS=orderer.example.com:9443 + - ORDERER_METRICS_PROVIDER=prometheus + working_dir: /root + command: orderer + volumes: + - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp + - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls + - orderer.example.com:/var/hyperledger/production/orderer + ports: + - 7050:7050 + - 7053:7053 + - 9443:9443 + networks: + - test + + orderer2.example.com: + container_name: orderer2.example.com + image: hyperledger/fabric-orderer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_LOGGING_SPEC=INFO + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7052 + - 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_GENERAL_BOOTSTRAPMETHOD=none + - ORDERER_CHANNELPARTICIPATION_ENABLED=true + - ORDERER_ADMIN_TLS_ENABLED=true + - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7055 + - ORDERER_OPERATIONS_LISTENADDRESS=orderer2.example.com:9446 + - ORDERER_METRICS_PROVIDER=prometheus + working_dir: /root + command: orderer + volumes: + - ../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: + - 7052:7052 + - 7055:7055 + - 9446:9446 + networks: + - test + + orderer3.example.com: + container_name: orderer3.example.com + image: hyperledger/fabric-orderer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_LOGGING_SPEC=INFO + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7056 + - 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_GENERAL_BOOTSTRAPMETHOD=none + - ORDERER_CHANNELPARTICIPATION_ENABLED=true + - ORDERER_ADMIN_TLS_ENABLED=true + - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7057 + - ORDERER_OPERATIONS_LISTENADDRESS=orderer3.example.com:9447 + - ORDERER_METRICS_PROVIDER=prometheus + working_dir: /root + command: orderer + volumes: + - ../organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/msp:/var/hyperledger/orderer/msp + - ../organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/:/var/hyperledger/orderer/tls + - orderer3.example.com:/var/hyperledger/production/orderer + ports: + - 7056:7056 + - 7057:7057 + - 9447:9447 + networks: + - test + + orderer4.example.com: + container_name: orderer4.example.com + image: hyperledger/fabric-orderer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_LOGGING_SPEC=INFO + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7058 + - 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_GENERAL_BOOTSTRAPMETHOD=none + - ORDERER_CHANNELPARTICIPATION_ENABLED=true + - ORDERER_ADMIN_TLS_ENABLED=true + - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7059 + - ORDERER_OPERATIONS_LISTENADDRESS=orderer4.example.com:9448 + - ORDERER_METRICS_PROVIDER=prometheus + working_dir: /root + command: orderer + volumes: + - ../organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/msp:/var/hyperledger/orderer/msp + - ../organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/:/var/hyperledger/orderer/tls + - orderer4.example.com:/var/hyperledger/production/orderer + ports: + - 7058:7058 + - 7059:7059 + - 9448:9448 + networks: + - test + + + + + peer0.org1.example.com: + container_name: peer0.org1.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=false + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org1.example.com + - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_LOCALMSPID=Org1MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_OPERATIONS_LISTENADDRESS=peer0.org1.example.com:9444 + - CORE_METRICS_PROVIDER=prometheus + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org1"} + - CORE_CHAINCODE_EXECUTETIMEOUT=300s + volumes: + - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com:/etc/hyperledger/fabric + - peer0.org1.example.com:/var/hyperledger/production + working_dir: /root + command: peer node start + ports: + - 7051:7051 + - 9444:9444 + networks: + - test + + peer0.org2.example.com: + container_name: peer0.org2.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=false + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org2.example.com + - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 + - CORE_PEER_LISTENADDRESS=0.0.0.0:9051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051 + - CORE_PEER_LOCALMSPID=Org2MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_OPERATIONS_LISTENADDRESS=peer0.org2.example.com:9445 + - CORE_METRICS_PROVIDER=prometheus + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org2"} + - CORE_CHAINCODE_EXECUTETIMEOUT=300s + volumes: + - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com:/etc/hyperledger/fabric + - peer0.org2.example.com:/var/hyperledger/production + working_dir: /root + command: peer node start + ports: + - 9051:9051 + - 9445:9445 + networks: + - test diff --git a/varion/compose/compose-ca.yaml b/varion/compose/compose-ca.yaml new file mode 100644 index 00000000..f678755b --- /dev/null +++ b/varion/compose/compose-ca.yaml @@ -0,0 +1,72 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + + ca_org1: + image: hyperledger/fabric-ca:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org1 + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_PORT=7054 + - FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS=0.0.0.0:17054 + ports: + - "7054:7054" + - "17054:17054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../organizations/fabric-ca/org1:/etc/hyperledger/fabric-ca-server + container_name: ca_org1 + networks: + - test + + ca_org2: + image: hyperledger/fabric-ca:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org2 + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_PORT=8054 + - FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS=0.0.0.0:18054 + ports: + - "8054:8054" + - "18054:18054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../organizations/fabric-ca/org2:/etc/hyperledger/fabric-ca-server + container_name: ca_org2 + networks: + - test + + ca_orderer: + image: hyperledger/fabric-ca:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-orderer + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_PORT=9054 + - FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS=0.0.0.0:19054 + ports: + - "9054:9054" + - "19054:19054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../organizations/fabric-ca/ordererOrg:/etc/hyperledger/fabric-ca-server + container_name: ca_orderer + networks: + - test diff --git a/varion/compose/compose-couch.yaml b/varion/compose/compose-couch.yaml new file mode 100644 index 00000000..4a88f45a --- /dev/null +++ b/varion/compose/compose-couch.yaml @@ -0,0 +1,69 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +networks: + test: + name: fabric_test + +services: + couchdb0: + container_name: couchdb0 + image: couchdb:3.3.3 + labels: + service: hyperledger-fabric + # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password + # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. + environment: + - COUCHDB_USER=admin + - COUCHDB_PASSWORD=adminpw + # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, + # for example map it to utilize Fauxton User Interface in dev environments. + ports: + - "5984:5984" + networks: + - test + + peer0.org1.example.com: + environment: + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984 + # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD + # provide the credentials for ledger to connect to CouchDB. The username and password must + # match the username and password set for the associated CouchDB. + - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin + - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw + depends_on: + - couchdb0 + + couchdb1: + container_name: couchdb1 + image: couchdb:3.3.3 + labels: + service: hyperledger-fabric + # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password + # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. + environment: + - COUCHDB_USER=admin + - COUCHDB_PASSWORD=adminpw + # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, + # for example map it to utilize Fauxton User Interface in dev environments. + ports: + - "7984:5984" + networks: + - test + + peer0.org2.example.com: + environment: + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984 + # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD + # provide the credentials for ledger to connect to CouchDB. The username and password must + # match the username and password set for the associated CouchDB. + - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin + - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw + depends_on: + - couchdb1 diff --git a/varion/compose/compose-test-net.yaml b/varion/compose/compose-test-net.yaml new file mode 100644 index 00000000..dcac21b0 --- /dev/null +++ b/varion/compose/compose-test-net.yaml @@ -0,0 +1,137 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +volumes: + orderer.example.com: + peer0.org1.example.com: + peer0.org2.example.com: + +networks: + test: + name: fabric_test + +services: + + orderer.example.com: + container_name: orderer.example.com + image: hyperledger/fabric-orderer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_LOGGING_SPEC=INFO + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_LISTENPORT=7050 + - 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_GENERAL_BOOTSTRAPMETHOD=none + - ORDERER_CHANNELPARTICIPATION_ENABLED=true + - ORDERER_ADMIN_TLS_ENABLED=true + - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt + - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key + - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] + - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7053 + - ORDERER_OPERATIONS_LISTENADDRESS=orderer.example.com:9443 + - ORDERER_METRICS_PROVIDER=prometheus + working_dir: /root + command: orderer + volumes: + - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp + - ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls + - orderer.example.com:/var/hyperledger/production/orderer + ports: + - 7050:7050 + - 7053:7053 + - 9443:9443 + networks: + - test + + peer0.org1.example.com: + container_name: peer0.org1.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=false + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org1.example.com + - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_LOCALMSPID=Org1MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_OPERATIONS_LISTENADDRESS=peer0.org1.example.com:9444 + - CORE_METRICS_PROVIDER=prometheus + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org1"} + - CORE_CHAINCODE_EXECUTETIMEOUT=300s + volumes: + - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com:/etc/hyperledger/fabric + - peer0.org1.example.com:/var/hyperledger/production + working_dir: /root + command: peer node start + ports: + - 7051:7051 + - 9444:9444 + networks: + - test + + peer0.org2.example.com: + container_name: peer0.org2.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + - FABRIC_CFG_PATH=/etc/hyperledger/peercfg + - FABRIC_LOGGING_SPEC=INFO + #- FABRIC_LOGGING_SPEC=DEBUG + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_PROFILE_ENABLED=false + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt + # Peer specific variables + - CORE_PEER_ID=peer0.org2.example.com + - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 + - CORE_PEER_LISTENADDRESS=0.0.0.0:9051 + - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052 + - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051 + - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051 + - CORE_PEER_LOCALMSPID=Org2MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_OPERATIONS_LISTENADDRESS=peer0.org2.example.com:9445 + - CORE_METRICS_PROVIDER=prometheus + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG={"peername":"peer0org2"} + - CORE_CHAINCODE_EXECUTETIMEOUT=300s + volumes: + - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com:/etc/hyperledger/fabric + - peer0.org2.example.com:/var/hyperledger/production + working_dir: /root + command: peer node start + ports: + - 9051:9051 + - 9445:9445 + networks: + - test diff --git a/varion/compose/docker/docker-compose-bft-test-net.yaml b/varion/compose/docker/docker-compose-bft-test-net.yaml new file mode 100644 index 00000000..421d8e0b --- /dev/null +++ b/varion/compose/docker/docker-compose-bft-test-net.yaml @@ -0,0 +1,32 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' +services: + peer0.org1.example.com: + container_name: peer0.org1.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + #Generic peer variables + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test + volumes: + - ./docker/peercfg:/etc/hyperledger/peercfg + - ${DOCKER_SOCK}:/host/var/run/docker.sock + + peer0.org2.example.com: + container_name: peer0.org2.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + #Generic peer variables + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test + volumes: + - ./docker/peercfg:/etc/hyperledger/peercfg + - ${DOCKER_SOCK}:/host/var/run/docker.sock diff --git a/varion/compose/docker/docker-compose-ca.yaml b/varion/compose/docker/docker-compose-ca.yaml new file mode 100644 index 00000000..16732f0c --- /dev/null +++ b/varion/compose/docker/docker-compose-ca.yaml @@ -0,0 +1,7 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + diff --git a/varion/compose/docker/docker-compose-couch.yaml b/varion/compose/docker/docker-compose-couch.yaml new file mode 100644 index 00000000..6ab883d4 --- /dev/null +++ b/varion/compose/docker/docker-compose-couch.yaml @@ -0,0 +1,6 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' diff --git a/varion/compose/docker/docker-compose-test-net.yaml b/varion/compose/docker/docker-compose-test-net.yaml new file mode 100644 index 00000000..421d8e0b --- /dev/null +++ b/varion/compose/docker/docker-compose-test-net.yaml @@ -0,0 +1,32 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' +services: + peer0.org1.example.com: + container_name: peer0.org1.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + #Generic peer variables + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test + volumes: + - ./docker/peercfg:/etc/hyperledger/peercfg + - ${DOCKER_SOCK}:/host/var/run/docker.sock + + peer0.org2.example.com: + container_name: peer0.org2.example.com + image: hyperledger/fabric-peer:latest + labels: + service: hyperledger-fabric + environment: + #Generic peer variables + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test + volumes: + - ./docker/peercfg:/etc/hyperledger/peercfg + - ${DOCKER_SOCK}:/host/var/run/docker.sock diff --git a/varion/compose/docker/peercfg/core.yaml b/varion/compose/docker/peercfg/core.yaml new file mode 100644 index 00000000..b20e421c --- /dev/null +++ b/varion/compose/docker/peercfg/core.yaml @@ -0,0 +1,777 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Settings for the Peer's gateway server. + gateway: + # Whether the gateway is enabled for this Peer. + enabled: true + # endorsementTimeout is the duration the gateway waits for a response + # from other endorsing peers before returning a timeout error to the client. + endorsementTimeout: 30s + # dialTimeout is the duration the gateway waits for a connection + # to other network nodes. + dialTimeout: 2m + + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is false, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: false + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + + # Path on the file system where peer will find MSP local configurations + mspConfigPath: msp + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: SampleOrg + + # CLI common client config options + client: + # connection timeout + connTimeout: 3s + + # Delivery service related config + deliveryclient: + # Enables this peer to disseminate blocks it pulled from the ordering service + # via gossip. + # Note that 'gossip.state.enabled' controls point to point block replication + # of blocks committed in the past. + blockGossipEnabled: true + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 3s + + # It sets the delivery service maximal delay between consecutive retries + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes GRPC server and client can receive + maxRecvMsgSize: 104857600 + # Max message size in bytes GRPC server and client can send + maxSendMsgSize: 104857600 + +############################################################################### +# +# VM section +# +############################################################################### +vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # If you utilize external chaincode builders and don't need the default Docker chaincode builder, + # the endpoint should be unconfigured so that the peer's Docker health checker doesn't get registered. + endpoint: unix:///var/run/docker.sock + + # settings for docker vms + docker: + tls: + enabled: false + ca: + file: docker/ca.crt + cert: + file: docker/tls.crt + key: + file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + hostConfig: + NetworkMode: host + Dns: + # - 192.168.0.1 + LogConfig: + Type: json-file + Config: + max-size: "50m" + max-file: "5" + Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. + # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/ccaas_builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + + snapshots: + # Path on the file system where peer will store ledger snapshots + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/varion/compose/podman/peercfg/core.yaml b/varion/compose/podman/peercfg/core.yaml new file mode 100644 index 00000000..b5000333 --- /dev/null +++ b/varion/compose/podman/peercfg/core.yaml @@ -0,0 +1,777 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################### +# +# Peer section +# +############################################################################### +peer: + + # The peer id provides a name for this peer instance and is used when + # naming docker resources. + id: jdoe + + # The networkId allows for logical separation of networks and is used when + # naming docker resources. + networkId: dev + + # The Address at local network interface this Peer will listen on. + # By default, it will listen on all network interfaces + listenAddress: 0.0.0.0:7051 + + # The endpoint this peer uses to listen for inbound chaincode connections. + # If this is commented-out, the listen address is selected to be + # the peer's address (see below) with port 7052 + # chaincodeListenAddress: 0.0.0.0:7052 + + # The endpoint the chaincode for this peer uses to connect to the peer. + # If this is not specified, the chaincodeListenAddress address is selected. + # And if chaincodeListenAddress is not specified, address is selected from + # peer address (see below). If specified peer address is invalid then it + # will fallback to the auto detected IP (local IP) regardless of the peer + # addressAutoDetect value. + # chaincodeAddress: 0.0.0.0:7052 + + # When used as peer config, this represents the endpoint to other peers + # in the same organization. For peers in other organization, see + # gossip.externalEndpoint for more info. + # When used as CLI config, this means the peer's endpoint to interact with + address: 0.0.0.0:7051 + + # Whether the Peer should programmatically determine its address + # This case is useful for docker containers. + # When set to true, will override peer address. + addressAutoDetect: false + + # Settings for the Peer's gateway server. + gateway: + # Whether the gateway is enabled for this Peer. + enabled: true + # endorsementTimeout is the duration the gateway waits for a response + # from other endorsing peers before returning a timeout error to the client. + endorsementTimeout: 30s + # dialTimeout is the duration the gateway waits for a connection + # to other network nodes. + dialTimeout: 2m + + + # Keepalive settings for peer server and clients + keepalive: + # Interval is the duration after which if the server does not see + # any activity from the client it pings the client to see if it's alive + interval: 7200s + # Timeout is the duration the server waits for a response + # from the client after sending a ping before closing the connection + timeout: 20s + # MinInterval is the minimum permitted time between client pings. + # If clients send pings more frequently, the peer server will + # disconnect them + minInterval: 60s + # Client keepalive settings for communicating with other peer nodes + client: + # Interval is the time between pings to peer nodes. This must + # greater than or equal to the minInterval specified by peer + # nodes + interval: 60s + # Timeout is the duration the client waits for a response from + # peer nodes before closing the connection + timeout: 20s + # DeliveryClient keepalive settings for communication with ordering + # nodes. + deliveryClient: + # Interval is the time between pings to ordering nodes. This must + # greater than or equal to the minInterval specified by ordering + # nodes. + interval: 60s + # Timeout is the duration the client waits for a response from + # ordering nodes before closing the connection + timeout: 20s + + + # Gossip related configuration + gossip: + # Bootstrap set to initialize gossip with. + # This is a list of other peers that this peer reaches out to at startup. + # Important: The endpoints here have to be endpoints of peers in the same + # organization, because the peer would refuse connecting to these endpoints + # unless they are in the same organization as the peer. + bootstrap: 127.0.0.1:7051 + + # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive. + # Setting both to true would result in the termination of the peer + # since this is undefined state. If the peers are configured with + # useLeaderElection=false, make sure there is at least 1 peer in the + # organization that its orgLeader is set to true. + + # Defines whenever peer will initialize dynamic algorithm for + # "leader" selection, where leader is the peer to establish + # connection with ordering service and use delivery protocol + # to pull ledger blocks from ordering service. + useLeaderElection: false + # Statically defines peer to be an organization "leader", + # where this means that current peer will maintain connection + # with ordering service and disseminate block across peers in + # its own organization. Multiple peers or all peers in an organization + # may be configured as org leaders, so that they all pull + # blocks directly from ordering service. + orgLeader: true + + # Interval for membershipTracker polling + membershipTrackerInterval: 5s + + # Overrides the endpoint that the peer publishes to peers + # in its organization. For peers in foreign organizations + # see 'externalEndpoint' + endpoint: + # Maximum count of blocks stored in memory + maxBlockCountToStore: 10 + # Max time between consecutive message pushes(unit: millisecond) + maxPropagationBurstLatency: 10ms + # Max number of messages stored until a push is triggered to remote peers + maxPropagationBurstSize: 10 + # Number of times a message is pushed to remote peers + propagateIterations: 1 + # Number of peers selected to push messages to + propagatePeerNum: 3 + # Determines frequency of pull phases(unit: second) + # Must be greater than digestWaitTime + responseWaitTime + pullInterval: 4s + # Number of peers to pull from + pullPeerNum: 3 + # Determines frequency of pulling state info messages from peers(unit: second) + requestStateInfoInterval: 4s + # Determines frequency of pushing state info messages to peers(unit: second) + publishStateInfoInterval: 4s + # Maximum time a stateInfo message is kept until expired + stateInfoRetentionInterval: + # Time from startup certificates are included in Alive messages(unit: second) + publishCertPeriod: 10s + # Should we skip verifying block messages or not (currently not in use) + skipBlockVerification: false + # Dial timeout(unit: second) + dialTimeout: 3s + # Connection timeout(unit: second) + connTimeout: 2s + # Buffer size of received messages + recvBuffSize: 20 + # Buffer size of sending messages + sendBuffSize: 200 + # Time to wait before pull engine processes incoming digests (unit: second) + # Should be slightly smaller than requestWaitTime + digestWaitTime: 1s + # Time to wait before pull engine removes incoming nonce (unit: milliseconds) + # Should be slightly bigger than digestWaitTime + requestWaitTime: 1500ms + # Time to wait before pull engine ends pull (unit: second) + responseWaitTime: 2s + # Alive check interval(unit: second) + aliveTimeInterval: 5s + # Alive expiration timeout(unit: second) + aliveExpirationTimeout: 25s + # Reconnect interval(unit: second) + reconnectInterval: 25s + # Max number of attempts to connect to a peer + maxConnectionAttempts: 120 + # Message expiration factor for alive messages + msgExpirationFactor: 20 + # This is an endpoint that is published to peers outside of the organization. + # If this isn't set, the peer will not be known to other organizations. + externalEndpoint: + # Leader election service configuration + election: + # Longest time peer waits for stable membership during leader election startup (unit: second) + startupGracePeriod: 15s + # Interval gossip membership samples to check its stability (unit: second) + membershipSampleInterval: 1s + # Time passes since last declaration message before peer decides to perform leader election (unit: second) + leaderAliveThreshold: 10s + # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) + leaderElectionDuration: 5s + + pvtData: + # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block + # would be attempted to be pulled from peers until the block would be committed without the private data + pullRetryThreshold: 60s + # As private data enters the transient store, it is associated with the peer's ledger's height at that time. + # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit, + # and the private data residing inside the transient store that is guaranteed not to be purged. + # Private data is purged from the transient store when blocks with sequences that are multiples + # of transientstoreMaxBlockRetention are committed. + transientstoreMaxBlockRetention: 1000 + # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer + # at private data push at endorsement time. + pushAckTimeout: 3s + # Block to live pulling margin, used as a buffer + # to prevent peer from trying to pull private data + # from peers that is soon to be purged in next N blocks. + # This helps a newly joined peer catch up to current + # blockchain height quicker. + btlPullMargin: 10 + # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to + # pull from the other peers the most recent missing blocks with a maximum batch size limitation. + # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a + # single iteration. + reconcileBatchSize: 10 + # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning + # of the next reconciliation iteration. + reconcileSleepInterval: 1m + # reconciliationEnabled is a flag that indicates whether private data reconciliation is enable or not. + reconciliationEnabled: true + # skipPullingInvalidTransactionsDuringCommit is a flag that indicates whether pulling of invalid + # transaction's private data from other peers need to be skipped during the commit time and pulled + # only through reconciler. + skipPullingInvalidTransactionsDuringCommit: false + # implicitCollectionDisseminationPolicy specifies the dissemination policy for the peer's own implicit collection. + # When a peer endorses a proposal that writes to its own implicit collection, below values override the default values + # for disseminating private data. + # Note that it is applicable to all channels the peer has joined. The implication is that requiredPeerCount has to + # be smaller than the number of peers in a channel that has the lowest numbers of peers from the organization. + implicitCollectionDisseminationPolicy: + # requiredPeerCount defines the minimum number of eligible peers to which the peer must successfully + # disseminate private data for its own implicit collection during endorsement. Default value is 0. + requiredPeerCount: 0 + # maxPeerCount defines the maximum number of eligible peers to which the peer will attempt to + # disseminate private data for its own implicit collection during endorsement. Default value is 1. + maxPeerCount: 1 + + # Gossip state transfer related configuration + state: + # indicates whenever state transfer is enabled or not + # default value is false, i.e. state transfer is active + # and takes care to sync up missing blocks allowing + # lagging peer to catch up to speed with rest network. + # Keep in mind that when peer.gossip.useLeaderElection is true + # and there are several peers in the organization, + # or peer.gossip.useLeaderElection is false alongside with + # peer.gossip.orgleader being false, the peer's ledger may lag behind + # the rest of the peers and will never catch up due to state transfer + # being disabled. + enabled: false + # checkInterval interval to check whether peer is lagging behind enough to + # request blocks via state transfer from another peer. + checkInterval: 10s + # responseTimeout amount of time to wait for state transfer response from + # other peers + responseTimeout: 3s + # batchSize the number of blocks to request via state transfer from another peer + batchSize: 10 + # blockBufferSize reflects the size of the re-ordering buffer + # which captures blocks and takes care to deliver them in order + # down to the ledger layer. The actual buffer size is bounded between + # 0 and 2*blockBufferSize, each channel maintains its own buffer + blockBufferSize: 20 + # maxRetries maximum number of re-tries to ask + # for single state transfer request + maxRetries: 3 + + # TLS Settings + tls: + # Require server-side TLS + enabled: false + # Require client certificates / mutual TLS for inbound connections. + # Note that clients that are not configured to use a certificate will + # fail to connect to the peer. + clientAuthRequired: false + # X.509 certificate used for TLS server + cert: + file: tls/server.crt + # Private key used for TLS server + key: + file: tls/server.key + # rootcert.file represents the trusted root certificate chain used for verifying certificates + # of other nodes during outbound connections. + # It is not required to be set, but can be used to augment the set of TLS CA certificates + # available from the MSPs of each channel’s configuration. + rootcert: + file: tls/ca.crt + # If mutual TLS is enabled, clientRootCAs.files contains a list of additional root certificates + # used for verifying certificates of client connections. + # It augments the set of TLS CA certificates available from the MSPs of each channel’s configuration. + # Minimally, set your organization's TLS CA root certificate so that the peer can receive join channel requests. + clientRootCAs: + files: + - tls/ca.crt + # Private key used for TLS when making client connections. + # If not set, peer.tls.key.file will be used instead + clientKey: + file: + # X.509 certificate used for TLS when making client connections. + # If not set, peer.tls.cert.file will be used instead + clientCert: + file: + + # Authentication contains configuration parameters related to authenticating + # client messages + authentication: + # the acceptable difference between the current server time and the + # client's time as specified in a client request message + timewindow: 15m + + # Path on the file system where peer will store data (eg ledger). This + # location must be access control protected to prevent unintended + # modification that might corrupt the peer operations. + fileSystemPath: /var/hyperledger/production + + # BCCSP (Blockchain crypto provider): Select which crypto implementation or + # library to use + BCCSP: + Default: SW + # Settings for the SW crypto provider (i.e. when DEFAULT: SW) + SW: + # TODO: The default Hash and Security level needs refactoring to be + # fully configurable. Changing these defaults requires coordination + # SHA2 is hardcoded in several places, not only BCCSP + Hash: SHA2 + Security: 256 + # Location of Key Store + FileKeyStore: + # If "", defaults to 'mspConfigPath'/keystore + KeyStore: + # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11) + PKCS11: + # Location of the PKCS11 module library + Library: + # Token Label + Label: + # User PIN + Pin: + Hash: + Security: + + # Path on the file system where peer will find MSP local configurations + mspConfigPath: msp + # Identifier of the local MSP + # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!---- + # Deployers need to change the value of the localMspId string. + # In particular, the name of the local MSP ID of a peer needs + # to match the name of one of the MSPs in each of the channel + # that this peer is a member of. Otherwise this peer's messages + # will not be identified as valid by other nodes. + localMspId: SampleOrg + + # CLI common client config options + client: + # connection timeout + connTimeout: 3s + + # Delivery service related config + deliveryclient: + # Enables this peer to disseminate blocks it pulled from the ordering service + # via gossip. + # Note that 'gossip.state.enabled' controls point to point block replication + # of blocks committed in the past. + blockGossipEnabled: true + # It sets the total time the delivery service may spend in reconnection + # attempts until its retry logic gives up and returns an error + reconnectTotalTimeThreshold: 3600s + + # It sets the delivery service <-> ordering service node connection timeout + connTimeout: 3s + + # It sets the delivery service maximal delay between consecutive retries + reConnectBackoffThreshold: 3600s + + # A list of orderer endpoint addresses which should be overridden + # when found in channel configurations. + addressOverrides: + # - from: + # to: + # caCertsFile: + # - from: + # to: + # caCertsFile: + + # Type for the local MSP - by default it's of type bccsp + localMspType: bccsp + + # Used with Go profiling tools only in none production environment. In + # production, it should be disabled (eg enabled: false) + profile: + enabled: false + listenAddress: 0.0.0.0:6060 + + # Handlers defines custom handlers that can filter and mutate + # objects passing within the peer, such as: + # Auth filter - reject or forward proposals from clients + # Decorators - append or mutate the chaincode input passed to the chaincode + # Endorsers - Custom signing over proposal response payload and its mutation + # Valid handler definition contains: + # - A name which is a factory method name defined in + # core/handlers/library/library.go for statically compiled handlers + # - library path to shared object binary for pluggable filters + # Auth filters and decorators are chained and executed in the order that + # they are defined. For example: + # authFilters: + # - + # name: FilterOne + # library: /opt/lib/filter.so + # - + # name: FilterTwo + # decorators: + # - + # name: DecoratorOne + # - + # name: DecoratorTwo + # library: /opt/lib/decorator.so + # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden. + # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality + # as the default ESCC. + # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar + # to auth filters and decorators. + # endorsers: + # escc: + # name: DefaultESCC + # library: /etc/hyperledger/fabric/plugin/escc.so + handlers: + authFilters: + - + name: DefaultAuth + - + name: ExpirationCheck # This filter checks identity x509 certificate expiration + decorators: + - + name: DefaultDecorator + endorsers: + escc: + name: DefaultEndorsement + library: + validators: + vscc: + name: DefaultValidation + library: + + # library: /etc/hyperledger/fabric/plugin/escc.so + # Number of goroutines that will execute transaction validation in parallel. + # By default, the peer chooses the number of CPUs on the machine. Set this + # variable to override that choice. + # NOTE: overriding this value might negatively influence the performance of + # the peer so please change this value only if you know what you're doing + validatorPoolSize: + + # The discovery service is used by clients to query information about peers, + # such as - which peers have joined a certain channel, what is the latest + # channel config, and most importantly - given a chaincode and a channel, + # what possible sets of peers satisfy the endorsement policy. + discovery: + enabled: true + # Whether the authentication cache is enabled or not. + authCacheEnabled: true + # The maximum size of the cache, after which a purge takes place + authCacheMaxSize: 1000 + # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation + authCachePurgeRetentionRatio: 0.75 + # Whether to allow non-admins to perform non channel scoped queries. + # When this is false, it means that only peer admins can perform non channel scoped queries. + orgMembersAllowedAccess: false + + # Limits is used to configure some internal resource limits. + limits: + # Concurrency limits the number of concurrently running requests to a service on each peer. + # Currently this option is only applied to endorser service and deliver service. + # When the property is missing or the value is 0, the concurrency limit is disabled for the service. + concurrency: + # endorserService limits concurrent requests to endorser service that handles chaincode deployment, query and invocation, + # including both user chaincodes and system chaincodes. + endorserService: 2500 + # deliverService limits concurrent event listeners registered to deliver service for blocks and transaction events. + deliverService: 2500 + + # Since all nodes should be consistent it is recommended to keep + # the default value of 100MB for MaxRecvMsgSize & MaxSendMsgSize + # Max message size in bytes GRPC server and client can receive + maxRecvMsgSize: 104857600 + # Max message size in bytes GRPC server and client can send + maxSendMsgSize: 104857600 + +############################################################################### +# +# VM section +# +############################################################################### +#vm: + + # Endpoint of the vm management system. For docker can be one of the following in general + # unix:///var/run/docker.sock + # http://localhost:2375 + # https://localhost:2376 + # If you utilize external chaincode builders and don't need the default Docker chaincode builder, + # the endpoint should be unconfigured so that the peer's Docker health checker doesn't get registered. +# endpoint: unix:///var/run/docker.sock + + # settings for docker vms + # docker: + # tls: + # enabled: false + # ca: + # file: docker/ca.crt + # cert: + # file: docker/tls.crt + # key: + # file: docker/tls.key + + # Enables/disables the standard out/err from chaincode containers for + # debugging purposes + # attachStdout: false + + # Parameters on creating docker container. + # Container may be efficiently created using ipam & dns-server for cluster + # NetworkMode - sets the networking mode for the container. Supported + # standard values are: `host`(default),`bridge`,`ipvlan`,`none`. + # Dns - a list of DNS servers for the container to use. + # Note: `Privileged` `Binds` `Links` and `PortBindings` properties of + # Docker Host Config are not supported and will not be used if set. + # LogConfig - sets the logging driver (Type) and related options + # (Config) for Docker. For more info, + # https://docs.docker.com/engine/admin/logging/overview/ + # Note: Set LogConfig using Environment Variables is not supported. + # hostConfig: + # NetworkMode: host + # Dns: + # # - 192.168.0.1 + # LogConfig: + # Type: json-file + # Config: + # max-size: "50m" + # max-file: "5" + # Memory: 2147483648 + +############################################################################### +# +# Chaincode section +# +############################################################################### +chaincode: + + # The id is used by the Chaincode stub to register the executing Chaincode + # ID with the Peer and is generally supplied through ENV variables + # the `path` form of ID is provided when installing the chaincode. + # The `name` is used for all other requests and can be any string. + id: + path: + name: + + # Generic builder environment, suitable for most chaincode types + builder: $(DOCKER_NS)/fabric-ccenv:$(TWO_DIGIT_VERSION) + + # Enables/disables force pulling of the base docker images (listed below) + # during user chaincode instantiation. + # Useful when using moving image tags (such as :latest) + pull: false + + golang: + # golang will never need more than baseos + runtime: $(DOCKER_NS)/fabric-baseos:$(TWO_DIGIT_VERSION) + + # whether or not golang chaincode should be linked dynamically + dynamicLink: false + + java: + # This is an image based on java:openjdk-8 with addition compiler + # tools added for java shim layer packaging. + # This image is packed with shim layer libraries that are necessary + # for Java chaincode runtime. + runtime: $(DOCKER_NS)/fabric-javaenv:$(TWO_DIGIT_VERSION) + + node: + # This is an image based on node:$(NODE_VER)-alpine + runtime: $(DOCKER_NS)/fabric-nodeenv:$(TWO_DIGIT_VERSION) + + # List of directories to treat as external builders and launchers for + # chaincode. The external builder detection processing will iterate over the + # builders in the order specified below. + # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. + # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/ccaas_builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + + + # The maximum duration to wait for the chaincode build and install process + # to complete. + installTimeout: 300s + + # Timeout duration for starting up a container and waiting for Register + # to come through. + startuptimeout: 300s + + # Timeout duration for Invoke and Init calls to prevent runaway. + # This timeout is used by all chaincodes in all the channels, including + # system chaincodes. + # Note that during Invoke, if the image is not available (e.g. being + # cleaned up when in development environment), the peer will automatically + # build the image, which might take more time. In production environment, + # the chaincode image is unlikely to be deleted, so the timeout could be + # reduced accordingly. + executetimeout: 30s + + # There are 2 modes: "dev" and "net". + # In dev mode, user runs the chaincode after starting peer from + # command line on local machine. + # In net mode, peer will run chaincode in a docker container. + mode: net + + # keepalive in seconds. In situations where the communication goes through a + # proxy that does not support keep-alive, this parameter will maintain connection + # between peer and chaincode. + # A value <= 0 turns keepalive off + keepalive: 0 + + # enabled system chaincodes + system: + _lifecycle: enable + cscc: enable + lscc: enable + qscc: enable + + # Logging section for the chaincode container + logging: + # Default level for all loggers within the chaincode container + level: info + # Override default level for the 'shim' logger + shim: warning + # Format for the chaincode container logs + format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' + +############################################################################### +# +# Ledger section - ledger configuration encompasses both the blockchain +# and the state +# +############################################################################### +ledger: + + blockchain: + + state: + # stateDatabase - options are "goleveldb", "CouchDB" + # goleveldb - default state database stored in goleveldb. + # CouchDB - store state database in CouchDB + stateDatabase: goleveldb + # Limit on the number of records to return per query + totalQueryLimit: 100000 + couchDBConfig: + # It is recommended to run CouchDB on the same server as the peer, and + # not map the CouchDB container port to a server port in docker-compose. + # Otherwise proper security must be provided on the connection between + # CouchDB client (on the peer) and server. + couchDBAddress: 127.0.0.1:5984 + # This username must have read and write authority on CouchDB + username: + # The password is recommended to pass as an environment variable + # during start up (eg CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD). + # If it is stored here, the file must be access control protected + # to prevent unintended users from discovering the password. + password: + # Number of retries for CouchDB errors + maxRetries: 3 + # Number of retries for CouchDB errors during peer startup. + # The delay between retries doubles for each attempt. + # Default of 10 retries results in 11 attempts over 2 minutes. + maxRetriesOnStartup: 10 + # CouchDB request timeout (unit: duration, e.g. 20s) + requestTimeout: 35s + # Limit on the number of records per each CouchDB query + # Note that chaincode queries are only bound by totalQueryLimit. + # Internally the chaincode may execute multiple CouchDB queries, + # each of size internalQueryLimit. + internalQueryLimit: 1000 + # Limit on the number of records per CouchDB bulk update batch + maxBatchUpdateSize: 1000 + # Create the _global_changes system database + # This is optional. Creating the global changes database will require + # additional system resources to track changes and maintain the database + createGlobalChangesDB: false + # CacheSize denotes the maximum mega bytes (MB) to be allocated for the in-memory state + # cache. Note that CacheSize needs to be a multiple of 32 MB. If it is not a multiple + # of 32 MB, the peer would round the size to the next multiple of 32 MB. + # To disable the cache, 0 MB needs to be assigned to the cacheSize. + cacheSize: 64 + + history: + # enableHistoryDatabase - options are true or false + # Indicates if the history of key updates should be stored. + # All history 'index' will be stored in goleveldb, regardless if using + # CouchDB or alternate database for the state. + enableHistoryDatabase: true + + pvtdataStore: + # the maximum db batch size for converting + # the ineligible missing data entries to eligible missing data entries + collElgProcMaxDbBatchSize: 5000 + # the minimum duration (in milliseconds) between writing + # two consecutive db batches for converting the ineligible missing data entries to eligible missing data entries + collElgProcDbBatchesInterval: 1000 + # The missing data entries are classified into two categories: + # (1) prioritized + # (2) deprioritized + # Initially, all missing data are in the prioritized list. When the + # reconciler is unable to fetch the missing data from other peers, + # the unreconciled missing data would be moved to the deprioritized list. + # The reconciler would retry deprioritized missing data after every + # deprioritizedDataReconcilerInterval (unit: minutes). Note that the + # interval needs to be greater than the reconcileSleepInterval + deprioritizedDataReconcilerInterval: 60m + + snapshots: + # Path on the file system where peer will store ledger snapshots + rootDir: /var/hyperledger/production/snapshots + +############################################################################### +# +# Operations section +# +############################################################################### +operations: + # host and port for the operations server + listenAddress: 127.0.0.1:9443 + + # TLS configuration for the operations endpoint + tls: + # TLS enabled + enabled: false + + # path to PEM encoded server certificate for the operations server + cert: + file: + + # path to PEM encoded server key for the operations server + key: + file: + + # most operations service endpoints require client authentication when TLS + # is enabled. clientAuthRequired requires client certificate authentication + # at the TLS layer to access all resources. + clientAuthRequired: false + + # paths to PEM encoded ca certificates to trust for client authentication + clientRootCAs: + files: [] + +############################################################################### +# +# Metrics section +# +############################################################################### +metrics: + # metrics provider is one of statsd, prometheus, or disabled + provider: disabled + + # statsd configuration + statsd: + # network type: tcp or udp + network: udp + + # statsd server address + address: 127.0.0.1:8125 + + # the interval at which locally cached counters and gauges are pushed + # to statsd; timings are pushed immediately + writeInterval: 10s + + # prefix is prepended to all emitted statsd metrics + prefix: diff --git a/varion/compose/podman/podman-compose-ca.yaml b/varion/compose/podman/podman-compose-ca.yaml new file mode 100644 index 00000000..6ab883d4 --- /dev/null +++ b/varion/compose/podman/podman-compose-ca.yaml @@ -0,0 +1,6 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' diff --git a/varion/compose/podman/podman-compose-couch.yaml b/varion/compose/podman/podman-compose-couch.yaml new file mode 100644 index 00000000..6ab883d4 --- /dev/null +++ b/varion/compose/podman/podman-compose-couch.yaml @@ -0,0 +1,6 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' diff --git a/varion/compose/podman/podman-compose-test-net.yaml b/varion/compose/podman/podman-compose-test-net.yaml new file mode 100644 index 00000000..8afe4149 --- /dev/null +++ b/varion/compose/podman/podman-compose-test-net.yaml @@ -0,0 +1,19 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '3.7' + +services: + peer0.org1.example.com: + volumes: + - ./podman/peercfg:/etc/hyperledger/peercfg + + peer0.org2.example.com: + volumes: + - ./podman/peercfg:/etc/hyperledger/peercfg + + cli: + volumes: + - ./podman/peercfg:/etc/hyperledger/peercfg diff --git a/varion/configtx/configtx.yaml b/varion/configtx/configtx.yaml new file mode 100644 index 00000000..6f783e2a --- /dev/null +++ b/varion/configtx/configtx.yaml @@ -0,0 +1,279 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + - &OrdererOrg + # SampleOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: OrdererOrg + # ID to load the MSP definition as + ID: OrdererMSP + # MSPDir is the filesystem path which contains the MSP configuration + MSPDir: ../organizations/ordererOrganizations/example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Writers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + Admins: + Type: Signature + Rule: "OR('OrdererMSP.admin')" + OrdererEndpoints: + - orderer.example.com:7050 + - &Org1 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org1MSP + # ID to load the MSP definition as + ID: Org1MSP + MSPDir: ../organizations/peerOrganizations/org1.example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org1MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org1MSP.peer')" + - &Org2 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org2MSP + # ID to load the MSP definition as + ID: Org2MSP + MSPDir: ../organizations/peerOrganizations/org2.example.com/msp + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: + Readers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org2MSP.admin')" + Endorsement: + Type: Signature + Rule: "OR('Org2MSP.peer')" +################################################################################ +# +# SECTION: Capabilities +# +# - This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. +# +################################################################################ +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. + # Set the value of the capability to true to require it. + Channel: &ChannelCapabilities + # V2_0 capability ensures that orderers and peers behave according + # to v2.0 channel capabilities. Orderers and peers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 capability. + # Prior to enabling V2.0 channel capabilities, ensure that all + # orderers and peers on a channel are at v2.0.0 or later. + V2_0: true + # Orderer capabilities apply only to the orderers, and may be safely + # used with prior release peers. + # Set the value of the capability to true to require it. + Orderer: &OrdererCapabilities + # V2_0 orderer capability ensures that orderers behave according + # to v2.0 orderer capabilities. Orderers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 orderer capability. + # Prior to enabling V2.0 orderer capabilities, ensure that all + # orderers on channel are at v2.0.0 or later. + V2_0: true + # Application capabilities apply only to the peer network, and may be safely + # used with prior release orderers. + # Set the value of the capability to true to require it. + Application: &ApplicationCapabilities + # V2.5 for Application enables the new non-backwards compatible + # features of fabric v2.5, namely the ability to purge private data. + # Prior to enabling V2.5 application capabilities, ensure that all + # peers on a channel are at v2.5.0 or later. + V2_5: true +################################################################################ +# +# SECTION: Application +# +# - This section defines the values to encode into a config transaction or +# genesis block for application related parameters +# +################################################################################ +Application: &ApplicationDefaults + # Organizations is the list of orgs which are defined as participants on + # the application side of the network + Organizations: + # Policies defines the set of policies at this level of the config tree + # For Application policies, their canonical path is + # /Channel/Application/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + LifecycleEndorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Endorsement: + Type: ImplicitMeta + Rule: "MAJORITY Endorsement" + Capabilities: + <<: *ApplicationCapabilities +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + # Addresses used to be the list of orderer addresses that clients and peers + # could connect to. However, this does not allow clients to associate orderer + # addresses and orderer organizations which can be useful for things such + # as TLS validation. The preferred way to specify orderer addresses is now + # to include the OrdererEndpoints item in your org definition + Addresses: + - orderer.example.com:7050 + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + # Batch Size: Controls the number of messages batched into a block + BatchSize: + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 99 MB + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: + # Policies defines the set of policies at this level of the config tree + # For Orderer policies, their canonical path is + # /Channel/Orderer/ + Policies: + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # BlockValidation specifies what signatures must be included in the block + # from the orderer for the peer to validate it. + BlockValidation: + Type: ImplicitMeta + Rule: "ANY Writers" +################################################################################ +# +# CHANNEL +# +# This section defines the values to encode into a config transaction or +# genesis block for channel related parameters. +# +################################################################################ +Channel: &ChannelDefaults + # Policies defines the set of policies at this level of the config tree + # For Channel policies, their canonical path is + # /Channel/ + Policies: + # Who may invoke the 'Deliver' API + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + # Who may invoke the 'Broadcast' API + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + # By default, who may modify elements at this config level + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" + # Capabilities describes the channel level capabilities, see the + # dedicated Capabilities section elsewhere in this file for a full + # description + Capabilities: + <<: *ChannelCapabilities +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + ChannelUsingRaft: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + OrdererType: etcdraft + EtcdRaft: + Consenters: + - Host: orderer.example.com + Port: 7050 + ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt + ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt + Organizations: + - *OrdererOrg + Capabilities: *OrdererCapabilities + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: *ApplicationCapabilities diff --git a/varion/monitordocker.sh b/varion/monitordocker.sh new file mode 100755 index 00000000..c32986c8 --- /dev/null +++ b/varion/monitordocker.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# This script uses the logspout and http stream tools to let you watch the docker containers +# in action. +# +# More information at https://github.com/gliderlabs/logspout/tree/master/httpstream + +if [ -z "$1" ]; then + DOCKER_NETWORK=fabric_test +else + DOCKER_NETWORK="$1" +fi + +if [ -z "$2" ]; then + PORT=8000 +else + PORT="$2" +fi + +echo Starting monitoring on all containers on the network ${DOCKER_NETWORK} + +docker kill logspout 2> /dev/null 1>&2 || true +docker rm logspout 2> /dev/null 1>&2 || true + +trap "docker kill logspout" SIGINT + +docker run -d --rm --name="logspout" \ + --volume=/var/run/docker.sock:/var/run/docker.sock \ + --publish=127.0.0.1:${PORT}:80 \ + --network ${DOCKER_NETWORK} \ + gliderlabs/logspout +sleep 3 +curl http://127.0.0.1:${PORT}/logs diff --git a/varion/network.config b/varion/network.config new file mode 100644 index 00000000..ec107bbe --- /dev/null +++ b/varion/network.config @@ -0,0 +1,58 @@ +# default image tag, example: "2.5.4". "default" will download the latest. (-i) +IMAGETAG="default" + +# default ca image tag, example: "1.5.7". "default" will download the latest. (-cai) +CA_IMAGETAG="default" + +# Using crpto vs CA. default is cryptogen +CRYPTO="cryptogen" + +# max number of retries before giving up (-r) +MAX_RETRY=5 + +# default for delay between commands (-d) +CLI_DELAY=3 + +# channel name defaults to "mychannel" (-c) +CHANNEL_NAME="mychannel" + +# default database (-s) +DATABASE="leveldb" + +# default org (-org) +ORG=1 + +# chaincode language defaults to "NA" (-ccl) +CC_SRC_LANGUAGE="go" + +# Chaincode version (-ccv) +CC_VERSION="1.0.1" + +# chaincode name defaults to "NA" (-ccn) +CC_NAME="basic" + +# default to running the docker commands for the CCAAS (-ccaasdocker) +CCAAS_DOCKER_RUN=true + +# chaincode path defaults to "NA" (-ccp) +CC_SRC_PATH="../asset-transfer-basic/chaincode-go" + +# endorsement policy defaults to "NA". This would allow chaincodes to use the majority default policy. (-ccep) +CC_END_POLICY="NA" + +# collection configuration defaults to "NA" (-cccg) +CC_COLL_CONFIG="NA" + +# chaincode init function defaults to "NA" (-cci) +CC_INIT_FCN="NA" + +# Chaincode definition sequence, this should be an integer or auto (-ccs) +CC_SEQUENCE=auto + +# Default constructor for testing a chaincode invoke (-ccic) +CC_INVOKE_CONSTRUCTOR=''{\"Args\":[\"InitLedger\"]}'' + +# Default constructor for testing a chaincode query (-cciq) +CC_QUERY_CONSTRUCTOR=''{\"Args\":[\"GetAllAssets\"]}'' + + diff --git a/varion/network.sh b/varion/network.sh new file mode 100755 index 00000000..569cee65 --- /dev/null +++ b/varion/network.sh @@ -0,0 +1,674 @@ +#!/bin/bash +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This script brings up a Hyperledger Fabric network for testing smart contracts +# and applications. The test network consists of two organizations with one +# peer each, and a single node Raft ordering service. Users can also use this +# script to create a channel deploy a chaincode on the channel +# +# prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries +# this may be commented out to resolve installed version of tools if desired +# +# However using PWD in the path has the side effect that location that +# this script is run from is critical. To ease this, get the directory +# this script is actually in and infer location from there. (putting first) + +ROOTDIR=$(cd "$(dirname "$0")" && pwd) +export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH +export FABRIC_CFG_PATH=${PWD}/configtx +export VERBOSE=false + +# push to the required directory & set a trap to go back if needed +pushd ${ROOTDIR} > /dev/null +trap "popd > /dev/null" EXIT + +. scripts/utils.sh + +: ${CONTAINER_CLI:="docker"} +if command -v ${CONTAINER_CLI}-compose > /dev/null 2>&1; then + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} +else + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI} compose"} +fi +infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" + +# Obtain CONTAINER_IDS and remove them +# This function is called when you bring a network down +function clearContainers() { + infoln "Removing remaining containers" + ${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter label=service=hyperledger-fabric) 2>/dev/null || true + ${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter name='dev-peer*') 2>/dev/null || true + ${CONTAINER_CLI} kill "$(${CONTAINER_CLI} ps -q --filter name=ccaas)" 2>/dev/null || true +} + +# Delete any images that were generated as a part of this setup +# specifically the following images are often left behind: +# This function is called when you bring the network down +function removeUnwantedImages() { + infoln "Removing generated chaincode docker images" + ${CONTAINER_CLI} image rm -f $(${CONTAINER_CLI} images -aq --filter reference='dev-peer*') 2>/dev/null || true +} + +# Versions of fabric known not to work with the test network +NONWORKING_VERSIONS="^1\.0\. ^1\.1\. ^1\.2\. ^1\.3\. ^1\.4\." + +# Do some basic sanity checking to make sure that the appropriate versions of fabric +# binaries/images are available. In the future, additional checking for the presence +# of go or other items could be added. +function checkPrereqs() { + ## Check if your have cloned the peer binaries and configuration files. + peer version > /dev/null 2>&1 + + if [[ $? -ne 0 || ! -d "../config" ]]; then + errorln "Peer binary and configuration files not found.." + errorln + errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:" + errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html" + exit 1 + fi + # use the fabric peer container to see if the samples and binaries match your + # docker images + LOCAL_VERSION=$(peer version | sed -ne 's/^ Version: //p') + DOCKER_IMAGE_VERSION=$(${CONTAINER_CLI} run --rm hyperledger/fabric-peer:latest peer version | sed -ne 's/^ Version: //p') + + infoln "LOCAL_VERSION=$LOCAL_VERSION" + infoln "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION" + + if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then + warnln "Local fabric binaries and docker images are out of sync. This may cause problems." + fi + + for UNSUPPORTED_VERSION in $NONWORKING_VERSIONS; do + infoln "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION + if [ $? -eq 0 ]; then + fatalln "Local Fabric binary version of $LOCAL_VERSION does not match the versions supported by the test network." + fi + + infoln "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION + if [ $? -eq 0 ]; then + fatalln "Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match the versions supported by the test network." + fi + done + + ## check for cfssl binaries + if [ "$CRYPTO" == "cfssl" ]; then + + cfssl version > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + errorln "cfssl binary not found.." + errorln + errorln "Follow the instructions to install the cfssl and cfssljson binaries:" + errorln "https://github.com/cloudflare/cfssl#installation" + exit 1 + fi + fi + + ## Check for fabric-ca + if [ "$CRYPTO" == "Certificate Authorities" ]; then + + fabric-ca-client version > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + errorln "fabric-ca-client binary not found.." + errorln + errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:" + errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html" + exit 1 + fi + CA_LOCAL_VERSION=$(fabric-ca-client version | sed -ne 's/ Version: //p') + CA_DOCKER_IMAGE_VERSION=$(${CONTAINER_CLI} run --rm hyperledger/fabric-ca:latest fabric-ca-client version | sed -ne 's/ Version: //p' | head -1) + infoln "CA_LOCAL_VERSION=$CA_LOCAL_VERSION" + infoln "CA_DOCKER_IMAGE_VERSION=$CA_DOCKER_IMAGE_VERSION" + + if [ "$CA_LOCAL_VERSION" != "$CA_DOCKER_IMAGE_VERSION" ]; then + warnln "Local fabric-ca binaries and docker images are out of sync. This may cause problems." + fi + fi +} + +# Before you can bring up a network, each organization needs to generate the crypto +# material that will define that organization on the network. Because Hyperledger +# Fabric is a permissioned blockchain, each node and user on the network needs to +# use certificates and keys to sign and verify its actions. In addition, each user +# needs to belong to an organization that is recognized as a member of the network. +# You can use the Cryptogen tool or Fabric CAs to generate the organization crypto +# material. + +# By default, the sample network uses cryptogen. Cryptogen is a tool that is +# meant for development and testing that can quickly create the certificates and keys +# that can be consumed by a Fabric network. The cryptogen tool consumes a series +# of configuration files for each organization in the "organizations/cryptogen" +# directory. Cryptogen uses the files to generate the crypto material for each +# org in the "organizations" directory. + +# You can also use Fabric CAs to generate the crypto material. CAs sign the certificates +# and keys that they generate to create a valid root of trust for each organization. +# The script uses Docker Compose to bring up three CAs, one for each peer organization +# and the ordering organization. The configuration file for creating the Fabric CA +# servers are in the "organizations/fabric-ca" directory. Within the same directory, +# the "registerEnroll.sh" script uses the Fabric CA client to create the identities, +# certificates, and MSP folders that are needed to create the test network in the +# "organizations/ordererOrganizations" directory. + +# Create Organization crypto material using cryptogen or CAs +function createOrgs() { + if [ -d "organizations/peerOrganizations" ]; then + rm -Rf organizations/peerOrganizations && rm -Rf organizations/ordererOrganizations + fi + + # Create crypto material using cryptogen + if [ "$CRYPTO" == "cryptogen" ]; then + which cryptogen + if [ "$?" -ne 0 ]; then + fatalln "cryptogen tool not found. exiting" + fi + infoln "Generating certificates using cryptogen tool" + + infoln "Creating Org1 Identities" + + set -x + cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations" + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate certificates..." + fi + + infoln "Creating Org2 Identities" + + set -x + cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations" + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate certificates..." + fi + + infoln "Creating Orderer Org Identities" + + set -x + cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations" + res=$? + { set +x; } 2>/dev/null + if [ $res -ne 0 ]; then + fatalln "Failed to generate certificates..." + fi + + fi + + # Create crypto material using cfssl + if [ "$CRYPTO" == "cfssl" ]; then + + . organizations/cfssl/registerEnroll.sh + #function_name cert-type CN org + peer_cert peer peer0.org1.example.com org1 + peer_cert admin Admin@org1.example.com org1 + + infoln "Creating Org2 Identities" + #function_name cert-type CN org + peer_cert peer peer0.org2.example.com org2 + peer_cert admin Admin@org2.example.com org2 + + infoln "Creating Orderer Org Identities" + #function_name cert-type CN + orderer_cert orderer orderer.example.com + orderer_cert admin Admin@example.com + + fi + + # Create crypto material using Fabric CA + if [ "$CRYPTO" == "Certificate Authorities" ]; then + infoln "Generating certificates using Fabric CA" + ${CONTAINER_CLI_COMPOSE} -f compose/$COMPOSE_FILE_CA -f compose/$CONTAINER_CLI/${CONTAINER_CLI}-$COMPOSE_FILE_CA up -d 2>&1 + + . organizations/fabric-ca/registerEnroll.sh + + while : + do + if [ ! -f "organizations/fabric-ca/org1/tls-cert.pem" ]; then + sleep 1 + else + break + fi + done + + infoln "Creating Org1 Identities" + + createOrg1 + + infoln "Creating Org2 Identities" + + createOrg2 + + infoln "Creating Orderer Org Identities" + + createOrderer + + fi + + infoln "Generating CCP files for Org1 and Org2" + ./organizations/ccp-generate.sh +} + +# Once you create the organization crypto material, you need to create the +# genesis block of the application channel. + +# The configtxgen tool is used to create the genesis block. Configtxgen consumes a +# "configtx.yaml" file that contains the definitions for the sample network. The +# genesis block is defined using the "ChannelUsingRaft" profile at the bottom +# of the file. This profile defines an application channel consisting of our two Peer Orgs. +# The peer and ordering organizations are defined in the "Profiles" section at the +# top of the file. As part of each organization profile, the file points to the +# location of the MSP directory for each member. This MSP is used to create the channel +# MSP that defines the root of trust for each organization. In essence, the channel +# MSP allows the nodes and users to be recognized as network members. +# +# If you receive the following warning, it can be safely ignored: +# +# [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP. +# +# You can ignore the logs regarding intermediate certs, we are not using them in +# this crypto implementation. + +# After we create the org crypto material and the application channel genesis block, +# we can now bring up the peers and ordering service. By default, the base +# file for creating the network is "docker-compose-test-net.yaml" in the ``docker`` +# folder. This file defines the environment variables and file mounts that +# point the crypto material and genesis block that were created in earlier. + +# Bring up the peer and orderer nodes using docker compose. +function networkUp() { + + checkPrereqs + + # generate artifacts if they don't exist + if [ ! -d "organizations/peerOrganizations" ]; then + createOrgs + fi + + COMPOSE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}" + + if [ "${DATABASE}" == "couchdb" ]; then + COMPOSE_FILES="${COMPOSE_FILES} -f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}" + fi + + DOCKER_SOCK="${DOCKER_SOCK}" ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} up -d 2>&1 + + $CONTAINER_CLI ps -a + if [ $? -ne 0 ]; then + fatalln "Unable to start network" + fi +} + +# call the script to create the channel, join the peers of org1 and org2, +# and then update the anchor peers for each organization +function createChannel() { + # Bring up the network if it is not already up. + bringUpNetwork="false" + + local bft_true=$1 + + if ! $CONTAINER_CLI info > /dev/null 2>&1 ; then + fatalln "$CONTAINER_CLI network is required to be running to create a channel" + fi + + # check if all containers are present + CONTAINERS=($($CONTAINER_CLI ps | grep hyperledger/ | awk '{print $2}')) + len=$(echo ${#CONTAINERS[@]}) + + if [[ $len -ge 4 ]] && [[ ! -d "organizations/peerOrganizations" ]]; then + echo "Bringing network down to sync certs with containers" + networkDown + fi + + [[ $len -lt 4 ]] || [[ ! -d "organizations/peerOrganizations" ]] && bringUpNetwork="true" || echo "Network Running Already" + + if [ $bringUpNetwork == "true" ]; then + infoln "Bringing up network" + networkUp + fi + + # now run the script that creates a channel. This script uses configtxgen once + # to create the channel creation transaction and the anchor peer updates. + scripts/createChannel.sh $CHANNEL_NAME $CLI_DELAY $MAX_RETRY $VERBOSE $bft_true +} + + +## Call the script to deploy a chaincode to the channel +function deployCC() { + scripts/deployCC.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE + + if [ $? -ne 0 ]; then + fatalln "Deploying chaincode failed" + fi +} + +## Call the script to deploy a chaincode to the channel +function deployCCAAS() { + scripts/deployCCAAS.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CCAAS_DOCKER_RUN $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE $CCAAS_DOCKER_RUN + + if [ $? -ne 0 ]; then + fatalln "Deploying chaincode-as-a-service failed" + fi +} + +## Call the script to package the chaincode +function packageChaincode() { + + infoln "Packaging chaincode" + + scripts/packageCC.sh $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION true + + if [ $? -ne 0 ]; then + fatalln "Packaging the chaincode failed" + fi + +} + +## Call the script to list installed and committed chaincode on a peer +function listChaincode() { + + export FABRIC_CFG_PATH=${PWD}/../config + + . scripts/envVar.sh + . scripts/ccutils.sh + + setGlobals $ORG + + println + queryInstalledOnPeer + println + + listAllCommitted + +} + +## Call the script to invoke +function invokeChaincode() { + + export FABRIC_CFG_PATH=${PWD}/../config + + . scripts/envVar.sh + . scripts/ccutils.sh + + setGlobals $ORG + + chaincodeInvoke $ORG $CHANNEL_NAME $CC_NAME $CC_INVOKE_CONSTRUCTOR + +} + +## Call the script to query chaincode +function queryChaincode() { + + export FABRIC_CFG_PATH=${PWD}/../config + + . scripts/envVar.sh + . scripts/ccutils.sh + + setGlobals $ORG + + chaincodeQuery $ORG $CHANNEL_NAME $CC_NAME $CC_QUERY_CONSTRUCTOR + +} + + +# Tear down running network +function networkDown() { + local temp_compose=$COMPOSE_FILE_BASE + COMPOSE_FILE_BASE=compose-bft-test-net.yaml + COMPOSE_BASE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}" + COMPOSE_COUCH_FILES="-f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}" + COMPOSE_CA_FILES="-f compose/${COMPOSE_FILE_CA} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_CA}" + COMPOSE_FILES="${COMPOSE_BASE_FILES} ${COMPOSE_COUCH_FILES} ${COMPOSE_CA_FILES}" + + # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3 + COMPOSE_ORG3_BASE_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_BASE} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_BASE}" + COMPOSE_ORG3_COUCH_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_COUCH} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_COUCH}" + COMPOSE_ORG3_CA_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_CA} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_CA}" + COMPOSE_ORG3_FILES="${COMPOSE_ORG3_BASE_FILES} ${COMPOSE_ORG3_COUCH_FILES} ${COMPOSE_ORG3_CA_FILES}" + + if [ "${CONTAINER_CLI}" == "docker" ]; then + DOCKER_SOCK=$DOCKER_SOCK ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes --remove-orphans + elif [ "${CONTAINER_CLI}" == "podman" ]; then + ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes + else + fatalln "Container CLI ${CONTAINER_CLI} not supported" + fi + + COMPOSE_FILE_BASE=$temp_compose + + # Don't remove the generated artifacts -- note, the ledgers are always removed + if [ "$MODE" != "restart" ]; then + # Bring down the network, deleting the volumes + ${CONTAINER_CLI} volume rm docker_orderer.example.com docker_peer0.org1.example.com docker_peer0.org2.example.com + #Cleanup the chaincode containers + clearContainers + #Cleanup images + removeUnwantedImages + # remove orderer block and other channel configuration transactions and certs + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf system-genesis-block/*.block organizations/peerOrganizations organizations/ordererOrganizations' + ## remove fabric ca artifacts + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org1/msp organizations/fabric-ca/org1/tls-cert.pem organizations/fabric-ca/org1/ca-cert.pem organizations/fabric-ca/org1/IssuerPublicKey organizations/fabric-ca/org1/IssuerRevocationPublicKey organizations/fabric-ca/org1/fabric-ca-server.db' + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org2/msp organizations/fabric-ca/org2/tls-cert.pem organizations/fabric-ca/org2/ca-cert.pem organizations/fabric-ca/org2/IssuerPublicKey organizations/fabric-ca/org2/IssuerRevocationPublicKey organizations/fabric-ca/org2/fabric-ca-server.db' + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/ordererOrg/msp organizations/fabric-ca/ordererOrg/tls-cert.pem organizations/fabric-ca/ordererOrg/ca-cert.pem organizations/fabric-ca/ordererOrg/IssuerPublicKey organizations/fabric-ca/ordererOrg/IssuerRevocationPublicKey organizations/fabric-ca/ordererOrg/fabric-ca-server.db' + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf addOrg3/fabric-ca/org3/msp addOrg3/fabric-ca/org3/tls-cert.pem addOrg3/fabric-ca/org3/ca-cert.pem addOrg3/fabric-ca/org3/IssuerPublicKey addOrg3/fabric-ca/org3/IssuerRevocationPublicKey addOrg3/fabric-ca/org3/fabric-ca-server.db' + # remove channel and script artifacts + ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf channel-artifacts log.txt *.tar.gz' + fi +} + +. ./network.config + +# use this as the default docker-compose yaml definition +COMPOSE_FILE_BASE=compose-test-net.yaml +# docker-compose.yaml file if you are using couchdb +COMPOSE_FILE_COUCH=compose-couch.yaml +# certificate authorities compose file +COMPOSE_FILE_CA=compose-ca.yaml +# use this as the default docker-compose yaml definition for org3 +COMPOSE_FILE_ORG3_BASE=compose-org3.yaml +# use this as the docker compose couch file for org3 +COMPOSE_FILE_ORG3_COUCH=compose-couch-org3.yaml +# certificate authorities compose file +COMPOSE_FILE_ORG3_CA=compose-ca-org3.yaml +# + +# Get docker sock path from environment variable +SOCK="${DOCKER_HOST:-/var/run/docker.sock}" +DOCKER_SOCK="${SOCK##unix://}" + +# BFT activated flag +BFT=0 + +# Parse commandline args + +## Parse mode +if [[ $# -lt 1 ]] ; then + printHelp + exit 0 +else + MODE=$1 + shift +fi + +## if no parameters are passed, show the help for cc +if [ "$MODE" == "cc" ] && [[ $# -lt 1 ]]; then + printHelp $MODE + exit 0 +fi + +# parse subcommands if used +if [[ $# -ge 1 ]] ; then + key="$1" + # check for the createChannel subcommand + if [[ "$key" == "createChannel" ]]; then + export MODE="createChannel" + shift + # check for the cc command + elif [[ "$MODE" == "cc" ]]; then + if [ "$1" != "-h" ]; then + export SUBCOMMAND=$key + shift + fi + fi +fi + + +# parse flags + +while [[ $# -ge 1 ]] ; do + key="$1" + case $key in + -h ) + printHelp $MODE + exit 0 + ;; + -c ) + CHANNEL_NAME="$2" + shift + ;; + -bft ) + BFT=1 + ;; + -ca ) + CRYPTO="Certificate Authorities" + ;; + -cfssl ) + CRYPTO="cfssl" + ;; + -r ) + MAX_RETRY="$2" + shift + ;; + -d ) + CLI_DELAY="$2" + shift + ;; + -s ) + DATABASE="$2" + shift + ;; + -ccl ) + CC_SRC_LANGUAGE="$2" + shift + ;; + -ccn ) + CC_NAME="$2" + shift + ;; + -ccv ) + CC_VERSION="$2" + shift + ;; + -ccs ) + CC_SEQUENCE="$2" + shift + ;; + -ccp ) + CC_SRC_PATH="$2" + shift + ;; + -ccep ) + CC_END_POLICY="$2" + shift + ;; + -cccg ) + CC_COLL_CONFIG="$2" + shift + ;; + -cci ) + CC_INIT_FCN="$2" + shift + ;; + -ccaasdocker ) + CCAAS_DOCKER_RUN="$2" + shift + ;; + -verbose ) + VERBOSE=true + ;; + -org ) + ORG="$2" + shift + ;; + -i ) + IMAGETAG="$2" + shift + ;; + -cai ) + CA_IMAGETAG="$2" + shift + ;; + -ccic ) + CC_INVOKE_CONSTRUCTOR="$2" + shift + ;; + -ccqc ) + CC_QUERY_CONSTRUCTOR="$2" + shift + ;; + * ) + errorln "Unknown flag: $key" + printHelp + exit 1 + ;; + esac + shift +done + +## Check if user attempts to use BFT orderer and CA together +if [[ $BFT -eq 1 && "$CRYPTO" == "Certificate Authorities" ]]; then + fatalln "This sample does not yet support the use of consensus type BFT and CA together." +fi + +if [ $BFT -eq 1 ]; then + export FABRIC_CFG_PATH=${PWD}/bft-config + COMPOSE_FILE_BASE=compose-bft-test-net.yaml +fi + +# Are we generating crypto material with this command? +if [ ! -d "organizations/peerOrganizations" ]; then + CRYPTO_MODE="with crypto from '${CRYPTO}'" +else + CRYPTO_MODE="" +fi + +# Determine mode of operation and printing out what we asked for +if [ "$MODE" == "prereq" ]; then + infoln "Installing binaries and fabric images. Fabric Version: ${IMAGETAG} Fabric CA Version: ${CA_IMAGETAG}" + installPrereqs +elif [ "$MODE" == "up" ]; then + infoln "Starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE}' ${CRYPTO_MODE}" + networkUp +elif [ "$MODE" == "createChannel" ]; then + infoln "Creating channel '${CHANNEL_NAME}'." + infoln "If network is not up, starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE} ${CRYPTO_MODE}" + createChannel $BFT +elif [ "$MODE" == "down" ]; then + infoln "Stopping network" + networkDown +elif [ "$MODE" == "restart" ]; then + infoln "Restarting network" + networkDown + networkUp +elif [ "$MODE" == "deployCC" ]; then + infoln "deploying chaincode on channel '${CHANNEL_NAME}'" + deployCC +elif [ "$MODE" == "deployCCAAS" ]; then + infoln "deploying chaincode-as-a-service on channel '${CHANNEL_NAME}'" + deployCCAAS +elif [ "$MODE" == "cc" ] && [ "$SUBCOMMAND" == "package" ]; then + packageChaincode +elif [ "$MODE" == "cc" ] && [ "$SUBCOMMAND" == "list" ]; then + listChaincode +elif [ "$MODE" == "cc" ] && [ "$SUBCOMMAND" == "invoke" ]; then + invokeChaincode +elif [ "$MODE" == "cc" ] && [ "$SUBCOMMAND" == "query" ]; then + queryChaincode +else + printHelp + exit 1 +fi diff --git a/varion/organizations/ccp-generate.sh b/varion/organizations/ccp-generate.sh new file mode 100755 index 00000000..7e091d0b --- /dev/null +++ b/varion/organizations/ccp-generate.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +function one_line_pem { + echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" +} + +function json_ccp { + local PP=$(one_line_pem $4) + local CP=$(one_line_pem $5) + sed -e "s/\${ORG}/$1/" \ + -e "s/\${P0PORT}/$2/" \ + -e "s/\${CAPORT}/$3/" \ + -e "s#\${PEERPEM}#$PP#" \ + -e "s#\${CAPEM}#$CP#" \ + organizations/ccp-template.json +} + +function yaml_ccp { + local PP=$(one_line_pem $4) + local CP=$(one_line_pem $5) + sed -e "s/\${ORG}/$1/" \ + -e "s/\${P0PORT}/$2/" \ + -e "s/\${CAPORT}/$3/" \ + -e "s#\${PEERPEM}#$PP#" \ + -e "s#\${CAPEM}#$CP#" \ + organizations/ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g' +} + +ORG=1 +P0PORT=7051 +CAPORT=7054 +PEERPEM=organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem +CAPEM=organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem + +echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > organizations/peerOrganizations/org1.example.com/connection-org1.json +echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > organizations/peerOrganizations/org1.example.com/connection-org1.yaml + +ORG=2 +P0PORT=9051 +CAPORT=8054 +PEERPEM=organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem +CAPEM=organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem + +echo "$(json_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > organizations/peerOrganizations/org2.example.com/connection-org2.json +echo "$(yaml_ccp $ORG $P0PORT $CAPORT $PEERPEM $CAPEM)" > organizations/peerOrganizations/org2.example.com/connection-org2.yaml diff --git a/varion/organizations/ccp-template.json b/varion/organizations/ccp-template.json new file mode 100755 index 00000000..e945bfe9 --- /dev/null +++ b/varion/organizations/ccp-template.json @@ -0,0 +1,49 @@ +{ + "name": "test-network-org${ORG}", + "version": "1.0.0", + "client": { + "organization": "Org${ORG}", + "connection": { + "timeout": { + "peer": { + "endorser": "300" + } + } + } + }, + "organizations": { + "Org${ORG}": { + "mspid": "Org${ORG}MSP", + "peers": [ + "peer0.org${ORG}.example.com" + ], + "certificateAuthorities": [ + "ca.org${ORG}.example.com" + ] + } + }, + "peers": { + "peer0.org${ORG}.example.com": { + "url": "grpcs://localhost:${P0PORT}", + "tlsCACerts": { + "pem": "${PEERPEM}" + }, + "grpcOptions": { + "ssl-target-name-override": "peer0.org${ORG}.example.com", + "hostnameOverride": "peer0.org${ORG}.example.com" + } + } + }, + "certificateAuthorities": { + "ca.org${ORG}.example.com": { + "url": "https://localhost:${CAPORT}", + "caName": "ca-org${ORG}", + "tlsCACerts": { + "pem": ["${CAPEM}"] + }, + "httpOptions": { + "verify": false + } + } + } +} diff --git a/varion/organizations/ccp-template.yaml b/varion/organizations/ccp-template.yaml new file mode 100755 index 00000000..b675c186 --- /dev/null +++ b/varion/organizations/ccp-template.yaml @@ -0,0 +1,35 @@ +--- +name: test-network-org${ORG} +version: 1.0.0 +client: + organization: Org${ORG} + connection: + timeout: + peer: + endorser: '300' +organizations: + Org${ORG}: + mspid: Org${ORG}MSP + peers: + - peer0.org${ORG}.example.com + certificateAuthorities: + - ca.org${ORG}.example.com +peers: + peer0.org${ORG}.example.com: + url: grpcs://localhost:${P0PORT} + tlsCACerts: + pem: | + ${PEERPEM} + grpcOptions: + ssl-target-name-override: peer0.org${ORG}.example.com + hostnameOverride: peer0.org${ORG}.example.com +certificateAuthorities: + ca.org${ORG}.example.com: + url: https://localhost:${CAPORT} + caName: ca-org${ORG} + tlsCACerts: + pem: + - | + ${CAPEM} + httpOptions: + verify: false diff --git a/varion/organizations/cfssl/admin-csr-template.json b/varion/organizations/cfssl/admin-csr-template.json new file mode 100644 index 00000000..5f52e3fa --- /dev/null +++ b/varion/organizations/cfssl/admin-csr-template.json @@ -0,0 +1,22 @@ +{ + "CN": "{USER}", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "admin" + } + ], + "hosts": [ + "{USER}", + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/ca-orderer.json b/varion/organizations/cfssl/ca-orderer.json new file mode 100644 index 00000000..d9ae6667 --- /dev/null +++ b/varion/organizations/cfssl/ca-orderer.json @@ -0,0 +1,21 @@ +{ + "CN": "cfssl-orderer-ca", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "client" + } + ], + "hosts": [ + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/ca-peer.json b/varion/organizations/cfssl/ca-peer.json new file mode 100644 index 00000000..394d8fd3 --- /dev/null +++ b/varion/organizations/cfssl/ca-peer.json @@ -0,0 +1,21 @@ +{ + "CN": "cfssl-peer-ca", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "Fabric" + } + ], + "hosts": [ + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/cert-signing-config.json b/varion/organizations/cfssl/cert-signing-config.json new file mode 100644 index 00000000..0c2daafa --- /dev/null +++ b/varion/organizations/cfssl/cert-signing-config.json @@ -0,0 +1,27 @@ +{ + "signing": { + "default": { + "expiry": "175200h" + }, + "profiles": { + "sign": { + "usages": [ + "signing", + "key encipherment", + "cert sign", + "digital signature" + ], + "expiry": "175200h" + }, + "tls": { + "usages": [ + "signing", + "key encipherment", + "server auth", + "client auth" + ], + "expiry": "175200h" + } + } + } +} diff --git a/varion/organizations/cfssl/client-csr-template.json b/varion/organizations/cfssl/client-csr-template.json new file mode 100644 index 00000000..1d67f7f6 --- /dev/null +++ b/varion/organizations/cfssl/client-csr-template.json @@ -0,0 +1,22 @@ +{ + "CN": "{USER}", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "client" + } + ], + "hosts": [ + "{USER}", + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/orderer-csr-template.json b/varion/organizations/cfssl/orderer-csr-template.json new file mode 100644 index 00000000..1a9af690 --- /dev/null +++ b/varion/organizations/cfssl/orderer-csr-template.json @@ -0,0 +1,22 @@ +{ + "CN": "{USER}", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "orderer" + } + ], + "hosts": [ + "{USER}", + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/peer-csr-template.json b/varion/organizations/cfssl/peer-csr-template.json new file mode 100644 index 00000000..09d66893 --- /dev/null +++ b/varion/organizations/cfssl/peer-csr-template.json @@ -0,0 +1,22 @@ +{ + "CN": "{USER}", + "key": { + "algo": "ecdsa", + "size": 256 + }, + "names": [ + { + "C": "IN", + "ST": "Delhi", + "L": "Aero city", + "O": "cfssl", + "OU": "peer" + } + ], + "hosts": [ + "{USER}", + "localhost", + "127.0.0.1", + "0.0.0.0" + ] +} diff --git a/varion/organizations/cfssl/registerEnroll.sh b/varion/organizations/cfssl/registerEnroll.sh new file mode 100755 index 00000000..d5bac21e --- /dev/null +++ b/varion/organizations/cfssl/registerEnroll.sh @@ -0,0 +1,276 @@ +#!/bin/bash +# Copyright 2023 Aditya Joshi, All rights reserved + +function peer_cert() { + + TYPE=$1 #peer user + USER=$2 + ORG=$3 + + mkdir -p "organizations/peerOrganizations/$ORG.example.com/ca" + mkdir -p "organizations/peerOrganizations/$ORG.example.com/msp/cacerts" + mkdir -p "organizations/peerOrganizations/$ORG.example.com/msp/tlscacerts" + mkdir -p "organizations/peerOrganizations/$ORG.example.com/peers" + mkdir -p "organizations/peerOrganizations/$ORG.example.com/tlsca" + + CERT_DIR=organizations/peerOrganizations/$ORG.example.com + + if [ ! -f "$CERT_DIR/ca/ca-key.pem" ]; then + + cfssl gencert -initca "${PWD}/organizations/cfssl/ca-peer.json" | cfssljson -bare "$CERT_DIR/ca/ca" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/tlsca/tlsca.$ORG.example.com-cert.pem" + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/ca/ca.$ORG.example.com-cert.pem" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/msp/cacerts/" + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/msp/tlscacerts/" + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: orderer' >"$CERT_DIR/msp/config.yaml" + + fi + + if [[ $TYPE == "peer" ]]; then + generate_peer_certs "$CERT_DIR" "$USER" + fi + if [[ $TYPE == "admin" ]]; then + generate_user_certs "$CERT_DIR" "$USER" "$TYPE" + fi + + find . -name "*.csr" -print0 | xargs -0 rm + +} + +function orderer_cert() { + TYPE=$1 #orderer user + USER=$2 #orderer.example.com + + mkdir -p organizations/ordererOrganizations/example.com/ca + mkdir -p organizations/ordererOrganizations/example.com/msp/cacerts + mkdir -p organizations/ordererOrganizations/example.com/msp/tlscacerts + mkdir -p organizations/ordererOrganizations/example.com/orderers + mkdir -p organizations/ordererOrganizations/example.com/tlsca + + CERT_DIR=organizations/ordererOrganizations/example.com + + if [ ! -f "$CERT_DIR/ca/ca-key.pem" ]; then + + cfssl gencert -initca "${PWD}/organizations/cfssl/ca-orderer.json" | cfssljson -bare "$CERT_DIR/ca/ca" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/tlsca/tlsca.example.com-cert.pem" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/msp/cacerts/" + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/msp/tlscacerts/tlsca.example.com-cert.pem" + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: orderer' >"$CERT_DIR/msp/config.yaml" + + fi + + if [[ $TYPE == "orderer" ]]; then + generate_orderer_certs $CERT_DIR "$USER" + fi + + if [[ $TYPE == "admin" ]]; then + generate_user_certs "$CERT_DIR" "$USER" "$TYPE" + fi + + find . -name "*.csr" -print0 | xargs -0 rm + +} + +function generate_user_certs() { + + CERT_DIR=$1 + USER=$2 + TYPE=$3 + + mkdir -p $CERT_DIR/users/$USER/tls + + for DIR in cacerts keystore signcerts tlscacerts; do + mkdir -p $CERT_DIR/users/$USER/msp/$DIR + done + + sed -e "s/{USER}/$USER/g" <"$PWD/organizations/cfssl/${TYPE}-csr-template.json" >$PWD/organizations/cfssl/${TYPE}-${USER}-csr.json + + cfssl gencert \ + -ca=$CERT_DIR/ca/ca.pem \ + -ca-key=$CERT_DIR/ca/ca-key.pem \ + -config=$PWD/organizations/cfssl/cert-signing-config.json \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="sign" \ + $PWD/organizations/cfssl/${TYPE}-${USER}-csr.json | cfssljson -bare $CERT_DIR/users/$USER/msp/signcerts/cert + + mv $CERT_DIR/users/$USER/msp/signcerts/cert-key.pem $CERT_DIR/users/$USER/msp/keystore/cert-key.pem + cp $CERT_DIR/ca/ca.pem $CERT_DIR/users/$USER/msp/cacerts + cp $CERT_DIR/ca/ca.pem $CERT_DIR/users/$USER/msp/tlscacerts + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: orderer' >$CERT_DIR/users/$USER/msp/config.yaml + + cfssl gencert \ + -ca=$CERT_DIR/ca/ca.pem \ + -ca-key=$CERT_DIR/ca/ca-key.pem \ + -config=$PWD/organizations/cfssl/cert-signing-config.json \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="tls" \ + $PWD/organizations/cfssl/${TYPE}-${USER}-csr.json | cfssljson -bare $CERT_DIR/users/$USER/tls/client + + cp $CERT_DIR/ca/ca.pem $CERT_DIR/users/$USER/tls/ca.crt + mv $CERT_DIR/users/$USER/tls/client-key.pem $CERT_DIR/users/$USER/tls/client.key + mv $CERT_DIR/users/$USER/tls/client.pem $CERT_DIR/users/$USER/tls/client.crt + + rm $PWD/organizations/cfssl/${TYPE}-${USER}-csr.json + +} + +function generate_peer_certs() { + CERT_DIR=$1 + USER=$2 + + for DIR in cacerts keystore signcerts tlscacerts; do + mkdir -p "$CERT_DIR/peers/$USER/msp/$DIR" + done + + mkdir -p "$CERT_DIR/peers/$USER/tls" + sed -e "s/{USER}/$USER/g" <"$PWD/organizations/cfssl/peer-csr-template.json" >"$PWD/organizations/cfssl/peer-${USER}.json" + + cfssl gencert \ + -ca="$CERT_DIR/ca/ca.pem" \ + -ca-key="$CERT_DIR/ca/ca-key.pem" \ + -config="$PWD/organizations/cfssl/cert-signing-config.json" \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="sign" \ + "$PWD/organizations/cfssl/peer-${USER}.json" | cfssljson -bare "$CERT_DIR/peers/${USER}/msp/signcerts/cert" + + mv "$CERT_DIR/peers/$USER/msp/signcerts/cert-key.pem" "$CERT_DIR/peers/$USER/msp/keystore" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/peers/$USER/msp/cacerts" + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/peers/$USER/msp/tlscacerts" + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: orderer' >"$CERT_DIR/peers/$USER/msp/config.yaml" + + cfssl gencert \ + -ca="$CERT_DIR/ca/ca.pem" \ + -ca-key="$CERT_DIR/ca/ca-key.pem" \ + -config="$PWD/organizations/cfssl/cert-signing-config.json" \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="tls" \ + "$PWD/organizations/cfssl/peer-${USER}.json" | cfssljson -bare "$CERT_DIR/peers/$USER/tls/server" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/peers/$USER/tls/ca.crt" + mv "$CERT_DIR/peers/$USER/tls/server.pem" "$CERT_DIR/peers/$USER/tls/server.crt" + mv "$CERT_DIR/peers/$USER/tls/server-key.pem" "$CERT_DIR/peers/$USER/tls/server.key" + + rm "$PWD/organizations/cfssl/peer-${USER}.json" +} + +function generate_orderer_certs() { + + CERT_DIR=$1 + USER=$2 + + for DIR in cacerts keystore signcerts tlscacerts; do + mkdir -p "organizations/ordererOrganizations/example.com/orderers/$USER/msp/$DIR" + done + + mkdir -p "organizations/ordererOrganizations/example.com/orderers/$USER/tls" + + sed -e "s/{USER}/$USER/g" <"$PWD/organizations/cfssl/orderer-csr-template.json" >"$PWD/organizations/cfssl/orderer-${USER}.json" + + cfssl gencert \ + -ca="$CERT_DIR/ca/ca.pem" \ + -ca-key="$CERT_DIR/ca/ca-key.pem" \ + -config="$PWD/organizations/cfssl/cert-signing-config.json" \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="sign" \ + "$PWD/organizations/cfssl/orderer-${USER}.json" | cfssljson -bare "$CERT_DIR/orderers/$USER/msp/signcerts/cert" + + mv "$CERT_DIR/orderers/$USER/msp/signcerts/cert-key.pem" "$CERT_DIR/orderers/$USER/msp/keystore" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/orderers/$USER/msp/cacerts" + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/orderers/$USER/msp/tlscacerts/tlsca.example.com-cert.pem" + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/ca.pem + OrganizationalUnitIdentifier: orderer' >"$CERT_DIR/orderers/$USER/msp/config.yaml" + + cfssl gencert \ + -ca="$CERT_DIR/ca/ca.pem" \ + -ca-key="$CERT_DIR/ca/ca-key.pem" \ + -config="$PWD/organizations/cfssl/cert-signing-config.json" \ + -cn="$USER" \ + -hostname="$USER,localhost,127.0.0.1" \ + -profile="tls" \ + "$PWD/organizations/cfssl/orderer-${USER}.json" | cfssljson -bare "$CERT_DIR/orderers/$USER/tls/server" + + cp "$CERT_DIR/ca/ca.pem" "$CERT_DIR/orderers/$USER/tls/ca.crt" + mv "$CERT_DIR/orderers/$USER/tls/server.pem" "$CERT_DIR/orderers/$USER/tls/server.crt" + mv "$CERT_DIR/orderers/$USER/tls/server-key.pem" "$CERT_DIR/orderers/$USER/tls/server.key" + rm "$PWD/organizations/cfssl/orderer-${USER}.json" +} diff --git a/varion/organizations/cryptogen/crypto-config-orderer.yaml b/varion/organizations/cryptogen/crypto-config-orderer.yaml new file mode 100755 index 00000000..e307ea2a --- /dev/null +++ b/varion/organizations/cryptogen/crypto-config-orderer.yaml @@ -0,0 +1,33 @@ +# 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 + - Hostname: orderer3 + SANS: + - localhost + - Hostname: orderer4 + SANS: + - localhost \ No newline at end of file diff --git a/varion/organizations/cryptogen/crypto-config-org1.yaml b/varion/organizations/cryptogen/crypto-config-org1.yaml new file mode 100755 index 00000000..40738450 --- /dev/null +++ b/varion/organizations/cryptogen/crypto-config-org1.yaml @@ -0,0 +1,61 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + + +# --------------------------------------------------------------------------- +# "PeerOrgs" - Definition of organizations managing peer nodes +# --------------------------------------------------------------------------- +PeerOrgs: + # --------------------------------------------------------------------------- + # Org1 + # --------------------------------------------------------------------------- + - Name: Org1 + Domain: org1.example.com + EnableNodeOUs: true + # --------------------------------------------------------------------------- + # "Specs" + # --------------------------------------------------------------------------- + # Uncomment this section to enable the explicit definition of hosts in your + # configuration. Most users will want to use Template, below + # + # Specs is an array of Spec entries. Each Spec entry consists of two fields: + # - Hostname: (Required) The desired hostname, sans the domain. + # - CommonName: (Optional) Specifies the template or explicit override for + # the CN. By default, this is the template: + # + # "{{.Hostname}}.{{.Domain}}" + # + # which obtains its values from the Spec.Hostname and + # Org.Domain, respectively. + # --------------------------------------------------------------------------- + # - Hostname: foo # implicitly "foo.org1.example.com" + # CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above + # - Hostname: bar + # - Hostname: baz + # --------------------------------------------------------------------------- + # "Template" + # --------------------------------------------------------------------------- + # Allows for the definition of 1 or more hosts that are created sequentially + # from a template. By default, this looks like "peer%d" from 0 to Count-1. + # You may override the number of nodes (Count), the starting index (Start) + # or the template used to construct the name (Hostname). + # + # Note: Template and Specs are not mutually exclusive. You may define both + # sections and the aggregate nodes will be created for you. Take care with + # name collisions + # --------------------------------------------------------------------------- + Template: + Count: 1 + SANS: + - localhost + # Start: 5 + # Hostname: {{.Prefix}}{{.Index}} # default + # --------------------------------------------------------------------------- + # "Users" + # --------------------------------------------------------------------------- + # Count: The number of user accounts _in addition_ to Admin + # --------------------------------------------------------------------------- + Users: + Count: 1 diff --git a/varion/organizations/cryptogen/crypto-config-org2.yaml b/varion/organizations/cryptogen/crypto-config-org2.yaml new file mode 100755 index 00000000..6298ff6d --- /dev/null +++ b/varion/organizations/cryptogen/crypto-config-org2.yaml @@ -0,0 +1,61 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# --------------------------------------------------------------------------- +# "PeerOrgs" - Definition of organizations managing peer nodes +# --------------------------------------------------------------------------- +PeerOrgs: + # --------------------------------------------------------------------------- + # Org2 + # --------------------------------------------------------------------------- + - Name: Org2 + Domain: org2.example.com + EnableNodeOUs: true + # --------------------------------------------------------------------------- + # "Specs" + # --------------------------------------------------------------------------- + # Uncomment this section to enable the explicit definition of hosts in your + # configuration. Most users will want to use Template, below + # + # Specs is an array of Spec entries. Each Spec entry consists of two fields: + # - Hostname: (Required) The desired hostname, sans the domain. + # - CommonName: (Optional) Specifies the template or explicit override for + # the CN. By default, this is the template: + # + # "{{.Hostname}}.{{.Domain}}" + # + # which obtains its values from the Spec.Hostname and + # Org.Domain, respectively. + # --------------------------------------------------------------------------- + # Specs: + # - Hostname: foo # implicitly "foo.org1.example.com" + # CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above + # - Hostname: bar + # - Hostname: baz + # --------------------------------------------------------------------------- + # "Template" + # --------------------------------------------------------------------------- + # Allows for the definition of 1 or more hosts that are created sequentially + # from a template. By default, this looks like "peer%d" from 0 to Count-1. + # You may override the number of nodes (Count), the starting index (Start) + # or the template used to construct the name (Hostname). + # + # Note: Template and Specs are not mutually exclusive. You may define both + # sections and the aggregate nodes will be created for you. Take care with + # name collisions + # --------------------------------------------------------------------------- + Template: + Count: 1 + SANS: + - localhost + # Start: 5 + # Hostname: {{.Prefix}}{{.Index}} # default + # --------------------------------------------------------------------------- + # "Users" + # --------------------------------------------------------------------------- + # Count: The number of user accounts _in addition_ to Admin + # --------------------------------------------------------------------------- + Users: + Count: 1 diff --git a/varion/organizations/fabric-ca/registerEnroll.sh b/varion/organizations/fabric-ca/registerEnroll.sh new file mode 100755 index 00000000..178db6cf --- /dev/null +++ b/varion/organizations/fabric-ca/registerEnroll.sh @@ -0,0 +1,247 @@ +#!/bin/bash + +function createOrg1() { + infoln "Enrolling the CA admin" + mkdir -p organizations/peerOrganizations/org1.example.com/ + + export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/ + + set -x + fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/localhost-7054-ca-org1.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/localhost-7054-ca-org1.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/localhost-7054-ca-org1.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/localhost-7054-ca-org1.pem + OrganizationalUnitIdentifier: orderer' > "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" + + # Since the CA serves as both the organization CA and TLS CA, copy the org's root cert that was generated by CA startup into the org level ca and tlsca directories + + # Copy org1's CA cert to org1's /msp/tlscacerts directory (for use in the channel MSP definition) + mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts" + cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt" + + # Copy org1's CA cert to org1's /tlsca directory (for use by clients) + mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/tlsca" + cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem" + + # Copy org1's CA cert to org1's /ca directory (for use by clients) + mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/ca" + cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem" + + infoln "Registering peer0" + set -x + fabric-ca-client register --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering user" + set -x + fabric-ca-client register --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering the org admin" + set -x + fabric-ca-client register --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Generating the peer0 msp" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml" + + infoln "Generating the peer0-tls certificates, use --csr.hosts to specify Subject Alternative Names" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls" --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + # Copy the tls CA cert, server cert, server keystore to well known file names in the peer's tls directory that are referenced by peer startup config + cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" + cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/signcerts/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt" + cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/keystore/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key" + + infoln "Generating the user msp" + set -x + fabric-ca-client enroll -u https://user1:user1pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/config.yaml" + + infoln "Generating the org admin msp" + set -x + fabric-ca-client enroll -u https://org1admin:org1adminpw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/config.yaml" +} + +function createOrg2() { + infoln "Enrolling the CA admin" + mkdir -p organizations/peerOrganizations/org2.example.com/ + + export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org2.example.com/ + + set -x + fabric-ca-client enroll -u https://admin:adminpw@localhost:8054 --caname ca-org2 --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/localhost-8054-ca-org2.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/localhost-8054-ca-org2.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/localhost-8054-ca-org2.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/localhost-8054-ca-org2.pem + OrganizationalUnitIdentifier: orderer' > "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" + + # Since the CA serves as both the organization CA and TLS CA, copy the org's root cert that was generated by CA startup into the org level ca and tlsca directories + + # Copy org2's CA cert to org2's /msp/tlscacerts directory (for use in the channel MSP definition) + mkdir -p "${PWD}/organizations/peerOrganizations/org2.example.com/msp/tlscacerts" + cp "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org2.example.com/msp/tlscacerts/ca.crt" + + # Copy org2's CA cert to org2's /tlsca directory (for use by clients) + mkdir -p "${PWD}/organizations/peerOrganizations/org2.example.com/tlsca" + cp "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem" + + # Copy org2's CA cert to org2's /ca directory (for use by clients) + mkdir -p "${PWD}/organizations/peerOrganizations/org2.example.com/ca" + cp "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem" + + infoln "Registering peer0" + set -x + fabric-ca-client register --caname ca-org2 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering user" + set -x + fabric-ca-client register --caname ca-org2 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering the org admin" + set -x + fabric-ca-client register --caname ca-org2 --id.name org2admin --id.secret org2adminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Generating the peer0 msp" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/config.yaml" + + infoln "Generating the peer0-tls certificates, use --csr.hosts to specify Subject Alternative Names" + set -x + fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls" --enrollment.profile tls --csr.hosts peer0.org2.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + # Copy the tls CA cert, server cert, server keystore to well known file names in the peer's tls directory that are referenced by peer startup config + cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/tlscacerts/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" + cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/signcerts/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt" + cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/keystore/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key" + + infoln "Generating the user msp" + set -x + fabric-ca-client enroll -u https://user1:user1pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/config.yaml" + + infoln "Generating the org admin msp" + set -x + fabric-ca-client enroll -u https://org2admin:org2adminpw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/config.yaml" +} + +function createOrderer() { + infoln "Enrolling the CA admin" + mkdir -p organizations/ordererOrganizations/example.com + + export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/ordererOrganizations/example.com + + set -x + fabric-ca-client enroll -u https://admin:adminpw@localhost:9054 --caname ca-orderer --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + echo 'NodeOUs: + Enable: true + ClientOUIdentifier: + Certificate: cacerts/localhost-9054-ca-orderer.pem + OrganizationalUnitIdentifier: client + PeerOUIdentifier: + Certificate: cacerts/localhost-9054-ca-orderer.pem + OrganizationalUnitIdentifier: peer + AdminOUIdentifier: + Certificate: cacerts/localhost-9054-ca-orderer.pem + OrganizationalUnitIdentifier: admin + OrdererOUIdentifier: + Certificate: cacerts/localhost-9054-ca-orderer.pem + OrganizationalUnitIdentifier: orderer' > "${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml" + + # Since the CA serves as both the organization CA and TLS CA, copy the org's root cert that was generated by CA startup into the org level ca and tlsca directories + + # Copy orderer org's CA cert to orderer org's /msp/tlscacerts directory (for use in the channel MSP definition) + mkdir -p "${PWD}/organizations/ordererOrganizations/example.com/msp/tlscacerts" + cp "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" "${PWD}/organizations/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem" + + # Copy orderer org's CA cert to orderer org's /tlsca directory (for use by clients) + mkdir -p "${PWD}/organizations/ordererOrganizations/example.com/tlsca" + cp "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" "${PWD}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem" + + infoln "Registering orderer" + set -x + fabric-ca-client register --caname ca-orderer --id.name orderer --id.secret ordererpw --id.type orderer --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Registering the orderer admin" + set -x + fabric-ca-client register --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + infoln "Generating the orderer msp" + set -x + fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml" "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/config.yaml" + + infoln "Generating the orderer-tls certificates, use --csr.hosts to specify Subject Alternative Names" + set -x + fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls" --enrollment.profile tls --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + # Copy the tls CA cert, server cert, server keystore to well known file names in the orderer's tls directory that are referenced by orderer startup config + cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt" + cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/signcerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt" + cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/keystore/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key" + + # Copy orderer org's CA cert to orderer's /msp/tlscacerts directory (for use in the orderer MSP definition) + mkdir -p "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts" + cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" + + infoln "Generating the admin msp" + set -x + fabric-ca-client enroll -u https://ordererAdmin:ordererAdminpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" + { set +x; } 2>/dev/null + + cp "${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml" "${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp/config.yaml" +} diff --git a/varion/prometheus-grafana/README.md b/varion/prometheus-grafana/README.md new file mode 100644 index 00000000..6da075d5 --- /dev/null +++ b/varion/prometheus-grafana/README.md @@ -0,0 +1,52 @@ +# Description + +This sample provides an environment to display and capture metrics from the test-network in real time. It consists of a docker-compose file that starts a Prometheus and Grafana server setup configured to collect and display metrics for the test network. + +## Requirements + +This sample has been tested and is recommended to be used on **linux** in order to fully benefit from its capabilities, however it can be deployed and works on MacOS-intel machine as well (some modification to the cadvisor docker image and related queries are required to show docker containers metrics). +You will need to have installed **docker-compose with version 1.29 or above** (note that this is higher than the v1.14 requirement requested for the test-network). + +## How to use + +1. Go to the test-network directory and run bring up the test-network **./network.sh up createChannel** +2. Bring up the Prometheus/Grafana network in the test-network/prometheus-grafana directory and run **docker-compose up -d** +3. Log in: type “localhost:3000” on your web browser -> username=“admin”, password=“admin” -> set a new password +4. Browse dashboard and analyse results + - The default dashboard "HLF Performances Review" can be found and displayed by hovering over the dashboard menu and clicking on the browse button. + ![picture alt]("https://user-images.githubusercontent.com/86831094/149115445-5e5f6d95-ecc3-4b46-aadb-5c01148770b3.png "Title is optional") + Once opened the dashboard, to display the collected metrics and data, adjust the timeframe on the top right to focus on the latest timespan when the network was up. +5. Deploy a chaincode (i.e. "./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go"), start using the test-network and use the Grafana dashboard to analyse and assess your network performances. +Extras: add new queries, modify dashboard & add relevant changes to main repo --> extract json and add it to "Grafana/dashboards/hlf-performances.json". +Metrics can also be displayed directly from Prometheus by going to "localhost:9090". + +## Docker Compose + +Brings up + +- a Prometheus server (port 9090) -> pulls metrics from peers, orderer, system(node exporter) and containers(cadvisor) +- Grafana server (port 3000) -> collects and display data from Prometheus +- node exporter (port 9100) -> exposes systems metrics +- cadvisor (port 8080) -> exposes docker containers metrics + +## Prometheus "configuration file" + +### Prometheus.yml + +Fabric metrics targets: + +- `peer0.org1.example.com:9444` +- `peer0.org2.example.com:9445` +- `orderer.example.com:9443` + +System and docker metrics targets: + +- `cadvisor:8080` +- `node-exporter:9100` + +Check the state of the connections with targets on http://localhost:9090/targets. + +## Sources + +[Prometheus docs](https://prometheus.io/docs/introduction/overview/) +[Grafana docs](https://grafana.com/docs/) diff --git a/varion/prometheus-grafana/docker-compose.yaml b/varion/prometheus-grafana/docker-compose.yaml new file mode 100644 index 00000000..b166f6ea --- /dev/null +++ b/varion/prometheus-grafana/docker-compose.yaml @@ -0,0 +1,68 @@ +version: '3' + +volumes: + prometheus_data: {} + grafana_storage: {} + +services: + prometheus: + image: prom/prometheus:v2.32.1 + container_name: prometheus + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + - prometheus_data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + - '--web.console.templates=/usr/share/prometheus/consoles' + ports: + - "9090:9090" + + grafana: + image: grafana/grafana:8.3.4 + container_name: grafana + user: "104" + depends_on: + - prometheus + ports: + - 3000:3000 + volumes: + - grafana_storage:/var/lib/grafana + - ./grafana/provisioning/:/etc/grafana/provisioning/ + env_file: + - ./grafana/config.monitoring + restart: always + + cadvisor: + image: google/cadvisor:latest # gcr.io/cadvisor/cadvisor:latest for ios + privileged: true + container_name: cadvisor + volumes: + - /var/run:/var/run:rw + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + # - /cgroup:/cgroup:ro + ports: + - 8080:8080 + restart: always + + node-exporter: + image: prom/node-exporter:v1.3.1 + container_name: node-exporter + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + command: + - '--path.procfs=/host/proc' + - '--path.sysfs=/host/sys' + - --collector.filesystem.ignored-mount-points + - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)" + ports: + - 9100:9100 + restart: always + +networks: + default: + external: true + name: fabric_test diff --git a/varion/prometheus-grafana/grafana/config.monitoring b/varion/prometheus-grafana/grafana/config.monitoring new file mode 100644 index 00000000..70d1cae1 --- /dev/null +++ b/varion/prometheus-grafana/grafana/config.monitoring @@ -0,0 +1,2 @@ +GF_SECURITY_ADMIN_PASSWORD=admin +GF_USERS_ALLOW_SIGN_UP=false diff --git a/varion/prometheus-grafana/grafana/provisioning/dashboards/dashboard.yml b/varion/prometheus-grafana/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 00000000..14716ee1 --- /dev/null +++ b/varion/prometheus-grafana/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: +- name: 'Prometheus' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/varion/prometheus-grafana/grafana/provisioning/dashboards/hlf-performances.json b/varion/prometheus-grafana/grafana/provisioning/dashboards/hlf-performances.json new file mode 100644 index 00000000..8bee1bd3 --- /dev/null +++ b/varion/prometheus-grafana/grafana/provisioning/dashboards/hlf-performances.json @@ -0,0 +1,2034 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Overview of the most important Fabric, system and Docker container metrics. ", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 893, + "graphTooltip": 1, + "iteration": 1643752938992, + "links": [], + "liveNow": false, + "panels": [ + { + "aliasColors": { + "{id=\"/\",instance=\"cadvisor:8080\",job=\"prometheus\"}": "#BA43A9" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 6, + "w": 5, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "100 - (avg(rate(node_cpu_seconds_total{job=\"node\",mode=\"idle\"}[$interval])) * 100)", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "E" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "System CPU Usage", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": false, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:7341", + "format": "percent", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:7342", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 3, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 6, + "w": 6, + "x": 5, + "y": 0 + }, + "hiddenSeries": false, + "id": 59, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum(container_memory_usage_bytes{name=~\".+\"}) - sum(container_memory_cache{name=~\".+\"})", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Memory Usage by all containers", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1101", + "format": "decbytes", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1102", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 11, + "y": 0 + }, + "id": 31, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.3.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "count(container_last_seen{name=~\".+\"})", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 1800 + } + ], + "title": "Containers", + "type": "stat" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 0.75 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 14, + "y": 0 + }, + "id": 26, + "links": [], + "maxDataPoints": 100, + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.3.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "min((node_filesystem_size_bytes - node_filesystem_free_bytes )/ node_filesystem_size_bytes)", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 1800 + } + ], + "title": "Disk space", + "type": "gauge" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 70 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 19, + "y": 0 + }, + "id": 25, + "links": [], + "maxDataPoints": 100, + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.3.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "((node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes) * 100", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 1800 + } + ], + "title": "Memory", + "type": "gauge" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 47, + "panels": [], + "title": "Docker Containers Metrics", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 5, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 1, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "avg by (name)(rate(container_cpu_usage_seconds_total{name!~\"cadvisor|node-exporter|grafana|prometheus||\"}[$interval])) * 100", + "hide": false, + "interval": "", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total CPU Usage per Container", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2189", + "format": "percent", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:2190", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 30, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 10, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.3.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "container_memory_usage_bytes{name!~\"cadvisor|node-exporter|grafana|prometheus||\"} - container_memory_cache{name!~\"cadvisor|node-exporter|grafana|prometheus||\"}", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{name}}", + "refId": "B", + "step": 240 + } + ], + "title": "Total Memory Usage per Container", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 10000000 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 25000000 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 37, + "links": [], + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "8.3.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "container_memory_usage_bytes{name!~\"prometheus|cadvisor|grafana|node-exporter\", name=~\".+\"} - container_memory_cache{name!~\"prometheus|cadvisor|grafana|node-exporter\", name=~\".+\"}", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{name}}", + "refId": "C", + "step": 240 + } + ], + "title": "Usage memory", + "transformations": [ + { + "id": "reduce", + "options": { + "includeTimeField": false, + "reducers": [ + "last" + ] + } + } + ], + "type": "table" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 38, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "avg by (name)(rate(container_cpu_usage_seconds_total{name!~\"cadvisor|node-exporter|grafana|prometheus||\"}[$interval])) * 100", + "hide": false, + "interval": "", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "CPU Usage per Container", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1693", + "format": "percent", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1694", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 35 + }, + "hiddenSeries": false, + "id": 39, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum by (name) (container_memory_usage_bytes{name!~\"prometheus|cadvisor|grafana|node-exporter|\"}-container_memory_cache{name!~\"prometheus|cadvisor|grafana|node-exporter|\"})", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{name}}", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Memory Usage per Container", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1101", + "format": "decbytes", + "label": "", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:1102", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 45 + }, + "id": 45, + "panels": [], + "title": "Chaincode Metrics", + "type": "row" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 0, + "y": 46 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum by(job, chaincode) (rate(chaincode_shim_request_duration_sum{chaincode!~\"_lifecycle.*|cscc|qscc\"}[$interval])) / sum by(job, chaincode) (rate(chaincode_shim_request_duration_count{chaincode!~\"_lifecycle.*|cscc|qscc\"}[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": " {{job}} {{chaincode}}", + "refId": "A" + } + ], + "title": "Request Duration", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 8, + "y": 46 + }, + "id": 43, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum without(channel,type) (rate(chaincode_shim_requests_received{chaincode!~\"_lifecycle.*|cscc|qscc\"}[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}} {{chaincode}}", + "refId": "A" + } + ], + "title": "Request Received", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 46 + }, + "id": 42, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum by (chaincode,job) (rate(chaincode_shim_requests_completed{chaincode!~\"_lifecycle.*|cscc|qscc\"}[$interval]))", + "hide": false, + "interval": "0.01m", + "intervalFactor": 1, + "legendFormat": "{{job}} {{chaincode}}", + "refId": "A" + } + ], + "title": "Requests Completed", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 57 + }, + "id": 49, + "panels": [], + "title": "Endorser Metrics", + "type": "row" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 0, + "y": 58 + }, + "id": 50, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum without(channel, chaincode) (rate(endorser_proposal_duration_sum{chaincode!~\"cscc|qscc|_lifecycle.*\",success=\"true\"}[$interval])) / sum without(channel, chaincode) (rate(endorser_proposal_duration_count{chaincode!~\"cscc|qscc|_lifecycle.*\",success=\"true\"}[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Successful Proposal Duration", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 8, + "y": 58 + }, + "id": 55, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "rate(endorser_proposals_received[$interval])", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Proposal Received", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 58 + }, + "id": 52, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "rate(endorser_successful_proposals[$interval])", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Successful Proposals", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 69 + }, + "id": 54, + "panels": [], + "title": "Ledger Metrics", + "type": "row" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 0, + "y": 70 + }, + "id": 56, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum without(channel) (rate(ledger_block_processing_time_sum[$interval])) / sum without(channel) (rate(ledger_block_processing_time_count[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Block Processing Time", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 6, + "y": 70 + }, + "id": 57, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum without(channel) (rate(ledger_blockstorage_commit_time_sum[$interval])) / sum without(channel) (rate(ledger_blockstorage_commit_time_count[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Block Storage Commit Time", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 12, + "y": 70 + }, + "id": 58, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "sum without(channel) (rate(ledger_statedb_commit_time_sum[$interval])) / sum without(channel) (rate(ledger_statedb_commit_time_count[$interval]))", + "hide": false, + "interval": "0.01m", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "StateDB Commit Time", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 18, + "y": 70 + }, + "id": 61, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "exemplar": true, + "expr": "ledger_blockchain_height", + "interval": "", + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "title": "Blockchain height", + "type": "timeseries" + } + ], + "refresh": "5s", + "schemaVersion": 34, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": ".+", + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Container Group", + "multi": true, + "name": "containergroup", + "options": [], + "query": { + "query": "label_values(container_group)", + "refId": "Prometheus-containergroup-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query", + "useTags": false + }, + { + "auto": true, + "auto_count": 50, + "auto_min": "50s", + "current": { + "selected": false, + "text": "auto", + "value": "$__auto_interval_interval" + }, + "hide": 0, + "includeAll": false, + "label": "Interval", + "multi": false, + "name": "interval", + "options": [ + { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "2m", + "value": "2m" + }, + { + "selected": false, + "text": "3m", + "value": "3m" + }, + { + "selected": false, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "7m", + "value": "7m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + }, + { + "selected": false, + "text": "7d", + "value": "7d" + }, + { + "selected": false, + "text": "14d", + "value": "14d" + }, + { + "selected": false, + "text": "30d", + "value": "30d" + } + ], + "query": "30s,1m,2m,3m,5m,7m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "queryValue": "", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + }, + { + "current": { + "selected": true, + "text": [ + "None" + ], + "value": [ + "" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Node", + "multi": true, + "name": "server", + "options": [], + "query": { + "query": "label_values(node_boot_time, instance)", + "refId": "Prometheus-server-Variable-Query" + }, + "refresh": 1, + "regex": "/([^:]+):.*/", + "skipUrlSync": false, + "sort": 0, + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "HLF Performances Review", + "uid": "UeOYeJpWy", + "version": 6, + "weekStart": "" +} \ No newline at end of file diff --git a/varion/prometheus-grafana/grafana/provisioning/datasources/datasource.yml b/varion/prometheus-grafana/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 00000000..4e58703f --- /dev/null +++ b/varion/prometheus-grafana/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,50 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + # name of the datasource. Required +- name: Prometheus + # datasource type. Required + type: prometheus + # access mode. direct or proxy. Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://prometheus:9090 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: true + # basic auth username + basicAuthUser: admin + # basic auth password + basicAuthPassword: foobar + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: true + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: false + tlsAuthWithCACert: false + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: true diff --git a/varion/prometheus-grafana/grafana_db/grafana.db b/varion/prometheus-grafana/grafana_db/grafana.db new file mode 100644 index 00000000..09d53057 Binary files /dev/null and b/varion/prometheus-grafana/grafana_db/grafana.db differ diff --git a/varion/prometheus-grafana/prometheus/prometheus.yml b/varion/prometheus-grafana/prometheus/prometheus.yml new file mode 100644 index 00000000..c8b7a71a --- /dev/null +++ b/varion/prometheus-grafana/prometheus/prometheus.yml @@ -0,0 +1,25 @@ +global: + scrape_interval: 1s + external_labels: + monitor: 'devopsage-monitor' + +scrape_configs: + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] + - job_name: "orderer" + static_configs: + - targets: ["orderer.example.com:9443"] + - job_name: "peer0_org1" + static_configs: + - targets: ["peer0.org1.example.com:9444"] + - job_name: "peer0_org2" + static_configs: + - targets: ["peer0.org2.example.com:9445"] + - job_name: cadvisor + scrape_interval: 5s + static_configs: + - targets: ['cadvisor:8080'] + - job_name: node + static_configs: + - targets: ['node-exporter:9100'] diff --git a/varion/scripts/add_new_orderer_to_config.py b/varion/scripts/add_new_orderer_to_config.py new file mode 100644 index 00000000..2daf2171 --- /dev/null +++ b/varion/scripts/add_new_orderer_to_config.py @@ -0,0 +1,98 @@ +# This is a sample Python script. + +# Press ⌃R to execute it or replace it with your code. +# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. +import argparse +import base64 +import copy +import json +import math +from typing import Any + + +def parse_args(): + parser = argparse.ArgumentParser( + prog='Config Update', + description='What the program does', + epilog='Text at the bottom of help') + parser.add_argument('config_path', type=str) + parser.add_argument('updated_config_path', type=str) + parser.add_argument('-a', '--address', type=str, required=True) + parser.add_argument('-i', '--identity', type=str, required=True) + parser.add_argument('-s', '--server-cert', type=str, required=True) + parser.add_argument('-c', '--client-cert', type=str, required=True) + return parser.parse_args() + + +def _pem_file_to_base64(path: str) -> str: + with open(path, 'rb') as binary_file: + binary_file_data = binary_file.read() + base64_encoded_data = base64.b64encode(binary_file_data) + return base64_encoded_data.decode('utf-8') + + +def _log_update(name: str, old: Any, new: Any) -> None: + print('=' * 50) + print(f'Updating {name}:') + print(f'{old}') + print(">" * 25) + print(f'{new}') + print('=' * 50) + + +def _calculate_bft_quorum(n: int) -> int: + f = int((n - 1) / 3) + return int(math.ceil((n + f + 1) / 2)) + + +def update_config(config_path: str, updated_config_path: str, address: str, identity_pem_path: str, server_pem_path: str, client_pem_path: str): + with open(config_path, 'r') as f: + config = json.load(f) + identity = _pem_file_to_base64(identity_pem_path) + client_cert = _pem_file_to_base64(client_pem_path) + server_cert = _pem_file_to_base64(server_pem_path) + host, port = address.split(':') + + addresses = config['channel_group']['groups']['Orderer']['groups']['OrdererOrg']['values']['Endpoints']['value']['addresses'] + addresses_before_update = copy.deepcopy(addresses) + original_orderers_count = len(addresses_before_update) + addresses.append(f'{addresses[0].split(":")[0]}:{port}') + new_orderers_count = len(addresses) + _log_update('addresses', addresses_before_update, addresses) + + identities = config['channel_group']['groups']['Orderer']['policies']['BlockValidation']['policy']['value']['identities'] + identities_before_update = copy.deepcopy(identities) + new_identity = copy.deepcopy(identities[0]) + new_identity['principal']['id_bytes'] = identity + identities.append(new_identity) + _log_update('block validation identities', identities_before_update, identities) + + rule = config['channel_group']['groups']['Orderer']['policies']['BlockValidation']['policy']['value'][ + 'rule'] + rule_before_update = copy.deepcopy(rule) + rule['n_out_of']['n'] = _calculate_bft_quorum(new_orderers_count) + rule['n_out_of']['rules'].append({'signed_by': new_orderers_count - 1}) + _log_update('block validation rules', rule_before_update, rule) + + consenter_mapping = config['channel_group']['groups']['Orderer']['values']['Orderers']['value']['consenter_mapping'] + consenter_mapping_before_update = copy.deepcopy(consenter_mapping) + consenter_mapping.append({ + 'client_tls_cert': client_cert, + 'host': host, + 'id': new_orderers_count, + 'identity': identity, + 'msp_id': consenter_mapping[0]['msp_id'], + 'port': port, + 'server_tls_cert': server_cert + }) + _log_update('consenter_mapping', consenter_mapping_before_update, consenter_mapping) + + with open(updated_config_path, 'w') as f: + json.dump(config, f) + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + args = parse_args() + update_config(args.config_path, args.updated_config_path, args.address, args.identity, args.server_cert, args.client_cert) + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/varion/scripts/ccutils.sh b/varion/scripts/ccutils.sh new file mode 100644 index 00000000..bc7f3bb0 --- /dev/null +++ b/varion/scripts/ccutils.sh @@ -0,0 +1,346 @@ +#!/bin/bash + +# installChaincode PEER ORG +function installChaincode() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode queryinstalled --output json | jq -r 'try (.installed_chaincodes[].package_id)' | grep ^${PACKAGE_ID}$ >&log.txt + if test $? -ne 0; then + peer lifecycle chaincode install ${CC_NAME}.tar.gz >&log.txt + res=$? + fi + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode installation on peer0.org${ORG} has failed" + successln "Chaincode is installed on peer0.org${ORG}" +} + +# queryInstalled PEER ORG +function queryInstalled() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode queryinstalled --output json | jq -r 'try (.installed_chaincodes[].package_id)' | grep ^${PACKAGE_ID}$ >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Query installed on peer0.org${ORG} has failed" + successln "Query installed successful on peer0.org${ORG} on channel" +} + +# approveForMyOrg VERSION PEER ORG +function approveForMyOrg() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --package-id ${PACKAGE_ID} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' failed" + successln "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME'" +} + +# checkCommitReadiness VERSION PEER ORG +function checkCommitReadiness() { + ORG=$1 + shift 1 + setGlobals $ORG + infoln "Checking the commit readiness of the chaincode definition on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to check the commit readiness of the chaincode definition on peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} --output json >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=0 + for var in "$@"; do + grep "$var" log.txt &>/dev/null || let rc=1 + done + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + infoln "Checking the commit readiness of the chaincode definition successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Check commit readiness result on peer0.org${ORG} is INVALID!" + fi +} + +# commitChaincodeDefinition VERSION PEER ORG (PEER ORG)... +function commitChaincodeDefinition() { + parsePeerConnectionParameters $@ + res=$? + verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters " + + # while 'peer chaincode' command can get the orderer endpoint from the + # peer (if join was successful), let's supply it directly as we know + # it using the "-o" option + set -x + peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID $CHANNEL_NAME --name ${CC_NAME} "${PEER_CONN_PARMS[@]}" --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode definition commit failed on peer0.org${ORG} on channel '$CHANNEL_NAME' failed" + successln "Chaincode definition committed on channel '$CHANNEL_NAME'" +} + +# queryCommitted ORG +function queryCommitted() { + ORG=$1 + setGlobals $ORG + EXPECTED_RESULT="Version: ${CC_VERSION}, Sequence: ${CC_SEQUENCE}, Endorsement Plugin: escc, Validation Plugin: vscc" + infoln "Querying chaincode definition on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Query committed status on peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME} >&log.txt + res=$? + { set +x; } 2>/dev/null + test $res -eq 0 && VALUE=$(cat log.txt | grep -o '^Version: '$CC_VERSION', Sequence: [0-9]*, Endorsement Plugin: escc, Validation Plugin: vscc') + test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Query chaincode definition successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Query chaincode definition result on peer0.org${ORG} is INVALID!" + fi +} + +function chaincodeInvokeInit() { + parsePeerConnectionParameters $@ + res=$? + verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters " + + local rc=1 + local COUNTER=1 + local fcn_call='{"function":"'${CC_INIT_FCN}'","Args":[]}' + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + # while 'peer chaincode' command can get the orderer endpoint from the + # peer (if join was successful), let's supply it directly as we know + # it using the "-o" option + set -x + infoln "invoke fcn call:${fcn_call}" + peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" -C $CHANNEL_NAME -n ${CC_NAME} "${PEER_CONN_PARMS[@]}" --isInit -c ${fcn_call} >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + verifyResult $res "Invoke execution on $PEERS failed " + successln "Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME'" +} + +function chaincodeQuery() { + ORG=$1 + setGlobals $ORG + infoln "Querying on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Query peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Query successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Query result on peer0.org${ORG} is INVALID!" + fi +} + +function resolveSequence() { + + #if the sequence is not "auto", then use the provided sequence + if [[ "${CC_SEQUENCE}" != "auto" ]]; then + return 0 + fi + + local rc=1 + local COUNTER=1 + # first, find the sequence number of the committed chaincode + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + set -x + COMMITTED_CC_SEQUENCE=$(peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME} | sed -n "/Version:/{s/.*Sequence: //; s/, Endorsement Plugin:.*$//; p;}") + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + + # if there are no committed versions, then set the sequence to 1 + if [ -z $COMMITTED_CC_SEQUENCE ]; then + CC_SEQUENCE=1 + return 0 + fi + + rc=1 + COUNTER=1 + # next, find the sequence number of the approved chaincode + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + set -x + APPROVED_CC_SEQUENCE=$(peer lifecycle chaincode queryapproved --channelID $CHANNEL_NAME --name ${CC_NAME} | sed -n "/sequence:/{s/^sequence: //; s/, version:.*$//; p;}") + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + + # if the committed sequence and the approved sequence match, then increment the sequence + # otherwise, use the approved sequence + if [ $COMMITTED_CC_SEQUENCE == $APPROVED_CC_SEQUENCE ]; then + CC_SEQUENCE=$((COMMITTED_CC_SEQUENCE+1)) + else + CC_SEQUENCE=$APPROVED_CC_SEQUENCE + fi + +} + +#. scripts/envVar.sh + +queryInstalledOnPeer() { + + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + #sleep $DELAY + #infoln "Attempting to list on peer0.org${ORG}, Retry after $DELAY seconds." + peer lifecycle chaincode queryinstalled >&log.txt + res=$? + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt +} + +queryCommittedOnChannel() { + CHANNEL=$1 + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + #sleep $DELAY + #infoln "Attempting to list on peer0.org${ORG}, Retry after $DELAY seconds." + peer lifecycle chaincode querycommitted -C $CHANNEL >&log.txt + res=$? + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -ne 0; then + fatalln "After $MAX_RETRY attempts, Failed to retrieve committed chaincode!" + fi + +} + +## Function to list chaincodes installed on the peer and committed chaincode visible to the org +listAllCommitted() { + + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + CHANNEL_LIST=$(peer channel list | sed '1,1d') + res=$? + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + if test $rc -eq 0; then + for channel in $CHANNEL_LIST + do + queryCommittedOnChannel "$channel" + done + else + fatalln "After $MAX_RETRY attempts, Failed to retrieve committed chaincode!" + fi + +} + +chaincodeInvoke() { + ORG=$1 + CHANNEL=$2 + CC_NAME=$3 + CC_INVOKE_CONSTRUCTOR=$4 + + infoln "Invoking on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Invoke on peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer chaincode invoke -o localhost:7050 -C $CHANNEL_NAME -n ${CC_NAME} -c ${CC_INVOKE_CONSTRUCTOR} --tls --cafile $ORDERER_CA --peerAddresses localhost:7051 --tlsRootCertFiles $PEER0_ORG1_CA --peerAddresses localhost:9051 --tlsRootCertFiles $PEER0_ORG2_CA >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Invoke successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Invoke result on peer0.org${ORG} is INVALID!" + fi +} + +chaincodeQuery() { + ORG=$1 + CHANNEL=$2 + CC_NAME=$3 + CC_QUERY_CONSTRUCTOR=$4 + + infoln "Querying on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Query peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c ${CC_QUERY_CONSTRUCTOR} >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Query successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Query result on peer0.org${ORG} is INVALID!" + fi +} \ No newline at end of file diff --git a/varion/scripts/configUpdate.sh b/varion/scripts/configUpdate.sh new file mode 100755 index 00000000..63586031 --- /dev/null +++ b/varion/scripts/configUpdate.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# import utils +# test network home var targets to test network folder +# the reason we use a var here is considering with org3 specific folder +# when invoking this for org3 as test-network/scripts/org3-scripts +# the value is changed from default as $PWD(test-network) +# to .. as relative path to make the import works +TEST_NETWORK_HOME=${TEST_NETWORK_HOME:-${PWD}} +. ${TEST_NETWORK_HOME}/scripts/envVar.sh + +# fetchChannelConfig +# Writes the current channel config for a given channel to a JSON file +# NOTE: this requires jq and configtxlator for execution. +fetchChannelConfig() { + ORG=$1 + CHANNEL=$2 + OUTPUT=$3 + + setGlobals $ORG + + infoln "Fetching the most recent configuration block for the channel" + set -x + peer channel fetch config ${TEST_NETWORK_HOME}/channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.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 ${TEST_NETWORK_HOME}/channel-artifacts/config_block.pb --type common.Block --output ${TEST_NETWORK_HOME}/channel-artifacts/config_block.json + jq .data.data[0].payload.data.config ${TEST_NETWORK_HOME}/channel-artifacts/config_block.json >"${OUTPUT}" + res=$? + { set +x; } 2>/dev/null + verifyResult $res "Failed to parse channel configuration, make sure you have jq installed" +} + +# createConfigUpdate +# Takes an original and modified config, and produces the config update tx +# which transitions between the two +# NOTE: this requires jq and configtxlator for execution. +createConfigUpdate() { + CHANNEL=$1 + ORIGINAL=$2 + MODIFIED=$3 + OUTPUT=$4 + + set -x + configtxlator proto_encode --input "${ORIGINAL}" --type common.Config --output ${TEST_NETWORK_HOME}/channel-artifacts/original_config.pb + configtxlator proto_encode --input "${MODIFIED}" --type common.Config --output ${TEST_NETWORK_HOME}/channel-artifacts/modified_config.pb + configtxlator compute_update --channel_id "${CHANNEL}" --original ${TEST_NETWORK_HOME}/channel-artifacts/original_config.pb --updated ${TEST_NETWORK_HOME}/channel-artifacts/modified_config.pb --output ${TEST_NETWORK_HOME}/channel-artifacts/config_update.pb + configtxlator proto_decode --input ${TEST_NETWORK_HOME}/channel-artifacts/config_update.pb --type common.ConfigUpdate --output ${TEST_NETWORK_HOME}/channel-artifacts/config_update.json + echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat ${TEST_NETWORK_HOME}/channel-artifacts/config_update.json)'}}}' | jq . > ${TEST_NETWORK_HOME}/channel-artifacts/config_update_in_envelope.json + configtxlator proto_encode --input ${TEST_NETWORK_HOME}/channel-artifacts/config_update_in_envelope.json --type common.Envelope --output "${OUTPUT}" + { set +x; } 2>/dev/null +} + +# signConfigtxAsPeerOrg +# Set the peerOrg admin of an org and sign the config update +signConfigtxAsPeerOrg() { + ORG=$1 + CONFIGTXFILE=$2 + setGlobals $ORG + set -x + peer channel signconfigtx -f "${CONFIGTXFILE}" + { set +x; } 2>/dev/null +} diff --git a/varion/scripts/createChannel.sh b/varion/scripts/createChannel.sh new file mode 100755 index 00000000..8f7980d4 --- /dev/null +++ b/varion/scripts/createChannel.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +# imports +. scripts/envVar.sh + +CHANNEL_NAME="$1" +DELAY="$2" +MAX_RETRY="$3" +VERBOSE="$4" +BFT="$5" +: ${CHANNEL_NAME:="mychannel"} +: ${DELAY:="3"} +: ${MAX_RETRY:="5"} +: ${VERBOSE:="false"} +: ${BFT:=0} + +: ${CONTAINER_CLI:="docker"} +if command -v ${CONTAINER_CLI}-compose > /dev/null 2>&1; then + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} +else + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI} compose"} +fi +infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" + +if [ ! -d "channel-artifacts" ]; then + mkdir channel-artifacts +fi + +createChannelGenesisBlock() { + setGlobals 1 + which configtxgen + if [ "$?" -ne 0 ]; then + fatalln "configtxgen tool not found." + fi + local bft_true=$1 + set -x + + if [ $bft_true -eq 1 ]; then + configtxgen -profile ChannelUsingBFT -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID $CHANNEL_NAME + else + configtxgen -profile ChannelUsingRaft -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID $CHANNEL_NAME + fi + res=$? + { set +x; } 2>/dev/null + verifyResult $res "Failed to generate channel configuration transaction..." +} + +createChannel() { + # Poll in case the raft leader is not set yet + local rc=1 + local COUNTER=1 + local bft_true=$1 + infoln "Adding orderers" + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ] ; do + sleep $DELAY + set -x + . scripts/orderer.sh ${CHANNEL_NAME}> /dev/null 2>&1 + if [ $bft_true -eq 1 ]; then + . scripts/orderer2.sh ${CHANNEL_NAME}> /dev/null 2>&1 + . scripts/orderer3.sh ${CHANNEL_NAME}> /dev/null 2>&1 + . scripts/orderer4.sh ${CHANNEL_NAME}> /dev/null 2>&1 + fi + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + verifyResult $res "Channel creation failed" +} + +# joinChannel ORG +joinChannel() { + ORG=$1 + FABRIC_CFG_PATH=$PWD/../config/ + setGlobals $ORG + local rc=1 + local COUNTER=1 + ## Sometimes Join takes time, hence retry + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ] ; do + sleep $DELAY + set -x + peer channel join -b $BLOCKFILE >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + verifyResult $res "After $MAX_RETRY attempts, peer0.org${ORG} has failed to join channel '$CHANNEL_NAME' " +} + +setAnchorPeer() { + ORG=$1 + . scripts/setAnchorPeer.sh $ORG $CHANNEL_NAME +} + + +## User attempts to use BFT orderer in Fabric network with CA +if [ $BFT -eq 1 ] && [ -d "organizations/fabric-ca/ordererOrg/msp" ]; then + fatalln "Fabric network seems to be using CA. This sample does not yet support the use of consensus type BFT and CA together." +fi + +## Create channel genesis block +FABRIC_CFG_PATH=$PWD/../config/ +BLOCKFILE="./channel-artifacts/${CHANNEL_NAME}.block" + +infoln "Generating channel genesis block '${CHANNEL_NAME}.block'" +FABRIC_CFG_PATH=${PWD}/configtx +if [ $BFT -eq 1 ]; then + FABRIC_CFG_PATH=${PWD}/bft-config +fi +createChannelGenesisBlock $BFT + + +## Create channel +infoln "Creating channel ${CHANNEL_NAME}" +createChannel $BFT +successln "Channel '$CHANNEL_NAME' created" + +## Join all the peers to the channel +infoln "Joining org1 peer to the channel..." +joinChannel 1 +infoln "Joining org2 peer to the channel..." +joinChannel 2 + +## Set the anchor peers for each org in the channel +infoln "Setting anchor peer for org1..." +setAnchorPeer 1 +infoln "Setting anchor peer for org2..." +setAnchorPeer 2 + +successln "Channel '$CHANNEL_NAME' joined" diff --git a/varion/scripts/deployCC.sh b/varion/scripts/deployCC.sh new file mode 100755 index 00000000..31e66925 --- /dev/null +++ b/varion/scripts/deployCC.sh @@ -0,0 +1,118 @@ +#!/bin/bash + +source scripts/utils.sh + +CHANNEL_NAME=${1:-"mychannel"} +CC_NAME=${2} +CC_SRC_PATH=${3} +CC_SRC_LANGUAGE=${4} +CC_VERSION=${5:-"1.0"} +CC_SEQUENCE=${6:-"1"} +CC_INIT_FCN=${7:-"NA"} +CC_END_POLICY=${8:-"NA"} +CC_COLL_CONFIG=${9:-"NA"} +DELAY=${10:-"3"} +MAX_RETRY=${11:-"5"} +VERBOSE=${12:-"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_SRC_PATH: ${C_GREEN}${CC_SRC_PATH}${C_RESET}" +println "- CC_SRC_LANGUAGE: ${C_GREEN}${CC_SRC_LANGUAGE}${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}" + +INIT_REQUIRED="--init-required" +# check if the init fcn should be called +if [ "$CC_INIT_FCN" = "NA" ]; then + INIT_REQUIRED="" +fi + +if [ "$CC_END_POLICY" = "NA" ]; then + CC_END_POLICY="" +else + CC_END_POLICY="--signature-policy $CC_END_POLICY" +fi + +if [ "$CC_COLL_CONFIG" = "NA" ]; then + CC_COLL_CONFIG="" +else + CC_COLL_CONFIG="--collections-config $CC_COLL_CONFIG" +fi + +FABRIC_CFG_PATH=$PWD/../config/ + +# import utils +. scripts/envVar.sh +. scripts/ccutils.sh + +function checkPrereqs() { + jq --version > /dev/null 2>&1 + + if [[ $? -ne 0 ]]; then + errorln "jq command not found..." + errorln + errorln "Follow the instructions in the Fabric docs to install the prereqs" + errorln "https://hyperledger-fabric.readthedocs.io/en/latest/prereqs.html" + exit 1 + fi +} + +#check for prerequisites +checkPrereqs + +## package the chaincode +./scripts/packageCC.sh $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION + +PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid ${CC_NAME}.tar.gz) + +## Install chaincode on peer0.org1 and peer0.org2 +infoln "Installing chaincode on peer0.org1..." +installChaincode 1 +infoln "Install chaincode on peer0.org2..." +installChaincode 2 + +resolveSequence + +## query whether the chaincode is installed +queryInstalled 1 + +## approve the definition for org1 +approveForMyOrg 1 + +## check whether the chaincode definition is ready to be committed +## expect org1 to have approved and org2 not to +checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": false" +checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": false" + +## now approve also for org2 +approveForMyOrg 2 + +## check whether the chaincode definition is ready to be committed +## expect them both to have approved +checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": true" +checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": true" + +## now that we know for sure both orgs have approved, commit the definition +commitChaincodeDefinition 1 2 + +## query on both orgs to see that the definition committed successfully +queryCommitted 1 +queryCommitted 2 + +## Invoke the chaincode - this does require that the chaincode have the 'initLedger' +## method defined +if [ "$CC_INIT_FCN" = "NA" ]; then + infoln "Chaincode initialization is not required" +else + chaincodeInvokeInit 1 2 +fi + +exit 0 diff --git a/varion/scripts/deployCCAAS.sh b/varion/scripts/deployCCAAS.sh new file mode 100755 index 00000000..bc36d589 --- /dev/null +++ b/varion/scripts/deployCCAAS.sh @@ -0,0 +1,223 @@ +#!/bin/bash +# +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +source scripts/utils.sh + +CHANNEL_NAME=${1:-"mychannel"} +CC_NAME=${2} +CC_SRC_PATH=${3} +CCAAS_DOCKER_RUN=${4:-"true"} +CC_VERSION=${5:-"1.0"} +CC_SEQUENCE=${6:-"1"} +CC_INIT_FCN=${7:-"NA"} +CC_END_POLICY=${8:-"NA"} +CC_COLL_CONFIG=${9:-"NA"} +DELAY=${10:-"3"} +MAX_RETRY=${11:-"5"} +VERBOSE=${12:-"false"} + +CCAAS_SERVER_PORT=9999 + +: ${CONTAINER_CLI:="docker"} +if command -v ${CONTAINER_CLI}-compose > /dev/null 2>&1; then + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} +else + : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI} compose"} +fi +infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" + +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_SRC_PATH: ${C_GREEN}${CC_SRC_PATH}${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 "- CCAAS_DOCKER_RUN: ${C_GREEN}${CCAAS_DOCKER_RUN}${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 +if [ -z "$CC_NAME" ] || [ "$CC_NAME" = "NA" ]; then + fatalln "No chaincode name was provided. Valid call example: ./network.sh deployCCAS -ccn basic -ccp ../asset-transfer-basic/chaincode-go " + +# User has not provided a path +elif [ -z "$CC_SRC_PATH" ] || [ "$CC_SRC_PATH" = "NA" ]; then + fatalln "No chaincode path was provided. Valid call example: ./network.sh deployCCAS -ccn basic -ccp ../asset-transfer-basic/chaincode-go " + +## Make sure that the path to the chaincode exists +elif [ ! -d "$CC_SRC_PATH" ]; then + fatalln "Path to chaincode does not exist. Please provide different path." +fi + + + +if [ "$CC_END_POLICY" = "NA" ]; then + CC_END_POLICY="" +else + CC_END_POLICY="--signature-policy $CC_END_POLICY" +fi + +if [ "$CC_COLL_CONFIG" = "NA" ]; then + CC_COLL_CONFIG="" +else + CC_COLL_CONFIG="--collections-config $CC_COLL_CONFIG" +fi + +# import utils +. scripts/envVar.sh +. scripts/ccutils.sh + +packageChaincode() { + + address="{{.peername}}_${CC_NAME}_ccaas:${CCAAS_SERVER_PORT}" + prefix=$(basename "$0") + tempdir=$(mktemp -d -t "$prefix.XXXXXXXX") || error_exit "Error creating temporary directory" + label=${CC_NAME}_${CC_VERSION} + mkdir -p "$tempdir/src" + +cat > "$tempdir/src/connection.json" < "$tempdir/pkg/metadata.json" +{ + "type": "ccaas", + "label": "$label" +} +METADATA-EOF + + tar -C "$tempdir/src" -czf "$tempdir/pkg/code.tar.gz" . + tar -C "$tempdir/pkg" -czf "$CC_NAME.tar.gz" metadata.json code.tar.gz + rm -Rf "$tempdir" + + PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid ${CC_NAME}.tar.gz) + + successln "Chaincode is packaged ${address}" +} + +buildDockerImages() { + # if set don't build - useful when you want to debug yourself + if [ "$CCAAS_DOCKER_RUN" = "true" ]; then + # build the docker container + infoln "Building Chaincode-as-a-Service docker image '${CC_NAME}' '${CC_SRC_PATH}'" + infoln "This may take several minutes..." + set -x + ${CONTAINER_CLI} build -f $CC_SRC_PATH/Dockerfile -t ${CC_NAME}_ccaas_image:latest --build-arg CC_SERVER_PORT=9999 $CC_SRC_PATH >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Docker build of chaincode-as-a-service container failed" + successln "Docker image '${CC_NAME}_ccaas_image:latest' built succesfully" + else + infoln "Not building docker image; this the command we would have run" + infoln " ${CONTAINER_CLI} build -f $CC_SRC_PATH/Dockerfile -t ${CC_NAME}_ccaas_image:latest --build-arg CC_SERVER_PORT=9999 $CC_SRC_PATH" + fi +} + +startDockerContainer() { + # start the docker container + if [ "$CCAAS_DOCKER_RUN" = "true" ]; then + infoln "Starting the Chaincode-as-a-Service docker container..." + set -x + ${CONTAINER_CLI} run --rm -d --name peer0org1_${CC_NAME}_ccaas \ + --network fabric_test \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + ${CC_NAME}_ccaas_image:latest + + ${CONTAINER_CLI} run --rm -d --name peer0org2_${CC_NAME}_ccaas \ + --network fabric_test \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + ${CC_NAME}_ccaas_image:latest + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Failed to start the container container '${CC_NAME}_ccaas_image:latest' " + successln "Docker container started succesfully '${CC_NAME}_ccaas_image:latest'" + else + + infoln "Not starting docker containers; these are the commands we would have run" + infoln " ${CONTAINER_CLI} run --rm -d --name peer0org1_${CC_NAME}_ccaas \ + --network fabric_test \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + ${CC_NAME}_ccaas_image:latest" + infoln " ${CONTAINER_CLI} run --rm -d --name peer0org2_${CC_NAME}_ccaas \ + --network fabric_test \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + ${CC_NAME}_ccaas_image:latest" + + fi +} + +# Build the docker image +buildDockerImages + +## package the chaincode +packageChaincode + +## Install chaincode on peer0.org1 and peer0.org2 +infoln "Installing chaincode on peer0.org1..." +installChaincode 1 +infoln "Install chaincode on peer0.org2..." +installChaincode 2 + +resolveSequence + +## query whether the chaincode is installed +queryInstalled 1 + +## approve the definition for org1 +approveForMyOrg 1 + +## check whether the chaincode definition is ready to be committed +## expect org1 to have approved and org2 not to +checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": false" +checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": false" + +## now approve also for org2 +approveForMyOrg 2 + +## check whether the chaincode definition is ready to be committed +## expect them both to have approved +checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": true" +checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": true" + +## now that we know for sure both orgs have approved, commit the definition +commitChaincodeDefinition 1 2 + +## query on both orgs to see that the definition committed successfully +queryCommitted 1 +queryCommitted 2 + +# start the container +startDockerContainer + +## Invoke the chaincode - this does require that the chaincode have the 'initLedger' +## method defined +if [ "$CC_INIT_FCN" = "NA" ]; then + infoln "Chaincode initialization is not required" +else + chaincodeInvokeInit 1 2 +fi + +exit 0 diff --git a/varion/scripts/envVar.sh b/varion/scripts/envVar.sh new file mode 100755 index 00000000..a446c9b3 --- /dev/null +++ b/varion/scripts/envVar.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This is a collection of bash functions used by different scripts + +# imports +# test network home var targets to test-network folder +# the reason we use a var here is to accommodate scenarios +# where execution occurs from folders outside of default as $PWD, such as the test-network/addOrg3 folder. +# For setting environment variables, simple relative paths like ".." could lead to unintended references +# due to how they interact with FABRIC_CFG_PATH. It's advised to specify paths more explicitly, +# such as using "../${PWD}", to ensure that Fabric's environment variables are pointing to the correct paths. +TEST_NETWORK_HOME=${TEST_NETWORK_HOME:-${PWD}} +. ${TEST_NETWORK_HOME}/scripts/utils.sh + +export CORE_PEER_TLS_ENABLED=true +export ORDERER_CA=${TEST_NETWORK_HOME}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem +export PEER0_ORG1_CA=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem +export PEER0_ORG2_CA=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem +export PEER0_ORG3_CA=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem + +# Set environment variables for the peer org +setGlobals() { + local USING_ORG="" + if [ -z "$OVERRIDE_ORG" ]; then + USING_ORG=$1 + else + USING_ORG="${OVERRIDE_ORG}" + fi + infoln "Using organization ${USING_ORG}" + if [ $USING_ORG -eq 1 ]; then + export CORE_PEER_LOCALMSPID=Org1MSP + export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA + export CORE_PEER_MSPCONFIGPATH=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp + export CORE_PEER_ADDRESS=localhost:7051 + elif [ $USING_ORG -eq 2 ]; then + export CORE_PEER_LOCALMSPID=Org2MSP + export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA + export CORE_PEER_MSPCONFIGPATH=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp + export CORE_PEER_ADDRESS=localhost:9051 + elif [ $USING_ORG -eq 3 ]; then + export CORE_PEER_LOCALMSPID=Org3MSP + export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA + export CORE_PEER_MSPCONFIGPATH=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp + export CORE_PEER_ADDRESS=localhost:11051 + else + errorln "ORG Unknown" + fi + + if [ "$VERBOSE" = "true" ]; then + env | grep CORE + fi +} + +# parsePeerConnectionParameters $@ +# Helper function that sets the peer connection parameters for a chaincode +# operation +parsePeerConnectionParameters() { + PEER_CONN_PARMS=() + PEERS="" + while [ "$#" -gt 0 ]; do + setGlobals $1 + PEER="peer0.org$1" + ## Set peer addresses + if [ -z "$PEERS" ] + then + PEERS="$PEER" + else + PEERS="$PEERS $PEER" + fi + PEER_CONN_PARMS=("${PEER_CONN_PARMS[@]}" --peerAddresses $CORE_PEER_ADDRESS) + ## Set path to TLS certificate + CA=PEER0_ORG$1_CA + TLSINFO=(--tlsRootCertFiles "${!CA}") + PEER_CONN_PARMS=("${PEER_CONN_PARMS[@]}" "${TLSINFO[@]}") + # shift by one to get to the next organization + shift + done +} + +verifyResult() { + if [ $1 -ne 0 ]; then + fatalln "$2" + fi +} diff --git a/varion/scripts/orderer.sh b/varion/scripts/orderer.sh new file mode 100644 index 00000000..e18a89c9 --- /dev/null +++ b/varion/scripts/orderer.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +channel_name=$1 + +export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH +export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt /dev/null 2>&1 +export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key /dev/null 2>&1 + +osnadmin channel join --channelID ${channel_name} --config-block ./channel-artifacts/${channel_name}.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" >> log.txt 2>&1 \ No newline at end of file diff --git a/varion/scripts/orderer2.sh b/varion/scripts/orderer2.sh new file mode 100755 index 00000000..978aab2d --- /dev/null +++ b/varion/scripts/orderer2.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +channel_name=$1 + +export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH +export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt /dev/null 2>&1 +export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.key > /dev/null 2>&1 + +osnadmin channel join --channelID ${channel_name} --config-block ./channel-artifacts/${channel_name}.block -o localhost:7055 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" >> log.txt 2>&1 \ No newline at end of file diff --git a/varion/scripts/orderer3.sh b/varion/scripts/orderer3.sh new file mode 100644 index 00000000..8b216eba --- /dev/null +++ b/varion/scripts/orderer3.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +channel_name=$1 + +export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH +export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt /dev/null 2>&1 +export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.key > /dev/null 2>&1 + +osnadmin channel join --channelID ${channel_name} --config-block ./channel-artifacts/${channel_name}.block -o localhost:7057 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" >> log.txt 2>&1 \ No newline at end of file diff --git a/varion/scripts/orderer4.sh b/varion/scripts/orderer4.sh new file mode 100644 index 00000000..3c572770 --- /dev/null +++ b/varion/scripts/orderer4.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +channel_name=$1 + +export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH +export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt /dev/null 2>&1 +export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.key > /dev/null 2>&1 + +osnadmin channel join --channelID ${channel_name} --config-block ./channel-artifacts/${channel_name}.block -o localhost:7059 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" >> log.txt 2>&1 \ No newline at end of file diff --git a/varion/scripts/org3-scripts/joinChannel.sh b/varion/scripts/org3-scripts/joinChannel.sh new file mode 100755 index 00000000..53f3f0b8 --- /dev/null +++ b/varion/scripts/org3-scripts/joinChannel.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This script is designed to be run by addOrg3.sh as the +# second step of the Adding an Org to a Channel tutorial. +# It joins the org3 peers to the channel previously setup in +# the test network tutorial. + +CHANNEL_NAME="$1" +DELAY="$2" +TIMEOUT="$3" +VERBOSE="$4" +: ${CHANNEL_NAME:="mychannel"} +: ${DELAY:="3"} +: ${TIMEOUT:="10"} +: ${VERBOSE:="false"} +COUNTER=1 +MAX_RETRY=5 + +# import environment variables +# test network home var targets to test-network folder +# the reason we use a var here is considering with org3 specific folder +# when invoking this for org3 as test-network/scripts/org3-scripts +# the value is changed from default as $PWD (test-network) +# to ${PWD}/.. to make the import works +export TEST_NETWORK_HOME="${PWD}/.." +. ${TEST_NETWORK_HOME}/scripts/envVar.sh + +# joinChannel ORG +joinChannel() { + ORG=$1 + setGlobals $ORG + local rc=1 + local COUNTER=1 + ## Sometimes Join takes time, hence retry + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ] ; do + sleep $DELAY + set -x + peer channel join -b $BLOCKFILE >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + verifyResult $res "After $MAX_RETRY attempts, peer0.org${ORG} has failed to join channel '$CHANNEL_NAME' " +} + +setAnchorPeer() { + ORG=$1 + ${TEST_NETWORK_HOME}/scripts/setAnchorPeer.sh $ORG $CHANNEL_NAME +} + +setGlobals 3 +BLOCKFILE="${TEST_NETWORK_HOME}/channel-artifacts/${CHANNEL_NAME}.block" + +echo "Fetching channel config block from orderer..." +set -x +peer channel fetch 0 $BLOCKFILE -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME --tls --cafile "$ORDERER_CA" >&log.txt +res=$? +{ set +x; } 2>/dev/null +cat log.txt +verifyResult $res "Fetching config block from orderer has failed" + +infoln "Joining org3 peer to the channel..." +joinChannel 3 + +infoln "Setting anchor peer for org3..." +setAnchorPeer 3 + +successln "Channel '$CHANNEL_NAME' joined" +successln "Org3 peer successfully added to network" diff --git a/varion/scripts/org3-scripts/updateChannelConfig.sh b/varion/scripts/org3-scripts/updateChannelConfig.sh new file mode 100755 index 00000000..a34b4e92 --- /dev/null +++ b/varion/scripts/org3-scripts/updateChannelConfig.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This script is designed to be run by addOrg3.sh as the +# first step of the Adding an Org to a Channel tutorial. +# It creates and submits a configuration transaction to +# add org3 to the test network + +CHANNEL_NAME="$1" +DELAY="$2" +TIMEOUT="$3" +VERBOSE="$4" +: ${CHANNEL_NAME:="mychannel"} +: ${DELAY:="3"} +: ${TIMEOUT:="10"} +: ${VERBOSE:="false"} +COUNTER=1 +MAX_RETRY=5 + + +# imports +# test network home var targets to test-network folder +# the reason we use a var here is considering with org3 specific folder +# when invoking this for org3 as test-network/scripts/org3-scripts +# the value is changed from default as $PWD (test-network) +# to ${PWD}/.. to make the import works +export TEST_NETWORK_HOME="${PWD}/.." +. ${TEST_NETWORK_HOME}/scripts/configUpdate.sh + +infoln "Creating config transaction to add org3 to network" + +# Fetch the config for the channel, writing it to config.json +fetchChannelConfig 1 ${CHANNEL_NAME} ${TEST_NETWORK_HOME}/channel-artifacts/config.json + +# Modify the configuration to append the new org +set -x +jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' ${TEST_NETWORK_HOME}/channel-artifacts/config.json ${TEST_NETWORK_HOME}/organizations/peerOrganizations/org3.example.com/org3.json > ${TEST_NETWORK_HOME}/channel-artifacts/modified_config.json +{ set +x; } 2>/dev/null + +# Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb +createConfigUpdate ${CHANNEL_NAME} ${TEST_NETWORK_HOME}/channel-artifacts/config.json ${TEST_NETWORK_HOME}/channel-artifacts/modified_config.json ${TEST_NETWORK_HOME}/channel-artifacts/org3_update_in_envelope.pb + +infoln "Signing config transaction" +signConfigtxAsPeerOrg 1 ${TEST_NETWORK_HOME}/channel-artifacts/org3_update_in_envelope.pb + +infoln "Submitting transaction from a different peer (peer0.org2) which also signs it" +setGlobals 2 +set -x +peer channel update -f ${TEST_NETWORK_HOME}/channel-artifacts/org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" +{ set +x; } 2>/dev/null + +successln "Config transaction to add org3 to network submitted" diff --git a/varion/scripts/packageCC.sh b/varion/scripts/packageCC.sh new file mode 100755 index 00000000..1b3d6b40 --- /dev/null +++ b/varion/scripts/packageCC.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +#!/bin/bash + +source scripts/utils.sh + +CC_NAME=${1} +CC_SRC_PATH=${2} +CC_SRC_LANGUAGE=${3} +CC_VERSION=${4} +CC_PACKAGE_ONLY=${5:-false} + +println "executing with the following" +println "- CC_NAME: ${C_GREEN}${CC_NAME}${C_RESET}" +println "- CC_SRC_PATH: ${C_GREEN}${CC_SRC_PATH}${C_RESET}" +println "- CC_SRC_LANGUAGE: ${C_GREEN}${CC_SRC_LANGUAGE}${C_RESET}" +println "- CC_VERSION: ${C_GREEN}${CC_VERSION}${C_RESET}" + +FABRIC_CFG_PATH=$PWD/../config/ + +#User has not provided a name +if [ -z "$CC_NAME" ] || [ "$CC_NAME" = "NA" ]; then + fatalln "No chaincode name was provided. Valid call example: ./network.sh packageCC -ccn basic -ccp chaincode/asset-transfer-basic/chaincode-go -ccv 1.0.0 -ccl go" + +# User has not provided a path +elif [ -z "$CC_SRC_PATH" ] || [ "$CC_SRC_PATH" = "NA" ]; then + fatalln "No chaincode path was provided. Valid call example: ./network.sh packageCC -ccn basic -ccp chaincode/asset-transfer-basic/chaincode-go -ccv 1.0.0 -ccl go" + +# User has not provided a language +elif [ -z "$CC_SRC_LANGUAGE" ] || [ "$CC_SRC_LANGUAGE" = "NA" ]; then + fatalln "No chaincode language was provided. Valid call example: ./network.sh packageCC -ccn basic -ccp chaincode/asset-transfer-basic/chaincode-go -ccv 1.0.0 -ccl go" + +## Make sure that the path to the chaincode exists +elif [ ! -d "$CC_SRC_PATH" ]; then + fatalln "Path to chaincode does not exist. Please provide different path." +fi + +CC_SRC_LANGUAGE=$(echo "$CC_SRC_LANGUAGE" | tr [:upper:] [:lower:]) + +# do some language specific preparation to the chaincode before packaging +if [ "$CC_SRC_LANGUAGE" = "go" ]; then + CC_RUNTIME_LANGUAGE=golang + + infoln "Vendoring Go dependencies at $CC_SRC_PATH" + pushd $CC_SRC_PATH + GO111MODULE=on go mod vendor + popd + successln "Finished vendoring Go dependencies" + +elif [ "$CC_SRC_LANGUAGE" = "java" ]; then + CC_RUNTIME_LANGUAGE=java + + infoln "Compiling Java code..." + pushd $CC_SRC_PATH + ./gradlew installDist + popd + successln "Finished compiling Java code" + CC_SRC_PATH=$CC_SRC_PATH/build/install/$CC_NAME + +elif [ "$CC_SRC_LANGUAGE" = "javascript" ]; then + CC_RUNTIME_LANGUAGE=node + +elif [ "$CC_SRC_LANGUAGE" = "typescript" ]; then + CC_RUNTIME_LANGUAGE=node + + infoln "Compiling TypeScript code into JavaScript..." + pushd $CC_SRC_PATH + npm install + npm run build + popd + successln "Finished compiling TypeScript code into JavaScript" + +else + fatalln "The chaincode language ${CC_SRC_LANGUAGE} is not supported by this script. Supported chaincode languages are: go, java, javascript, and typescript" + exit 1 +fi + +verifyResult() { + if [ $1 -ne 0 ]; then + fatalln "$2" + fi +} + +packageChaincode() { + set -x + if [ ${CC_PACKAGE_ONLY} = true ] ; then + mkdir -p packagedChaincode + peer lifecycle chaincode package packagedChaincode/${CC_NAME}_${CC_VERSION}.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label ${CC_NAME}_${CC_VERSION} >&log.txt + else + peer lifecycle chaincode package ${CC_NAME}.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label ${CC_NAME}_${CC_VERSION} >&log.txt + fi + res=$? + { set +x; } 2>/dev/null + cat log.txt + PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid ${CC_NAME}.tar.gz) + verifyResult $res "Chaincode packaging has failed" + successln "Chaincode is packaged" +} + +## package the chaincode +packageChaincode + +exit 0 diff --git a/varion/scripts/pkgcc.sh b/varion/scripts/pkgcc.sh new file mode 100755 index 00000000..6b89461f --- /dev/null +++ b/varion/scripts/pkgcc.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# +# SPDX-License-Identifier: Apache-2.0 +# + +function usage() { + echo "Usage: pkgcc.sh -l