From 9a37ef10588bb29c7db9adc6743d56dfba9b2948 Mon Sep 17 00:00:00 2001 From: "nkl199@yahoo.co.uk" Date: Fri, 5 Oct 2018 09:36:31 +0100 Subject: [PATCH] [FABN-975] cucumber test framework - Framework for cucumber testing driven by CCP - Addition of scenarios for create/join channels based on CCP - Addition of scenarios for install/instantiate chaincode based on CCP - Addition of scenarios for network API submit/execute transaction - Modification of gulp test.js to include cucumber test suite Change-Id: I1abe78254db09abe28339b8f5ed58e9a55f20511 Signed-off-by: nkl199@yahoo.co.uk --- build/tasks/test.js | 140 ++-- fabric-ca-client/package.json | 6 +- fabric-client/lib/Client.js | 1 - fabric-client/package.json | 5 +- package.json | 3 + scripts/Jenkins_Scripts/CI_Script.sh | 2 +- .../src/node_cc/example_cc/chaincode.js | 8 +- .../src/node_cc/example_cc1/chaincode.js | 8 +- .../javachaincode/instantiate-chaincode.js | 2 +- test/integration/javachaincode/query.js | 1 - test/scenario/README.md | 71 ++ test/scenario/chaincode/marbles/go/marbles.go | 642 ++++++++++++++++++ .../statedb/couchdb/indexes/indexOwner.json | 1 + .../chaincode/marbles/node/marbles.js | 509 ++++++++++++++ .../statedb/couchdb/indexes/indexOwner.json | 1 + .../chaincode/marbles/node/package.json | 17 + test/scenario/config/ccp-tls.json | 142 ++++ .../config/crypto-config/adminconfig.tx | Bin 0 -> 350 bytes .../config/crypto-config/configtx.yaml | 316 +++++++++ .../config/crypto-config/configtxgen.sh | 9 + .../config/crypto-config/mychannel.tx | Bin 0 -> 346 bytes .../config/crypto-config/mychannelator.json | 69 ++ .../example.com/ca/example.com-cert.pem | 14 + .../example.com/ca/key.pem | 5 + .../msp/admincerts/Admin@example.com-cert.pem | 14 + .../msp/cacerts/example.com-cert.pem | 14 + .../msp/cacerts/example.com-tls-cert.pem | 10 + .../msp/cacerts/org1.example.com-cert.pem | 15 + .../msp/cacerts/org1.example.com-tls-cert.pem | 10 + .../msp/cacerts/org2.example.com-cert.pem | 15 + .../msp/cacerts/org2.example.com-tls-cert.pem | 10 + .../msp/signcerts/example.com-cert.pem | 14 + .../msp/tlscacerts/example.com-cert.pem | 14 + .../msp/tlscacerts/example.com-tls-cert.pem | 14 + .../msp/tlscacerts/org1.example.com-cert.pem | 15 + .../tlscacerts/org1.example.com-tls-cert.pem | 15 + .../msp/tlscacerts/org2.example.com-cert.pem | 15 + .../tlscacerts/org2.example.com-tls-cert.pem | 15 + .../admincerts/Admin@example.com-cert.pem | 14 + .../cacerts/example.com-cert.pem | 14 + .../orderer.example.com/keystore/key.pem | 5 + .../signcerts/orderer.example.com-cert.pem | 14 + .../tlscacerts/example.com-cert.pem | 14 + .../admincerts/example.com-cert.pem | 14 + .../cacerts/example.com-cert.pem | 14 + .../users/Admin@example.com/keystore/key.pem | 5 + .../signcerts/Admin@example.com-cert.pem | 14 + .../org1.example.com/ca/key.pem | 5 + .../ca/org1.example.com-cert.pem | 15 + .../Admin@org1.example.com-cert.pem | 14 + .../msp/cacerts/org1.example.com-cert.pem | 15 + .../msp/cacerts/org1.example.com-tls-cert.pem | 10 + .../msp/cacerts/org2.example.com-tls-cert.pem | 10 + .../msp/signcerts/org1.example.com-cert.pem | 15 + .../msp/tlscacerts/org1.example.com-cert.pem | 15 + .../Admin@org1.example.com-cert.pem | 14 + .../cacerts/org1.example.com-cert.pem | 15 + .../peer0.org1.example.com/keystore/key.pem | 5 + .../signcerts/peer0.org1.example.com-cert.pem | 14 + .../peers/peer0.org1.example.com/tls/cert.pem | 16 + .../peers/peer0.org1.example.com/tls/key.pem | 5 + .../tlscacerts/org1.example.com-cert.pem | 15 + .../admincerts/org1.example.com-cert.pem | 15 + .../cacerts/org1.example.com-cert.pem | 15 + .../Admin@org1.example.com/keystore/key.pem | 5 + .../signcerts/Admin@org1.example.com-cert.pem | 14 + .../admincerts/org1.example.com-cert.pem | 15 + .../cacerts/org1.example.com-cert.pem | 15 + .../User1@org1.example.com/keystore/key.pem | 5 + .../signcerts/User1@org1.example.com-cert.pem | 14 + .../org2.example.com/ca/key.pem | 5 + .../ca/org2.example.com-cert.pem | 15 + .../Admin@org2.example.com-cert.pem | 14 + .../msp/cacerts/org2.example.com-cert.pem | 15 + .../msp/signcerts/org2.example.com-cert.pem | 15 + .../msp/tlscacerts/org2.example.com-cert.pem | 15 + .../Admin@org2.example.com-cert.pem | 14 + .../cacerts/org2.example.com-cert.pem | 15 + .../peer0.org2.example.com/keystore/key.pem | 5 + .../signcerts/peer0.org2.example.com-cert.pem | 14 + .../peers/peer0.org2.example.com/tls/cert.pem | 16 + .../peers/peer0.org2.example.com/tls/key.pem | 5 + .../tlscacerts/org2.example.com-cert.pem | 15 + .../admincerts/org2.example.com-cert.pem | 15 + .../cacerts/org2.example.com-cert.pem | 15 + .../Admin@org2.example.com/keystore/key.pem | 5 + .../signcerts/Admin@org2.example.com-cert.pem | 14 + .../admincerts/org2.example.com-cert.pem | 15 + .../cacerts/org2.example.com-cert.pem | 15 + .../User1@org2.example.com/keystore/key.pem | 5 + .../signcerts/User1@org2.example.com-cert.pem | 14 + test/scenario/config/crypto-config/rename.sh | 7 + .../crypto-config/twoorgs.genesis.block | 372 ++++++++++ test/scenario/config/policies.json | 39 ++ .../docker-compose/docker-compose-base.yaml | 102 +++ .../docker-compose/docker-compose-tls.yaml | 139 ++++ .../docker-compose/docker-compose.yaml | 109 +++ .../features/deploy_network_tls.feature | 22 + test/scenario/features/lib/chaincode.js | 309 +++++++++ test/scenario/features/lib/channel.js | 221 ++++++ .../features/lib/common_connection.js | 194 ++++++ test/scenario/features/lib/network.js | 167 +++++ test/scenario/features/lib/utils.js | 290 ++++++++ test/scenario/features/network_api.feature | 20 + test/scenario/features/steps/admin_steps.js | 246 +++++++ test/scenario/features/steps/docker_steps.js | 34 + test/scenario/features/steps/index.js | 16 + test/scenario/features/steps/network_steps.js | 53 ++ test/scenario/features/support/hooks.js | 21 + test/scenario/features/support/index.js | 18 + 110 files changed, 5117 insertions(+), 74 deletions(-) create mode 100644 test/scenario/README.md create mode 100644 test/scenario/chaincode/marbles/go/marbles.go create mode 100644 test/scenario/chaincode/marbles/go/metadata/statedb/couchdb/indexes/indexOwner.json create mode 100644 test/scenario/chaincode/marbles/node/marbles.js create mode 100644 test/scenario/chaincode/marbles/node/metadata/statedb/couchdb/indexes/indexOwner.json create mode 100644 test/scenario/chaincode/marbles/node/package.json create mode 100644 test/scenario/config/ccp-tls.json create mode 100644 test/scenario/config/crypto-config/adminconfig.tx create mode 100644 test/scenario/config/crypto-config/configtx.yaml create mode 100755 test/scenario/config/crypto-config/configtxgen.sh create mode 100644 test/scenario/config/crypto-config/mychannel.tx create mode 100644 test/scenario/config/crypto-config/mychannelator.json create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/key.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/admincerts/Admin@example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/signcerts/example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/admincerts/Admin@example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/cacerts/example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/signcerts/orderer.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/admincerts/example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/cacerts/example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/signcerts/Admin@example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/admincerts/Admin@org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org2.example.com-tls-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/signcerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/admincerts/Admin@org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/signcerts/peer0.org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/admincerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/cacerts/org1.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/signcerts/Admin@org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/admincerts/org1.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/cacerts/org1.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/signcerts/User1@org1.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/admincerts/Admin@org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/cacerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/signcerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/tlscacerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/admincerts/Admin@org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/cacerts/org2.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/signcerts/peer0.org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/admincerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/cacerts/org2.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/signcerts/Admin@org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/admincerts/org2.example.com-cert.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/cacerts/org2.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/keystore/key.pem create mode 100644 test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/signcerts/User1@org2.example.com-cert.pem create mode 100755 test/scenario/config/crypto-config/rename.sh create mode 100644 test/scenario/config/crypto-config/twoorgs.genesis.block create mode 100644 test/scenario/config/policies.json create mode 100644 test/scenario/docker-compose/docker-compose-base.yaml create mode 100644 test/scenario/docker-compose/docker-compose-tls.yaml create mode 100644 test/scenario/docker-compose/docker-compose.yaml create mode 100644 test/scenario/features/deploy_network_tls.feature create mode 100644 test/scenario/features/lib/chaincode.js create mode 100644 test/scenario/features/lib/channel.js create mode 100644 test/scenario/features/lib/common_connection.js create mode 100644 test/scenario/features/lib/network.js create mode 100644 test/scenario/features/lib/utils.js create mode 100644 test/scenario/features/network_api.feature create mode 100644 test/scenario/features/steps/admin_steps.js create mode 100644 test/scenario/features/steps/docker_steps.js create mode 100644 test/scenario/features/steps/index.js create mode 100644 test/scenario/features/steps/network_steps.js create mode 100644 test/scenario/features/support/hooks.js create mode 100644 test/scenario/features/support/index.js diff --git a/build/tasks/test.js b/build/tasks/test.js index 7980e2ffeb..01dfd33835 100644 --- a/build/tasks/test.js +++ b/build/tasks/test.js @@ -12,7 +12,7 @@ const addsrc = require('gulp-add-src'); const gulp = require('gulp'); const mocha = require('gulp-mocha'); const tape = require('gulp-tape'); - +const runSequence = require('run-sequence'); const tapColorize = require('tap-colorize'); const fs = require('fs-extra'); @@ -22,6 +22,9 @@ const util = require('util'); const shell = require('gulp-shell'); const testConstants = require('../../test/unit/constants.js'); +// Debug level of Docker containers used in scenario tests +process.env.DOCKER_DEBUG='INFO'; + // by default for running the tests print debug to a file const debugPath = path.join(testConstants.tempdir, 'test-log/debug.log'); process.env.HFC_LOGGING = util.format('{"debug":"%s"}', escapeWindowsPath(debugPath)); @@ -88,14 +91,17 @@ gulp.task('clean-up', () => { gulp.task('docker-clean', shell.task([ // stop and remove chaincode docker instances - 'docker kill $(docker ps | grep "dev-peer0.org[12].example.com-[en]" | awk \'{print $1}\')', - 'docker rm $(docker ps -a | grep "dev-peer0.org[12].example.com-[en]" | awk \'{print $1}\')', + 'docker kill $(docker ps | grep "dev-" | awk \'{print $1}\')', + 'docker rm $(docker ps -a | grep "dev-" | awk \'{print $1}\')', // remove chaincode images so that they get rebuilt during test - 'docker rmi $(docker images | grep "^dev-peer0.org[12].example.com-[en]" | awk \'{print $3}\')', + 'docker rmi $(docker images | grep "^dev-" | awk \'{print $3}\')', // clean up all the containers created by docker-compose - 'docker-compose -f test/fixtures/docker-compose.yaml down' + // -tape + 'docker-compose -f test/fixtures/docker-compose.yaml down', + // -cucumber + 'docker-compose -f test/scenario/docker-compose/docker-compose-tls.yaml down' ], { verbose: true, // so we can see the docker command output ignoreErrors: true // kill and rm may fail because the containers may have been cleaned up @@ -113,21 +119,37 @@ gulp.task('compile', shell.task([ ignoreErrors: false // once compile failed, throw error })); -// Use nyc instead of gulp-istanbul to generate coverage report -// Cannot use gulp-istabul because it throws "unexpected identifier" for async/await functions +// Execute specific tests with code coverage enabled +// - Use nyc instead of gulp-istanbul to generate coverage report +// - Cannot use gulp-istabul because it throws "unexpected identifier" for async/await functions + +// Main test to run all tests gulp.task('test', shell.task( './node_modules/nyc/bin/nyc.js gulp run-test' )); +// Test to run all unit tests gulp.task('test-headless', shell.task( './node_modules/nyc/bin/nyc.js gulp run-test-headless' )); +// Only run Mocha unit tests gulp.task('test-mocha', shell.task( './node_modules/nyc/bin/nyc.js gulp run-test-mocha' )); -gulp.task('run-test-mocha', ['mocha-fabric-client', 'mocha-fabric-network'], +// Only run scenario tests +gulp.task('test-cucumber', shell.task( + './node_modules/nyc/bin/nyc.js npm run test:cucumber' +)); + +// Definition of Mocha (unit) test suites +gulp.task('run-test-mocha', (done) => { + const tasks = ['mocha-fabric-ca-client', 'mocha-fabric-client', 'mocha-fabric-network']; + runSequence(...tasks, done); +}); + +gulp.task('mocha-fabric-ca-client', () => { return gulp.src(['./fabric-ca-client/test/**/*.js'], { read: false }) .pipe(mocha({ reporter: 'list', exit: true })); @@ -148,22 +170,56 @@ gulp.task('mocha-fabric-network', } ); -gulp.task('run-test', ['run-full', 'mocha-fabric-client', 'mocha-fabric-network'], - () => { - return gulp.src(['./fabric-ca-client/test/**/*.js'], { read: false }) - .pipe(mocha({ reporter: 'list', exit: true })); - } -); +// Test to run all unit tests +gulp.task('test-tape', shell.task( + './node_modules/nyc/bin/nyc.js gulp run-tape-unit' +)); + +// Definition of Cucumber (scenario) test suite +gulp.task('run-test-cucumber', shell.task( + 'npm run test:cucumber' +)); + +// Main test method to run all test suites +// - lint, unit first, then FV, then scenario +gulp.task('run-test', (done) => { + const tasks = ['clean-up', 'docker-clean', 'pre-test', 'ca', 'compile', 'lint', 'run-test-mocha', 'run-tape-unit', 'docker-clean', 'run-test-cucumber']; + runSequence(...tasks, done); +}); -gulp.task('run-test-headless', ['run-headless', 'mocha-fabric-client', 'mocha-fabric-network'], +// Run all non-integration tests +gulp.task('run-test-headless', (done) => { + const tasks = ['clean-up', 'pre-test', 'ca', 'lint', 'run-test-mocha', 'run-tape-unit']; + runSequence(...tasks, done); +}); + +gulp.task('run-tape-unit', () => { - return gulp.src(['./fabric-ca-client/test/**/*.js'], { read: false }) - .pipe(mocha({ reporter: 'list', exit: true })); - } -); + // this is needed to avoid a problem in tape-promise with adding + // too many listeners to the "unhandledRejection" event + process.setMaxListeners(0); -gulp.task('run-full', ['clean-up', 'lint', 'pre-test', 'compile', 'docker-ready', 'ca'], + return gulp.src(shouldRunPKCS11Tests([ + 'test/unit/**/*.js', + '!test/unit/constants.js', + '!test/unit/util.js', + '!test/unit/logger.js', + ])) + .pipe(addsrc.append( + 'test/unit/logger.js' // put this to the last so the debugging levels are not mixed up + )) + .pipe(tape({ + reporter: tapColorize() + })); + }); + +// Run tape e2e test suite +gulp.task('run-tape-e2e', ['docker-ready'], () => { + // this is needed to avoid a problem in tape-promise with adding + // too many listeners to the "unhandledRejection" event + process.setMaxListeners(0); + // use individual tests to control the sequence they get executed // first run the ca-tests that tests all the member registration // and enrollment scenarios (good and bad calls). Then the rest @@ -172,19 +228,13 @@ gulp.task('run-full', ['clean-up', 'lint', 'pre-test', 'compile', 'docker-ready' // network return gulp.src(shouldRunPKCS11Tests([ 'test/unit/config.js', // needs to be first - 'test/unit/**/*.js', - '!test/unit/constants.js', - '!test/unit/util.js', - '!test/unit/logger.js', 'test/integration/fabric-ca-affiliation-service-tests.js', 'test/integration/fabric-ca-identity-service-tests.js', 'test/integration/fabric-ca-certificate-service-tests.js', 'test/integration/fabric-ca-services-tests.js', - // channel: mychannel, chaincode: e2enodecc:v0 'test/integration/nodechaincode/e2e.js', 'test/integration/network-e2e/e2e.js', 'test/integration/network-e2e/e2e-hsm.js', - // channel: mychannel, chaincode: end2endnodesdk:v0/v1 'test/integration/e2e.js', 'test/integration/signTransactionOffline.js', 'test/integration/query.js', @@ -196,10 +246,8 @@ gulp.task('run-full', ['clean-up', 'lint', 'pre-test', 'compile', 'docker-ready' 'test/integration/install.js', 'test/integration/events.js', 'test/integration/channel-event-hub.js', - // channel: mychannel, chaincode: end2endnodesdk:v3 'test/integration/upgrade.js', 'test/integration/get-config.js', - // channel: mychanneltx, chaincode: end2endnodesdk:v0 'test/integration/create-configtx-channel.js', 'test/integration/e2e/join-channel.js', 'test/integration/instantiate.js', @@ -211,46 +259,22 @@ gulp.task('run-full', ['clean-up', 'lint', 'pre-test', 'compile', 'docker-ready' 'test/integration/javachaincode/e2e.js', 'test/integration/discovery.js', 'test/integration/grpc.js', - // channel: mychannelts chaincode: examplets:v1 + + // Typescript 'test/typescript/test.js', + // Perf 'test/integration/perf/orderer.js', 'test/integration/perf/peer.js' ])) - .pipe(addsrc.append( - 'test/unit/logger.js' // put this to the last so the debugging levels are not mixed up - )) - .pipe(tape({ - reporter: tapColorize() - })); - }); - -gulp.task('run-headless', ['clean-up', 'lint', 'pre-test', 'ca'], - () => { - // this is needed to avoid a problem in tape-promise with adding - // too many listeners - // to the "unhandledRejection" event - process.setMaxListeners(0); - - return gulp.src(shouldRunPKCS11Tests([ - 'test/unit/**/*.js', - '!test/unit/constants.js', - '!test/unit/util.js', - '!test/unit/logger.js' - ])) - .pipe(addsrc.append( - 'test/unit/logger.js' // put this to the last so the debugging levels are not mixed up - )) .pipe(tape({ reporter: tapColorize() })); }); -// currently only the x64 CI jobs are configured with SoftHSM -// disable the pkcs11.js test for s390 or other jobs -// also skip it by default and allow it to be turned on manuall -// with an environment variable so everyone don't have to -// install SoftHsm just to run unit tests +// Filter out tests that should not be run on specific operating systems since only the x64 CI jobs are configured with SoftHSM +// - disable the pkcs11.js test for s390 or other jobs +// - may be enabled manually with an environment variable function shouldRunPKCS11Tests(tests) { if (typeof process.env.PKCS11_TESTS === 'string' && process.env.PKCS11_TESTS.toLowerCase() === 'false' && os.arch().match(/(x64|x86)/) !== null) { tests.push('!test/unit/pkcs11.js'); diff --git a/fabric-ca-client/package.json b/fabric-ca-client/package.json index 1873b7086e..65ca283e93 100644 --- a/fabric-ca-client/package.json +++ b/fabric-ca-client/package.json @@ -1,7 +1,10 @@ { "name": "fabric-ca-client", "description": "SDK for writing node.js applications to interact with Hyperledger Fabric. This package encapsulates the APIs to interact with the Fabric CA to manage user certificates lifecycle such as register, enroll, renew and revoke.", - "keywords" : ["hyperledger", "blockchain"], + "keywords": [ + "hyperledger", + "blockchain" + ], "version": "1.4.0-snapshot", "tag": "unstable", "main": "index.js", @@ -22,6 +25,7 @@ "bn.js": "^4.11.3", "elliptic": "^6.2.3", "fs-extra": "^6.0.1", + "grpc": "1.14.2", "js-sha3": "^0.7.0", "jsrsasign": "^7.2.2", "jssha": "^2.1.0", diff --git a/fabric-client/lib/Client.js b/fabric-client/lib/Client.js index c675bf089d..179eb7010b 100644 --- a/fabric-client/lib/Client.js +++ b/fabric-client/lib/Client.js @@ -1048,7 +1048,6 @@ const Client = class extends BaseClient { throw new Error('Missing "chaincodePath" parameter in the proposal request'); } - console.log('request.targets', request.targets); let peers = this.getTargetPeers(request.targets); if (!peers && request.channelNames) { peers = this.getPeersForOrgOnChannel(request.channelNames); diff --git a/fabric-client/package.json b/fabric-client/package.json index 0b60db40c9..e43915b07b 100644 --- a/fabric-client/package.json +++ b/fabric-client/package.json @@ -1,7 +1,10 @@ { "name": "fabric-client", "description": "SDK for writing node.js applications to interact with Hyperledger Fabric. This package encapsulates the APIs to interact with Peers and Orderers of the Fabric network to install and instantiate chaincodes, send transaction invocations and perform chaincode queries.", - "keywords" : ["hyperledger", "blockchain"], + "keywords": [ + "hyperledger", + "blockchain" + ], "version": "1.4.0-snapshot", "tag": "unstable", "main": "index.js", diff --git a/package.json b/package.json index 894d94f42e..696356f893 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "test:ca-client": "npm run coverage -- fabric-ca-client/test", "test:client": "npm run coverage -- fabric-client/test", "test:network": "npm run coverage -- fabric-network/test", + "test:cucumber": "cucumber-js ./test/scenario/features/*.feature", "test:all": "nyc npm run unit-test:all", "unit-test:all": "npm run unit-test -- fabric-ca-client/test && npm run unit-test -- fabric-client/test && npm run unit-test -- fabric-network/test", "coverage": "nyc npm run unit-test", @@ -32,6 +33,7 @@ "bunyan": "^1.8.10", "chai": "^4.1.2", "chai-as-promised": "^7.1.1", + "cucumber": "5.0.1", "del": "^3.0.0", "elliptic": "^6.3.2", "eslint": "^5.1.0", @@ -64,6 +66,7 @@ "require-dir": "^1.0.0", "rewire": "^4.0.1", "rimraf": "2.6.2", + "run-sequence": "^2.2.1", "sinon": "6.1.3", "tap-colorize": "^1.2.0", "tape": "^4.5.1", diff --git a/scripts/Jenkins_Scripts/CI_Script.sh b/scripts/Jenkins_Scripts/CI_Script.sh index 9ea391bd3d..cb80d4c1b9 100755 --- a/scripts/Jenkins_Scripts/CI_Script.sh +++ b/scripts/Jenkins_Scripts/CI_Script.sh @@ -182,7 +182,7 @@ sdk_E2e_Tests() { ~/npm/bin/gulp ca || err_Check "ERROR!!! gulp ca failed" rm -rf node_modules/fabric-ca-client && npm install || err_Check "ERROR!!! npm install failed" - echo "------> Run node headless & e2e tests" + echo "------> Run Node SDK Unit, FV, and scenario tests" echo "============" ~/npm/bin/gulp test if [ $? == 0 ]; then diff --git a/test/fixtures/src/node_cc/example_cc/chaincode.js b/test/fixtures/src/node_cc/example_cc/chaincode.js index 282f32a7fe..34f00a99ce 100644 --- a/test/fixtures/src/node_cc/example_cc/chaincode.js +++ b/test/fixtures/src/node_cc/example_cc/chaincode.js @@ -94,16 +94,14 @@ const Chaincode = class { async move(stub, args) { logger.info('########### example_cc0 move ###########'); - let A, B; let Aval, Bval; - let X; if (args.length != 3) { return shim.error('Incorrect number of arguments. Expecting 4, function followed by 2 names and 1 value'); } - A = args[0]; - B = args[1]; + const A = args[0]; + const B = args[1]; try { const Avalbytes = await stub.getState(A); @@ -127,7 +125,7 @@ const Chaincode = class { return shim.error('Failed to get state B'); } // Perform the execution - X = parseInt(args[2]); + const X = parseInt(args[2]); if (isNaN(X)) { return shim.error('Invalid transaction amount, expecting a integer value'); } diff --git a/test/fixtures/src/node_cc/example_cc1/chaincode.js b/test/fixtures/src/node_cc/example_cc1/chaincode.js index 0dc3a520a8..42db8a779a 100644 --- a/test/fixtures/src/node_cc/example_cc1/chaincode.js +++ b/test/fixtures/src/node_cc/example_cc1/chaincode.js @@ -65,16 +65,14 @@ const Chaincode = class { } async move(stub, args) { - let A, B; let Aval, Bval; - let X; if (args.length != 3) { return shim.error('Incorrect number of arguments. Expecting 4, function followed by 2 names and 1 value'); } - A = args[0]; - B = args[1]; + const A = args[0]; + const B = args[1]; try { const Avalbytes = await stub.getState(A); @@ -98,7 +96,7 @@ const Chaincode = class { return shim.error('Failed to get state B'); } // Perform the execution - X = parseInt(args[2]); + const X = parseInt(args[2]); if (isNaN(X)) { return shim.error('Invalid transaction amount, expecting a integer value'); } diff --git a/test/integration/javachaincode/instantiate-chaincode.js b/test/integration/javachaincode/instantiate-chaincode.js index 7466aaa190..0a4c4b7c72 100644 --- a/test/integration/javachaincode/instantiate-chaincode.js +++ b/test/integration/javachaincode/instantiate-chaincode.js @@ -18,7 +18,7 @@ test('\n\n***** Java-Chaincode End-to-end flow: instantiate chaincode *****\n\n' const chaincode_id = 'example_java'; const version = 'v0'; try { - const result = await e2eUtils.instantiateChaincodeWithId('org1', chaincode_id, testUtil.JAVA_CHAINCODE_PATH, version, 'java', false, false, t); + await e2eUtils.instantiateChaincodeWithId('org1', chaincode_id, testUtil.JAVA_CHAINCODE_PATH, version, 'java', false, false, t); t.pass('Successfully instantiated java chaincode on the channel'); await testUtil.sleep(5000); } catch(err) { diff --git a/test/integration/javachaincode/query.js b/test/integration/javachaincode/query.js index 1915432706..e38dd568e3 100644 --- a/test/integration/javachaincode/query.js +++ b/test/integration/javachaincode/query.js @@ -12,7 +12,6 @@ const tape = require('tape'); const _test = require('tape-promise').default; const test = _test(tape); const e2eUtils = require('../e2e/e2eUtils.js'); -const testUtils = require('../../unit/util'); test('\n\n***** Java-Chaincode End-to-end flow: query chaincode *****\n\n', async (t) => { const chaincode_id = 'example_java'; diff --git a/test/scenario/README.md b/test/scenario/README.md new file mode 100644 index 0000000000..a6f808799c --- /dev/null +++ b/test/scenario/README.md @@ -0,0 +1,71 @@ +# Cucumber Test Sceanrios For Fabric-SDK-Node + +Welcome to the Fabric-SDK-Node Cucmber test readme. Below are some notes on these tests, but before you go any further, here are some general contribution guide lines: + - Each feature file must have its own tag + - All features and scenarios must be isolated from one another (no relying on other tests to create things for you!) + - Each feature must be runnable in isolation + - Each scenario must be runnable in isolation +- Full suite should complete in the presence of failures; it is important that the suite completes on all eventualities and not hang if a test fails. For instance, this can occur if a process is not terminated. +- When adding new step files, these must be included within `/steps/index.js` so that they are discoverable by the feature file(s) +- Tags are used to run Before/After functions for specific scenarios. For examples of this, refer to the `network_api.feature` that requires a clean up process to run in the event of a test failure. + +This test suite is intended to provide high level test coverage from a scenario perspective, and tests herein represent those at the top of the test pyramid. Consequently, these test should be added to with due consideration and should encapsulate the completion of a high level user task; for more fine grained testing, the FV or unit test frameworks should be used. + +## Structure + +The folder structure is the following: + +``` +scenario +│ README.md +│ +└───chaincode +│ │ +│ └───cc1 +│ │ +│ └───go +│ └───node +│ +└───config +│ │ profile.json +│ │ policies.json +│ └───crypto-config +│ +└───docker-compose +│ compose-files.yaml +│ +└───features + │ feature_file.feature + │ + └───lib + │ helper-files.js + └───steps + │ step-files.js + └───support + support-files.js + +``` + +- The scenario tests and all required files are conatained within the `scenario` directory +- `chaincode` holds all the chaincode files used within the cucmber tesst, with each chaincode contained within a specific named folder, itself decomposed into goLang and node. The structure here is important, since step files rely on the consistent location and naming strategy to deploy named chaincode of a specific type. +- `config` contains connection profiles, a json document of all possible endorsement policies, and a crypto-config directory that contains the crypto-material for the network defined within the docker-compose folder. +- `docker-compose` contains the two test networks, tls and non-tls, that are used within the cucumber tests. +- All feature files and supporting files are contained in the `features` directory + - `*.feature` the self contained feature file that describes a set of feature scenarios that decompose into programatic steps + - `lib` contains helper files used by step files. + - `steps` contains all the step files required by the feature files that exist in the parent directory. + - `support` contains two framework files: the main `index.js` file called by the cucumber test runner, and a `hooks.js` file that is used to provide tag based before/after hooks. + + +## Running the Tests + +The tests are run at a high level within the `/build` directory using the main `test.js` gulp file, or the npm script: +- To run the test using gulp, issue the command `gulp run-test-cucumber`. +- To run the test using npm script, issue the command `npm run test:cucumber`. +Both commands will run all feature files located within `/test/scenario/features`. + + +## FAQ + +What docker network do the tests run on? +> The cucumber tests run on the `cucumber_default` docker network, which is created by `docker_steps.js` when using the network definition files defined in `/docker-compose` diff --git a/test/scenario/chaincode/marbles/go/marbles.go b/test/scenario/chaincode/marbles/go/marbles.go new file mode 100644 index 0000000000..1d7905d031 --- /dev/null +++ b/test/scenario/chaincode/marbles/go/marbles.go @@ -0,0 +1,642 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +/* +* NOTE: This implementation is a replica of the following: +* https://github.com/hyperledger/fabric-samples/blob/release-1.1/chaincode/marbles02/node/marbles_chaincode.js +*/ + +// ====CHAINCODE EXECUTION SAMPLES (CLI) ================== + +// ==== Invoke marbles ==== +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}' +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}' +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}' +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}' +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}' +// peer chaincode invoke -C myc1 -n marbles -c '{"Args":["delete","marble1"]}' + +// ==== Query marbles ==== +// peer chaincode query -C myc1 -n marbles -c '{"Args":["readMarble","marble1"]}' +// peer chaincode query -C myc1 -n marbles -c '{"Args":["getMarblesByRange","marble1","marble3"]}' +// peer chaincode query -C myc1 -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}' + +// Rich Query (Only supported if CouchDB is used as state database): +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarblesByOwner","tom"]}' +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"tom\"}}"]}' + +// INDEXES TO SUPPORT COUCHDB RICH QUERIES +// +// Indexes in CouchDB are required in order to make JSON queries efficient and are required for +// any JSON query with a sort. As of Hyperledger Fabric 1.1, indexes may be packaged alongside +// chaincode in a META-INF/statedb/couchdb/indexes directory. Each index must be defined in its own +// text file with extension *.json with the index definition formatted in JSON following the +// CouchDB index JSON syntax as documented at: +// http://docs.couchdb.org/en/2.1.1/api/database/find.html#db-index +// +// This marbles02 example chaincode demonstrates a packaged +// index which you can find in META-INF/statedb/couchdb/indexes/indexOwner.json. +// For deployment of chaincode to production environments, it is recommended +// to define any indexes alongside chaincode so that the chaincode and supporting indexes +// are deployed automatically as a unit, once the chaincode has been installed on a peer and +// instantiated on a channel. See Hyperledger Fabric documentation for more details. +// +// If you have access to the your peer's CouchDB state database in a development environment, +// you may want to iteratively test various indexes in support of your chaincode queries. You +// can use the CouchDB Fauxton interface or a command line curl utility to create and update +// indexes. Then once you finalize an index, include the index definition alongside your +// chaincode in the META-INF/statedb/couchdb/indexes directory, for packaging and deployment +// to managed environments. +// +// In the examples below you can find index definitions that support marbles02 +// chaincode queries, along with the syntax that you can use in development environments +// to create the indexes in the CouchDB Fauxton interface or a curl command line utility. +// + +//Example hostname:port configurations to access CouchDB. +// +//To access CouchDB docker container from within another docker container or from vagrant environments: +// http://couchdb:5984/ +// +//Inside couchdb docker container +// http://127.0.0.1:5984/ + +// Index for docType, owner. +// Note that docType and owner fields must be prefixed with the "data" wrapper +// +// Index definition for use with Fauxton interface +// {"index":{"fields":["data.docType","data.owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} +// +// Example curl command line to define index in the CouchDB channel_chaincode database +// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[\"data.docType\",\"data.owner\"]},\"name\":\"indexOwner\",\"ddoc\":\"indexOwnerDoc\",\"type\":\"json\"}" http://hostname:port/myc1_marbles/_index +// + +// Index for docType, owner, size (descending order). +// Note that docType, owner and size fields must be prefixed with the "data" wrapper +// +// Index definition for use with Fauxton interface +// {"index":{"fields":[{"data.size":"desc"},{"data.docType":"desc"},{"data.owner":"desc"}]},"ddoc":"indexSizeSortDoc", "name":"indexSizeSortDesc","type":"json"} +// +// Example curl command line to define index in the CouchDB channel_chaincode database +// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[{\"data.size\":\"desc\"},{\"data.docType\":\"desc\"},{\"data.owner\":\"desc\"}]},\"ddoc\":\"indexSizeSortDoc\", \"name\":\"indexSizeSortDesc\",\"type\":\"json\"}" http://hostname:port/myc1_marbles/_index + +// Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}' + +// Rich Query with index design doc specified only (Only supported if CouchDB is used as state database): +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":{\"$eq\":\"marble\"},\"owner\":{\"$eq\":\"tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}' + +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" +) + +// SimpleChaincode example simple Chaincode implementation +type SimpleChaincode struct { +} + +type marble struct { + ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database + Name string `json:"name"` //the fieldtags are needed to keep case from bouncing around + Color string `json:"color"` + Size int `json:"size"` + Owner string `json:"owner"` +} + +// =================================================================================== +// Main +// =================================================================================== +func main() { + err := shim.Start(new(SimpleChaincode)) + if err != nil { + fmt.Printf("Error starting Simple chaincode: %s", err) + } +} + +// Init initializes chaincode +// =========================== +func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { + return shim.Success(nil) +} + +// Invoke - Our entry point for Invocations +// ======================================== +func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { + function, args := stub.GetFunctionAndParameters() + fmt.Println("invoke is running " + function) + + // Handle different functions + if function == "initMarble" { //create a new marble + return t.initMarble(stub, args) + } else if function == "transferMarble" { //change owner of a specific marble + return t.transferMarble(stub, args) + } else if function == "transferMarblesBasedOnColor" { //transfer all marbles of a certain color + return t.transferMarblesBasedOnColor(stub, args) + } else if function == "delete" { //delete a marble + return t.delete(stub, args) + } else if function == "readMarble" { //read a marble + return t.readMarble(stub, args) + } else if function == "queryMarblesByOwner" { //find marbles for owner X using rich query + return t.queryMarblesByOwner(stub, args) + } else if function == "queryMarbles" { //find marbles based on an ad hoc rich query + return t.queryMarbles(stub, args) + } else if function == "getHistoryForMarble" { //get history of values for a marble + return t.getHistoryForMarble(stub, args) + } else if function == "getMarblesByRange" { //get marbles based on range query + return t.getMarblesByRange(stub, args) + } + + fmt.Println("invoke did not find func: " + function) //error + return shim.Error("Received unknown function invocation") +} + +// ============================================================ +// initMarble - create a new marble, store into chaincode state +// ============================================================ +func (t *SimpleChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var err error + + // 0 1 2 3 + // "asdf", "blue", "35", "bob" + if len(args) != 4 { + return shim.Error("Incorrect number of arguments. Expecting 4") + } + + // ==== Input sanitation ==== + fmt.Println("- start init marble") + if len(args[0]) <= 0 { + return shim.Error("1st argument must be a non-empty string") + } + if len(args[1]) <= 0 { + return shim.Error("2nd argument must be a non-empty string") + } + if len(args[2]) <= 0 { + return shim.Error("3rd argument must be a non-empty string") + } + if len(args[3]) <= 0 { + return shim.Error("4th argument must be a non-empty string") + } + marbleName := args[0] + color := strings.ToLower(args[1]) + owner := strings.ToLower(args[3]) + size, err := strconv.Atoi(args[2]) + if err != nil { + return shim.Error("3rd argument must be a numeric string") + } + + // ==== Check if marble already exists ==== + marbleAsBytes, err := stub.GetState(marbleName) + if err != nil { + return shim.Error("Failed to get marble: " + err.Error()) + } else if marbleAsBytes != nil { + fmt.Println("This marble already exists: " + marbleName) + return shim.Error("This marble already exists: " + marbleName) + } + + // ==== Create marble object and marshal to JSON ==== + objectType := "marble" + marble := &marble{objectType, marbleName, color, size, owner} + marbleJSONasBytes, err := json.Marshal(marble) + if err != nil { + return shim.Error(err.Error()) + } + //Alternatively, build the marble json string manually if you don't want to use struct marshalling + //marbleJSONasString := `{"docType":"Marble", "name": "` + marbleName + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "owner": "` + owner + `"}` + //marbleJSONasBytes := []byte(str) + + // === Save marble to state === + err = stub.PutState(marbleName, marbleJSONasBytes) + if err != nil { + return shim.Error(err.Error()) + } + + // ==== Index the marble to enable color-based range queries, e.g. return all blue marbles ==== + // An 'index' is a normal key/value entry in state. + // The key is a composite key, with the elements that you want to range query on listed first. + // In our case, the composite key is based on indexName~color~name. + // This will enable very efficient state range queries based on composite keys matching indexName~color~* + indexName := "color~name" + colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marble.Color, marble.Name}) + if err != nil { + return shim.Error(err.Error()) + } + // Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble. + // Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value + value := []byte{0x00} + stub.PutState(colorNameIndexKey, value) + + // ==== Marble saved and indexed. Return success ==== + fmt.Println("- end init marble") + return shim.Success(nil) +} + +// =============================================== +// readMarble - read a marble from chaincode state +// =============================================== +func (t *SimpleChaincode) readMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var name, jsonResp string + var err error + + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting name of the marble to query") + } + + name = args[0] + valAsbytes, err := stub.GetState(name) //get the marble from chaincode state + if err != nil { + jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}" + return shim.Error(jsonResp) + } else if valAsbytes == nil { + jsonResp = "{\"Error\":\"Marble does not exist: " + name + "\"}" + return shim.Error(jsonResp) + } + + return shim.Success(valAsbytes) +} + +// ================================================== +// delete - remove a marble key/value pair from state +// ================================================== +func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var jsonResp string + var marbleJSON marble + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + marbleName := args[0] + + // to maintain the color~name index, we need to read the marble first and get its color + valAsbytes, err := stub.GetState(marbleName) //get the marble from chaincode state + if err != nil { + jsonResp = "{\"Error\":\"Failed to get state for " + marbleName + "\"}" + return shim.Error(jsonResp) + } else if valAsbytes == nil { + jsonResp = "{\"Error\":\"Marble does not exist: " + marbleName + "\"}" + return shim.Error(jsonResp) + } + + err = json.Unmarshal([]byte(valAsbytes), &marbleJSON) + if err != nil { + jsonResp = "{\"Error\":\"Failed to decode JSON of: " + marbleName + "\"}" + return shim.Error(jsonResp) + } + + err = stub.DelState(marbleName) //remove the marble from chaincode state + if err != nil { + return shim.Error("Failed to delete state:" + err.Error()) + } + + // maintain the index + indexName := "color~name" + colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marbleJSON.Color, marbleJSON.Name}) + if err != nil { + return shim.Error(err.Error()) + } + + // Delete index entry to state. + err = stub.DelState(colorNameIndexKey) + if err != nil { + return shim.Error("Failed to delete state:" + err.Error()) + } + return shim.Success(nil) +} + +// =========================================================== +// transfer a marble by setting a new owner name on the marble +// =========================================================== +func (t *SimpleChaincode) transferMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 1 + // "name", "bob" + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + marbleName := args[0] + newOwner := strings.ToLower(args[1]) + fmt.Println("- start transferMarble ", marbleName, newOwner) + + marbleAsBytes, err := stub.GetState(marbleName) + if err != nil { + return shim.Error("Failed to get marble:" + err.Error()) + } else if marbleAsBytes == nil { + return shim.Error("Marble does not exist") + } + + marbleToTransfer := marble{} + err = json.Unmarshal(marbleAsBytes, &marbleToTransfer) //unmarshal it aka JSON.parse() + if err != nil { + return shim.Error(err.Error()) + } + marbleToTransfer.Owner = newOwner //change the owner + + marbleJSONasBytes, _ := json.Marshal(marbleToTransfer) + err = stub.PutState(marbleName, marbleJSONasBytes) //rewrite the marble + if err != nil { + return shim.Error(err.Error()) + } + + fmt.Println("- end transferMarble (success)") + return shim.Success(nil) +} + +// =========================================================================================== +// getMarblesByRange performs a range query based on the start and end keys provided. + +// Read-only function results are not typically submitted to ordering. If the read-only +// results are submitted to ordering, or if the query is used in an update transaction +// and submitted to ordering, then the committing peers will re-execute to guarantee that +// result sets are stable between endorsement time and commit time. The transaction is +// invalidated by the committing peers if the result set has changed between endorsement +// time and commit time. +// Therefore, range queries are a safe option for performing update transactions based on query results. +// =========================================================================================== +func (t *SimpleChaincode) getMarblesByRange(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + startKey := args[0] + endKey := args[1] + + resultsIterator, err := stub.GetStateByRange(startKey, endKey) + if err != nil { + return shim.Error(err.Error()) + } + defer resultsIterator.Close() + + // buffer is a JSON array containing QueryResults + var buffer bytes.Buffer + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + for resultsIterator.HasNext() { + queryResponse, err := resultsIterator.Next() + if err != nil { + return shim.Error(err.Error()) + } + // Add a comma before array members, suppress it for the first array member + if bArrayMemberAlreadyWritten == true { + buffer.WriteString(",") + } + buffer.WriteString("{\"Key\":") + buffer.WriteString("\"") + buffer.WriteString(queryResponse.Key) + buffer.WriteString("\"") + + buffer.WriteString(", \"Record\":") + // Record is a JSON object, so we write as-is + buffer.WriteString(string(queryResponse.Value)) + buffer.WriteString("}") + bArrayMemberAlreadyWritten = true + } + buffer.WriteString("]") + + fmt.Printf("- getMarblesByRange queryResult:\n%s\n", buffer.String()) + + return shim.Success(buffer.Bytes()) +} + +// ==== Example: GetStateByPartialCompositeKey/RangeQuery ========================================= +// transferMarblesBasedOnColor will transfer marbles of a given color to a certain new owner. +// Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'. +// Committing peers will re-execute range queries to guarantee that result sets are stable +// between endorsement time and commit time. The transaction is invalidated by the +// committing peers if the result set has changed between endorsement time and commit time. +// Therefore, range queries are a safe option for performing update transactions based on query results. +// =========================================================================================== +func (t *SimpleChaincode) transferMarblesBasedOnColor(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 1 + // "color", "bob" + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + color := args[0] + newOwner := strings.ToLower(args[1]) + fmt.Println("- start transferMarblesBasedOnColor ", color, newOwner) + + // Query the color~name index by color + // This will execute a key range query on all keys starting with 'color' + coloredMarbleResultsIterator, err := stub.GetStateByPartialCompositeKey("color~name", []string{color}) + if err != nil { + return shim.Error(err.Error()) + } + defer coloredMarbleResultsIterator.Close() + + // Iterate through result set and for each marble found, transfer to newOwner + var i int + for i = 0; coloredMarbleResultsIterator.HasNext(); i++ { + // Note that we don't get the value (2nd return variable), we'll just get the marble name from the composite key + responseRange, err := coloredMarbleResultsIterator.Next() + if err != nil { + return shim.Error(err.Error()) + } + + // get the color and name from color~name composite key + objectType, compositeKeyParts, err := stub.SplitCompositeKey(responseRange.Key) + if err != nil { + return shim.Error(err.Error()) + } + returnedColor := compositeKeyParts[0] + returnedMarbleName := compositeKeyParts[1] + fmt.Printf("- found a marble from index:%s color:%s name:%s\n", objectType, returnedColor, returnedMarbleName) + + // Now call the transfer function for the found marble. + // Re-use the same function that is used to transfer individual marbles + response := t.transferMarble(stub, []string{returnedMarbleName, newOwner}) + // if the transfer failed break out of loop and return error + if response.Status != shim.OK { + return shim.Error("Transfer failed: " + response.Message) + } + } + + responsePayload := fmt.Sprintf("Transferred %d %s marbles to %s", i, color, newOwner) + fmt.Println("- end transferMarblesBasedOnColor: " + responsePayload) + return shim.Success([]byte(responsePayload)) +} + +// =======Rich queries ========================================================================= +// Two examples of rich queries are provided below (parameterized query and ad hoc query). +// Rich queries pass a query string to the state database. +// Rich queries are only supported by state database implementations +// that support rich query (e.g. CouchDB). +// The query string is in the syntax of the underlying state database. +// With rich queries there is no guarantee that the result set hasn't changed between +// endorsement time and commit time, aka 'phantom reads'. +// Therefore, rich queries should not be used in update transactions, unless the +// application handles the possibility of result set changes between endorsement and commit time. +// Rich queries can be used for point-in-time queries against a peer. +// ============================================================================================ + +// ===== Example: Parameterized rich query ================================================= +// queryMarblesByOwner queries for marbles based on a passed in owner. +// This is an example of a parameterized query where the query logic is baked into the chaincode, +// and accepting a single query parameter (owner). +// Only available on state databases that support rich query (e.g. CouchDB) +// ========================================================================================= +func (t *SimpleChaincode) queryMarblesByOwner(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 + // "bob" + if len(args) < 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + owner := strings.ToLower(args[0]) + + queryString := fmt.Sprintf("{\"selector\":{\"docType\":\"marble\",\"owner\":\"%s\"}}", owner) + + queryResults, err := getQueryResultForQueryString(stub, queryString) + if err != nil { + return shim.Error(err.Error()) + } + return shim.Success(queryResults) +} + +// ===== Example: Ad hoc rich query ======================================================== +// queryMarbles uses a query string to perform a query for marbles. +// Query string matching state database syntax is passed in and executed as is. +// Supports ad hoc queries that can be defined at runtime by the client. +// If this is not desired, follow the queryMarblesForOwner example for parameterized queries. +// Only available on state databases that support rich query (e.g. CouchDB) +// ========================================================================================= +func (t *SimpleChaincode) queryMarbles(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 + // "queryString" + if len(args) < 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + queryString := args[0] + + queryResults, err := getQueryResultForQueryString(stub, queryString) + if err != nil { + return shim.Error(err.Error()) + } + return shim.Success(queryResults) +} + +// ========================================================================================= +// getQueryResultForQueryString executes the passed in query string. +// Result set is built and returned as a byte array containing the JSON results. +// ========================================================================================= +func getQueryResultForQueryString(stub shim.ChaincodeStubInterface, queryString string) ([]byte, error) { + + fmt.Printf("- getQueryResultForQueryString queryString:\n%s\n", queryString) + + resultsIterator, err := stub.GetQueryResult(queryString) + if err != nil { + return nil, err + } + defer resultsIterator.Close() + + // buffer is a JSON array containing QueryRecords + var buffer bytes.Buffer + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + for resultsIterator.HasNext() { + queryResponse, err := resultsIterator.Next() + if err != nil { + return nil, err + } + // Add a comma before array members, suppress it for the first array member + if bArrayMemberAlreadyWritten == true { + buffer.WriteString(",") + } + buffer.WriteString("{\"Key\":") + buffer.WriteString("\"") + buffer.WriteString(queryResponse.Key) + buffer.WriteString("\"") + + buffer.WriteString(", \"Record\":") + // Record is a JSON object, so we write as-is + buffer.WriteString(string(queryResponse.Value)) + buffer.WriteString("}") + bArrayMemberAlreadyWritten = true + } + buffer.WriteString("]") + + fmt.Printf("- getQueryResultForQueryString queryResult:\n%s\n", buffer.String()) + + return buffer.Bytes(), nil +} + +func (t *SimpleChaincode) getHistoryForMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + if len(args) < 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + marbleName := args[0] + + fmt.Printf("- start getHistoryForMarble: %s\n", marbleName) + + resultsIterator, err := stub.GetHistoryForKey(marbleName) + if err != nil { + return shim.Error(err.Error()) + } + defer resultsIterator.Close() + + // buffer is a JSON array containing historic values for the marble + var buffer bytes.Buffer + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + for resultsIterator.HasNext() { + response, err := resultsIterator.Next() + if err != nil { + return shim.Error(err.Error()) + } + // Add a comma before array members, suppress it for the first array member + if bArrayMemberAlreadyWritten == true { + buffer.WriteString(",") + } + buffer.WriteString("{\"TxId\":") + buffer.WriteString("\"") + buffer.WriteString(response.TxId) + buffer.WriteString("\"") + + buffer.WriteString(", \"Value\":") + // if it was a delete operation on given key, then we need to set the + //corresponding value null. Else, we will write the response.Value + //as-is (as the Value itself a JSON marble) + if response.IsDelete { + buffer.WriteString("null") + } else { + buffer.WriteString(string(response.Value)) + } + + buffer.WriteString(", \"Timestamp\":") + buffer.WriteString("\"") + buffer.WriteString(time.Unix(response.Timestamp.Seconds, int64(response.Timestamp.Nanos)).String()) + buffer.WriteString("\"") + + buffer.WriteString(", \"IsDelete\":") + buffer.WriteString("\"") + buffer.WriteString(strconv.FormatBool(response.IsDelete)) + buffer.WriteString("\"") + + buffer.WriteString("}") + bArrayMemberAlreadyWritten = true + } + buffer.WriteString("]") + + fmt.Printf("- getHistoryForMarble returning:\n%s\n", buffer.String()) + + return shim.Success(buffer.Bytes()) +} diff --git a/test/scenario/chaincode/marbles/go/metadata/statedb/couchdb/indexes/indexOwner.json b/test/scenario/chaincode/marbles/go/metadata/statedb/couchdb/indexes/indexOwner.json new file mode 100644 index 0000000000..305f090444 --- /dev/null +++ b/test/scenario/chaincode/marbles/go/metadata/statedb/couchdb/indexes/indexOwner.json @@ -0,0 +1 @@ +{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} diff --git a/test/scenario/chaincode/marbles/node/marbles.js b/test/scenario/chaincode/marbles/node/marbles.js new file mode 100644 index 0000000000..9b3ed6e2ac --- /dev/null +++ b/test/scenario/chaincode/marbles/node/marbles.js @@ -0,0 +1,509 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +/* eslint-disable no-console */ + +'use strict'; +const shim = require('fabric-shim'); +const util = require('util'); + +/** + * Marble asset management chaincode written in node.js, implementing {@link ChaincodeInterface}. + * @type {SimpleChaincode} + * @extends {ChaincodeInterface} + */ +const Chaincode = class { + + /** + * Called during chaincode instantiate and upgrade. This method can be used + * to initialize asset states. + * @async + * @param {ChaincodeStub} stub The chaincode stub is implemented by the fabric-shim + * library and passed to the {@link ChaincodeInterface} calls by the Hyperledger Fabric platform. The stub + * encapsulates the APIs between the chaincode implementation and the Fabric peer. + * @return {Promise} Returns a promise of a response indicating the result of the invocation. + */ + async Init(stub) { + const ret = stub.getFunctionAndParameters(); + console.info(ret); + console.info('=========== Instantiated Marbles Chaincode ==========='); + return shim.success(); + } + + /** + * Called throughout the life time of the chaincode to carry out business + * transaction logic and effect the asset states. + * The provided functions are the following: initMarble, delete, transferMarble, readMarble, getMarblesByRange, + * transferMarblesBasedOnColor, queryMarblesByOwner, queryMarbles, getHistoryForMarble. + * @async + * @param {ChaincodeStub} stub The chaincode stub is implemented by the fabric-shim + * library and passed to the {@link ChaincodeInterface} calls by the Hyperledger Fabric platform. The stub + * encapsulates the APIs between the chaincode implementation and the Fabric peer. + * @return {Promise} Returns a promise of a response indicating the result of the invocation. + */ + async Invoke(stub) { + console.info('Transaction ID: ' + stub.getTxID()); + console.info(util.format('Args: %j', stub.getArgs())); + + const ret = stub.getFunctionAndParameters(); + const fcn = ret.fcn; + const args = ret.params; + + if (fcn === 'initMarble') { + return this.initMarble(stub, args, this); + } + + if (fcn === 'readMarble') { + return this.readMarble(stub, args, this); + } + + if (fcn === 'delete') { + return this.delete(stub, args, this); + } + + if (fcn === 'transferMarble') { + return this.transferMarble(stub, args, this); + } + + if (fcn === 'getMarblesByRange') { + return this.delete(stub, args, this); + } + + if (fcn === 'transferMarblesBasedOnColor') { + return this.transferMarblesBasedOnColor(stub, args, this); + } + + if (fcn === 'queryMarblesByOwner') { + return this.queryMarblesByOwner(stub, args, this); + } + + if (fcn === 'queryMarbles') { + return this.queryMarbles(stub, args, this); + } + + if (fcn === 'getAllResults') { + return this.getAllResults(stub, args, this); + } + + if (fcn === 'getHistoryForMarble') { + return this.getHistoryForMarble(stub, args, this); + } + + console.log(`Unknown action, check the first argument, must be one of 'delete', 'query', or 'move'. But got: ${fcn}`); + return shim.error(`Unknown action, check the first argument, must be one of 'delete', 'query', or 'move'. But got: ${fcn}`); + } + + /** + * Creates a new marble with the given attributes. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble name. Index 1: marble color. + * Index 2: marble size. Index 3: marble owner. + * @return {Promise} notification of success of failure. + */ + async initMarble(stub, args) { + if (args.length !== 4) { + return shim.error('Incorrect number of arguments. Expecting 4'); + } + // ==== Input sanitation ==== + console.info('--- start init marble ---'); + if (args[0].length <= 0) { + return shim.error('1st argument must be a non-empty string'); + } + if (args[1].length <= 0) { + return shim.error('2nd argument must be a non-empty string'); + } + if (args[2].length <= 0) { + return shim.error('3rd argument must be a non-empty string'); + } + if (args[3].length <= 0) { + return shim.error('4th argument must be a non-empty string'); + } + const marbleName = args[0]; + const color = args[1].toLowerCase(); + const owner = args[3].toLowerCase(); + const size = parseInt(args[2]); + if (isNaN(size)) { + return shim.error('3rd argument must be a numeric string'); + } + + // ==== Check if marble already exists ==== + const marbleState = await stub.getState(marbleName); + if (marbleState.toString()) { + return shim.error('This marble already exists: ' + marbleName); + } + + // ==== Create marble object and marshal to JSON ==== + const marble = {}; + marble.docType = 'marble'; + marble.name = marbleName; + marble.color = color; + marble.size = size; + marble.owner = owner; + + // === Save marble to state === + await stub.putState(marbleName, Buffer.from(JSON.stringify(marble))); + const indexName = 'color~name'; + const colorNameIndexKey = await stub.createCompositeKey(indexName, [marble.color, marble.name]); + console.info(colorNameIndexKey); + // Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble. + // Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value + await stub.putState(colorNameIndexKey, Buffer.from('\u0000')); + // ==== Marble saved and indexed. Return success ==== + console.info('- end init marble'); + return shim.success('init marble success'); + } + + /** + * Retrieves the information about a marble. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble name. + * @return {Promise} The byte representation of the marble. + */ + async readMarble(stub, args) { + if (args.length !== 1) { + return shim.error('Incorrect number of arguments. Expecting name of the marble to query'); + } + + const name = args[0]; + if (!name) { + return shim.error(' marble name must not be empty'); + } + const marbleAsBytes = await stub.getState(name); //get the marble from chaincode state + if (!marbleAsBytes.toString()) { + const jsonResp = {}; + jsonResp.Error = 'Marble does not exist: ' + name; + return shim.error(JSON.stringify(jsonResp)); + } + console.info('======================================='); + console.log(marbleAsBytes.toString()); + console.info('======================================='); + return shim.success(marbleAsBytes); + } + + /** + * Deletes the given marble. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble name. + * @returns {success|error} shim.success or shim.error + */ + async delete(stub, args) { + if (args.length !== 1) { + return shim.error('Incorrect number of arguments. Expecting name of the marble to delete'); + } + const marbleName = args[0]; + if (!marbleName) { + return shim.error('marble name must not be empty'); + } + // to maintain the color~name index, we need to read the marble first and get its color + const valAsBytes = await stub.getState(marbleName); //get the marble from chaincode state + let jsonResp = {}; + if (!valAsBytes) { + jsonResp.error = 'marble does not exist: ' + marbleName; + return shim.error(jsonResp); + } + let marbleJSON = {}; + try { + marbleJSON = JSON.parse(valAsBytes.toString()); + } catch (err) { + jsonResp = {}; + jsonResp.error = 'Failed to decode JSON of: ' + marbleName; + return shim.error(jsonResp); + } + + await stub.deleteState(marbleName); //remove the marble from chaincode state + + // delete the index + const indexName = 'color~name'; + const colorNameIndexKey = stub.createCompositeKey(indexName, [marbleJSON.color, marbleJSON.name]); + if (!colorNameIndexKey) { + return shim.error(' Failed to create the createCompositeKey'); + } + // Delete index entry to state. + await stub.deleteState(colorNameIndexKey); + return shim.success('delete success'); + } + + // =========================================================== + // transfer a marble by setting a new owner name on the marble + // =========================================================== + + /** + * Transfers the given marble to a new owner. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble name. Index 1: the new owner. + * @returns {success|error} shim.success or shim.error + */ + async transferMarble(stub, args) { + if (args.length !== 2) { + return shim.error('Incorrect number of arguments. Expecting marble name and owner'); + } + + const marbleName = args[0]; + const newOwner = args[1].toLowerCase(); + console.info('- start transferMarble ', marbleName, newOwner); + + const marbleAsBytes = await stub.getState(marbleName); + if (!marbleAsBytes || !marbleAsBytes.toString()) { + return shim.error('marble does not exist'); + } + let marbleToTransfer = {}; + try { + marbleToTransfer = JSON.parse(marbleAsBytes.toString()); //unmarshal + } catch (err) { + const jsonResp = {}; + jsonResp.error = 'Failed to decode JSON of: ' + marbleName; + return shim.error(jsonResp); + } + console.info(marbleToTransfer); + marbleToTransfer.owner = newOwner; //change the owner + + const marbleJSONasBytes = Buffer.from(JSON.stringify(marbleToTransfer)); + await stub.putState(marbleName, marbleJSONasBytes); //rewrite the marble + + console.info('- end transferMarble (success)'); + return shim.success('transferMarble success'); + } + + /** + * Performs a range query based on the start and end keys provided. + * + * Read-only function results are not typically submitted to ordering. If the read-only + * results are submitted to ordering, or if the query is used in an update transaction + * and submitted to ordering, then the committing peers will re-execute to guarantee that + * result sets are stable between endorsement time and commit time. The transaction is + * invalidated by the committing peers if the result set has changed between endorsement + * time and commit time. + * Therefore, range queries are a safe option for performing update transactions based on query results. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: start key. Index 1: end key. + * @param {Chaincode} thisObject The chaincode object context. + * @return {Promise} The marbles in the given range. + */ + async getMarblesByRange(stub, args, thisObject) { + + if (args.length !== 2) { + return shim.error('Incorrect number of arguments. Expecting 2'); + } + + const startKey = args[0]; + const endKey = args[1]; + + const resultsIterator = await stub.getStateByRange(startKey, endKey); + const results = await thisObject.getAllResults(resultsIterator, false); + + return shim.success(Buffer.from(JSON.stringify(results))); + } + + /** + * Transfers marbles of a given color to a certain new owner. + * + * Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'. + * Committing peers will re-execute range queries to guarantee that result sets are stable + * between endorsement time and commit time. The transaction is invalidated by the + * committing peers if the result set has changed between endorsement time and commit time. + * Therefore, range queries are a safe option for performing update transactions based on query results. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble color. Index 1: new owner. + * @param {Chaincode} thisObject The chaincode object context. + * @returns {success|error} shim.success or shim.error + */ + async transferMarblesBasedOnColor(stub, args, thisObject) { + if (args.length !== 2) { + return shim.error('Incorrect number of arguments. Expecting color and owner'); + } + + const color = args[0]; + const newOwner = args[1].toLowerCase(); + console.info('- start transferMarblesBasedOnColor ', color, newOwner); + + // Query the color~name index by color + // This will execute a key range query on all keys starting with 'color' + const coloredMarbleResultsIterator = await stub.getStateByPartialCompositeKey('color~name', [color]); + + let hasNext = true; + // Iterate through result set and for each marble found, transfer to newOwner + while (hasNext) { + let responseRange; + try { + responseRange = await coloredMarbleResultsIterator.next(); + } catch (err) { + hasNext = false; + continue; + } + + if (!responseRange || !responseRange.value || !responseRange.value.key) { + return; + } + console.log(responseRange.value.key); + + const splitKey = await stub.splitCompositeKey(responseRange.value.key); + const objectType = splitKey.objectType; + const attributes = splitKey.attributes; + + const returnedColor = attributes[0]; + const returnedMarbleName = attributes[1]; + console.info(util.format('- found a marble from index:%s color:%s name:%s\n', objectType, returnedColor, returnedMarbleName)); + + // Now call the transfer function for the found marble. + // Re-use the same function that is used to transfer individual marbles + await thisObject.transferMarble(stub, [returnedMarbleName, newOwner]); + } + + const responsePayload = util.format('Transferred %s marbles to %s', color, newOwner); + console.info('- end transferMarblesBasedOnColor: ' + responsePayload); + return shim.success('- end transferMarblesBasedOnColor: ' + responsePayload); + } + + /** + * Queries for marbles based on a passed in owner. + * This is an example of a parameterized query where the query logic is baked into the chaincode, + * and accepting a single query parameter (owner). + * Only available on state databases that support rich query (e.g. CouchDB) + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble owner. + * @param {Chaincode} thisObject The chaincode object context. + * @return {Promise} The marbles of the specified owner. + */ + async queryMarblesByOwner(stub, args, thisObject) { + if (args.length !== 1) { + return shim.error('Incorrect number of arguments. Expecting owner name.'); + } + + const owner = args[0].toLowerCase(); + const queryString = {}; + queryString.selector = {}; + queryString.selector.docType = 'marble'; + queryString.selector.owner = owner; + const queryResults = await thisObject.getQueryResultForQueryString(stub, JSON.stringify(queryString), thisObject); //; + return shim.success(queryResults); + } + + /** + * Uses a query string to perform a query for marbles. + * Query string matching state database syntax is passed in and executed as is. + * Supports ad hoc queries that can be defined at runtime by the client. + * If this is not desired, follow the queryMarblesForOwner example for parameterized queries. + * Only available on state databases that support rich query (e.g. CouchDB) + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: query string. + * @param {Chaincode} thisObject The chaincode object context. + * @return {Promise} The results of the specified query. + */ + async queryMarbles(stub, args, thisObject) { + if (args.length !== 1) { + return shim.error('Incorrect number of arguments. Expecting queryString'); + } + const queryString = args[0]; + if (!queryString) { + return shim.error('queryString must not be empty'); + } + + const queryResults = await thisObject.getQueryResultForQueryString(stub, queryString, thisObject); + return shim.success(queryResults); + } + + /** + * Gets the results of a specified iterator. + * @async + * @param {Object} iterator The iterator to use. + * @param {Boolean} isHistory Specifies whether the iterator returns history entries or not. + * @return {Promise} The array of results in JSON format. + */ + async getAllResults(iterator, isHistory) { + const allResults = []; + let hasNext = true; + while (hasNext) { + let res; + try { + res = await iterator.next(); + } catch (err) { + hasNext = false; + continue; + } + + if (res.value && res.value.value.toString()) { + const jsonRes = {}; + console.log(res.value.value.toString('utf8')); + + if (isHistory && isHistory === true) { + jsonRes.TxId = res.value.tx_id; + jsonRes.Timestamp = res.value.timestamp; + jsonRes.IsDelete = res.value.is_delete.toString(); + try { + jsonRes.Value = JSON.parse(res.value.value.toString('utf8')); + } catch (err) { + console.log(err); + jsonRes.Value = res.value.value.toString('utf8'); + } + } else { + jsonRes.Key = res.value.key; + try { + jsonRes.Record = JSON.parse(res.value.value.toString('utf8')); + } catch (err) { + console.log(err); + jsonRes.Record = res.value.value.toString('utf8'); + } + } + allResults.push(jsonRes); + } + if (res.done) { + console.log('end of data'); + await iterator.close(); + console.info(allResults); + return allResults; + } + } + } + + /** + * Executes the provided query string. + * Result set is built and returned as a byte array containing the JSON results. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String} queryString The query string to execute. + * @param {Chaincode} thisObject The chaincode object context. + * @return {Promise} The results of the specified query. + */ + async getQueryResultForQueryString(stub, queryString, thisObject) { + + console.info('- getQueryResultForQueryString queryString:\n' + queryString); + const resultsIterator = await stub.getQueryResult(queryString); + + const results = await thisObject.getAllResults(resultsIterator, false); + + return Buffer.from(JSON.stringify(results)); + } + + /** + * Retrieves the history for a marble. + * @async + * @param {ChaincodeStub} stub The chaincode stub. + * @param {String[]} args The arguments of the function. Index 0: marble name. + * @param {Chaincode} thisObject The chaincode object context. + * @return {Promise} The history entries of the specified marble. + */ + async getHistoryForMarble(stub, args, thisObject) { + + if (args.length !== 1) { + return shim.error('Incorrect number of arguments. Expecting 1'); + } + const marbleName = args[0]; + console.info('- start getHistoryForMarble: %s\n', marbleName); + + const resultsIterator = await stub.getHistoryForKey(marbleName); + const results = await thisObject.getAllResults(resultsIterator, true); + + return shim.success(Buffer.from(JSON.stringify(results))); + } +}; + +shim.start(new Chaincode()); diff --git a/test/scenario/chaincode/marbles/node/metadata/statedb/couchdb/indexes/indexOwner.json b/test/scenario/chaincode/marbles/node/metadata/statedb/couchdb/indexes/indexOwner.json new file mode 100644 index 0000000000..305f090444 --- /dev/null +++ b/test/scenario/chaincode/marbles/node/metadata/statedb/couchdb/indexes/indexOwner.json @@ -0,0 +1 @@ +{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} diff --git a/test/scenario/chaincode/marbles/node/package.json b/test/scenario/chaincode/marbles/node/package.json new file mode 100644 index 0000000000..215d07c515 --- /dev/null +++ b/test/scenario/chaincode/marbles/node/package.json @@ -0,0 +1,17 @@ +{ + "name": "marbles", + "version": "1.0.0", + "description": "marbles chaincode implemented in node.js", + "engines": { + "node": ">=8.4.0", + "npm": ">=5.3.0" + }, + "scripts": { + "start": "node marbles.js" + }, + "engine-strict": true, + "license": "Apache-2.0", + "dependencies": { + "fabric-shim": "~1.1.0" + } +} diff --git a/test/scenario/config/ccp-tls.json b/test/scenario/config/ccp-tls.json new file mode 100644 index 0000000000..7656e80e7d --- /dev/null +++ b/test/scenario/config/ccp-tls.json @@ -0,0 +1,142 @@ +{ + "name":"cucmber-network", + "description":"The network to be in if you like scenario tests, not vegetables", + "version":"1.0", + "client":{ + "organization":"Org1", + "credentialStore":{ + "path":"/tmp/hfc-kvs", + "cryptoStore":{ + "path":"/tmp/hfc-cvs" + }, + "wallet":"wallet-name" + } + }, + "channels":{ + "mychannel":{ + "orderers":[ + "orderer.example.com" + ], + "peers":{ + "peer0.org1.example.com":{ + "endorsingPeer":true, + "chaincodeQuery":true, + "ledgerQuery":true, + "eventSource":true + }, + "peer0.org2.example.com":{ + "endorsingPeer":true, + "chaincodeQuery":false, + "ledgerQuery":true, + "eventSource":false + } + }, + "chaincodes":[ + ] + } + }, + "organizations":{ + "Org1":{ + "mspid":"Org1MSP", + "peers":[ + "peer0.org1.example.com" + ], + "certificateAuthorities":[ + "ca-org1" + ], + "adminPrivateKeyPEM":{ + "path":"../config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/keystore/key.pem" + }, + "signedCertPEM":{ + "path":"../config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/signcerts/Admin@org1.example.com-cert.pem" + } + }, + "Org2":{ + "mspid":"Org2MSP", + "peers":[ + "peer0.org2.example.com" + ], + "certificateAuthorities":[ + "ca-org2" + ], + "adminPrivateKeyPEM":{ + "path":"../config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/keystore/key.pem" + }, + "signedCertPEM":{ + "path":"../config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/signcerts/Admin@org2.example.com-cert.pem" + } + } + }, + "orderers":{ + "orderer.example.com":{ + "url":"grpcs://localhost:7050", + "mspid": "OrdererMSP", + "grpcOptions":{ + "ssl-target-name-override":"orderer.example.com" + }, + "tlsCACerts":{ + "path":"../config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem" + }, + "adminPrivateKeyPEM":{ + "path":"../config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/keystore/key.pem" + }, + "signedCertPEM":{ + "path":"../config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/signcerts/Admin@example.com-cert.pem" + } + } + }, + "peers":{ + "peer0.org1.example.com":{ + "url":"grpcs://localhost:7051", + "grpcOptions":{ + "ssl-target-name-override":"peer0.org1.example.com", + "request-timeout": 120001 + }, + "tlsCACerts":{ + "path":"../config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem" + } + }, + "peer0.org2.example.com":{ + "url":"grpcs://localhost:8051", + "grpcOptions":{ + "ssl-target-name-override":"peer0.org2.example.com", + "request-timeout": 120001 + }, + "tlsCACerts":{ + "path":"../config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem" + } + } + }, + "certificateAuthorities":{ + "ca-org1":{ + "url":"https://localhost:7054", + "grpcOptions":{ + "verify":true + }, + "tlsCACerts":{ + "path":"../config/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem" + }, + "registrar":[ + { + "enrollId":"admin", + "enrollSecret":"adminpw" + } + ] + }, + "ca-org2":{ + "url":"https://localhost:8054", + "grpcOptions":{ + "verify":true + }, + "tlsCACerts":{ + "path":"../config/crypto-config/peerOrganizations/org2.example.com/ca/org2.example.com-cert.pem" + }, + "registrar":[ + { + "enrollId":"admin", + "enrollSecret":"adminpw" + } + ] + } + } +} diff --git a/test/scenario/config/crypto-config/adminconfig.tx b/test/scenario/config/crypto-config/adminconfig.tx new file mode 100644 index 0000000000000000000000000000000000000000..54cf14cf461308ed6ac60ef563b69a6911bf4c7d GIT binary patch literal 350 zcmd8O5BMlxtV#%`FUxX=|X#%xOOpdp$J(EX>xHp78K-U zCMT9;=I04X32}3=`xm7f`UVFGF+e#+V2%_Y7ngH>UU7a=NoHxT5QEfPMxkSjsM@zN zaxkK3LNQKCg^R~Iu^=%iGbghoGqqSqM2L%vgNr51Fy07g9-AY`vBgSCTB`9j30!V70CJIRi@d1tD;)3!8fB^)tOAAU%DWUjHL`aBB NAUH9%ASV^!V*t|)TiyTw literal 0 HcmV?d00001 diff --git a/test/scenario/config/crypto-config/configtx.yaml b/test/scenario/config/crypto-config/configtx.yaml new file mode 100644 index 0000000000..08e9981046 --- /dev/null +++ b/test/scenario/config/crypto-config/configtx.yaml @@ -0,0 +1,316 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +--- +################################################################################ +# +# 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: &ApplicationDefaultPolicies + Readers: + Type: ImplicitMeta + Rule: "ANY Readers" + Writers: + Type: ImplicitMeta + Rule: "ANY Writers" + Admins: + Type: ImplicitMeta + Rule: "MAJORITY Admins" +################################################################################ +# +# SECTION: Capabilities +################################################################################ +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 + # V1.1 for Channel is a catchall flag for behavior which has been + # determined to be desired for all orderers and peers running v1.0.x, + # but the modification of which would cause incompatibilities. Users + # should leave this flag set to true. + V1_1: true + + # Orderer capabilities apply only to the orderers, and may be safely + # manipulated without concern for upgrading peers. Set the value of the + # capability to true to require it. + Orderer: &OrdererCapabilities + # V1.1 for Order is a catchall flag for behavior which has been + # determined to be desired for all orderers running v1.0.x, but the + # modification of which would cause incompatibilities. Users should + # leave this flag set to true. + V1_1: true + + # Application capabilities apply only to the peer network, and may be + # safely manipulated without concern for upgrading orderers. Set the value + # of the capability to true to require it. + Application: &ApplicationCapabilities + # V1.2 for Application enables the new non-backwards compatible + # features and fixes of fabric v1.2, it implies V1_1. + V1_2: true + # V1.1 for Application enables the new non-backwards compatible + # features and fixes of fabric v1.1 (note, this need not be set if + # V1_2 is set). + V1_1: false + +################################################################################ +# +# 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 + + +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + + # Orderer Type: The orderer implementation to start + # Available types are "solo" and "kafka" + OrdererType: solo + + Addresses: + - orderer.example.com:7050 + + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 0.5s + + # 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: 98 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 + + Kafka: + # Brokers: A list of Kafka brokers to which the orderer connects + # NOTE: Use IP:port notation + Brokers: + - 127.0.0.1:9092 + + # 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" + +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + + # OrdererOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions + - &OrdererOrg + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: OrdererMSP + + # ID to load the MSP definition as + ID: OrdererMSP + + # MSPDir is the filesystem path which contains the MSP configuration + MSPDir: crypto-config/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: &OrdererOrgPolicies + Readers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('OrdererMSP.admin', 'OrdererMSP.peer', 'OrdererMSP.client')" + Writers: + Type: Signature + Rule: "OR('OrdererMSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('OrdererMSP.admin', 'OrdererMSP.client')" + Admins: + Type: Signature + Rule: "OR('OrdererMSP.admin')" + + - &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: crypto-config/peerOrganizations/org1.example.com/msp + + AnchorPeers: + # AnchorPeers defines the location of peers which can be used + # for cross org gossip communication. Note, this value is only + # encoded in the genesis block in the Application section context + - Host: peer0.org1.example.com + Port: 7051 + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: &Org1Policies + Readers: + Type: Signature + Rule: "OR('Org1MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org1MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org1MSP.admin')" + + - &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: crypto-config/peerOrganizations/org2.example.com/msp + + AnchorPeers: + # AnchorPeers defines the location of peers which can be used + # for cross org gossip communication. Note, this value is only + # encoded in the genesis block in the Application section context + - Host: peer0.org2.example.com + Port: 7051 + + # Policies defines the set of policies at this level of the config tree + # For organization policies, their canonical path is usually + # /Channel/// + Policies: &Org2Policies + Readers: + Type: Signature + Rule: "OR('Org2MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" + Writers: + Type: Signature + Rule: "OR('Org2MSP.member')" + # If your MSP is configured with the new NodeOUs, you might + # want to use a more specific rule like the following: + # Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" + Admins: + Type: Signature + Rule: "OR('Org2MSP.admin')" + +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + + TwoOrgsOrdererGenesis: + <<: *ChannelDefaults + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Capabilities: + <<: *OrdererCapabilities + Consortiums: + SampleConsortium: + Organizations: + - *Org1 + - *Org2 + TwoOrgsChannel: + Consortium: SampleConsortium + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: + <<: *ApplicationCapabilities diff --git a/test/scenario/config/crypto-config/configtxgen.sh b/test/scenario/config/crypto-config/configtxgen.sh new file mode 100755 index 0000000000..d84daed9b8 --- /dev/null +++ b/test/scenario/config/crypto-config/configtxgen.sh @@ -0,0 +1,9 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +export FABRIC_CFG_PATH=$PWD +configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./twoorgs.genesis.block +configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./mychannel.tx -channelID mychannel +configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./mychanneltx.tx -channelID mychanneltx +configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./adminconfig.tx -channelID adminconfig diff --git a/test/scenario/config/crypto-config/mychannel.tx b/test/scenario/config/crypto-config/mychannel.tx new file mode 100644 index 0000000000000000000000000000000000000000..68876d9caaf87c0ce15fee41d5a9dfb15fab20b2 GIT binary patch literal 346 zcmd8N}Rcs$r*`xd8s)eBF9)*_CtLtoO?Xje35pu10FoN0i9!-Wd_ZHkxS)IiVBkRP(t^@bN+^C45fb7O N2u{o`$Vo-`7y!Q0T224} literal 0 HcmV?d00001 diff --git a/test/scenario/config/crypto-config/mychannelator.json b/test/scenario/config/crypto-config/mychannelator.json new file mode 100644 index 0000000000..e50c700e88 --- /dev/null +++ b/test/scenario/config/crypto-config/mychannelator.json @@ -0,0 +1,69 @@ +{ + "channel_id": "mychannelator", + "read_set": { + "groups": { + "Application": { + "groups": { + "Org1MSP": {}, + "Org2MSP": {} + } + } + }, + "values": { + "Consortium": { + "value": { + "name": "SampleConsortium" + } + } + } + }, + "write_set": { + "groups": { + "Application": { + "groups": { + "Org1MSP": {}, + "Org2MSP": {} + }, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + } + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "sub_policy": "Readers" + } + } + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "sub_policy": "Writers" + } + } + } + }, + "version": "1" + } + }, + "values": { + "Consortium": { + "value": { + "name": "SampleConsortium" + } + } + } + } +} diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/key.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/key.pem new file mode 100755 index 0000000000..278a8edbc4 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/ca/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgMOKUs/EytOuKG/kW +qZ8OHBb1aJ4zodJVqYWwcpH5FluhRANCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCU +PEe1Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQ +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/admincerts/Admin@example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/admincerts/Admin@example.com-cert.pem new file mode 100644 index 0000000000..cb68b5959b --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/admincerts/Admin@example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHDCCAcOgAwIBAgIRAOVchZuZsk52YC0d82t2qj0wCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRowGAYDVQQDDBFBZG1pbkBleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABKR5qsiBaQSx0sy1K/7EFpBJDeVPC6cLbfqIjjtosuMfNNjDrVR9X8s+ +dPLeWbUP5qJmWnE1kZ/J0WyTnqRbKA2jYjBgMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIOqt5ZCH +xtl/zzUOlPN62fLGkrtm8YIUjOWJQN5wrenOMAoGCCqGSM49BAMCA0cAMEQCIEkj +Aoe3iCG+7t2BYDRmZgF/6jUZVDjHrNaRsabLzvXTAiA6PM/0GLppYtIcGQDA7qeJ +VfRO4IGE/M3rSnpBrQCodA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-tls-cert.pem new file mode 100644 index 0000000000..604c9c35d4 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/example.com-tls-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl +ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD +DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06 +fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv +jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq +xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT +MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod +zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-tls-cert.pem new file mode 100644 index 0000000000..ac4f5af8d4 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org1.example.com-tls-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB +K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF +1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B +NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG +SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA +pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-tls-cert.pem new file mode 100644 index 0000000000..d02884fa17 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/cacerts/org2.example.com-tls-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo +zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf +mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf +KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG +SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA +yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/signcerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/signcerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/signcerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-tls-cert.pem new file mode 100644 index 0000000000..0309ef551f --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/example.com-tls-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNTCCAdygAwIBAgIRAPMzoI7K8QG4k7AzN7IhxhEwCgYIKoZIzj0EAwIwbDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRowGAYDVQQDExF0bHNjYS5l +eGFtcGxlLmNvbTAeFw0xODAyMjExODQwMzJaFw0yODAyMTkxODQwMzJaMGwxCzAJ +BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh +bmNpc2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEaMBgGA1UEAxMRdGxzY2EuZXhh +bXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARXNh/8ySinCUnJi2T3 +cs4m3au0lHjallzAe6PcDz9++1bOl4CggAY0HxNov3nxtYoUJZcRhnE5an1PPipM +71hdo18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMB +Af8EBTADAQH/MCkGA1UdDgQiBCBQa5ovzv+NOu9CqfL/a885FjzDQZCg0D1kB+Oe +IdcBUTAKBggqhkjOPQQDAgNHADBEAiAZ7PcHMWpc2iu0dc43lwhq0wKLLVleCfgZ +JgRwdjw3wgIgMhcaHqv/W5MAudy9kjeJHIFembEJuWe/+krL6v//yw8= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-tls-cert.pem new file mode 100644 index 0000000000..886ecf1092 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org1.example.com-tls-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSTCCAfCgAwIBAgIRAN6NNLMddiNQbv9O9XXVtYkwCgYIKoZIzj0EAwIwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTgwMjIxMTg0MDMyWhcNMjgwMjE5MTg0 +MDMyWjB2MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0G +A1UEAxMWdGxzY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABDcanv4coQ10L/0jwxXuHcn8YtJEiqQRNSbKWLqf3/1mwYk8EEDHT4k9 +u1f+zS4T+qmSHSXbnFY+EN/ML5/1OGmjXzBdMA4GA1UdDwEB/wQEAwIBpjAPBgNV +HSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEIJDbRSUVw/eK +6MzDHCybxAB60iGHBjtRkAIrOcT3xytTMAoGCCqGSM49BAMCA0cAMEQCIAGAMw2G +Kn0n52XceSFMyioH4Uo0dpkYaxKFk0P9vBTTAiBd0AQ0WFc/w1wuaShK3hWNg9Ey +F9kotvRE5Hu0gweb1w== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-tls-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-tls-cert.pem new file mode 100644 index 0000000000..76d7be38cd --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/org2.example.com-tls-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSTCCAfCgAwIBAgIRAMXlqdLr7+td1aShJFAZungwCgYIKoZIzj0EAwIwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzIuZXhhbXBsZS5jb20wHhcNMTgwMjIxMTg0MDMyWhcNMjgwMjE5MTg0 +MDMyWjB2MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0G +A1UEAxMWdGxzY2Eub3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABO7WAyDbk/B2w9mmauuRSlOwFL1crwmiu9oDu83/Veh9ghrNRsbK2chV +j5PoY+H5PlRbqA8ZdbmDhHhDho9KBqejXzBdMA4GA1UdDwEB/wQEAwIBpjAPBgNV +HSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEIO+KUPKtAXWt +BPdjC4N80Yys3wJ9i4/mxz1ikCFJ890EMAoGCCqGSM49BAMCA0cAMEQCID4dOXH8 +6ginPTS17oyyowkdM34Z5ATPdA7WytfA8IW+AiA0jguTMYimuWEWuTulOgyNZ3ai +hzFkzY/dm7duN86yJQ== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/admincerts/Admin@example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/admincerts/Admin@example.com-cert.pem new file mode 100644 index 0000000000..cb68b5959b --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/admincerts/Admin@example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHDCCAcOgAwIBAgIRAOVchZuZsk52YC0d82t2qj0wCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRowGAYDVQQDDBFBZG1pbkBleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABKR5qsiBaQSx0sy1K/7EFpBJDeVPC6cLbfqIjjtosuMfNNjDrVR9X8s+ +dPLeWbUP5qJmWnE1kZ/J0WyTnqRbKA2jYjBgMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIOqt5ZCH +xtl/zzUOlPN62fLGkrtm8YIUjOWJQN5wrenOMAoGCCqGSM49BAMCA0cAMEQCIEkj +Aoe3iCG+7t2BYDRmZgF/6jUZVDjHrNaRsabLzvXTAiA6PM/0GLppYtIcGQDA7qeJ +VfRO4IGE/M3rSnpBrQCodA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/cacerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/cacerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/cacerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/key.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/key.pem new file mode 100755 index 0000000000..9f83a878a0 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0D9/qySG+JbELX4u +WYxknY5CP4p6sVnetkfHGs7WBW+hRANCAATcybHflJqj6M8vzGCT30gfoZBPpbiP +jp4GgIOUHbiIuHz7y5I480+1YY++JcbS6nDZCh2EJRhFAQ5ZtJZLbbHO +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/signcerts/orderer.example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/signcerts/orderer.example.com-cert.pem new file mode 100644 index 0000000000..7501ca153b --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/signcerts/orderer.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHzCCAcWgAwIBAgIRANzg3GjG7MdyBWTlVQ42QbAwCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFgxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRwwGgYDVQQDExNvcmRlcmVyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZI +zj0DAQcDQgAE3Mmx35Sao+jPL8xgk99IH6GQT6W4j46eBoCDlB24iLh8+8uSOPNP +tWGPviXG0upw2QodhCUYRQEOWbSWS22xzqNiMGAwDgYDVR0PAQH/BAQDAgWgMBMG +A1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAg6q3l +kIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt6c4wCgYIKoZIzj0EAwIDSAAwRQIh +APf6n3hu/VwDz0N3GeJrsfksmq6ZRJ74NgKL7jHpNtsvAiALjSzODY+s48c5rF+A +Kn4JjmSH4UlcXcRGBsQpP+qXfg== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/admincerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/admincerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/admincerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/cacerts/example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/cacerts/example.com-cert.pem new file mode 100644 index 0000000000..b151531181 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/cacerts/example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/keystore/key.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/keystore/key.pem new file mode 100755 index 0000000000..7cc31b4915 --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgKi/7SbU0tzemhB4/ +gZY1pts4cjYsrMTL7SSGkDSpSkahRANCAASkearIgWkEsdLMtSv+xBaQSQ3lTwun +C236iI47aLLjHzTYw61UfV/LPnTy3lm1D+aiZlpxNZGfydFsk56kWygN +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/signcerts/Admin@example.com-cert.pem b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/signcerts/Admin@example.com-cert.pem new file mode 100644 index 0000000000..cb68b5959b --- /dev/null +++ b/test/scenario/config/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/signcerts/Admin@example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHDCCAcOgAwIBAgIRAOVchZuZsk52YC0d82t2qj0wCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRowGAYDVQQDDBFBZG1pbkBleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABKR5qsiBaQSx0sy1K/7EFpBJDeVPC6cLbfqIjjtosuMfNNjDrVR9X8s+ +dPLeWbUP5qJmWnE1kZ/J0WyTnqRbKA2jYjBgMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIOqt5ZCH +xtl/zzUOlPN62fLGkrtm8YIUjOWJQN5wrenOMAoGCCqGSM49BAMCA0cAMEQCIEkj +Aoe3iCG+7t2BYDRmZgF/6jUZVDjHrNaRsabLzvXTAiA6PM/0GLppYtIcGQDA7qeJ +VfRO4IGE/M3rSnpBrQCodA== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/key.pem new file mode 100755 index 0000000000..7f4833522f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg7hAb34OQ5le9208+ +LC0V5mvjS9223gy8/LWaHy+bnUWhRANCAAS4ud+Na5q4hhRwplUy3YDxqQxUYMIJ +h0ri2sjLBj9MhJrF4d4SgMtuH9Zo8f7fFk/RtrAHcDjbD7HyjEgiqWka +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/admincerts/Admin@org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/admincerts/Admin@org1.example.com-cert.pem new file mode 100644 index 0000000000..0797d01c88 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/admincerts/Admin@org1.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQIVQ6HvVnJP1qZ5YKfh50hzAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +MS5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2eFOeD+VXC +HV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6aNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgoi2vNWsqq1eS6lPjX2b8zvHX8aorOiuS2/v5akSOomowCgYIKoZI +zj0EAwIDRwAwRAIgbEqKoKrFuYQG0ndiX7dT7GKGlF17Skf8DYil9cqbp00CID5T +URQPp0/vJ3tldK0z9xjFvsSecj8aqnDvZvGz07/v +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-tls-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-tls-cert.pem new file mode 100644 index 0000000000..ac4f5af8d4 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org1.example.com-tls-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB +K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF +1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B +NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG +SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA +pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org2.example.com-tls-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org2.example.com-tls-cert.pem new file mode 100644 index 0000000000..d02884fa17 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/cacerts/org2.example.com-tls-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo +zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf +mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf +KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG +SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA +yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/signcerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/signcerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/signcerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/admincerts/Admin@org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/admincerts/Admin@org1.example.com-cert.pem new file mode 100644 index 0000000000..0797d01c88 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/admincerts/Admin@org1.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQIVQ6HvVnJP1qZ5YKfh50hzAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +MS5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2eFOeD+VXC +HV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6aNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgoi2vNWsqq1eS6lPjX2b8zvHX8aorOiuS2/v5akSOomowCgYIKoZI +zj0EAwIDRwAwRAIgbEqKoKrFuYQG0ndiX7dT7GKGlF17Skf8DYil9cqbp00CID5T +URQPp0/vJ3tldK0z9xjFvsSecj8aqnDvZvGz07/v +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/key.pem new file mode 100755 index 0000000000..50c8b1e6be --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg+tWlPzRwoknNCHmn +QIw/DiQ5WXOoq8TbclyNz8CwApChRANCAAQlWnZyzstbrL/UpBdf/zB6G2yydJgY +AWRytAhXEGMAXXw/RpneaJNpZlUgGOJ0q47IUTKzRvlr6vK31kyULKJK +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/signcerts/peer0.org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/signcerts/peer0.org1.example.com-cert.pem new file mode 100644 index 0000000000..f02881d90f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/signcerts/peer0.org1.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCAdKgAwIBAgIRALLqpJNBvjJnfDisCe33w6wwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBb +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNvbTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABCVadnLOy1usv9SkF1//MHobbLJ0mBgBZHK0 +CFcQYwBdfD9Gmd5ok2lmVSAY4nSrjshRMrNG+Wvq8rfWTJQsokqjYjBgMA4GA1Ud +DwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsG +A1UdIwQkMCKAIKItrzVrKqtXkupT419m/M7x1/GqKzorktv7+WpEjqJqMAoGCCqG +SM49BAMCA0gAMEUCIQCHf6KuKNKDY65EEzxh2hg8Nxx33d35wUX5H9GkjtnphQIg +X2qGwCc+YoPDg+8JZmRlZ0zAy/6dWiY0xzVJ3/CMbYI= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/cert.pem new file mode 100644 index 0000000000..5403e6cdb6 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICfzCCAiWgAwIBAgIUNAqZVk9s5/HR7k30feNp8DrYbK4wCgYIKoZIzj0EAwIw +cDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMT +EG9yZzEuZXhhbXBsZS5jb20wHhcNMTgwMjI2MjAwOTAwWhcNMTkwMjI2MjAxNDAw +WjBdMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExFDASBgNV +BAoTC0h5cGVybGVkZ2VyMQ8wDQYDVQQLEwZjbGllbnQxDjAMBgNVBAMTBWFkbWlu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEz05miTKv6Vz+qhc5362WIZ44fs/H +X5m9zDOifle5HIjt4Usj+TiUgT1hpbI8UI9pueWhbrZpZXlX6+mImi52HaOBrzCB +rDAOBgNVHQ8BAf8EBAMCA6gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPnxMtT6jgYsMAgI38ponGs8sgbqMCsG +A1UdIwQkMCKAIKItrzVrKqtXkupT419m/M7x1/GqKzorktv7+WpEjqJqMCEGA1Ud +EQQaMBiCFnBlZXIwLm9yZzEuZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDSAAwRQIh +AM1JowZMshCRs6dnOfRmUHV7399KnNvs5QoNw93cuQuAAiBtBEGh1Xt50tZjDcYN +j+yx4IraL4JvMrCHbR5/R+Xo1Q== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/key.pem new file mode 100755 index 0000000000..ddc6db8ae1 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbTXpl4NGXuPtSC/V +PTVNGVBgVv8pZ6kGktVcnQD0KiKhRANCAATPTmaJMq/pXP6qFznfrZYhnjh+z8df +mb3MM6J+V7kciO3hSyP5OJSBPWGlsjxQj2m55aFutmlleVfr6YiaLnYd +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/admincerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/admincerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/admincerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/cacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/cacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/cacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/keystore/key.pem new file mode 100755 index 0000000000..fe50ae38bc --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgS0L+WeTBa4vdUW4j +rogLu8JmLSjda0YcA2TWOfaR+8yhRANCAAQO41JsWQE2pt2UZ/DBdIcpa/inDZ4U +54P5VcIdXgISsEqdRcGLBz+cvvrpTNedaeyNRSndk5LMIJ/npw2Qua/p +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/signcerts/Admin@org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/signcerts/Admin@org1.example.com-cert.pem new file mode 100644 index 0000000000..0797d01c88 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/signcerts/Admin@org1.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQIVQ6HvVnJP1qZ5YKfh50hzAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +MS5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2eFOeD+VXC +HV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6aNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgoi2vNWsqq1eS6lPjX2b8zvHX8aorOiuS2/v5akSOomowCgYIKoZI +zj0EAwIDRwAwRAIgbEqKoKrFuYQG0ndiX7dT7GKGlF17Skf8DYil9cqbp00CID5T +URQPp0/vJ3tldK0z9xjFvsSecj8aqnDvZvGz07/v +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/admincerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/admincerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/admincerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/cacerts/org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/cacerts/org1.example.com-cert.pem new file mode 100644 index 0000000000..527a90e8a0 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/cacerts/org1.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/keystore/key.pem new file mode 100755 index 0000000000..6554d7b6c7 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQglAOKVjiJSAYj5KnC +vmX99WJhlSwjZ07F8a+gohlPOKihRANCAARVCrjQpYsFfROLZkm1lnd7b/+GROpO +AhiImGijSYx2COmFY5UzBJdja7ElnDjGdWsrPvcSdhMI7ELw2omQZyT3 +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/signcerts/User1@org1.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/signcerts/User1@org1.example.com-cert.pem new file mode 100644 index 0000000000..33e53db9cd --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/signcerts/User1@org1.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCAdKgAwIBAgIRAKZHheCZPE+GMLRV2WXBr10wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBb +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEfMB0GA1UEAwwWVXNlcjFAb3JnMS5leGFtcGxlLmNvbTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABFUKuNCliwV9E4tmSbWWd3tv/4ZE6k4CGIiY +aKNJjHYI6YVjlTMEl2NrsSWcOMZ1ays+9xJ2EwjsQvDaiZBnJPejYjBgMA4GA1Ud +DwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsG +A1UdIwQkMCKAIKItrzVrKqtXkupT419m/M7x1/GqKzorktv7+WpEjqJqMAoGCCqG +SM49BAMCA0gAMEUCIQD3hsHS1DS9Ox7tq46p7x0QWP9yc++M7XA7PRf8L7wX/QIg +U0LdIXJrhxAXX29tC/qG2QGPA4T5QTCKZZcVNaAT/LQ= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/key.pem new file mode 100755 index 0000000000..0023b96e4f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTevmjSx6rk995Flz +Z1lLWbSCPnpkV2+H6+0fbLHgGxehRANCAAQ6GE1wdDI/Y/oklMjNbO22WVWw5j+7 +U3o9KljaUtSuz0bEDtoU30rosEK86Wk7hieFED2ILvZkySk1shFVkNqU +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/ca/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/admincerts/Admin@org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/admincerts/Admin@org2.example.com-cert.pem new file mode 100644 index 0000000000..273d43d183 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/admincerts/Admin@org2.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQAjgHxmmRePMUA7W89J4iJDAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +Mi5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcyLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAE/LzcUga8gVut24gLEXfECATFQUZZw3uVYvML +fqefDQEqA7v12Dd/DUSWvTGzOCR2wpFUqX9zidR0EUajqnOl4KNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgRk1VD+m/nn2Jds31nRpdRyWY9UwFjDVGMXxcX7Dd/W4wCgYIKoZI +zj0EAwIDRwAwRAIgBweV4tP8pYd4osOWIawmQTD4oqXtpp3F8y1g85Qz1BICIE8E +VNeXeNlxRoUdToSMOBHSJE0EVqK4BP4NXibBJSgH +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/cacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/cacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/cacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/signcerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/signcerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/signcerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/tlscacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/tlscacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/msp/tlscacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/admincerts/Admin@org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/admincerts/Admin@org2.example.com-cert.pem new file mode 100644 index 0000000000..273d43d183 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/admincerts/Admin@org2.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQAjgHxmmRePMUA7W89J4iJDAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +Mi5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcyLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAE/LzcUga8gVut24gLEXfECATFQUZZw3uVYvML +fqefDQEqA7v12Dd/DUSWvTGzOCR2wpFUqX9zidR0EUajqnOl4KNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgRk1VD+m/nn2Jds31nRpdRyWY9UwFjDVGMXxcX7Dd/W4wCgYIKoZI +zj0EAwIDRwAwRAIgBweV4tP8pYd4osOWIawmQTD4oqXtpp3F8y1g85Qz1BICIE8E +VNeXeNlxRoUdToSMOBHSJE0EVqK4BP4NXibBJSgH +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/cacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/cacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/cacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/key.pem new file mode 100755 index 0000000000..cb4c08d36a --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgjlkrze8DhYt8LpCh +kXJyUr6HOp9Jga5RXoOMPFC+J0yhRANCAARYOh3QPZB39zR+JKqVHD+NZqGwMSa3 +05zPyTod7ySx+qbXOXQOZo9AxX9eg7alhlQrSniME8YZIucNANKTEMp0 +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/signcerts/peer0.org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/signcerts/peer0.org2.example.com-cert.pem new file mode 100644 index 0000000000..da45859abb --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/signcerts/peer0.org2.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCAdKgAwIBAgIRAOvtY/+3TfiQKgN49CsrpLEwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBb +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMi5leGFtcGxlLmNvbTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABFg6HdA9kHf3NH4kqpUcP41mobAxJrfTnM/J +Oh3vJLH6ptc5dA5mj0DFf16DtqWGVCtKeIwTxhki5w0A0pMQynSjYjBgMA4GA1Ud +DwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsG +A1UdIwQkMCKAIEZNVQ/pv559iXbN9Z0aXUclmPVMBYw1RjF8XF+w3f1uMAoGCCqG +SM49BAMCA0gAMEUCIQC2FP9CW85/5dwQ0/4perHKGYaL2h/pZKpZTvlqA6AjdwIg +bee43v7a0+TqKkvI41rW6L5l+scxf9R+1Dp2s8UASus= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/cert.pem new file mode 100644 index 0000000000..93c4cc43f8 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICfzCCAiWgAwIBAgIUP10YV9H0k3awYvx/YQGbt4xSU0gwCgYIKoZIzj0EAwIw +cDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMT +EG9yZzIuZXhhbXBsZS5jb20wHhcNMTgwMjI2MjAxMDAwWhcNMTkwMjI2MjAxNTAw +WjBdMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExFDASBgNV +BAoTC0h5cGVybGVkZ2VyMQ8wDQYDVQQLEwZjbGllbnQxDjAMBgNVBAMTBWFkbWlu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4tZMwelomMmJuRuX2z2f+LzSK4vS +VwCxQezCUADzEbImVknEXbL0OGf+JfXFhdyer7NRu05ErU9DbW9dkvBJeaOBrzCB +rDAOBgNVHQ8BAf8EBAMCA6gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFE9WIFRHLVEBLb1cLkfly9pIPd5XMCsG +A1UdIwQkMCKAIEZNVQ/pv559iXbN9Z0aXUclmPVMBYw1RjF8XF+w3f1uMCEGA1Ud +EQQaMBiCFnBlZXIwLm9yZzIuZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDSAAwRQIh +AM6xI6LLT/P75KefAeP6Lmh0Ih0onbh5KeE6IbDVYOItAiBaRJ1z7aMUHy/ve5jb +TMhvWNDb463/VdvupdJ+o5J73w== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/key.pem new file mode 100755 index 0000000000..d844789eb1 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg2tjri0pHTTlGOt1n +EwgqxdqIfgpZdMIsnO2dLTX2qKOhRANCAATi1kzB6WiYyYm5G5fbPZ/4vNIri9JX +ALFB7MJQAPMRsiZWScRdsvQ4Z/4l9cWF3J6vs1G7TkStT0Ntb12S8El5 +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/admincerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/admincerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/admincerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/cacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/cacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/cacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/keystore/key.pem new file mode 100755 index 0000000000..5953ddb1a4 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg9cyRkWbKn8mFu2/H +HxMneHaDJgUIYD1NNMill5Etb9uhRANCAAT8vNxSBryBW63biAsRd8QIBMVBRlnD +e5Vi8wt+p58NASoDu/XYN38NRJa9MbM4JHbCkVSpf3OJ1HQRRqOqc6Xg +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/signcerts/Admin@org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/signcerts/Admin@org2.example.com-cert.pem new file mode 100644 index 0000000000..273d43d183 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/signcerts/Admin@org2.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQAjgHxmmRePMUA7W89J4iJDAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +Mi5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcyLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAE/LzcUga8gVut24gLEXfECATFQUZZw3uVYvML +fqefDQEqA7v12Dd/DUSWvTGzOCR2wpFUqX9zidR0EUajqnOl4KNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgRk1VD+m/nn2Jds31nRpdRyWY9UwFjDVGMXxcX7Dd/W4wCgYIKoZI +zj0EAwIDRwAwRAIgBweV4tP8pYd4osOWIawmQTD4oqXtpp3F8y1g85Qz1BICIE8E +VNeXeNlxRoUdToSMOBHSJE0EVqK4BP4NXibBJSgH +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/admincerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/admincerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/admincerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/cacerts/org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/cacerts/org2.example.com-cert.pem new file mode 100644 index 0000000000..8ebfe2531f --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/cacerts/org2.example.com-cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/keystore/key.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/keystore/key.pem new file mode 100755 index 0000000000..6d633fec79 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/keystore/key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0ToCLZ9mCaZovZpA +/5MZqxjfuZBbyLVftjP/Wsji9tmhRANCAAR2xaWMIy41g2N9svC/4bFtEYYSdwf9 +RdGSgYZn1WDbOpAUl1g9Ro7Ys4JkFrRqdbg8V8RPtmcJGFJbZVPfOx9h +-----END PRIVATE KEY----- diff --git a/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/signcerts/User1@org2.example.com-cert.pem b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/signcerts/User1@org2.example.com-cert.pem new file mode 100644 index 0000000000..62b830c180 --- /dev/null +++ b/test/scenario/config/crypto-config/peerOrganizations/org2.example.com/users/User1@org2.example.com/signcerts/User1@org2.example.com-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKzCCAdGgAwIBAgIQLKJhtKqqMCGzcyWeO+oNVDAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +Mi5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZVc2VyMUBvcmcyLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAEdsWljCMuNYNjfbLwv+GxbRGGEncH/UXRkoGG +Z9Vg2zqQFJdYPUaO2LOCZBa0anW4PFfET7ZnCRhSW2VT3zsfYaNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgRk1VD+m/nn2Jds31nRpdRyWY9UwFjDVGMXxcX7Dd/W4wCgYIKoZI +zj0EAwIDSAAwRQIhAN6yovenryWzuNLg7/tWVlAuVIfEcMNXzsPqkDnjZ62+AiAN +T8K300zijaLfUoeyxNiNclT3JAhNjNxPkYkRKVb/6A== +-----END CERTIFICATE----- diff --git a/test/scenario/config/crypto-config/rename.sh b/test/scenario/config/crypto-config/rename.sh new file mode 100755 index 0000000000..6731f3ef70 --- /dev/null +++ b/test/scenario/config/crypto-config/rename.sh @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Rename the key files we use to be key.pem instead of a uuid +for KEY in $(find crypto-config -type f -name "*_sk"); do + KEY_DIR=$(dirname ${KEY}) + mv ${KEY} ${KEY_DIR}/key.pem +done diff --git a/test/scenario/config/crypto-config/twoorgs.genesis.block b/test/scenario/config/crypto-config/twoorgs.genesis.block new file mode 100644 index 0000000000..79773c1a73 --- /dev/null +++ b/test/scenario/config/crypto-config/twoorgs.genesis.block @@ -0,0 +1,372 @@ + +" %,���|��Vt��(x�=dbU�� ̽���� +�� +�� +y +[쳶�" testchainid*@cdad2d7a639cab769332bf889e0f4bc59a5db7e21c21441783a4d6bd7d10b7ad�jL��"w{���K?�7��Ӹ6�� +�����S +Orderer�S�P + +OrdererMSP�P�O +MSP�O�O�O + +OrdererMSP�-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl +ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD +DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06 +fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv +jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq +xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT +MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod +zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY= +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB +K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF +1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B +NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG +SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA +pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo +zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf +mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf +KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG +SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA +yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= +-----END CERTIFICATE----- +"�-----BEGIN CERTIFICATE----- +MIICHDCCAcOgAwIBAgIRAOVchZuZsk52YC0d82t2qj0wCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRowGAYDVQQDDBFBZG1pbkBleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABKR5qsiBaQSx0sy1K/7EFpBJDeVPC6cLbfqIjjtosuMfNNjDrVR9X8s+ +dPLeWbUP5qJmWnE1kZ/J0WyTnqRbKA2jYjBgMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIOqt5ZCH +xtl/zzUOlPN62fLGkrtm8YIUjOWJQN5wrenOMAoGCCqGSM49BAMCA0cAMEQCIEkj +Aoe3iCG+7t2BYDRmZgF/6jUZVDjHrNaRsabLzvXTAiA6PM/0GLppYtIcGQDA7qeJ +VfRO4IGE/M3rSnpBrQCodA== +-----END CERTIFICATE----- +B +SHA2SHA256J�-----BEGIN CERTIFICATE----- +MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl +LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv +MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1 +Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV +HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/ +BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt +6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb +RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA== +-----END CERTIFICATE----- +J�-----BEGIN CERTIFICATE----- +MIICNTCCAdygAwIBAgIRAPMzoI7K8QG4k7AzN7IhxhEwCgYIKoZIzj0EAwIwbDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRowGAYDVQQDExF0bHNjYS5l +eGFtcGxlLmNvbTAeFw0xODAyMjExODQwMzJaFw0yODAyMTkxODQwMzJaMGwxCzAJ +BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh +bmNpc2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEaMBgGA1UEAxMRdGxzY2EuZXhh +bXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARXNh/8ySinCUnJi2T3 +cs4m3au0lHjallzAe6PcDz9++1bOl4CggAY0HxNov3nxtYoUJZcRhnE5an1PPipM +71hdo18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMB +Af8EBTADAQH/MCkGA1UdDgQiBCBQa5ovzv+NOu9CqfL/a885FjzDQZCg0D1kB+Oe +IdcBUTAKBggqhkjOPQQDAgNHADBEAiAZ7PcHMWpc2iu0dc43lwhq0wKLLVleCfgZ +JgRwdjw3wgIgMhcaHqv/W5MAudy9kjeJHIFembEJuWe/+krL6v//yw8= +-----END CERTIFICATE----- +J�-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- +J�-----BEGIN CERTIFICATE----- +MIICSTCCAfCgAwIBAgIRAN6NNLMddiNQbv9O9XXVtYkwCgYIKoZIzj0EAwIwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTgwMjIxMTg0MDMyWhcNMjgwMjE5MTg0 +MDMyWjB2MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0G +A1UEAxMWdGxzY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABDcanv4coQ10L/0jwxXuHcn8YtJEiqQRNSbKWLqf3/1mwYk8EEDHT4k9 +u1f+zS4T+qmSHSXbnFY+EN/ML5/1OGmjXzBdMA4GA1UdDwEB/wQEAwIBpjAPBgNV +HSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEIJDbRSUVw/eK +6MzDHCybxAB60iGHBjtRkAIrOcT3xytTMAoGCCqGSM49BAMCA0cAMEQCIAGAMw2G +Kn0n52XceSFMyioH4Uo0dpkYaxKFk0P9vBTTAiBd0AQ0WFc/w1wuaShK3hWNg9Ey +F9kotvRE5Hu0gweb1w== +-----END CERTIFICATE----- +J�-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- +J�-----BEGIN CERTIFICATE----- +MIICSTCCAfCgAwIBAgIRAMXlqdLr7+td1aShJFAZungwCgYIKoZIzj0EAwIwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzIuZXhhbXBsZS5jb20wHhcNMTgwMjIxMTg0MDMyWhcNMjgwMjE5MTg0 +MDMyWjB2MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0G +A1UEAxMWdGxzY2Eub3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABO7WAyDbk/B2w9mmauuRSlOwFL1crwmiu9oDu83/Veh9ghrNRsbK2chV +j5PoY+H5PlRbqA8ZdbmDhHhDho9KBqejXzBdMA4GA1UdDwEB/wQEAwIBpjAPBgNV +HSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEIO+KUPKtAXWt +BPdjC4N80Yys3wJ9i4/mxz1ikCFJ890EMAoGCCqGSM49BAMCA0cAMEQCID4dOXH8 +6ginPTS17oyyowkdM34Z5ATPdA7WytfA8IW+AiA0jguTMYimuWEWuTulOgyNZ3ai +hzFkzY/dm7duN86yJQ== +-----END CERTIFICATE----- +Admins"4 +Admins*  + +OrdererMSPAdmins"3 +Readers( + +OrdererMSPAdmins"3 +Writers( + +OrdererMSPAdmins*Admins! + ConsensusType +soloAdmins" + BatchSize  +���1�� Admins! + BatchTimeout +500msAdmins +ChannelRestrictionsAdmins$ + Capabilities + + +V1_1Admins"" +Readers  +ReadersAdmins"" +Writers  +WritersAdmins"" +Admins + +AdminsAdmins"* +BlockValidation  +WritersAdmins*Admins�5 + Consortiums�5�4 +SampleConsortium�4� +Org1MSP�� +MSP��� +Org1MSP�-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB +K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF +1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B +NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG +SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA +pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= +-----END CERTIFICATE----- +�-----BEGIN CERTIFICATE----- +MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y +ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw +ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo +zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf +mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf +KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG +SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA +yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= +-----END CERTIFICATE----- +"�-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQIVQ6HvVnJP1qZ5YKfh50hzAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +MS5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2eFOeD+VXC +HV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6aNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgoi2vNWsqq1eS6lPjX2b8zvHX8aorOiuS2/v5akSOomowCgYIKoZI +zj0EAwIDRwAwRAIgbEqKoKrFuYQG0ndiX7dT7GKGlF17Skf8DYil9cqbp00CID5T +URQPp0/vJ3tldK0z9xjFvsSecj8aqnDvZvGz07/v +-----END CERTIFICATE----- +B +SHA2SHA256J�-----BEGIN CERTIFICATE----- +MIICSDCCAe6gAwIBAgIRAPnKpS42wlgtHsddm6q+kYcwCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzEuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLi5341r +mriGFHCmVTLdgPGpDFRgwgmHSuLayMsGP0yEmsXh3hKAy24f1mjx/t8WT9G2sAdw +ONsPsfKMSCKpaRqjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCiLa81ayqrV5Lq +U+NfZvzO8dfxqis6K5Lb+/lqRI6iajAKBggqhkjOPQQDAgNIADBFAiEAr8LYCY2b +q5kNqOUxgHwBa2KTi/zJBR9L3IsTRDjJo8ECICf1xiDgKqZKrAMh0OCebskYwf53 +dooG04HBoqBLvB8Q +-----END CERTIFICATE----- +Admins"0 +Readers%  +Org1MSPAdmins"0 +Writers%  +Org1MSPAdmins"1 +Admins'  +Org1MSPAdmins*Admins� +Org2MSP�� +MSP��� +Org2MSP�-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- +"�-----BEGIN CERTIFICATE----- +MIICKjCCAdGgAwIBAgIQAjgHxmmRePMUA7W89J4iJDAKBggqhkjOPQQDAjBwMQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn +Mi5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g +RnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcyLmV4YW1wbGUuY29tMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAE/LzcUga8gVut24gLEXfECATFQUZZw3uVYvML +fqefDQEqA7v12Dd/DUSWvTGzOCR2wpFUqX9zidR0EUajqnOl4KNiMGAwDgYDVR0P +AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD +VR0jBCQwIoAgRk1VD+m/nn2Jds31nRpdRyWY9UwFjDVGMXxcX7Dd/W4wCgYIKoZI +zj0EAwIDRwAwRAIgBweV4tP8pYd4osOWIawmQTD4oqXtpp3F8y1g85Qz1BICIE8E +VNeXeNlxRoUdToSMOBHSJE0EVqK4BP4NXibBJSgH +-----END CERTIFICATE----- +B +SHA2SHA256J�-----BEGIN CERTIFICATE----- +MIICRzCCAe6gAwIBAgIRAO33HJTheTwvBgWroB6JK40wCgYIKoZIzj0EAwIwcDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xGTAXBgNVBAMTEG9y +ZzIuZXhhbXBsZS5jb20wHhcNMTcwNDIyMTIwMjU2WhcNMjcwNDIwMTIwMjU2WjBw +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu +IEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEZMBcGA1UEAxMQ +b3JnMi5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDoYTXB0 +Mj9j+iSUyM1s7bZZVbDmP7tTej0qWNpS1K7PRsQO2hTfSuiwQrzpaTuGJ4UQPYgu +9mTJKTWyEVWQ2pSjaTBnMA4GA1UdDwEB/wQEAwIBpjAZBgNVHSUEEjAQBgRVHSUA +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBGTVUP6b+efYl2 +zfWdGl1HJZj1TAWMNUYxfFxfsN39bjAKBggqhkjOPQQDAgNHADBEAiB2XoqoNSRw +YzY6sgomVYtidm7HwiXEsqkrThUHasnOugIgejAgkgXWid6WEdFSAUVpEDsRiek4 +nM2KGw+XJ5/pm/Q= +-----END CERTIFICATE----- +Admins"0 +Writers%  +Org2MSPAdmins"1 +Admins'  +Org2MSPAdmins"0 +Readers%  +Org2MSPAdmins*Admins@ +ChannelCreationPolicy'  +Admins/Channel/Orderer/Admins*/Channel/Orderer/Admins"- +Admins#/Channel/Orderer/Admins*/Channel/Orderer/Admins& +HashingAlgorithm +SHA256Admins- +BlockDataHashingStructure����AdminsI +OrdererAddresses5 +orderer.example.com:7050/Channel/Orderer/Admins$ + Capabilities + + +V1_1Admins"" +Writers  +WritersAdmins"" +Admins + +AdminsAdmins"" +Readers  +ReadersAdmins*Admins + + + + \ No newline at end of file diff --git a/test/scenario/config/policies.json b/test/scenario/config/policies.json new file mode 100644 index 0000000000..e89670cbe7 --- /dev/null +++ b/test/scenario/config/policies.json @@ -0,0 +1,39 @@ +{ + "1ofAny": { + "identities": [ + { "role": { "name": "member", "mspId": "Org1MSP" }}, + { "role": { "name": "member", "mspId": "Org2MSP" }}, + { "role": { "name": "admin", "mspId": "Org1MSP" }}, + { "role": { "name": "admin", "mspId": "Org2MSP" }} + ], + "policy": { + "1-of": [{ "signed-by": 0}, { "signed-by": 1 }, { "signed-by": 2 }, { "signed-by": 3}] + } + }, + "1AdminOr2Other": { + "identities": [ + { "role": { "name": "member", "mspId": "Org1MSP" }}, + { "role": { "name": "member", "mspId": "Org2MSP" }}, + { "role": { "name": "admin", "mspId": "Org1MSP" }}, + { "role": { "name": "admin", "mspId": "Org2MSP" }} + ], + "policy": { + "1-of": [ + { "signed-by": 2}, + { "signed-by": 3}, + { "2-of": [{ "signed-by": 0}, { "signed-by": 1 }]} + ] + } + }, + "2ofAny": { + "identities": [ + { "role": { "name": "member", "mspId": "Org1MSP" }}, + { "role": { "name": "member", "mspId": "Org2MSP" }}, + { "role": { "name": "admin", "mspId": "Org1MSP" }}, + { "role": { "name": "admin", "mspId": "Org2MSP" }} + ], + "policy": { + "2-of": [{"signed-by": 0}, {"signed-by": 1}, {"signed-by": 2}, {"signed-by": 3}] + } + } +} diff --git a/test/scenario/docker-compose/docker-compose-base.yaml b/test/scenario/docker-compose/docker-compose-base.yaml new file mode 100644 index 0000000000..5f41002fb7 --- /dev/null +++ b/test/scenario/docker-compose/docker-compose-base.yaml @@ -0,0 +1,102 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +version: '2' + +services: + ca0: + image: hyperledger/fabric-ca${DOCKER_IMG_TAG} + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org1 + - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem + - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/key.pem + ports: + - "7054:7054" + command: sh -c 'fabric-ca-server start --cfg.identities.allowremove --cfg.affiliations.allowremove -b admin:adminpw -d' + volumes: + - ../config/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config + container_name: ca_peerOrg1 + + ca1: + image: hyperledger/fabric-ca${DOCKER_IMG_TAG} + environment: + - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server + - FABRIC_CA_SERVER_CA_NAME=ca-org2 + - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem + - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/key.pem + ports: + - "8054:7054" + command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + volumes: + - ../config/crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config + container_name: ca_peerOrg2 + + orderer: + container_name: orderer + image: hyperledger/fabric-orderer${DOCKER_IMG_TAG} + environment: + - ORDERER_GENERAL_LOGLEVEL=${DOCKER_DEBUG} + - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 + - ORDERER_GENERAL_GENESISMETHOD=file + - ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/twoorgs.genesis.block + - ORDERER_GENERAL_LOCALMSPID=OrdererMSP + - ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=cucumber_default + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer + command: orderer + ports: + - 7050:7050 + volumes: + - ../config/crypto-config:/etc/hyperledger/configtx + - ../config/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer + - ../config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peerOrg1 + - ../config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peerOrg2 + + peer: + container_name: peer + image: hyperledger/fabric-peer${DOCKER_IMG_TAG} + environment: + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_PEER_ADDRESSAUTODETECT=true + - CORE_PEER_GOSSIP_ORGLEADER=false + - CORE_PEER_GOSSIP_USELEADERELECTION=true + - CORE_PEER_PROFILE_ENABLED=true + + # LOGGING SETTINGS + - CORE_LOGGING_LEVEL=${DOCKER_DEBUG} + - CORE_CHAINCODE_LOGGING_LEVE=${DOCKER_DEBUG} + - CORE_LOGGING_MSP=${DOCKER_DEBUG} + - CORE_LOGGING_GRPC=${DOCKER_DEBUG} + - CORE_LOGGING_LEDGER=${DOCKER_DEBUG} + - CORE_LOGGING_GOSSIP=${DOCKER_DEBUG} + - CORE_LOGGING_PEER_GOSSIP=${DOCKER_DEBUG} + + # TLS SETTINGS + - CORE_PEER_TLS_ENABLED=false + + ## the following setting redirects chaincode container logs to the peer container logs + - CORE_VM_DOCKER_ATTACHSTDOUT=true + + # # the following setting starts chaincode containers on the same + # # bridge network as the peers + # # https://docs.docker.com/compose/networking/ + - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=cucumber_default + working_dir: /opt/gopath/src/github.com/hyperledger/fabric + command: peer node start + volumes: + - /var/run/:/host/var/run/ + + couchdb: + container_name: couchdb + image: hyperledger/fabric-couchdb diff --git a/test/scenario/docker-compose/docker-compose-tls.yaml b/test/scenario/docker-compose/docker-compose-tls.yaml new file mode 100644 index 0000000000..1a1390ade1 --- /dev/null +++ b/test/scenario/docker-compose/docker-compose-tls.yaml @@ -0,0 +1,139 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +version: '2' + +services: + + ca0.example.com: + extends: + file: docker-compose-base.yaml + service: ca0 + container_name: ca0.example.com + environment: + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem + - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/key.pem + + ca1.example.com: + extends: + file: docker-compose-base.yaml + service: ca1 + container_name: ca1.example.com + environment: + - FABRIC_CA_SERVER_TLS_ENABLED=true + - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/org2.example.com-cert.pem + - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/key.pem + + orderer.example.com: + extends: + file: docker-compose-base.yaml + service: orderer + container_name: orderer.example.com + environment: + - ORDERER_GENERAL_TLS_ENABLED=true + - ORDERER_GENERAL_TLS_CLIENTAUTHREQUIRED=true + - ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/msp/orderer/keystore/key.pem + - ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/msp/orderer/signcerts/orderer.example.com-cert.pem + - ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/msp/orderer/cacerts/example.com-cert.pem, /etc/hyperledger/msp/peerOrg1/cacerts/org1.example.com-cert.pem, /etc/hyperledger/msp/peerOrg2/cacerts/org2.example.com-cert.pem] + - ORDERER_GENERAL_TLS_CLIENTROOTCAS=[/etc/hyperledger/msp/orderer/cacerts/example.com-cert.pem, /etc/hyperledger/msp/peerOrg1/cacerts/org1.example.com-cert.pem, /etc/hyperledger/msp/peerOrg2/cacerts/org2.example.com-cert.pem] + + peer0.org1.example.com: + extends: + file: docker-compose-base.yaml + service: peer + container_name: peer0.org1.example.com + environment: + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_PEER_ID=peer0.org1.example.com + - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_LISTENADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_ENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_LOCALMSPID=Org1MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ + + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb.org1.example.com:5984 + + ## Enable TLS + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_TLS_CLIENTAUTHREQUIRED=true + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/tls/key.pem + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/tls/cert.pem + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org1.example.com-cert.pem + - CORE_PEER_TLS_CLIENTROOTCAS_FILES=/etc/hyperledger/msp/peer/cacerts/org1.example.com-cert.pem + + ports: + - 7051:7051 + volumes: + - /var/run/:/host/var/run/ + - ../config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peer + depends_on: + - orderer.example.com + - couchdb.org1.example.com + + couchdb.org1.example.com: + extends: + file: docker-compose-base.yaml + service: couchdb + container_name: couchdb.org1.example.com + ports: + - 5984:5984 + environment: + DB_URL: http://localhost:5984/member_db + + peer0.org2.example.com: + extends: + file: docker-compose-base.yaml + service: peer + container_name: peer0.org2.example.com + + environment: + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_PEER_ID=peer0.org2.example.com + - CORE_PEER_ADDRESS=peer0.org2.example.com:8051 + - CORE_PEER_LISTENADDRESS=peer0.org2.example.com:8051 + - CORE_PEER_GOSSIP_ENDPOINT=peer0.org2.example.com:8051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:8051 + - CORE_PEER_LOCALMSPID=Org2MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ + + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb.org2.example.com:5984 + + ## Enable TLS + - CORE_PEER_TLS_ENABLED=true + - CORE_PEER_TLS_CLIENTAUTHREQUIRED=true + - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/msp/peer/tls/key.pem + - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/msp/peer/tls/cert.pem + - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/msp/peer/cacerts/org2.example.com-cert.pem + - CORE_PEER_TLS_CLIENTROOTCAS_FILES=/etc/hyperledger/msp/peer/cacerts/org2.example.com-cert.pem + ports: + - 8051:8051 + volumes: + - /var/run/:/host/var/run/ + - ../config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peer + depends_on: + - orderer.example.com + - couchdb.org2.example.com + + couchdb.org2.example.com: + extends: + file: docker-compose-base.yaml + service: couchdb + container_name: couchdb.org2.example.com + ports: + - 6984:5984 + environment: + DB_URL: http://localhost:5984/member_db diff --git a/test/scenario/docker-compose/docker-compose.yaml b/test/scenario/docker-compose/docker-compose.yaml new file mode 100644 index 0000000000..91e49039c4 --- /dev/null +++ b/test/scenario/docker-compose/docker-compose.yaml @@ -0,0 +1,109 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +version: '2' + +services: + + ca0.example.com: + extends: + file: docker-compose-base.yaml + service: ca0 + container_name: ca0.example.com + + + ca1.example.com: + extends: + file: docker-compose-base.yaml + service: ca1 + container_name: ca1.example.com + + orderer.example.com: + extends: + file: docker-compose-base.yaml + service: orderer + container_name: orderer.example.com + + peer0.org1.example.com: + extends: + file: docker-compose-base.yaml + service: peer + container_name: peer0.org1.example.com + environment: + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_PEER_ID=peer0.org1.example.com + - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_LISTENADDRESS=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_ENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 + - CORE_PEER_LOCALMSPID=Org1MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ + + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb.org1.example.com:5984 + + ports: + - 7051:7051 + volumes: + - /var/run/:/host/var/run/ + - ../config/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peer + depends_on: + - orderer.example.com + - couchdb.org1.example.com + + couchdb.org1.example.com: + extends: + file: docker-compose-base.yaml + service: couchdb + container_name: couchdb.org1.example.com + ports: + - 5984:5984 + environment: + DB_URL: http://localhost:5984/member_db + + peer0.org2.example.com: + extends: + file: docker-compose-base.yaml + service: peer + container_name: peer0.org2.example.com + + environment: + - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock + - CORE_PEER_ID=peer0.org2.example.com + - CORE_PEER_ADDRESS=peer0.org2.example.com:8051 + - CORE_PEER_LISTENADDRESS=peer0.org2.example.com:8051 + - CORE_PEER_GOSSIP_ENDPOINT=peer0.org2.example.com:8051 + - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:8051 + - CORE_PEER_LOCALMSPID=Org2MSP + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ + + - CORE_LEDGER_STATE_STATEDATABASE=CouchDB + - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb.org2.example.com:5984 + ports: + - 8051:8051 + volumes: + - /var/run/:/host/var/run/ + - ../config/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/etc/hyperledger/msp/peer + depends_on: + - orderer.example.com + - couchdb.org2.example.com + + couchdb.org2.example.com: + extends: + file: docker-compose-base.yaml + service: couchdb + container_name: couchdb.org2.example.com + ports: + - 6984:5984 + environment: + DB_URL: http://localhost:5984/member_db diff --git a/test/scenario/features/deploy_network_tls.feature b/test/scenario/features/deploy_network_tls.feature new file mode 100644 index 0000000000..e06ded4598 --- /dev/null +++ b/test/scenario/features/deploy_network_tls.feature @@ -0,0 +1,22 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +@deploy +Feature: Configure Fabric using SDK + + Background: + Given I have forcibly taken down all docker containers + + Scenario: Using the SDK I can create and join a channel + Given I have deployed a tls Fabric network + Then I can create a channels from the tls common connection profile + And I can join organization Org1 to the tls enabled channel named mychannel + And I can join organization Org2 to the tls enabled channel named mychannel + + Scenario: Using the SDK I can install and instantiate chaincode + Given I have deployed a tls Fabric network + Then I can create and join all channels from the tls common connection profile + And I can install node chaincode at version 1.0.0 named marbles to the tls Fabric network as organization Org1 on channel mychannel + And I can install node chaincode at version 1.0.0 named marbles to the tls Fabric network as organization Org2 on channel mychannel + And I can instantiate the newly installed node chaincode at version 1.0.0 named marbles on the tls Fabric network as organization Org1 on channel mychannel with endorsement policy 2ofAny and args [init,a,1000,b,2000] diff --git a/test/scenario/features/lib/chaincode.js b/test/scenario/features/lib/chaincode.js new file mode 100644 index 0000000000..e4d93e1532 --- /dev/null +++ b/test/scenario/features/lib/chaincode.js @@ -0,0 +1,309 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const Client = require('fabric-client'); + +const testUtil = require('./utils.js'); +const fs = require('fs'); +const path = require('path'); + +const supportedLanguageTypes = ['node', 'golang']; +const chaincodePath = '../../chaincode'; +/** + * Deploy the given chaincode to the given organization's peers. + * @param {String} ccName The name of the chaincode to install. + * @param {String} ccId The identifier for the chaincode to install. + * @param {String} ccType The chaincode type to install (node | goLang | Java ...) + * @param {String} ccVersion The chaincode version + * @param {Boolean} tls boolean true if a tls network, false if not + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {String} orgName The organisation to use to install + * @param {String} channel The channel to install on + * @return {Promise} The return promise. + */ +async function installChaincode(ccName, ccId, ccType, ccVersion, tls, ccp, orgName, channelName) { + + if (!supportedLanguageTypes.includes(ccType)){ + Promise.reject('Unsupported test ccType: ' + ccType); + } + + Client.setConfigSetting('request-timeout', 60000); + const client = new Client(); + const channel = client.newChannel(channelName); + + // Conditional action on TLS enablement + if (tls) { + const caName = ccp.getCertificatAuthoritiesForOrg(orgName)[0]; + const fabricCAEndpoint = ccp.getCertificateAuthority(caName).url; + const tlsInfo = await testUtil.tlsEnroll(fabricCAEndpoint, caName); + client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key); + } + + const cryptoSuite = Client.newCryptoSuite(); + cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({ path: testUtil.storePathForOrg(orgName) })); + client.setCryptoSuite(cryptoSuite); + + const ordererName = ccp.getOrderersForChannel(channelName)[0]; + const caRootsPath = ccp.getOrderer(ordererName).tlsCACerts.path; + let data = fs.readFileSync(caRootsPath); + const caroots = Buffer.from(data).toString(); + + channel.addOrderer( + client.newOrderer( + ccp.getOrderer(ordererName).url, + { + 'pem': caroots, + 'ssl-target-name-override': ccp.getOrderer(ordererName).grpcOptions['ssl-target-name-override'] + } + ) + ); + + const targets = []; + const peers = ccp.getPeersForOrganization(orgName); + peers.forEach((peerName) => { + const peer = ccp.getPeer(peerName); + data = fs.readFileSync(peer.tlsCACerts.path); + targets.push( + client.newPeer( + peer.url, + { + pem: Buffer.from(data).toString(), + 'ssl-target-name-override': peer.grpcOptions['ssl-target-name-override'] + } + ) + ); + }); + + try { + const store = await Client.newDefaultKeyValueStore({ path: testUtil.storePathForOrg(orgName) }); + client.setStateStore(store); + + // set user to send install chaincode requests + await testUtil.getSubmitter(client, true /* get peer org admin */, orgName, ccp); + + // chaincode and metadata paths + const ccPath = path.join(__dirname, chaincodePath, ccName, ccType); + const metadataPath = path.join(ccPath, 'metadata'); + + // send proposal to endorser + const request = { + targets: targets, + chaincodePath: ccPath, + metadataPath: metadataPath, + chaincodeId: ccId, + chaincodeType: ccType, + chaincodeVersion: ccVersion + }; + + testUtil.logMsg('Installing chaincode with ID [' + ccId + '] on ' + orgName + ' peers [' + ccp.getPeersForOrganization(orgName).toString() + '] ...'); + + const results = await client.installChaincode(request); + + const proposalResponses = results[0]; + + let proposalResponsesValid = true; + const errors = []; + for (const i in proposalResponses) { + let valid = false; + if (proposalResponses && proposalResponses[i].response && proposalResponses[i].response.status === 200) { + valid = true; + } else { + errors.push(proposalResponses[i]); + } + proposalResponsesValid = proposalResponsesValid && valid; + } + if (!proposalResponsesValid) { + throw new Error('Failed to send install Proposal or receive valid response: %s', JSON.stringify(errors)); + } else { + testUtil.logMsg('Successfully installed chaincode with ID [' + ccName + ']'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + } + } catch (err) { + testUtil.logError('Failed to install chaincode'); + throw err; + } +} + +/** + * Instantiate or upgrade the given chaincode with the given endorsement policy. + * @param {Boolean} upgrade Indicates whether the call is an upgrade or a new instantiation. + * @param {String} ccName The name of the chaincode to instantiate + * @param {String} ccId The identifier of the installed chaincode to instantiate + * @param {String} ccType The chaincode type to install (node | goLang | Java ...) + * @param {String[]} args Chaincode arguments + * @param {String} version The chaincode version + * @param {Boolean} tls true if tls enabled network; false if not + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {String} orgName The name of the organization to use + * @param {String} channelName The channel name + * @param {String} policy The endorsement policy object from the configuration file. + * @return {Promise} The return promise. + */ +async function instantiateChaincode(ccName, ccId, ccType, args, version, upgrade, tls, ccp, orgName, channelName, policy) { + if (!supportedLanguageTypes.includes(ccType)){ + Promise.reject('Unsupported test ccType: ' + ccType); + } + + Client.setConfigSetting('request-timeout', 120000); + + const type = upgrade? 'upgrade' : 'instantiate'; + + const targets = []; + const eventhubs = []; + const client = new Client(); + const channel = client.newChannel(channelName); + + const cryptoSuite = Client.newCryptoSuite(); + cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({ path: testUtil.storePathForOrg(orgName) })); + client.setCryptoSuite(cryptoSuite); + + // Conditional action on TLS enablement + if (tls) { + const caName = ccp.getCertificatAuthoritiesForOrg(orgName)[0]; + const fabricCAEndpoint = ccp.getCertificateAuthority(caName).url; + const tlsInfo = await testUtil.tlsEnroll(fabricCAEndpoint, caName); + client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key); + } + + const ordererName = ccp.getOrderersForChannel(channelName)[0]; + const caRootsPath = ccp.getOrderer(ordererName).tlsCACerts.path; + const data = fs.readFileSync(caRootsPath); + const caroots = Buffer.from(data).toString(); + + channel.addOrderer( + client.newOrderer( + ccp.getOrderer(ordererName).url, + { + 'pem': caroots, + 'ssl-target-name-override': ccp.getOrderer(ordererName).grpcOptions['ssl-target-name-override'] + } + ) + ); + + try { + testUtil.logMsg('Performing ' + type + ' transaction on chaincode with ID [' + ccName + '] as organization [' + orgName + '] ...'); + + const store = await Client.newDefaultKeyValueStore({ path: testUtil.storePathForOrg(orgName) }); + client.setStateStore(store); + + // set user to send install chaincode requests + await testUtil.getSubmitter(client, true /* get peer org admin */, orgName, ccp); + + const peers = ccp.getPeersForOrganization(orgName); + peers.forEach((peerName) => { + const thisPeer = ccp.getPeer(peerName); + const data = fs.readFileSync(thisPeer.tlsCACerts.path); + const peer = client.newPeer( + thisPeer.url, + { + pem: Buffer.from(data).toString(), + 'ssl-target-name-override': thisPeer.grpcOptions['ssl-target-name-override'] + }); + + targets.push(peer); + channel.addPeer(peer); + const eh = channel.newChannelEventHub(peer); + eventhubs.push(eh); + }); + + await channel.initialize(); + + const transientMap = { 'test': 'transientValue' }; + const ccPath = path.join(__dirname, chaincodePath, ccName, ccType); + const proposalRequest = buildChaincodeProposal(client, ccId, ccPath, version, ccType, args, upgrade, transientMap, policy); + + let results; + if (upgrade) { + results = await channel.sendUpgradeProposal(proposalRequest); + } else { + results = await channel.sendInstantiateProposal(proposalRequest); + } + + const proposalResponses = results[0]; + const proposal = results[1]; + for (const i in proposalResponses) { + if (!(proposalResponses && proposalResponses[i].response && proposalResponses[i].response.status === 200)) { + Promise.reject(type + ' proposal was bad: ' + JSON.stringify(proposalResponses[i])); + } + } + + const request = { + proposalResponses: proposalResponses, + proposal: proposal + }; + + const deployId = proposalRequest.txId.getTransactionID(); + + const eventPromises = []; + eventPromises.push(channel.sendTransaction(request)); + eventhubs.forEach((eh) => { + const txPromise = new Promise((resolve, reject) => { + const handle = setTimeout(reject, 300000); + + eh.registerTxEvent(deployId.toString(), (tx, code) => { + clearTimeout(handle); + if (code !== 'VALID') { + testUtil.logError('The chaincode ' + type + ' transaction was invalid, code = ' + code); + reject('The chaincode ' + type + ' transaction was invalid, code = ' + code); + } else { + resolve(); + } + }, (err) => { + clearTimeout(handle); + testUtil.logError('There was a problem with the ' + type + ' transaction event ' + JSON.stringify(err)); + reject('There was a problem with the ' + type + ' transaction event ' + JSON.stringify(err)); + }, { + disconnect: true + }); + eh.connect(); + }); + eventPromises.push(txPromise); + }); + + results = await Promise.all(eventPromises); + if (results && !(results[0] instanceof Error) && results[0].status === 'SUCCESS') { + testUtil.logMsg('Successfully performed ' + type + ' transaction on chaincode with ID [' + ccName + ']'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + } else { + testUtil.logError('Failed to order the ' + type + 'transaction. Error code: ' + results[0].status); + throw new Error('Failed to order the ' + type + 'transaction. Error code: ' + results[0].status); + } + } catch (err) { + testUtil.logError('Failed to perform ' + type + ' instantiation on chaincode with ID [' + ccName + ']'); + throw new Error('Failed to perform ' + type + ' instantiation on chaincode with ID [' + ccName + '] due to error: ' + err.stack ? err.stack : err); + } +} + +function buildChaincodeProposal(client, ccId, ccPath, version, ccType, args, upgrade, transientMap, policy) { + const tx_id = client.newTransactionID(); + + // args is a string array for the arguments to pass [function, arg0, arg1, arg2, ..., argn] + const argArray = args.slice(1,-1).split(','); + const func = argArray[0]; + const funcArgs = argArray.slice(1); + + // send proposal to endorser + const request = { + chaincodePath: ccPath, + chaincodeId: ccId, + chaincodeVersion: version, + fcn: func, + args: funcArgs, + txId: tx_id, + chaincodeType: ccType, + 'endorsement-policy': policy + }; + + if(upgrade) { + // use this call to test the transient map support during chaincode instantiation + request.transientMap = transientMap; + } + + return request; +} + +module.exports.installChaincode = installChaincode; +module.exports.instantiateChaincode = instantiateChaincode; diff --git a/test/scenario/features/lib/channel.js b/test/scenario/features/lib/channel.js new file mode 100644 index 0000000000..5dcf89839e --- /dev/null +++ b/test/scenario/features/lib/channel.js @@ -0,0 +1,221 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const utils = require('fabric-client/lib/utils.js'); +const Client = require('fabric-client'); +const testUtil = require('./utils.js'); + +const path = require('path'); +const fs = require('fs'); + +/** + * Create the channels located in the given common connection profile. + * @param {string} configPath The path to the Fabric network common connection profile and associated data. + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {Boolean} tls Boolean true if tls network; false if not + * @return {Promise} The return promise. + */ +async function create_channels(configPath, ccp, tls) { + Client.setConfigSetting('request-timeout', 60000); + const channels = ccp.getChannels(); + if (!Object.keys(channels) || Object.keys(channels).length === 0) { + return Promise.reject(new Error('No channel information found')); + } + + try { + utils.setConfigSetting('key-value-store', 'fabric-client/lib/impl/FileKeyValueStore.js'); + + for (const channelName in channels) { + const channel = channels[channelName]; + + testUtil.logMsg('Creating channel [' + channelName + '] ...'); + + // Acting as a client in first org when creating the channel + const client = new Client(); + const orgs = ccp.getOrganizations(); + const orgName = Object.keys(orgs)[0]; + const org = orgs[orgName]; + + const ordererName = channel.orderers[0]; + const caRootsPath = ccp.getOrderer(ordererName).tlsCACerts.path; + const data = fs.readFileSync(caRootsPath); + const caroots = Buffer.from(data).toString(); + + // Conditional action on TLS enablement + if (tls) { + const caName = org.certificateAuthorities[0]; + const fabricCAEndpoint = ccp.getCertificateAuthority(caName).url; + const tlsInfo = await testUtil.tlsEnroll(fabricCAEndpoint, caName); + client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key); + } + + const orderer = client.newOrderer( + ccp.getOrderer(ordererName).url, + { + 'pem': caroots, + 'ssl-target-name-override': ccp.getOrderer(ordererName).grpcOptions['ssl-target-name-override'] + } + ); + + let config = null; + const signatures = []; + + const store = await Client.newDefaultKeyValueStore({ path: testUtil.storePathForOrg(org) }); + client.setStateStore(store); + const cryptoSuite = Client.newCryptoSuite(); + cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({ path: testUtil.storePathForOrg(org) })); + client.setCryptoSuite(cryptoSuite); + + // Run this to set the required identity on the client object + await testUtil.getOrdererAdmin(client, ordererName, ccp); + + // use the config update created by the configtx tool + const envelope_bytes = fs.readFileSync((path.join(configPath, 'crypto-config', channelName + '.tx'))); + config = client.extractChannelConfig(envelope_bytes); + + // sign the config for each org + for (const organization in ccp.getOrganizations()) { + client._userContext = null; + await testUtil.getSubmitter(client, true, organization, ccp); + // sign the config + const signature = client.signChannelConfig(config).toBuffer().toString('hex'); + signatures.push(signature); + } + + client._userContext = null; + + // Run this to set the required identity on the client object + await testUtil.getOrdererAdmin(client, ordererName, ccp); + + // sign the config + const signature = client.signChannelConfig(config); + // collect signature from orderer admin + signatures.push(signature); + // build up the create request + const tx_id = client.newTransactionID(); + const request = { + name: channelName, + config: config, + signatures: signatures, + orderer: orderer, + txId: tx_id + }; + + // send create request to orderer + const result = await client.createChannel(request); + if (result.status && result.status === 'SUCCESS') { + testUtil.logMsg('Successfully created channel [' + channelName + ']'); + await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + return Promise.resolve(); + } + else { + throw new Error('Failed to create channels, with status: ' + result.status); + } + } + } catch (err) { + testUtil.logError('Failed to create channels ' + (err.stack ? err.stack : err)); + return Promise.reject(err); + } +} + +/** + * Join the peers of the given organization to the given channel. + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {Boolean} tls true if a tls network; false if not + * @param {String} channelName the name of the channel to join + * @param {String} orgName the name of the org + */ +async function join_channel(ccp, tls, channelName, orgName) { + Client.setConfigSetting('request-timeout', 60000); + const client = new Client(); + const channel = client.newChannel(channelName); + const targets = []; + + const ordererName = ccp.getOrderersForChannel(channelName)[0]; + const caRootsPath = ccp.getOrderer(ordererName).tlsCACerts.path; + let data = fs.readFileSync(caRootsPath); + const caroots = Buffer.from(data).toString(); + let genesis_block = null; + + try { + testUtil.logMsg('Joining organization [' + orgName + '] to channel [' + channelName + '] ...'); + + // Conditional action on TLS enablement + if (tls) { + const caName = ccp.getCertificatAuthoritiesForOrg(orgName)[0]; + const fabricCAEndpoint = ccp.getCertificateAuthority(caName).url; + const tlsInfo = await testUtil.tlsEnroll(fabricCAEndpoint, caName); + client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key); + } + + const store = await Client.newDefaultKeyValueStore({ path: testUtil.storePathForOrg(orgName) }); + client.setStateStore(store); + + // set user internal to client + await testUtil.getOrdererAdmin(client, ordererName, ccp); + + channel.addOrderer( + client.newOrderer( + ccp.getOrderer(ordererName).url, + { + 'pem': caroots, + 'ssl-target-name-override': ccp.getOrderer(ordererName).grpcOptions['ssl-target-name-override'] + } + ) + ); + + let tx_id = client.newTransactionID(); + let request = { + txId: tx_id + }; + + const block = await channel.getGenesisBlock(request); + genesis_block = block; + + // get the peer org's admin required to send join channel requests + client._userContext = null; + + await testUtil.getSubmitter(client, true /* get peer org admin */, orgName, ccp); + + const peers = ccp.getOrganization(orgName).peers; + peers.forEach((peerName) => { + const peer = ccp.getPeer(peerName); + data = fs.readFileSync(peer.tlsCACerts.path); + targets.push( + client.newPeer( + peer.url, + { + pem: Buffer.from(data).toString(), + 'ssl-target-name-override': peer.grpcOptions['ssl-target-name-override'] + } + ) + ); + }); + + tx_id = client.newTransactionID(); + request = { + targets: targets, + block: genesis_block, + txId: tx_id + }; + + const results = await channel.joinChannel(request, 130000); + + if (!(results && results[0] && results[0].response && results[0].response.status === 200)) { + throw new Error('Unexpected join channel response: ' + results.toString()); + } else { + testUtil.logMsg('Successfully joined organization [' + orgName + '] to channel [' + channelName + ']'); + await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + return client; + } + } catch (err) { + testUtil.logError(err); + return Promise.reject(err); + } +} + +module.exports.create_channels = create_channels; +module.exports.join_channel = join_channel; diff --git a/test/scenario/features/lib/common_connection.js b/test/scenario/features/lib/common_connection.js new file mode 100644 index 0000000000..62a616452a --- /dev/null +++ b/test/scenario/features/lib/common_connection.js @@ -0,0 +1,194 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const path = require('path'); + +/** + * CommonConnectionProfile + * + * Utility class for dealing with a common connection profile + */ +class CommonConnectionProfile { + + /** + * Constructor for the CCP class + * @param {String} profilePath path to the common connection profile + * @param {Boolean} json true if a json profile; false if not + */ + constructor(profilePath, json) { + if (json) { + this.profile = require(profilePath); + this._makeJsonPathsAbsolute(this.profile, path.dirname(profilePath)); + } else { + throw new Error('Only JSON profile currently accepted'); + } + } + + /** + * Check all file paths in the profile and make absolute if required + * @param {JSON} profile the JSON format common connection profile + * @param {String} rootPath the root path to use when setting absolute + */ + _makeJsonPathsAbsolute(parent, rootPath) { + if (parent && typeof parent == 'object') { + Object.entries(parent).forEach(([key, value]) => { + // key is either an array index or object key + if (key.localeCompare('path') === 0) { + if(!path.isAbsolute(value)){ + parent[key] = path.join(rootPath, value); + } + } else { + this._makeJsonPathsAbsolute(parent[key], rootPath); + } + }); + } + } + + /** + * Retrieve the channels named in the profile + * @return {Object[]} an objeect array of all channels within the profile + */ + getChannels() { + return this.profile.channels; + } + + /** + * Retrieve the channel Object based on name + * @param {String} channelName the channel of interest + * @return {Object} the channel object + */ + getChannel(channelName) { + return this.profile.channels[channelName]; + } + + /** + * Retrieve all the organizations named in the profile + * @return {Object[]} all organizations + */ + getOrganizations() { + return this.profile.organizations; + } + + /** + * Retrieve the organization object + * @param {String} orgName the organization of interest + * @return {Object} the organization object + */ + getOrganization(orgName) { + return this.profile.organizations[orgName]; + } + + /** + * Retrieve the organizations included within a channel + * @param {String} channelName the channel of interest + * @return {String[]} the organizations associated with a channel + */ + getOrganizationsForChannel(channelName) { + const channelPeers = Object.keys(this.profile.channels[channelName].peers); + const orgs = this.profile.organizations; + + const channelOrgs = new Array(); + for (const key in orgs){ + const org = orgs[key]; + const orgPeers = org.peers; + + if (orgPeers.filter(peerName => channelPeers.includes(peerName)).length>0){ + channelOrgs.push(key); + } + } + return channelOrgs; + + } + + /** + * Retrieve all the orderers named in the profile + * @return {Object[]} all orderers + */ + getOrderers() { + return this.profile.orderers; + } + + /** + * Retrieve a named orderer from the profile + * @param {String} ordererName the name of the orderer + * @return {Object} the named orderer + */ + getOrderer(ordererName) { + return this.profile.orderers[ordererName]; + } + + /** + * Retrieve all orderers from a named channel + * @param {String} channelName the channel of interest + * @return {Object[]} orderers for the named channel + */ + getOrderersForChannel(channelName) { + return this.profile.channels[channelName].orderers; + } + + /** + * Retrieve all the certificate authorities named in the profile + * @return {Object[]} all certificate authorities + */ + getCertificateAuthorities() { + return this.profile.certificateAuthorities; + } + + /** + * Retrieve a certificate authority named in the profile + * @param {String} caName the name of the certificate authority + * @return {Object} the certifaicate authority + */ + getCertificateAuthority(caName) { + return this.profile.certificateAuthorities[caName]; + } + + /** + * Retrieve certificate authorities for a named organization + * @param {String} orgName the organization name + * @return {Object[]} certificate authorities for the named organization + */ + getCertificatAuthoritiesForOrg(orgName) { + return this.profile.organizations[orgName].certificateAuthorities; + } + + /** + * Retrieve all the peers named in the profile + * @return {Object[]} the peers named in the profile + */ + getPeers() { + return this.profile.peers; + } + + /** + * Retrieve a named peers from the profile + * @param {String} peerName the peer name + * @return {Object} the peer object + */ + getPeer(peerName) { + return this.profile.peers[peerName]; + } + + /** + * Retrieve all peers for an organization from the profile + * @param {String} orgName the organizartion name + * @return {Object[]} all peers for the named organization + */ + getPeersForOrganization(orgName) { + return this.profile.organizations[orgName].peers; + } + + /** + * Retrieve all peers for a named channel in the profile + * @param {String} channelName the channel name of interest + * @return {String[]} the string array of all peer for the channel + */ + getPeersForChannel(channelName) { + return this.profile.channels[channelName].peers; + } +} + +module.exports = CommonConnectionProfile; diff --git a/test/scenario/features/lib/network.js b/test/scenario/features/lib/network.js new file mode 100644 index 0000000000..cc00b80d50 --- /dev/null +++ b/test/scenario/features/lib/network.js @@ -0,0 +1,167 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const {Gateway, InMemoryWallet, X509WalletMixin} = require('../../../../fabric-network'); +const testUtil = require('./utils.js'); +const fs = require('fs'); + +// Internal Map of connected gateways +const gateways = new Map(); + +/** + * Perform an in memeory ID setup + * @param {InMemoryWallet} inMemoryWallet the in memory wallet to use + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {String} orgName the organization name + * @param {String} userName the user name + * @return {String} the identity name + */ +async function inMemoryIdentitySetup(inMemoryWallet, ccp, orgName, userName) { + + const org = ccp.getOrganization(orgName); + const orgMsp = org.mspid; + + const identity = userName + '@' + orgName; + + const userCertPath = org.signedCertPEM.path.replace(/Admin/g, userName); + const userKeyPath = org.adminPrivateKeyPEM.path.replace(/Admin/g, userName); + + const cert = fs.readFileSync(userCertPath); + const key = fs.readFileSync(userKeyPath); + await inMemoryWallet.import(identity, X509WalletMixin.createIdentity(orgMsp, cert, key)); + return identity; +} + +/** + * Connect a gateway + * @param {CommonConnectionProfile} ccp The common connection profile + * @param {Booelan} tls boolean true if tls network; otherwise false + * @param {String} userName the user name to perform actinos with + * @param {String} orgName the Organization to which the user belongs + * @param {String} gatewayName the name of the gateway + * @return {Gateway} the connected gateway + */ +async function connectGateway(ccp, tls, userName, orgName, gatewayName) { + + const gateway = new Gateway(); + const inMemoryWallet = new InMemoryWallet(); + + // import specified user to wallet + const userIdentity = await inMemoryIdentitySetup(inMemoryWallet, ccp, orgName, userName); + + if (tls) { + const caName = ccp.getCertificatAuthoritiesForOrg(orgName)[0]; + const fabricCAEndpoint = ccp.getCertificateAuthority(caName).url; + const tlsInfo = await testUtil.tlsEnroll(fabricCAEndpoint, caName); + await inMemoryWallet.import('tlsId', X509WalletMixin.createIdentity(userIdentity, tlsInfo.certificate, tlsInfo.key)); + } + + const opts = { + wallet: inMemoryWallet, + identity: userIdentity + }; + + if (tls) { + opts.clientTlsIdentity = 'tlsId'; + } + + await gateway.connect(ccp.profile, opts); + gateways.set(gatewayName, gateway); + + // Ensure that all connections have had time to process in the background + await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + + return gateway; +} + +/** + * Disconnect and delete the named gateway + * @param {String} gatewayName the name of the gateway to work with + */ +async function disconnectGateway(gatewayName) { + try { + const gateway = gateways.get(gatewayName); + await gateway.disconnect(); + gateways.delete(gatewayName); + } catch (err) { + testUtil.logError('disconnectGateway failed with error ', err); + throw err; + } +} + +/** + * Disconnect all gateways within the `gateways` Map + */ +async function disconnectAllGateways() { + try { + for (const key of gateways.keys()) { + testUtil.logMsg('disconnecting from Gateway ', key); + const gateway = gateways.get(key); + await gateway.disconnect(); + } + gateways.clear(); + } catch (err) { + testUtil.logError('disconnectAllGateways() failed with error ', err); + throw err; + } +} + +/** + * Retrieve the smart contract from teh gateway + * @param {Gateway} gateway the gateway to work with + * @param {String} channelName the channel name to use + * @param {String} chaincodeId the chaincode ID to retrieve the smart contract for + * @return {Contract} the contract for the instantiated chaincode ID on the channel + */ +async function retrieveContractFromGateway(gateway, channelName, chaincodeId) { + try { + const network = await gateway.getNetwork(channelName); + return network.getContract(chaincodeId); + } catch (err) { + testUtil.logError('createContract failed with error ', err); + throw err; + } +} + +/** + * Perform a submit or evaluate transaction using the network API + * @param {String} gatewayName the name of the Gateway to use + * @param {String} ccName the chaincode ID + * @param {String} channelName the name of the channel the chaincode is instantiated on + * @param {String[]} args the argument array [func, arg0, arg1, ..., argn] + * @param {Boolean} submit flag to idicate if a submit transaction (true) or evaluate (false) + * @return {Object} resolved Promise if a submit transaction; evaluate result if not + */ +async function performGatewayTransaction(gatewayName, ccName, channelName, args, submit) { + // Get contract from Gateway + const gateway = gateways.get(gatewayName); + const contract = await retrieveContractFromGateway(gateway, channelName, ccName); + + // Split args + const argArray = args.slice(1,-1).split(','); + const func = argArray[0]; + const funcArgs = argArray.slice(1); + try { + if (submit){ + testUtil.logMsg('Submitting transaction [' + func + '] ...'); + await contract.submitTransaction(func, ...funcArgs); + testUtil.logMsg('Successfully submitted transaction [' + func + ']'); + } else { + testUtil.logMsg('Evaluating transaction [' + func + '] ...'); + const result = await contract.evaluateTransaction(func, ...funcArgs); + testUtil.logMsg('Successfully evaluated transaction [' + func + '] with result [' + result + ']'); + return result.toString(); + } + } catch (err) { + testUtil.logError(err); + throw err; + } +} + +module.exports.connectGateway = connectGateway; +module.exports.performGatewayTransaction = performGatewayTransaction; +module.exports.disconnectGateway = disconnectGateway; +module.exports.disconnectAllGateways = disconnectAllGateways; diff --git a/test/scenario/features/lib/utils.js b/test/scenario/features/lib/utils.js new file mode 100644 index 0000000000..818d743a16 --- /dev/null +++ b/test/scenario/features/lib/utils.js @@ -0,0 +1,290 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const Client = require('../../../../fabric-client'); +const copService = require('../../../../fabric-ca-client/lib/FabricCAClient.js'); +const FabricCAServices = require('../../../../fabric-ca-client'); +const User = require('../../../../fabric-client/lib/User.js'); + +const childProcess = require('child_process'); +const stripAnsi = require('strip-ansi'); +const path = require('path'); +const fs = require('fs-extra'); +const os = require('os'); + +// High level constants for timeouts +const TIMEOUTS = { + LONG_STEP : 240 * 1000, + MED_STEP : 120 * 1000, + SHORT_STEP: 60 * 1000, + LONG_INC : 30 * 1000, + MED_INC : 10 * 1000, + SHORT_INC: 5 * 1000 +}; + + +// all temporary files and directories are created under here +const tempdir = path.join(os.tmpdir(), 'hfc'); + +// directory for file based KeyValueStore +module.exports.KVS = path.join(tempdir, 'hfc-test-kvs'); +function storePathForOrg(org) { + return module.exports.KVS + '_' + org; +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +/** + * Run a shell command + * @param {Boolean} pass - Boolean pass/fail case expected, undefined if unchecked case + * @param {DataTable} cmd - CLI command with parameters to be run + * @return {Promise} - Promise that will be resolved or rejected with an error + */ +function runShellCommand(pass, cmd) { + if (typeof cmd !== 'string') { + return Promise.reject('Command passed to function was not a string'); + } else { + const command = cmd.replace(/\s*[\n\r]+\s*/g, ' '); + let stdout = ''; + let stderr = ''; + const env = Object.create(process.env); + + return new Promise((resolve, reject) => { + + const options = { + env : env, + maxBuffer: 100000000 + }; + const childCliProcess = childProcess.exec(command, options); + + childCliProcess.stdout.setEncoding('utf8'); + childCliProcess.stderr.setEncoding('utf8'); + + childCliProcess.stdout.on('data', (data) => { + data = stripAnsi(data); + logMsg('STDOUT: ', data); + stdout += data; + }); + + childCliProcess.stderr.on('data', (data) => { + data = stripAnsi(data); + logMsg('STDERR: ', data); + stderr += data; + }); + + childCliProcess.on('error', (error) => { + this.lastResp = {error : error, stdout : stdout, stderr : stderr}; + if (pass) { + reject(this.lastResp); + } + }); + + childCliProcess.on('close', (code) => { + if (pass === undefined) { + // don't care case + this.lastResp = {code : code, stdout : stdout, stderr : stderr}; + resolve(this.lastResp); + } else if (code && code !== 0 && pass) { + // non zero return code, should pass + this.lastResp = {code : code, stdout : stdout, stderr : stderr}; + reject(this.lastResp); + } else if (code && code === 0 && !pass) { + // zero return code, should fail + this.lastResp = {code : code, stdout : stdout, stderr : stderr}; + reject(this.lastResp); + } else { + this.lastResp = {code : code, stdout : stdout, stderr : stderr}; + resolve(this.lastResp); + } + }); + }); + } +} + +/** + * Retrieve an enrolled user, or enroll the user if necessary. + * @param {string} username The name of the user. + * @param {string} password The enrollment secret necessary to enroll the user. + * @param {Client} client The Fabric client object. + * @param {string} userOrg The name of the user's organization. + * @param {CommonConnectionProfile} ccp the common connection profile + * @return {Promise} The retrieved and enrolled user object. + */ +async function getMember(username, password, client, userOrg, ccp) { + + const org = ccp.getOrganization(userOrg); + if(!org) { + throw new Error('Could not find ' + userOrg + ' in configuration'); + } + + const caUrl = org.ca.url; + + const user = await client.getUserContext(username, true); + + try { + if (user && user.isEnrolled()) { + return user; + } + + const member = new User(username); + let cryptoSuite = client.getCryptoSuite(); + if (!cryptoSuite) { + cryptoSuite = Client.newCryptoSuite(); + if (userOrg) { + cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({path: module.exports.storePathForOrg(org.name)})); + client.setCryptoSuite(cryptoSuite); + } + } + member.setCryptoSuite(cryptoSuite); + + // need to enroll it with CA server + const tlsOptions = { + trustedRoots: [], + verify: false + }; + const cop = new copService(caUrl, tlsOptions, org.ca.name, cryptoSuite); + + const enrollment = await cop.enroll({enrollmentID: username, enrollmentSecret: password}); + + await member.setEnrollment(enrollment.key, enrollment.certificate, org.mspid); + + let skipPersistence = false; + if (!client.getStateStore()) { + skipPersistence = true; + } + await client.setUserContext(member, skipPersistence); + return member; + } catch (err) { + logError('Failed to enroll and persist user. Error: ' + (err.stack ? err.stack : err)); + return Promise.reject(err); + } +} + +/** + * Retrieve the admin identity for the given organization. + * @param {Client} client The Fabric client object. + * @param {string} userOrg The name of the user's organization. + * @param {CommonConnectionProfile} ccp the common connection profile + * @return {User} The admin user identity. + */ +function getOrgAdmin(client, userOrg, ccp) { + try { + + const org = ccp.getOrganization(userOrg); + if(!org) { + throw new Error('Could not find ' + userOrg + ' in configuration'); + } + + const keyPEM = fs.readFileSync(org.adminPrivateKeyPEM.path); + const certPEM = fs.readFileSync(org.signedCertPEM.path); + + const cryptoSuite = Client.newCryptoSuite(); + cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({path: module.exports.storePathForOrg(userOrg)})); + client.setCryptoSuite(cryptoSuite); + + return Promise.resolve(client.createUser({ + username: 'peer'+userOrg+'Admin', + mspid: org.mspid, + cryptoContent: { + privateKeyPEM: keyPEM.toString(), + signedCertPEM: certPEM.toString() + } + })); + } + catch(err) { + return Promise.reject(err); + } +} + +/** + * Retrieve the admin identity of the orderer service organization. + * @param {Client} client The Fabric client object. + * @param {CommonConnectionProfile} ccp the common connection profile + * @return {User} The retrieved orderer admin identity. + */ +function getOrdererAdmin(client, ordererName, ccp) { + try { + const orderer = ccp.getOrderer(ordererName); + const keyPEM = fs.readFileSync(orderer.adminPrivateKeyPEM.path); + const certPEM = fs.readFileSync(orderer.signedCertPEM.path); + + return Promise.resolve(client.createUser({ + username: 'ordererAdmin', + mspid: orderer.mspid, + cryptoContent: { + privateKeyPEM: keyPEM.toString(), + signedCertPEM: certPEM.toString() + } + })); + } + catch(err) { + return Promise.reject(err); + } +} + +function getSubmitter(client, peerAdmin, org, ccp) { + if (peerAdmin) { + return getOrgAdmin(client, org, ccp); + } else { + return getMember('admin', 'adminpw', client, org, ccp); + } +} + +/** + * Enrol and get the cert + * @param {*} fabricCAEndpoint url of org endpoint + * @param {*} caName name of caName + * @return {Object} something useful in a promise + */ +async function tlsEnroll(fabricCAEndpoint, caName) { + const tlsOptions = { + trustedRoots: [], + verify: false + }; + const caService = new FabricCAServices(fabricCAEndpoint, tlsOptions, caName); + const req = { + enrollmentID: 'admin', + enrollmentSecret: 'adminpw', + profile: 'tls' + }; + + const enrollment = await caService.enroll(req); + enrollment.key = enrollment.key.toBytes(); + return enrollment; +} + + +function logMsg(msg, obj){ + if (obj){ + // eslint-disable-next-line no-console + console.log(msg, obj); + } else { + // eslint-disable-next-line no-console + console.log(msg); + } +} + +function logError(msg, obj){ + if (obj){ + // eslint-disable-next-line no-console + console.error(msg, obj); + } else { + // eslint-disable-next-line no-console + console.error(msg); + } +} + +module.exports.TIMEOUTS = TIMEOUTS; +module.exports.storePathForOrg = storePathForOrg; +module.exports.sleep = sleep; +module.exports.runShellCommand = runShellCommand; +module.exports.getOrdererAdmin = getOrdererAdmin; +module.exports.getSubmitter = getSubmitter; +module.exports.tlsEnroll = tlsEnroll; +module.exports.logMsg = logMsg; +module.exports.logError = logError; diff --git a/test/scenario/features/network_api.feature b/test/scenario/features/network_api.feature new file mode 100644 index 0000000000..63f735d88b --- /dev/null +++ b/test/scenario/features/network_api.feature @@ -0,0 +1,20 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +@networkAPI +@clean-gateway +Feature: Configure Fabric using SDK and submit/evaluate using a network Gateway + + Background: + Given I have forcibly taken down all docker containers + And I have disconnected from all gateways + + Scenario: Using a Gateway I can submit and evaluate transactions on instantiated chaincode + Given I have deployed a tls Fabric network + Then I can create and join all channels from the tls common connection profile + And I can install/instantiate node chaincode at version 1.0.0 named marbles to the tls Fabric network for all organizations on channel mychannel with endorsement policy 1AdminOr2Other and args [init,a,1000,b,2000] + And I can create a gateway named test_gateway as user User1 within Org1 using the tls common connection profile + And I use the gateway named test_gateway to submit a transaction with args [initMarble,marble1,blue,35,tom] for chaincode marbles instantiated on channel mychannel + And I use the gateway named test_gateway to evaluate transaction with args [readMarble,marble1] for chaincode marbles instantiated on channel mychannel with the response matching {"color":"blue","docType":"marble","name":"marble1","owner":"tom","size":35} + And I can disconnect from the gateway named test_gateway diff --git a/test/scenario/features/steps/admin_steps.js b/test/scenario/features/steps/admin_steps.js new file mode 100644 index 0000000000..9fe0e9e816 --- /dev/null +++ b/test/scenario/features/steps/admin_steps.js @@ -0,0 +1,246 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const channel_util = require('../lib/channel'); +const chaincode_util = require('../lib/chaincode'); +const CCP = require('../lib/common_connection'); +const testUtil = require('../lib/utils'); + +const path = require('path'); + +const configRoot = '../../config'; +const ccpPath = '../../config/ccp.json'; +const tlsCcpPath = '../../config/ccp-tls.json'; +const policiesPath = '../../config/policies.json'; + +module.exports = function () { + + this.Then(/^I can create a channels from the (.+?) common connection profile$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (tlsType) => { + if (tlsType.localeCompare('non-tls') == 0) { + const profile = new CCP(path.join(__dirname, ccpPath), true); + return channel_util.create_channels(path.join(__dirname, configRoot), profile, false); + } else { + const profile = new CCP(path.join(__dirname, tlsCcpPath), true); + return channel_util.create_channels(path.join(__dirname, configRoot), profile, true); + } + }); + + this.Then(/^I can join organization (.+?) to the (.+?) enabled channel named (.+?)$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (orgName, tlsType, channelName) => { + if (tlsType.localeCompare('non-tls') == 0) { + const profile = new CCP(path.join(__dirname, ccpPath), true); + return channel_util.join_channel(profile, false, channelName, orgName); + } else { + const profile = new CCP(path.join(__dirname, tlsCcpPath), true); + return channel_util.join_channel(profile, true, channelName, orgName); + } + }); + + this.Then(/^I can create and join all channels from the (.+?) common connection profile$/, {timeout: testUtil.TIMEOUTS.MED_STEP}, async (tlsType) => { + let tls; + let profile; + + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + + await channel_util.create_channels(path.join(__dirname, configRoot), profile, tls); + + const channels = profile.getChannels(); + try { + for (const channelName in channels){ + const channel = profile.getChannel(channelName); + const orgs = profile.getOrganizations(); + for (const orgName in orgs){ + const org = profile.getOrganization(orgName); + const orgPeers = org.peers; + if (Object.keys(channel.peers).some((peerName)=> orgPeers.includes(peerName))) { + await channel_util.join_channel(profile, tls, channelName, orgName); + } + } + } + return Promise.resolve(); + } catch (err) { + return Promise.reject(err); + } + }); + + this.Then(/^I can install (.+?) chaincode at version (.+?) named (.+?) to the (.+?) Fabric network as organization (.+?) on channel (.+?)$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (ccType, version, ccName, tlsType, orgName, channelName) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + return chaincode_util.installChaincode(ccName, ccName, ccType, version, tls, profile, orgName, channelName); + }); + + this.Then(/^I can install (.+?) chaincode at version (.+?) named (.+?) as (.+?) to the (.+?) Fabric network as organization (.+?) on channel (.+?)$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (ccType, version, ccName, ccId, tlsType, orgName, channelName) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + return chaincode_util.installChaincode(ccName, ccId, ccType, version, tls, profile, orgName, channelName); + }); + + this.Then(/^I can install (.+?) chaincode named (.+?) to the (.+?) Fabric network$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (ccType, ccName, tlsType) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + + // use first org in ccp + const orgName = profile.getOrganizations()[0]; + + // use first channel in ccp + const channelName = profile.getChannels()[0]; + + // fixed version + const version = '1.0.0'; + + return chaincode_util.installChaincode(ccName, ccName, ccType, version, tls, profile, orgName, channelName); + }); + + this.Then(/^I can install (.+?) chaincode named (.+?) as (.+?) to the (.+?) Fabric network$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (ccType, ccName, ccId, tlsType) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + + // use first org in ccp + const orgName = profile.getOrganizations()[0]; + + // use first channel in ccp + const channelName = profile.getChannels()[0]; + + // fixed version + const version = '1.0.0'; + + return chaincode_util.installChaincode(ccName, ccId, ccType, version, tls, profile, orgName, channelName); + }); + + this.Then(/^I can instantiate the (.+?) installed (.+?) chaincode at version (.+?) named (.+?) on the (.+?) Fabric network as organization (.+?) on channel (.+?) with endorsement policy (.+?) and args (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (exisiting, ccType, version, ccName, tlsType, orgName, channelName, policyType, args) => { + let profile; + let tls; + let upgrade; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + + if (exisiting.localeCompare('newly') == 0) { + upgrade = false; + } else { + upgrade = true; + } + + const policy = require(path.join(__dirname, policiesPath))[policyType]; + return chaincode_util.instantiateChaincode(ccName, ccName, ccType, args, version, upgrade, tls, profile, orgName, channelName, policy); + }); + + this.Then(/^I can instantiate the (.+?) installed (.+?) chaincode at version (.+?) named (.+?) with identifier (.+?) on the (.+?) Fabric network as organization (.+?) on channel (.+?) with endorsement policy (.+?) and args (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (exisiting, ccType, version, ccName, ccId, tlsType, orgName, channelName, policyType, args) => { + let profile; + let tls; + let upgrade; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + + if (exisiting.localeCompare('newly') == 0) { + upgrade = false; + } else { + upgrade = true; + } + + const policy = require(path.join(__dirname, policiesPath))[policyType]; + return chaincode_util.instantiateChaincode(ccName, ccId, ccType, args, version, upgrade, tls, profile, orgName, channelName, policy); + }); + + this.Then(/^I can install\/instantiate (.+?) chaincode at version (.+?) named (.+?) to the (.+?) Fabric network for all organizations on channel (.+?) with endorsement policy (.+?) and args (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (ccType, version, ccName, tlsType, channelName, policyType, args) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + const policy = require(path.join(__dirname, policiesPath))[policyType]; + + const orgs = profile.getOrganizationsForChannel(channelName); + + try { + for (const org in orgs) { + const orgName = orgs[org]; + await chaincode_util.installChaincode(ccName, ccName, ccType, version, tls, profile, orgName, channelName); + } + + return chaincode_util.instantiateChaincode(ccName, ccName, ccType, args, version, false, tls, profile, orgs[0], channelName, policy); + } catch (err) { + testUtil.logError('Install/Instantiate failed with error: ', err); + throw err; + } + + }); + + this.Then(/^I can install\/instantiate (.+?) chaincode at version (.+?) named (.+?) to the (.+?) Fabric network for all organizations on channel (.+?) as (.+?) with endorsement policy (.+?) and args (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (ccType, version, ccName, tlsType, channelName, ccId, policyType, args) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + const policy = require(path.join(__dirname, policiesPath))[policyType]; + + const orgs = profile.getOrganizationsForChannel(channelName); + + try { + for (const org in orgs) { + const orgName = orgs[org]; + await chaincode_util.installChaincode(ccName, ccId, ccType, version, tls, profile, orgName, channelName); + } + + return chaincode_util.instantiateChaincode(ccName, ccId, ccType, args, version, false, tls, profile, orgs[0], channelName, policy); + } catch (err) { + testUtil.logError('Install/Instantiate failed with error: ', err); + throw err; + } + + }); + +}; diff --git a/test/scenario/features/steps/docker_steps.js b/test/scenario/features/steps/docker_steps.js new file mode 100644 index 0000000000..2bf865cc3c --- /dev/null +++ b/test/scenario/features/steps/docker_steps.js @@ -0,0 +1,34 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const testUtil = require('../lib/utils'); +const path = require('path'); + +module.exports = function () { + + this.Given(/^I have deployed a (.+?) Fabric network/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (type) => { + await testUtil.runShellCommand(undefined, 'docker kill $(docker ps -aq); docker rm $(docker ps -aq)'); + if (type.localeCompare('non-tls') === 0) { + await testUtil.runShellCommand(true, 'docker-compose -f ' + path.join(__dirname, '../../docker-compose/docker-compose.yaml') + ' -p cucumber up -d'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + } else { + await testUtil.runShellCommand(true, 'docker-compose -f ' + path.join(__dirname, '../../docker-compose/docker-compose-tls.yaml') + ' -p cucumber up -d'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + } + }); + + this.Given(/^I have forcibly taken down all docker containers/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async () => { + await testUtil.runShellCommand(undefined, 'docker kill $(docker ps -aq); docker rm $(docker ps -aq)'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + }); + + + this.Given(/^I have deleted all dev images/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async () => { + await testUtil.runShellCommand(undefined, 'docker rmi $(docker images dev-* -q)'); + return await testUtil.sleep(testUtil.TIMEOUTS.SHORT_INC); + }); + +}; diff --git a/test/scenario/features/steps/index.js b/test/scenario/features/steps/index.js new file mode 100644 index 0000000000..86511806c6 --- /dev/null +++ b/test/scenario/features/steps/index.js @@ -0,0 +1,16 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const dockersteps = require('./docker_steps'); +const adminsteps = require('./admin_steps'); +const networksteps = require('./network_steps'); + + +module.exports = function () { + adminsteps.call(this); + dockersteps.call(this); + networksteps.call(this); +}; diff --git a/test/scenario/features/steps/network_steps.js b/test/scenario/features/steps/network_steps.js new file mode 100644 index 0000000000..cc21941bbb --- /dev/null +++ b/test/scenario/features/steps/network_steps.js @@ -0,0 +1,53 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const network_util = require('../lib/network'); +const CCP = require('../lib/common_connection'); +const testUtil = require('../lib/utils'); + +const path = require('path'); + +const ccpPath = '../../config/ccp.json'; +const tlsCcpPath = '../../config/ccp-tls.json'; + +module.exports = function () { + this.Then(/^I can create a gateway named (.+?) as user (.+?) within (.+?) using the (.+?) common connection profile$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async (gatewayName, userName, orgName, tlsType) => { + let profile; + let tls; + if (tlsType.localeCompare('non-tls') == 0) { + tls = false; + profile = new CCP(path.join(__dirname, ccpPath), true); + } else { + tls = true; + profile = new CCP(path.join(__dirname, tlsCcpPath), true); + } + return network_util.connectGateway(profile, tls, userName, orgName, gatewayName); + }); + + this.Then(/^I use the gateway named (.+?) to submit a transaction with args (.+?) for chaincode (.+?) instantiated on channel (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (gatewayName, args, ccName, channelName) => { + return network_util.performGatewayTransaction(gatewayName, ccName, channelName, args, true); + }); + + this.Then(/^I use the gateway named (.+?) to evaluate transaction with args (.+?) for chaincode (.+?) instantiated on channel (.+?) with the response matching (.+?)$/, {timeout: testUtil.TIMEOUTS.LONG_STEP}, async (gatewayName, args, ccName, channelName, expected) => { + + const result = await network_util.performGatewayTransaction(gatewayName, ccName, channelName, args, false); + + if (result === expected) { + return Promise.resolve(); + } else { + throw new Error('Expected and actual results from evaluateTransaction() did not match'); + } + + }); + + this.Then(/^I can disconnect from the gateway named (.+?)$/, {timeout:testUtil.TIMEOUTS.SHORT_STEP}, async (gatewayName) => { + return await network_util.disconnectGateway(gatewayName); + }); + + this.Then(/^I have disconnected from all gateways$/, {timeout: testUtil.TIMEOUTS.SHORT_STEP}, async () => { + return await network_util.disconnectAllGateways(); + }); +}; diff --git a/test/scenario/features/support/hooks.js b/test/scenario/features/support/hooks.js new file mode 100644 index 0000000000..862b6a1f44 --- /dev/null +++ b/test/scenario/features/support/hooks.js @@ -0,0 +1,21 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const {After} = require('cucumber'); +const testUtils = require('../lib/utils'); +const network_utils = require('../lib/network'); + +After({tags: '@clean-images'}, async () => { + // Instantiation will result in docker images being generated, clean them up with this After hook by using the referenced tag + testUtils.logMsg('Removing dev images ...'); + await testUtils.runShellCommand(undefined, 'docker rmi $(docker images dev-* -q)'); +}); + +After({tags: '@clean-gateway'}, async () => { + // If a test fails without disconnecting gateways, then the tests will hang + testUtils.logMsg('Disconnecting from all gateways ...'); + await network_utils.disconnectAllGateways(); +}); diff --git a/test/scenario/features/support/index.js b/test/scenario/features/support/index.js new file mode 100644 index 0000000000..23c734c0df --- /dev/null +++ b/test/scenario/features/support/index.js @@ -0,0 +1,18 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const cucumber = require('cucumber'); +const sdkSteps = require('../steps'); + +module.exports = function () { + sdkSteps.call(this); +}; + +if (cucumber.defineSupportCode) { + cucumber.defineSupportCode((context) => { + module.exports.call(context); + }); +}