From d9f846d3b348d4c4448df225abf801346dc44ae3 Mon Sep 17 00:00:00 2001 From: Atsushin <atsushin@fast.au.fujitsu.com> Date: Tue, 26 Jan 2021 18:15:54 +1100 Subject: [PATCH] BE-852 Fix to get RWset for config TX synced correctly (#211) * BE-852 Fix to get RWset for config TX synced correctly Also added computation of ID for config TX Signed-off-by: Atsushi Neki <nekiaiken@gmail.com> * BE-852 Add unit test for SyncServices class Mainly added test cases for processBlockEvent method. Signed-off-by: Atsushi Neki <nekiaiken@gmail.com> --- app/platform/fabric/sync/SyncService.ts | 476 ++++++----- app/test/FabricGateway.test.ts | 4 +- app/test/SyncService.test.ts | 179 ++++ app/test/block.json | 167 ++++ app/test/block_config.json | 1040 +++++++++++++++++++++++ 5 files changed, 1645 insertions(+), 221 deletions(-) create mode 100644 app/test/SyncService.test.ts create mode 100644 app/test/block.json create mode 100644 app/test/block_config.json diff --git a/app/platform/fabric/sync/SyncService.ts b/app/platform/fabric/sync/SyncService.ts index e14a39211..b2414cf3e 100644 --- a/app/platform/fabric/sync/SyncService.ts +++ b/app/platform/fabric/sync/SyncService.ts @@ -5,6 +5,7 @@ import * as convertHex from 'convert-hex'; import fabprotos from 'fabric-protos'; import includes from 'lodash/includes'; +import * as sha from 'js-sha256'; import { helper } from '../../../common/helper'; import { ExplorerError } from '../../../common/ExplorerError'; @@ -16,8 +17,6 @@ const logger = helper.getLogger('SyncServices'); const fabric_const = FabricConst.fabric.const; -const blocksInProcess = []; - // Transaction validation code const _validation_codes = {}; for (const key in fabprotos.protos.TxValidationCode) { @@ -34,6 +33,7 @@ export class SyncServices { persistence: any; platform: any; synchInProcess: string[]; + blocksInProcess: string[]; /** * Creates an instance of SyncServices. @@ -45,6 +45,7 @@ export class SyncServices { this.platform = platform; this.persistence = persistence; this.synchInProcess = []; + this.blocksInProcess = []; } /** @@ -390,6 +391,50 @@ export class SyncServices { this.synchInProcess.splice(index, 1); } + async updateDiscoveredChannel(client, channel_name, channel_genesis_hash) { + const network_id = client.getNetworkId(); + // get discovery and insert new peer, orders details to db + await client.initializeChannelFromDiscover(channel_name); + await this.insertFromDiscoveryResults( + client, + channel_name, + channel_genesis_hash + ); + const notify = { + notify_type: fabric_const.NOTITY_TYPE_UPDATECHANNEL, + network_id, + channel_name + }; + + this.platform.send(notify); + } + + async insertDiscoveredChannel(client, channel_name, block) { + const network_id = client.getNetworkId(); + await client.initializeNewChannel(channel_name); + const channel_genesis_hash = client.getChannelGenHash(channel_name); + // inserting new channel details to DB + await this.insertNewChannel( + client, + channel_name, + block, + channel_genesis_hash + ); + await this.insertFromDiscoveryResults( + client, + channel_name, + channel_genesis_hash + ); + + const notify = { + notify_type: fabric_const.NOTITY_TYPE_NEWCHANNEL, + network_id, + channel_name + }; + + this.platform.send(notify); + } + /** * * @@ -407,53 +452,34 @@ export class SyncServices { const channel_name = header.channel_header.channel_id; const blockPro_key = `${channel_name}_${block.header.number.toString()}`; - if (blocksInProcess.includes(blockPro_key)) { - return 'Block already in processing'; - } - blocksInProcess.push(blockPro_key); - logger.debug('New Block >>>>>>> %j', block.header.number); - let channel_genesis_hash = client.getChannelGenHash(channel_name); + const channel_genesis_hash = client.getChannelGenHash(channel_name); // Checking block is channel CONFIG block /* eslint-disable */ if (!channel_genesis_hash) { // get discovery and insert channel details to db and create new channel object in client context setTimeout( async (cli, chName, blk) => { - await cli.initializeNewChannel(chName); - channel_genesis_hash = cli.getChannelGenHash(chName); - // inserting new channel details to DB - await this.insertNewChannel(cli, chName, blk, channel_genesis_hash); - await this.insertFromDiscoveryResults(cli, chName, channel_genesis_hash); - - const notify = { - notify_type: fabric_const.NOTITY_TYPE_NEWCHANNEL, - network_id, - channel_name: chName - }; - - this.platform.send(notify); + await this.insertDiscoveredChannel(cli, chName, blk); }, 10000, client, channel_name, block ); - } else if ( - header.channel_header.typeString === fabric_const.BLOCK_TYPE_CONFIG - ) { + logger.warn('Insert discovered new channel', channel_name); + throw new ExplorerError(`${channel_name} has not been inserted yet`); + } + + if (this.blocksInProcess.includes(blockPro_key)) { + throw new ExplorerError('Block already in processing'); + } + this.blocksInProcess.push(blockPro_key); + + if (header.channel_header.typeString === fabric_const.BLOCK_TYPE_CONFIG) { setTimeout( async (cli, chName, chGenHash) => { - // get discovery and insert new peer, orders details to db - await cli.initializeChannelFromDiscover(chName); - await this.insertFromDiscoveryResults(cli, chName, chGenHash); - const notify = { - notify_type: fabric_const.NOTITY_TYPE_UPDATECHANNEL, - network_id, - channel_name: chName - }; - - this.platform.send(notify); + await this.updateDiscoveredChannel(cli, chName, chGenHash); }, 10000, client, @@ -461,208 +487,218 @@ export class SyncServices { channel_genesis_hash ); } - /* eslint-enable */ + const createdt = await FabricUtils.getBlockTimeStamp( header.channel_header.timestamp ); const blockhash = await FabricUtils.generateBlockHash(block.header); - if (channel_genesis_hash) { - const block_row = { - blocknum: block.header.number.toString(), - datahash: block.header.data_hash.toString('hex'), - prehash: block.header.previous_hash.toString('hex'), - txcount: block.data.data.length, - createdt, - prev_blockhash: '', - blockhash, - channel_genesis_hash, - blksize: jsonObjSize(block) - }; - const txLen = block.data.data.length; - for (let txIndex = 0; txIndex < txLen; txIndex++) { - const txObj = block.data.data[txIndex]; - const txid = txObj.payload.header.channel_header.tx_id; - let validation_code = ''; - let endorser_signature = ''; - let payload_proposal_hash = ''; - let endorser_id_bytes = ''; - let chaincode_proposal_input = ''; - let chaincode = ''; - let rwset; - let readSet; - let writeSet; - let chaincodeID; - let status; - let mspId = []; - this.convertFormatOfValue( - 'value', - client.fabricGateway.fabricConfig.getRWSetEncoding(), - txObj + const block_row = { + blocknum: block.header.number.toString(), + datahash: block.header.data_hash.toString('hex'), + prehash: block.header.previous_hash.toString('hex'), + txcount: block.data.data.length, + createdt, + prev_blockhash: '', + blockhash, + channel_genesis_hash, + blksize: jsonObjSize(block) + }; + const txLen = block.data.data.length; + for (let txIndex = 0; txIndex < txLen; txIndex++) { + const txObj = block.data.data[txIndex]; + const txStr = JSON.stringify(txObj); + const size = Buffer.byteLength(txStr); + let txid = txObj.payload.header.channel_header.tx_id; + + let validation_code = ''; + let endorser_signature = ''; + let payload_proposal_hash = ''; + let endorser_id_bytes = ''; + let chaincode_proposal_input = ''; + let chaincode = ''; + let rwset; + let readSet; + let writeSet; + let chaincodeID; + let status; + let mspId = []; + + this.convertFormatOfValue( + 'value', + client.fabricGateway.fabricConfig.getRWSetEncoding(), + txObj + ); + if (txid && txid !== '') { + const validation_codes = + block.metadata.metadata[ + fabprotos.common.BlockMetadataIndex.TRANSACTIONS_FILTER + ]; + const val_code = validation_codes[txIndex]; + validation_code = convertValidationCode(val_code); + } + let envelope_signature = txObj.signature; + if (envelope_signature !== undefined) { + envelope_signature = convertHex.bytesToHex(envelope_signature); + } + let payload_extension = txObj.payload.header.channel_header.extension; + if (payload_extension !== undefined) { + payload_extension = convertHex.bytesToHex(payload_extension); + } + let creator_nonce = txObj.payload.header.signature_header.nonce; + if (creator_nonce !== undefined) { + creator_nonce = convertHex.bytesToHex(creator_nonce); + } + /* eslint-disable */ + const creator_id_bytes = + txObj.payload.header.signature_header.creator.id_bytes; + if (txObj.payload.data.actions !== undefined) { + chaincode = + txObj.payload.data.actions[0].payload.action.proposal_response_payload + .extension.chaincode_id.name; + chaincodeID = new Uint8Array( + txObj.payload.data.actions[0].payload.action.proposal_response_payload.extension ); - if (txid && txid !== '') { - const validation_codes = - block.metadata.metadata[ - fabprotos.common.BlockMetadataIndex.TRANSACTIONS_FILTER - ]; - const val_code = validation_codes[txIndex]; - validation_code = convertValidationCode(val_code); - } - let envelope_signature = txObj.signature; - if (envelope_signature !== undefined) { - envelope_signature = convertHex.bytesToHex(envelope_signature); - } - let payload_extension = txObj.payload.header.channel_header.extension; - if (payload_extension !== undefined) { - payload_extension = convertHex.bytesToHex(payload_extension); - } - let creator_nonce = txObj.payload.header.signature_header.nonce; - if (creator_nonce !== undefined) { - creator_nonce = convertHex.bytesToHex(creator_nonce); - } - /* eslint-disable */ - const creator_id_bytes = - txObj.payload.header.signature_header.creator.id_bytes; - if (txObj.payload.data.actions !== undefined) { - chaincode = - txObj.payload.data.actions[0].payload.action.proposal_response_payload - .extension.chaincode_id.name; - chaincodeID = new Uint8Array( - txObj.payload.data.actions[0].payload.action.proposal_response_payload.extension - ); - status = - txObj.payload.data.actions[0].payload.action.proposal_response_payload - .extension.response.status; - mspId = txObj.payload.data.actions[0].payload.action.endorsements.map( - endorsement => endorsement.endorser.mspid - ); - rwset = - txObj.payload.data.actions[0].payload.action.proposal_response_payload - .extension.results.ns_rwset; - readSet = rwset.map(rw => ({ - chaincode: rw.namespace, - set: rw.rwset.reads - })); - writeSet = rwset.map(rw => ({ - chaincode: rw.namespace, - set: rw.rwset.writes - })); - chaincode_proposal_input = - txObj.payload.data.actions[0].payload.chaincode_proposal_payload.input - .chaincode_spec.input.args; - if (chaincode_proposal_input !== undefined) { - let inputs = ''; - for (const input of chaincode_proposal_input) { - inputs = - (inputs === '' ? inputs : `${inputs},`) + convertHex.bytesToHex(input); - } - chaincode_proposal_input = inputs; - } - endorser_signature = - txObj.payload.data.actions[0].payload.action.endorsements[0].signature; - if (endorser_signature !== undefined) { - endorser_signature = convertHex.bytesToHex(endorser_signature); + status = + txObj.payload.data.actions[0].payload.action.proposal_response_payload + .extension.response.status; + mspId = txObj.payload.data.actions[0].payload.action.endorsements.map( + endorsement => endorsement.endorser.mspid + ); + rwset = + txObj.payload.data.actions[0].payload.action.proposal_response_payload + .extension.results.ns_rwset; + readSet = rwset.map(rw => ({ + chaincode: rw.namespace, + set: rw.rwset.reads + })); + writeSet = rwset.map(rw => ({ + chaincode: rw.namespace, + set: rw.rwset.writes + })); + chaincode_proposal_input = + txObj.payload.data.actions[0].payload.chaincode_proposal_payload.input + .chaincode_spec.input.args; + if (chaincode_proposal_input !== undefined) { + let inputs = ''; + for (const input of chaincode_proposal_input) { + inputs = + (inputs === '' ? inputs : `${inputs},`) + convertHex.bytesToHex(input); } - payload_proposal_hash = txObj.payload.data.actions[0].payload.action.proposal_response_payload.proposal_hash.toString( - 'hex' - ); - endorser_id_bytes = - txObj.payload.data.actions[0].payload.action.endorsements[0].endorser - .IdBytes; + chaincode_proposal_input = inputs; } - - const read_set = JSON.stringify(readSet, null, 2); - const write_set = JSON.stringify(writeSet, null, 2); - - const chaincode_id = String.fromCharCode.apply(null, chaincodeID); - // checking new chaincode is deployed - if ( - header.channel_header.typeString === - fabric_const.BLOCK_TYPE_ENDORSER_TRANSACTION && - chaincode === fabric_const.CHAINCODE_LSCC - ) { - setTimeout( - async (cli, chName, chGenHash) => { - // get discovery and insert chaincode details to db - await this.insertFromDiscoveryResults(cli, chName, chGenHash); - - const notify = { - notify_type: fabric_const.NOTITY_TYPE_CHAINCODE, - network_id, - channel_name: chName - }; - - this.platform.send(notify); - }, - 10000, - client, - channel_name, - channel_genesis_hash - ); + endorser_signature = + txObj.payload.data.actions[0].payload.action.endorsements[0].signature; + if (endorser_signature !== undefined) { + endorser_signature = convertHex.bytesToHex(endorser_signature); } - /* eslint-enable */ - const transaction_row = { - blockid: block.header.number.toString(), - txhash: txObj.payload.header.channel_header.tx_id, - createdt: txObj.payload.header.channel_header.timestamp, - chaincodename: chaincode, - chaincode_id, - status, - creator_msp_id: txObj.payload.header.signature_header.creator.mspid, - endorser_msp_id: mspId, - type: txObj.payload.header.channel_header.typeString, - read_set, - write_set, - channel_genesis_hash, - validation_code, - envelope_signature, - payload_extension, - creator_nonce, - chaincode_proposal_input, - endorser_signature, - creator_id_bytes, - payload_proposal_hash, - endorser_id_bytes - }; + payload_proposal_hash = txObj.payload.data.actions[0].payload.action.proposal_response_payload.proposal_hash.toString( + 'hex' + ); + endorser_id_bytes = + txObj.payload.data.actions[0].payload.action.endorsements[0].endorser + .IdBytes; + } - // Insert transaction + if (txObj.payload.header.channel_header.typeString === 'CONFIG') { + txid = sha.sha256(txStr); + readSet = + txObj.payload.data.last_update.payload.data.config_update.read_set; + writeSet = + txObj.payload.data.last_update.payload.data.config_update.write_set; + } - const res = await this.persistence - .getCrudService() - .saveTransaction(network_id, transaction_row); - logger.debug('saveTransaction ', res); + const read_set = JSON.stringify(readSet, null, 2); + const write_set = JSON.stringify(writeSet, null, 2); + + const chaincode_id = String.fromCharCode.apply(null, chaincodeID); + // checking new chaincode is deployed + if ( + header.channel_header.typeString === + fabric_const.BLOCK_TYPE_ENDORSER_TRANSACTION && + chaincode === fabric_const.CHAINCODE_LSCC + ) { + setTimeout( + async (cli, chName, chGenHash) => { + // get discovery and insert chaincode details to db + await this.insertFromDiscoveryResults(cli, chName, chGenHash); + + const notify = { + notify_type: fabric_const.NOTITY_TYPE_CHAINCODE, + network_id, + channel_name: chName + }; + + this.platform.send(notify); + }, + 10000, + client, + channel_name, + channel_genesis_hash + ); } + /* eslint-enable */ + const transaction_row = { + blockid: block.header.number.toString(), + txhash: txid, + createdt: txObj.payload.header.channel_header.timestamp, + chaincodename: chaincode, + chaincode_id, + status, + creator_msp_id: txObj.payload.header.signature_header.creator.mspid, + endorser_msp_id: mspId, + type: txObj.payload.header.channel_header.typeString, + read_set, + write_set, + channel_genesis_hash, + validation_code, + envelope_signature, + payload_extension, + creator_nonce, + chaincode_proposal_input, + endorser_signature, + creator_id_bytes, + payload_proposal_hash, + endorser_id_bytes + }; + + // Insert transaction - // Insert block - logger.info('block_row.blocknum ', block_row.blocknum); - const successSaveBlock = await this.persistence + const res = await this.persistence .getCrudService() - .saveBlock(network_id, block_row); - logger.debug('result of SaveBlock ', successSaveBlock); + .saveTransaction(network_id, transaction_row); + logger.debug('saveTransaction ', res); + } - if (successSaveBlock) { - // Push last block - const notify = { - notify_type: fabric_const.NOTITY_TYPE_BLOCK, - network_id, - channel_name, - title: `Block ${block.header.number.toString()} added to Channel: ${channel_name}`, - type: 'block', - message: `Block ${block.header.number.toString()} established with ${ - block.data.data.length - } tx`, - time: createdt, - txcount: block.data.data.length, - datahash: block.header.data_hash.toString('hex'), - blksize: block_row.blksize - }; + // Insert block + logger.info('block_row.blocknum ', block_row.blocknum); + const successSaveBlock = await this.persistence + .getCrudService() + .saveBlock(network_id, block_row); + logger.debug('result of SaveBlock ', successSaveBlock); + + if (successSaveBlock) { + // Push last block + const notify = { + notify_type: fabric_const.NOTITY_TYPE_BLOCK, + network_id, + channel_name, + title: `Block ${block.header.number.toString()} added to Channel: ${channel_name}`, + type: 'block', + message: `Block ${block.header.number.toString()} established with ${ + block.data.data.length + } tx`, + time: createdt, + txcount: block.data.data.length, + datahash: block.header.data_hash.toString('hex'), + blksize: block_row.blksize + }; - this.platform.send(notify); - } - } else { - logger.error('Failed to process the block %j', block); + this.platform.send(notify); } - const index = blocksInProcess.indexOf(blockPro_key); - blocksInProcess.splice(index, 1); + + const index = this.blocksInProcess.indexOf(blockPro_key); + this.blocksInProcess.splice(index, 1); + return true; } convertFormatOfValue(prop, encoding, obj) { diff --git a/app/test/FabricGateway.test.ts b/app/test/FabricGateway.test.ts index 37315fbc2..fc3f31c26 100644 --- a/app/test/FabricGateway.test.ts +++ b/app/test/FabricGateway.test.ts @@ -19,6 +19,7 @@ const stubConnect = sinon.stub(); // logger const stubError = sinon.stub(); +const stubWarn = sinon.stub(); const stubInfo = sinon.stub(); // Client @@ -56,6 +57,7 @@ function getFabricGatewayInstance() { getLogger: function() { return { error: stubError, + warn: stubWarn, info: stubInfo }; } @@ -180,7 +182,7 @@ describe('sendDiscoveryRequest', () => { it('should throw error when failed to call getDiscoveryResults()', async () => { stubGetDiscoveryResults.throws(); await gw.sendDiscoveryRequest(); - expect(stubError.called).be.equal(true); + expect(stubWarn.called).be.equal(true); expect(stubClose.calledOnce).be.equal(true); }); }); diff --git a/app/test/SyncService.test.ts b/app/test/SyncService.test.ts new file mode 100644 index 000000000..5923d31d2 --- /dev/null +++ b/app/test/SyncService.test.ts @@ -0,0 +1,179 @@ +/* + *SPDX-License-Identifier: Apache-2.0 + */ + +import { expect } from './expect'; +import { FabricConfig } from '../platform/fabric/FabricConfig'; + +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; +import { SyncServices } from '../platform/fabric/sync/SyncService'; +import * as stubBlock from './block.json'; +import * as stubConfigBlock from './block_config.json'; + +import { ExplorerError } from '../common/ExplorerError'; +import * as FabricConst from '../platform/fabric/utils/FabricConst'; +const fabric_const = FabricConst.fabric.const; + +// logger +const stubError = sinon.stub(); +const stubInfo = sinon.stub(); +const stubDebug = sinon.stub(); + +const VALID_GENESIS_HASH = '8A+HyzS4sqZynD06BfNW7T1Vtv2SOXAOUJQK4itulus='; +const VALID_NETWORK_ID = 'test-network-id'; + +const stubPlatform = { + send: sinon.spy() +}; +const spySaveTransaction = sinon.spy(); +const stubGetChannelGenHash = sinon.stub(); + +function getSyncServicesInstance() { + const { SyncServices } = proxyquire + .noCallThru() + .load('../platform/fabric/sync/SyncService', { + 'convert-hex': { + bytesToHex: sinon.stub() + }, + '../../../common/helper': { + helper: { + getLogger: function() { + return { + error: stubError, + info: stubInfo, + debug: stubDebug, + warn: sinon.stub() + }; + } + } + } + }); + const config = new FabricConfig(); + config.initialize('first-network', { + name: 'My first network', + profile: './connection-profile/first-network.json' + }); + sinon.stub(config, 'getPeerTlsCACertsPem'); + const stubGetCrudService = sinon.stub(); + stubGetCrudService.returns({ + saveBlock: sinon.stub().resolves(true), + saveTransaction: spySaveTransaction + }); + const stubPersistence = { + getCrudService: stubGetCrudService + }; + const sync = new SyncServices(stubPlatform, stubPersistence); + + return sync; +} + +function resetAllStubs(sync) { + // logger + stubError.reset(); + stubInfo.reset(); + + sync.blocksInProcess = []; + stubGetChannelGenHash.reset(); + stubPlatform.send.resetHistory(); + spySaveTransaction.resetHistory(); +} + +function setupClient() { + const stubGetNetworkID = sinon.stub(); + stubGetNetworkID.returns(VALID_NETWORK_ID); + stubGetChannelGenHash.returns(VALID_GENESIS_HASH); + const stubClient = { + getNetworkId: stubGetNetworkID, + getChannelGenHash: stubGetChannelGenHash, + initializeNewChannel: sinon.stub().resolves(true), + fabricGateway: { + fabricConfig: { + getRWSetEncoding: sinon.stub() + } + } + }; + return stubClient; +} + +describe('processBlockEvent', () => { + let sync: SyncServices; + + before(() => { + sync = getSyncServicesInstance(); + }); + + beforeEach(() => { + resetAllStubs(sync); + }); + + it('should return without error', async () => { + const stubClient = setupClient(); + + await expect(sync.processBlockEvent(stubClient, stubBlock)).eventually.to.be + .true; + sinon.assert.calledOnce(stubPlatform.send); + sinon.assert.calledWith( + stubPlatform.send, + sinon.match({ notify_type: fabric_const.NOTITY_TYPE_BLOCK }) + ); + expect(sync.blocksInProcess.length).equals(0); + }); + + it('should throw an error if it has already been in proces', async () => { + const stubClient = setupClient(); + sync.blocksInProcess = ['mychannel_9']; + + await expect(sync.processBlockEvent(stubClient, stubBlock)) + .to.eventually.be.rejectedWith('Block already in processing') + .and.be.an.instanceOf(ExplorerError); + sinon.assert.notCalled(stubPlatform.send); + expect(sync.blocksInProcess.length).equals(1); + }); + + it('should raise new channel notification if genesis has not already been stored yet', async () => { + const stubClient = setupClient(); + + stubGetChannelGenHash.onFirstCall().returns(null); + stubGetChannelGenHash.onSecondCall().returns(VALID_GENESIS_HASH); + stubClient.getChannelGenHash = stubGetChannelGenHash; + const spyInsertDiscoveredCH = sinon.spy(sync, 'insertDiscoveredChannel'); + + const clock = sinon.useFakeTimers(); + await expect(sync.processBlockEvent(stubClient, stubBlock)) + .to.eventually.be.rejectedWith('mychannel has not been inserted yet') + .and.be.an.instanceOf(ExplorerError); + clock.tick(20000); + + sinon.assert.calledOnce(spyInsertDiscoveredCH); + expect(sync.blocksInProcess.length).equals(0); + clock.restore(); + }); + + it('should raise update channel notification if config block is processed', async () => { + const stubClient = setupClient(); + + const spyUpdateDiscoveredCH = sinon.spy(sync, 'updateDiscoveredChannel'); + + const clock = sinon.useFakeTimers(); + await expect(sync.processBlockEvent(stubClient, stubConfigBlock)).to + .eventually.to.be.true; + clock.tick(20000); + + sinon.assert.calledWith( + spySaveTransaction, + VALID_NETWORK_ID, + sinon.match(obj => { + return 'txhash' in obj && obj['txhash'] !== undefined; + }, 'txhash undefined') + ); + sinon.assert.calledOnce(spyUpdateDiscoveredCH); + expect(sync.blocksInProcess.length).equals(0); + sinon.assert.calledOnce(stubPlatform.send); + sinon.assert.calledWith( + stubPlatform.send, + sinon.match({ notify_type: fabric_const.NOTITY_TYPE_BLOCK }) + ); + clock.restore(); + }); +}); diff --git a/app/test/block.json b/app/test/block.json new file mode 100644 index 000000000..09259d38a --- /dev/null +++ b/app/test/block.json @@ -0,0 +1,167 @@ +{ + "data": { + "data": [ + { + "payload": { + "data": { + "actions": [ + { + "header": { + "creator": { + "id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWRDZ0F3SUJBZ0lSQU55dDRVVkhaRFRpSDhDb3lHNUtDVDh3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJd01USXhNREF3V2hjTk16RXdNVEU0TVRJeE1EQXcKV2pCck1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFT01Bd0dBMVVFQ3hNRllXUnRhVzR4SHpBZEJnTlZCQU1NRmtGa2JXbHVRRzl5Clp6RXVaWGhoYlhCc1pTNWpiMjB3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVF0ZUkxb043akoKajVnSTh5YUtlc0xjcXVBdDY1TWZuT2Q1c0x5SHhSZmhlMzhiZ2pVZzR2MUhGZnR3MG0wOWIrSzNOR296RGhtSAo1SzJSNDJNUTFVYUtvMDB3U3pBT0JnTlZIUThCQWY4RUJBTUNCNEF3REFZRFZSMFRBUUgvQkFJd0FEQXJCZ05WCkhTTUVKREFpZ0NBVlNZblQya2I3dDdPK2tHTHBjeW9mSW9yRXhObS9qVkxmRHBubXhKSVV0REFLQmdncWhrak8KUFFRREFnTkhBREJFQWlCbzgrbU04MUIxNG1FOG1JL2VzQ0QvQmVDRmt0bC92WUUwaWhqN1FFc0FsZ0lnSEhweQpERlFtdDhYUExtRGdIR0U0Szh2SE85aXNvRlROS1phS1ZsSHVBdVE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "mspid": "Org1MSP" + }, + "nonce": "7oL90IjpS7sU2e5GY5OkaOqOglyZmaVz" + }, + "payload": { + "action": { + "endorsements": [ + { + "endorser": "CgdPcmcyTVNQEqoGLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLRENDQWMrZ0F3SUJBZ0lSQU1aRUtwTDFwWnVZK2cwSFJPTnQ5UEl3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJd01USXhNREF3V2hjTk16RXdNVEU0TVRJeE1EQXcKV2pCcU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ3hNRWNHVmxjakVmTUIwR0ExVUVBeE1XY0dWbGNqQXViM0puCk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCT1JXb0dMQWFPRlkKZSttbk9rUThVdEpEZmYwZlRZTDRQMjR1SHhTNmNubG5oRTFVTVZKSVp4bmJlU0sxTCtpak4yRFQveUdtdi96SgorSEI2ZmlacjNYNmpUVEJMTUE0R0ExVWREd0VCL3dRRUF3SUhnREFNQmdOVkhSTUJBZjhFQWpBQU1Dc0dBMVVkCkl3UWtNQ0tBSUh1K3hDYjVlSUlzaWIzZVZtK1VIZGZPYTNvWEUrRCt3Z3VQb1QxaDVzL1NNQW9HQ0NxR1NNNDkKQkFNQ0EwY0FNRVFDSURrTXdZV29LVlZxNkZ6MjJFL3lCc0h3c0xOOXJVMTN5akpDb3F3VVRaK3lBaUFkYkdoVApVMnRmRHhjZlZkQW9vWkliNEhHcUR2cEZZT3p4UTBBU0hXOFlBQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "signature": "MEQCIF/+3/b6RUgoi46T1ErRZI7+2BPibURUEyxLEUcSGmQmAiA0wEAMw9gqgPsAOzFTHYKBRyKVe8iNbNEuo5B5auumew==" + }, + { + "endorser": "CgdPcmcxTVNQEqYGLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNKekNDQWM2Z0F3SUJBZ0lRSmhPK25kYlJmR3hHL3Z5SVVvdmpqVEFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpBeE1qRXdNREJhRncwek1UQXhNVGd4TWpFd01EQmEKTUdveEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFMRXdSd1pXVnlNUjh3SFFZRFZRUURFeFp3WldWeU1DNXZjbWN4CkxtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVDcUJ5RTdCTDUzNG4KQ3ljT29wTSt3bm5BeU9vZFZrUkRTTDJXT3dFRGhTKzhrb0cyOC9pN0t4ZnlKOUhaMnpRUjVKU3dLejlkZm11NApoM2dadGNNM2ZLTk5NRXN3RGdZRFZSMFBBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0t3WURWUjBqCkJDUXdJb0FnRlVtSjA5cEcrN2V6dnBCaTZYTXFIeUtLeE1UWnY0MVMzdzZaNXNTU0ZMUXdDZ1lJS29aSXpqMEUKQXdJRFJ3QXdSQUlnY0FWcjJrNnk5UVNVVnZtdnp3YUJRVEZuUkJJakVLNkVrSnFwbHdTbUd5Z0NJRFN2K0NxQQpRMjJ2M2M1TG84c0YzWkpkWk1mYmdIMzFyd092dXdYMkJYd0IKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "signature": "MEUCIQC/OOzEXMEltu0I7Sui9sZAQbTYcDocTUdC159NTrLYPgIgZpZW6zW8o+9TsoDDA0Djkl3nDGirnKDoE2Okk+86h1Q=" + } + ], + "proposal_response_payload": { + "extension": { + "chaincode_id": { + "name": "fabcar", + "path": "", + "version": "1" + }, + "events": null, + "response": { + "message": "", + "payload": null, + "status": 200 + }, + "results": { + "data_model": "KV", + "ns_rwset": [ + { + "collection_hashed_rwset": [], + "namespace": "_lifecycle", + "rwset": { + "metadata_writes": [], + "range_queries_info": [], + "reads": [ + { + "key": "namespaces/fields/fabcar/Sequence", + "version": { + "block_num": "5", + "tx_num": "0" + } + } + ], + "writes": [] + } + }, + { + "collection_hashed_rwset": [], + "namespace": "fabcar", + "rwset": { + "metadata_writes": [], + "range_queries_info": [], + "reads": [ + { + "key": "\u0000initialized", + "version": { + "block_num": "6", + "tx_num": "0" + } + }, + { + "key": "CAR9", + "version": { + "block_num": "8", + "tx_num": "0" + } + } + ], + "writes": [ + { + "is_delete": false, + "key": "CAR9", + "value": "eyJtYWtlIjoiSG9sZGVuIiwibW9kZWwiOiJCYXJpbmEiLCJjb2xvdXIiOiJicm93biIsIm93bmVyIjoiRGF2ZSJ9" + } + ] + } + } + ] + } + }, + "proposal_hash": "feHvqSfYsWqO2QjiZ8Q5NxoXWpT9x3ytXPBYk86Ery4=" + } + }, + "chaincode_proposal_payload": { + "TransientMap": {}, + "input": { + "chaincode_spec": { + "chaincode_id": { + "name": "fabcar", + "path": "", + "version": "" + }, + "input": { + "args": ["Y2hhbmdlQ2FyT3duZXI=", "Q0FSOQ==", "RGF2ZQ=="], + "decorations": {}, + "is_init": false + }, + "timeout": 0, + "type": "GOLANG" + } + } + } + } + } + ] + }, + "header": { + "channel_header": { + "channel_id": "mychannel", + "epoch": "0", + "extension": { + "chaincode_id": { + "name": "fabcar", + "path": "", + "version": "" + } + }, + "timestamp": "2021-01-20T12:24:51.121507600Z", + "tls_cert_hash": null, + "tx_id": "2f63b0cb5d0cf575073ec9247cfaf04ef42bfceb7723695cc5c14b3724b74a66", + "type": 3, + "typeString": "ENDORSER_TRANSACTION", + "version": 0 + }, + "signature_header": { + "creator": { + "id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWRDZ0F3SUJBZ0lSQU55dDRVVkhaRFRpSDhDb3lHNUtDVDh3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJd01USXhNREF3V2hjTk16RXdNVEU0TVRJeE1EQXcKV2pCck1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFT01Bd0dBMVVFQ3hNRllXUnRhVzR4SHpBZEJnTlZCQU1NRmtGa2JXbHVRRzl5Clp6RXVaWGhoYlhCc1pTNWpiMjB3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVF0ZUkxb043akoKajVnSTh5YUtlc0xjcXVBdDY1TWZuT2Q1c0x5SHhSZmhlMzhiZ2pVZzR2MUhGZnR3MG0wOWIrSzNOR296RGhtSAo1SzJSNDJNUTFVYUtvMDB3U3pBT0JnTlZIUThCQWY4RUJBTUNCNEF3REFZRFZSMFRBUUgvQkFJd0FEQXJCZ05WCkhTTUVKREFpZ0NBVlNZblQya2I3dDdPK2tHTHBjeW9mSW9yRXhObS9qVkxmRHBubXhKSVV0REFLQmdncWhrak8KUFFRREFnTkhBREJFQWlCbzgrbU04MUIxNG1FOG1JL2VzQ0QvQmVDRmt0bC92WUUwaWhqN1FFc0FsZ0lnSEhweQpERlFtdDhYUExtRGdIR0U0Szh2SE85aXNvRlROS1phS1ZsSHVBdVE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "mspid": "Org1MSP" + }, + "nonce": "7oL90IjpS7sU2e5GY5OkaOqOglyZmaVz" + } + } + }, + "signature": "MEQCIBEWArcB+ScAdRzIfia3xk76yHEK2VcmtLs7JWrHVg3NAiA9eXrPFnBMZVJEnBzFADtksGXF8gdefg0MYrYiwz6TZw==" + } + ] + }, + "header": { + "data_hash": "6bA3IrcPOOLsSTBDzt/nYQdJaXtCA2iVEAPz67rHvy8=", + "number": "9", + "previous_hash": "8A+HyzS4sqZynD06BfNW7T1Vtv2SOXAOUJQK4itulus=" + }, + "metadata": { + "metadata": [ + "Cg8KAggCEgkKBwoBARACGAsSkgcKxgYKqQYKCk9yZGVyZXJNU1ASmgYtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ0hqQ0NBY1dnQXdJQkFnSVJBT1F0Ym1TZ1B4a1lvbnQ2TllvejJ3Y3dDZ1lJS29aSXpqMEVBd0l3YVRFTApNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdUQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjVERWTmhiaUJHCmNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMyVjRZVzF3YkdVdVkyOXRNUmN3RlFZRFZRUURFdzVqWVM1bGVHRnQKY0d4bExtTnZiVEFlRncweU1UQXhNakF4TWpFd01EQmFGdzB6TVRBeE1UZ3hNakV3TURCYU1Hb3hDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSUV3cERZV3hwWm05eWJtbGhNUll3RkFZRFZRUUhFdzFUWVc0Z1JuSmhibU5wCmMyTnZNUkF3RGdZRFZRUUxFd2R2Y21SbGNtVnlNUnd3R2dZRFZRUURFeE52Y21SbGNtVnlMbVY0WVcxd2JHVXUKWTI5dE1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVhXa0tmNDBoQmtEdGdNdjNnbHRLcWdyTwp0b1FuTUxSRG5vTVNyVWRxcVhrcGg4Y0NzanEwK2pQRG9wMkl1TkVUYkNhUnc5QTJBbksyTDZwcmdRV3pLYU5OCk1Fc3dEZ1lEVlIwUEFRSC9CQVFEQWdlQU1Bd0dBMVVkRXdFQi93UUNNQUF3S3dZRFZSMGpCQ1F3SW9BZ3Z4WTIKbUlLMTRFZ1RmMXZwbGJjc0tJOWtDWElMMUpCdmNpNnc5NXM3Witnd0NnWUlLb1pJemowRUF3SURSd0F3UkFJZwpEZnJHQzZRdllKMlY4MUdRd2s0UmF3UFBvOW1RdHpIaVM1QzYzbmtlOGVjQ0lCRUhvSDVtWXNUR2dTeTdXOGNNClZ1OUQ0aXE3L2J2ZDE2ZjBldkIwZkZyWQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tChIYQPiYduHrlc19w0+Za5aq/Pq9SaoGRj4IEkcwRQIhANuCanTMTbBcVU6gNxyyJoGVfbPF0gvH1NhUpmNVQ7QpAiA1vSdj+vRg+OcG+lE3lR0y8zsTEVefb8mic+jtgYlUzA==", + "CgIIAg==", + "AA==", + "", + "CiBLNP9Ive7xg6/s6dYsQQUyCUfYpEjP704HKyVZqRnEGQ==" + ] + } +} diff --git a/app/test/block_config.json b/app/test/block_config.json new file mode 100644 index 000000000..eccfc24c7 --- /dev/null +++ b/app/test/block_config.json @@ -0,0 +1,1040 @@ +{ + "data": { + "data": [ + { + "payload": { + "data": { + "config": { + "channel_group": { + "groups": { + "Application": { + "groups": { + "Org1MSP": { + "groups": {}, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Endorsement": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "PEER" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "PEER" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "CLIENT" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + }, + { + "signed_by": 1 + }, + { + "signed_by": 2 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org1MSP", + "role": "CLIENT" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + }, + { + "signed_by": 1 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + } + }, + "values": { + "AnchorPeers": { + "mod_policy": "Admins", + "value": { + "anchor_peers": [ + { + "host": "peer0.org1.example.com", + "port": 7051 + } + ] + }, + "version": "0" + }, + "MSP": { + "mod_policy": "Admins", + "value": { + "config": { + "admins": [], + "crypto_config": { + "identity_identifier_hash_function": "SHA256", + "signature_hash_family": "SHA2" + }, + "fabric_node_ous": { + "admin_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZlZ0F3SUJBZ0lRVThHZjA1T2NKTkN2UUUvZWMrQitRakFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVJrd0Z3WURWUVFLRXhCdmNtY3hMbVY0WVcxd2JHVXVZMjl0TVJ3d0dnWURWUVFECkV4TmpZUzV2Y21jeExtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUKZmVCcjg5UVZTQUhqYllnQVB6R0lMcnFhYkN5V1I4bHdyQnNEK2N5MHNvZ2l5TitUSjBCK3J6Tm1NZzRxWnNiVApwVDFFcUppVUNkVnVnOWxEbzkwaDFhTnRNR3N3RGdZRFZSMFBBUUgvQkFRREFnR21NQjBHQTFVZEpRUVdNQlFHCkNDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Da0dBMVVkRGdRaUJDQm8KQ0tsTmlxTEo1NFBSUXVRakZBRGFpMGZMd2hsaE0za0xBVnYxQnlQTlp6QUtCZ2dxaGtqT1BRUURBZ05JQURCRgpBaUVBODU4cXhUeFVJTDNRVHd1VTNYeEcxTHFxMUcxMVVIR3hmS0FLM2krWGVLc0NJQWJUYUpqU0V1azBNMzFDClJubElKdHhkTm9xZVB4THdzbXlmMjE4dTF1WEoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "admin" + }, + "client_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZlZ0F3SUJBZ0lRVThHZjA1T2NKTkN2UUUvZWMrQitRakFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVJrd0Z3WURWUVFLRXhCdmNtY3hMbVY0WVcxd2JHVXVZMjl0TVJ3d0dnWURWUVFECkV4TmpZUzV2Y21jeExtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUKZmVCcjg5UVZTQUhqYllnQVB6R0lMcnFhYkN5V1I4bHdyQnNEK2N5MHNvZ2l5TitUSjBCK3J6Tm1NZzRxWnNiVApwVDFFcUppVUNkVnVnOWxEbzkwaDFhTnRNR3N3RGdZRFZSMFBBUUgvQkFRREFnR21NQjBHQTFVZEpRUVdNQlFHCkNDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Da0dBMVVkRGdRaUJDQm8KQ0tsTmlxTEo1NFBSUXVRakZBRGFpMGZMd2hsaE0za0xBVnYxQnlQTlp6QUtCZ2dxaGtqT1BRUURBZ05JQURCRgpBaUVBODU4cXhUeFVJTDNRVHd1VTNYeEcxTHFxMUcxMVVIR3hmS0FLM2krWGVLc0NJQWJUYUpqU0V1azBNMzFDClJubElKdHhkTm9xZVB4THdzbXlmMjE4dTF1WEoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "client" + }, + "enable": true, + "orderer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZlZ0F3SUJBZ0lRVThHZjA1T2NKTkN2UUUvZWMrQitRakFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVJrd0Z3WURWUVFLRXhCdmNtY3hMbVY0WVcxd2JHVXVZMjl0TVJ3d0dnWURWUVFECkV4TmpZUzV2Y21jeExtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUKZmVCcjg5UVZTQUhqYllnQVB6R0lMcnFhYkN5V1I4bHdyQnNEK2N5MHNvZ2l5TitUSjBCK3J6Tm1NZzRxWnNiVApwVDFFcUppVUNkVnVnOWxEbzkwaDFhTnRNR3N3RGdZRFZSMFBBUUgvQkFRREFnR21NQjBHQTFVZEpRUVdNQlFHCkNDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Da0dBMVVkRGdRaUJDQm8KQ0tsTmlxTEo1NFBSUXVRakZBRGFpMGZMd2hsaE0za0xBVnYxQnlQTlp6QUtCZ2dxaGtqT1BRUURBZ05JQURCRgpBaUVBODU4cXhUeFVJTDNRVHd1VTNYeEcxTHFxMUcxMVVIR3hmS0FLM2krWGVLc0NJQWJUYUpqU0V1azBNMzFDClJubElKdHhkTm9xZVB4THdzbXlmMjE4dTF1WEoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "orderer" + }, + "peer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZlZ0F3SUJBZ0lRVThHZjA1T2NKTkN2UUUvZWMrQitRakFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVJrd0Z3WURWUVFLRXhCdmNtY3hMbVY0WVcxd2JHVXVZMjl0TVJ3d0dnWURWUVFECkV4TmpZUzV2Y21jeExtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUKZmVCcjg5UVZTQUhqYllnQVB6R0lMcnFhYkN5V1I4bHdyQnNEK2N5MHNvZ2l5TitUSjBCK3J6Tm1NZzRxWnNiVApwVDFFcUppVUNkVnVnOWxEbzkwaDFhTnRNR3N3RGdZRFZSMFBBUUgvQkFRREFnR21NQjBHQTFVZEpRUVdNQlFHCkNDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Da0dBMVVkRGdRaUJDQm8KQ0tsTmlxTEo1NFBSUXVRakZBRGFpMGZMd2hsaE0za0xBVnYxQnlQTlp6QUtCZ2dxaGtqT1BRUURBZ05JQURCRgpBaUVBODU4cXhUeFVJTDNRVHd1VTNYeEcxTHFxMUcxMVVIR3hmS0FLM2krWGVLc0NJQWJUYUpqU0V1azBNMzFDClJubElKdHhkTm9xZVB4THdzbXlmMjE4dTF1WEoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "peer" + } + }, + "intermediate_certs": [], + "name": "Org1MSP", + "organizational_unit_identifiers": [], + "revocation_list": [], + "root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZlZ0F3SUJBZ0lRVThHZjA1T2NKTkN2UUUvZWMrQitRakFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NUzVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUhNeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVJrd0Z3WURWUVFLRXhCdmNtY3hMbVY0WVcxd2JHVXVZMjl0TVJ3d0dnWURWUVFECkV4TmpZUzV2Y21jeExtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUKZmVCcjg5UVZTQUhqYllnQVB6R0lMcnFhYkN5V1I4bHdyQnNEK2N5MHNvZ2l5TitUSjBCK3J6Tm1NZzRxWnNiVApwVDFFcUppVUNkVnVnOWxEbzkwaDFhTnRNR3N3RGdZRFZSMFBBUUgvQkFRREFnR21NQjBHQTFVZEpRUVdNQlFHCkNDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01Da0dBMVVkRGdRaUJDQm8KQ0tsTmlxTEo1NFBSUXVRakZBRGFpMGZMd2hsaE0za0xBVnYxQnlQTlp6QUtCZ2dxaGtqT1BRUURBZ05JQURCRgpBaUVBODU4cXhUeFVJTDNRVHd1VTNYeEcxTHFxMUcxMVVIR3hmS0FLM2krWGVLc0NJQWJUYUpqU0V1azBNMzFDClJubElKdHhkTm9xZVB4THdzbXlmMjE4dTF1WEoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + ], + "signing_identity": null, + "tls_intermediate_certs": [], + "tls_root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXRENDQWY2Z0F3SUJBZ0lSQU01aXhvUzVOSkd6dEtIbGs1WG5nVmt3Q2dZSUtvWkl6ajBFQXdJd2RqRUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIekFkQmdOVkJBTVRGblJzCmMyTmhMbTl5WnpFdVpYaGhiWEJzWlM1amIyMHdIaGNOTWpFd01USTFNRFEwTlRBd1doY05NekV3TVRJek1EUTAKTlRBd1dqQjJNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRQpCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWZNQjBHCkExVUVBeE1XZEd4elkyRXViM0puTVM1bGVHRnRjR3hsTG1OdmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDkKQXdFSEEwSUFCRXlOM1J1ODYyS0V1ZlRrYnNXOHJZZnNKeTR6dit0WkVYVGFtSmhpbUNHNnB5eDZ5Z0U4dG1TSwpSREhVb2FuZWcwUjM5T1NpVTdURTU5TUY4dDVJVjl5amJUQnJNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WCkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVIQXdFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlYKSFE0RUlnUWd5QVVqVVVTTDBkV09EckRnYVVVVFhrY0o2cVZXY3o3dWZzUVJyN1FTVUZVd0NnWUlLb1pJemowRQpBd0lEU0FBd1JRSWdIR2RUSjRqV1RHRzBCUy91SG5Id3hNNGEyYWdydE9yQWVVcmh2VVhja2JBQ0lRREhsZWtTCmhOUWZoYVIwMFZqdnd4VnVyVUEvbFJrSmZmKzV5UTRyVGRONGFRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + ] + }, + "type": 0 + }, + "version": "0" + } + }, + "version": "1" + }, + "Org2MSP": { + "groups": {}, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Endorsement": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "PEER" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "PEER" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "CLIENT" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + }, + { + "signed_by": 1 + }, + { + "signed_by": 2 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + }, + { + "principal": { + "msp_identifier": "Org2MSP", + "role": "CLIENT" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + }, + { + "signed_by": 1 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + } + }, + "values": { + "AnchorPeers": { + "mod_policy": "Admins", + "value": { + "anchor_peers": [ + { + "host": "peer0.org2.example.com", + "port": 9051 + } + ] + }, + "version": "0" + }, + "MSP": { + "mod_policy": "Admins", + "value": { + "config": { + "admins": [], + "crypto_config": { + "identity_identifier_hash_function": "SHA256", + "signature_hash_family": "SHA2" + }, + "fabric_node_ous": { + "admin_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVekNDQWZpZ0F3SUJBZ0lSQUlSayt5WUdySUMza2d3blpRRnJIZlF3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJMU1EUTBOVEF3V2hjTk16RXdNVEl6TURRME5UQXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NaTVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQlBnV2lyUjBKOFlCRXo5d2xXZlliT3JzUlltMEpFUW4veVB5SXR3OUhmMmJCcFV2VDhkcFVWaEROZ1ltQzhIMgoxeW5OV2lHY0dvVW56NjluY3RyY2ovcWpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKOHVOa2hBa2RTanc2U2ViWGNuWlhETXpseG1Kdk94d2I4cWU3eTgwbEkyMHdDZ1lJS29aSXpqMEVBd0lEU1FBdwpSZ0loQUxycW1nRzZ5MC92VEc1TThSNVNOa2Z6TytFazd3NzVUSVA0aWRHdVV1S2RBaUVBN3dQNi9MMkMyQ0lCCmJETEptMlVFNitHZjhFdTBaNy9zKzJZYjhwVVg0M2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "organizational_unit_identifier": "admin" + }, + "client_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVekNDQWZpZ0F3SUJBZ0lSQUlSayt5WUdySUMza2d3blpRRnJIZlF3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJMU1EUTBOVEF3V2hjTk16RXdNVEl6TURRME5UQXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NaTVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQlBnV2lyUjBKOFlCRXo5d2xXZlliT3JzUlltMEpFUW4veVB5SXR3OUhmMmJCcFV2VDhkcFVWaEROZ1ltQzhIMgoxeW5OV2lHY0dvVW56NjluY3RyY2ovcWpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKOHVOa2hBa2RTanc2U2ViWGNuWlhETXpseG1Kdk94d2I4cWU3eTgwbEkyMHdDZ1lJS29aSXpqMEVBd0lEU1FBdwpSZ0loQUxycW1nRzZ5MC92VEc1TThSNVNOa2Z6TytFazd3NzVUSVA0aWRHdVV1S2RBaUVBN3dQNi9MMkMyQ0lCCmJETEptMlVFNitHZjhFdTBaNy9zKzJZYjhwVVg0M2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "organizational_unit_identifier": "client" + }, + "enable": true, + "orderer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVekNDQWZpZ0F3SUJBZ0lSQUlSayt5WUdySUMza2d3blpRRnJIZlF3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJMU1EUTBOVEF3V2hjTk16RXdNVEl6TURRME5UQXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NaTVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQlBnV2lyUjBKOFlCRXo5d2xXZlliT3JzUlltMEpFUW4veVB5SXR3OUhmMmJCcFV2VDhkcFVWaEROZ1ltQzhIMgoxeW5OV2lHY0dvVW56NjluY3RyY2ovcWpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKOHVOa2hBa2RTanc2U2ViWGNuWlhETXpseG1Kdk94d2I4cWU3eTgwbEkyMHdDZ1lJS29aSXpqMEVBd0lEU1FBdwpSZ0loQUxycW1nRzZ5MC92VEc1TThSNVNOa2Z6TytFazd3NzVUSVA0aWRHdVV1S2RBaUVBN3dQNi9MMkMyQ0lCCmJETEptMlVFNitHZjhFdTBaNy9zKzJZYjhwVVg0M2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "organizational_unit_identifier": "orderer" + }, + "peer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVekNDQWZpZ0F3SUJBZ0lSQUlSayt5WUdySUMza2d3blpRRnJIZlF3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJMU1EUTBOVEF3V2hjTk16RXdNVEl6TURRME5UQXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NaTVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQlBnV2lyUjBKOFlCRXo5d2xXZlliT3JzUlltMEpFUW4veVB5SXR3OUhmMmJCcFV2VDhkcFVWaEROZ1ltQzhIMgoxeW5OV2lHY0dvVW56NjluY3RyY2ovcWpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKOHVOa2hBa2RTanc2U2ViWGNuWlhETXpseG1Kdk94d2I4cWU3eTgwbEkyMHdDZ1lJS29aSXpqMEVBd0lEU1FBdwpSZ0loQUxycW1nRzZ5MC92VEc1TThSNVNOa2Z6TytFazd3NzVUSVA0aWRHdVV1S2RBaUVBN3dQNi9MMkMyQ0lCCmJETEptMlVFNitHZjhFdTBaNy9zKzJZYjhwVVg0M2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "organizational_unit_identifier": "peer" + } + }, + "intermediate_certs": [], + "name": "Org2MSP", + "organizational_unit_identifiers": [], + "revocation_list": [], + "root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVekNDQWZpZ0F3SUJBZ0lSQUlSayt5WUdySUMza2d3blpRRnJIZlF3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NakV3TVRJMU1EUTBOVEF3V2hjTk16RXdNVEl6TURRME5UQXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NaTVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQlBnV2lyUjBKOFlCRXo5d2xXZlliT3JzUlltMEpFUW4veVB5SXR3OUhmMmJCcFV2VDhkcFVWaEROZ1ltQzhIMgoxeW5OV2lHY0dvVW56NjluY3RyY2ovcWpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKOHVOa2hBa2RTanc2U2ViWGNuWlhETXpseG1Kdk94d2I4cWU3eTgwbEkyMHdDZ1lJS29aSXpqMEVBd0lEU1FBdwpSZ0loQUxycW1nRzZ5MC92VEc1TThSNVNOa2Z6TytFazd3NzVUSVA0aWRHdVV1S2RBaUVBN3dQNi9MMkMyQ0lCCmJETEptMlVFNitHZjhFdTBaNy9zKzJZYjhwVVg0M2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + ], + "signing_identity": null, + "tls_intermediate_certs": [], + "tls_root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXRENDQWYyZ0F3SUJBZ0lRVmJLZXFUUEl5L3ZUS2dmYmYrYVhkakFLQmdncWhrak9QUVFEQWpCMk1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTWk1bGVHRnRjR3hsTG1OdmJURWZNQjBHQTFVRUF4TVdkR3h6ClkyRXViM0puTWk1bGVHRnRjR3hsTG1OdmJUQWVGdzB5TVRBeE1qVXdORFExTURCYUZ3MHpNVEF4TWpNd05EUTEKTURCYU1IWXhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSApFdzFUWVc0Z1JuSmhibU5wYzJOdk1Sa3dGd1lEVlFRS0V4QnZjbWN5TG1WNFlXMXdiR1V1WTI5dE1SOHdIUVlEClZRUURFeFowYkhOallTNXZjbWN5TG1WNFlXMXdiR1V1WTI5dE1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMEQKQVFjRFFnQUVDQUZ1S0kxMnpNY0FpVGMyZUgrQnlseVlqNlBaUUhLeTBTMkZrQ01ValBISFhmRllua21XU05XagpNTG1CZnZxRW9KS2FoMXdkTm1sNUpid21KejlXb3FOdE1Hc3dEZ1lEVlIwUEFRSC9CQVFEQWdHbU1CMEdBMVVkCkpRUVdNQlFHQ0NzR0FRVUZCd01DQmdnckJnRUZCUWNEQVRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUNrR0ExVWQKRGdRaUJDQmNQcHRUSUViL2pvLzFoTS9lMjVldzhsc3ZjRElOUkVMRllrYlFHamt3U0RBS0JnZ3Foa2pPUFFRRApBZ05KQURCR0FpRUFwc1VmR1hsa3VpK3htOTBQZCtudnhqTXRJdmdqaDE4UjBTTzZESXNsMHlNQ0lRRDVQNmg1Ck1ud0lOU2kvaEhQODNNVTdkcDFoNXZtWWk0eG8yUXFmSmlqNlB3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + ] + }, + "type": 0 + }, + "version": "0" + } + }, + "version": "1" + } + }, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + }, + "version": "0" + }, + "Endorsement": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Endorsement" + } + }, + "version": "0" + }, + "LifecycleEndorsement": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Endorsement" + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Readers" + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" + } + }, + "values": { + "Capabilities": { + "mod_policy": "Admins", + "value": { + "capabilities": { + "V2_0": {} + } + }, + "version": "0" + } + }, + "version": "1" + }, + "Orderer": { + "groups": { + "OrdererOrg": { + "groups": {}, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "OrdererMSP", + "role": "ADMIN" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "OrdererMSP", + "role": "MEMBER" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 1, + "value": { + "identities": [ + { + "principal": { + "msp_identifier": "OrdererMSP", + "role": "MEMBER" + }, + "principal_classification": "ROLE" + } + ], + "rule": { + "n_out_of": { + "n": 1, + "rules": [ + { + "signed_by": 0 + } + ] + } + }, + "version": 0 + } + }, + "version": "0" + } + }, + "values": { + "Endpoints": { + "mod_policy": "Admins", + "value": { + "addresses": ["orderer.example.com:7050"] + }, + "version": "0" + }, + "MSP": { + "mod_policy": "Admins", + "value": { + "config": { + "admins": [], + "crypto_config": { + "identity_identifier_hash_function": "SHA256", + "signature_hash_family": "SHA2" + }, + "fabric_node_ous": { + "admin_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWVPZ0F3SUJBZ0lRZlRqTkJTOTJYV3RlQnpOYUF3RE9KVEFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERUSXhNREV5TlRBME5EVXdNRm9YRFRNeE1ERXlNekEwTkRVd01Gb3dhVEVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4RkRBU0JnTlZCQW9UQzJWNFlXMXdiR1V1WTI5dE1SY3dGUVlEVlFRREV3NWpZUzVsZUdGdGNHeGxMbU52CmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJMzdkazZKLzRvMzV5WHViNDNjUG9NRUFHWDcKM0pCQ25iTlJyMFEyOVUxdXJlNEl2TTcxMXdERXI0d2xzV0RSN3NnOGlSdjFiWnVpZ2hqRlpvQnhxQmVqYlRCcgpNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBZ1lJS3dZQkJRVUhBd0V3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlZIUTRFSWdRZ0lZM01NUDEvR1FRQzFaVHpHUXpRMnpiS2VPbEMKTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaEFNNTZ2U2wvblN3QTRYZDY5QUNmTDhkWApBbHlQWC82QkJFVjdFVWRBMlA0WEFpQTdVdmhDNU5ETFdYN1BlSlhkVjg4YzRRV1hrUVJZVzlRQWFjV25ld2U5CjVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "admin" + }, + "client_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWVPZ0F3SUJBZ0lRZlRqTkJTOTJYV3RlQnpOYUF3RE9KVEFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERUSXhNREV5TlRBME5EVXdNRm9YRFRNeE1ERXlNekEwTkRVd01Gb3dhVEVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4RkRBU0JnTlZCQW9UQzJWNFlXMXdiR1V1WTI5dE1SY3dGUVlEVlFRREV3NWpZUzVsZUdGdGNHeGxMbU52CmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJMzdkazZKLzRvMzV5WHViNDNjUG9NRUFHWDcKM0pCQ25iTlJyMFEyOVUxdXJlNEl2TTcxMXdERXI0d2xzV0RSN3NnOGlSdjFiWnVpZ2hqRlpvQnhxQmVqYlRCcgpNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBZ1lJS3dZQkJRVUhBd0V3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlZIUTRFSWdRZ0lZM01NUDEvR1FRQzFaVHpHUXpRMnpiS2VPbEMKTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaEFNNTZ2U2wvblN3QTRYZDY5QUNmTDhkWApBbHlQWC82QkJFVjdFVWRBMlA0WEFpQTdVdmhDNU5ETFdYN1BlSlhkVjg4YzRRV1hrUVJZVzlRQWFjV25ld2U5CjVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "client" + }, + "enable": true, + "orderer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWVPZ0F3SUJBZ0lRZlRqTkJTOTJYV3RlQnpOYUF3RE9KVEFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERUSXhNREV5TlRBME5EVXdNRm9YRFRNeE1ERXlNekEwTkRVd01Gb3dhVEVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4RkRBU0JnTlZCQW9UQzJWNFlXMXdiR1V1WTI5dE1SY3dGUVlEVlFRREV3NWpZUzVsZUdGdGNHeGxMbU52CmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJMzdkazZKLzRvMzV5WHViNDNjUG9NRUFHWDcKM0pCQ25iTlJyMFEyOVUxdXJlNEl2TTcxMXdERXI0d2xzV0RSN3NnOGlSdjFiWnVpZ2hqRlpvQnhxQmVqYlRCcgpNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBZ1lJS3dZQkJRVUhBd0V3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlZIUTRFSWdRZ0lZM01NUDEvR1FRQzFaVHpHUXpRMnpiS2VPbEMKTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaEFNNTZ2U2wvblN3QTRYZDY5QUNmTDhkWApBbHlQWC82QkJFVjdFVWRBMlA0WEFpQTdVdmhDNU5ETFdYN1BlSlhkVjg4YzRRV1hrUVJZVzlRQWFjV25ld2U5CjVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "orderer" + }, + "peer_ou_identifier": { + "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWVPZ0F3SUJBZ0lRZlRqTkJTOTJYV3RlQnpOYUF3RE9KVEFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERUSXhNREV5TlRBME5EVXdNRm9YRFRNeE1ERXlNekEwTkRVd01Gb3dhVEVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4RkRBU0JnTlZCQW9UQzJWNFlXMXdiR1V1WTI5dE1SY3dGUVlEVlFRREV3NWpZUzVsZUdGdGNHeGxMbU52CmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJMzdkazZKLzRvMzV5WHViNDNjUG9NRUFHWDcKM0pCQ25iTlJyMFEyOVUxdXJlNEl2TTcxMXdERXI0d2xzV0RSN3NnOGlSdjFiWnVpZ2hqRlpvQnhxQmVqYlRCcgpNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBZ1lJS3dZQkJRVUhBd0V3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlZIUTRFSWdRZ0lZM01NUDEvR1FRQzFaVHpHUXpRMnpiS2VPbEMKTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaEFNNTZ2U2wvblN3QTRYZDY5QUNmTDhkWApBbHlQWC82QkJFVjdFVWRBMlA0WEFpQTdVdmhDNU5ETFdYN1BlSlhkVjg4YzRRV1hrUVJZVzlRQWFjV25ld2U5CjVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", + "organizational_unit_identifier": "peer" + } + }, + "intermediate_certs": [], + "name": "OrdererMSP", + "organizational_unit_identifiers": [], + "revocation_list": [], + "root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWVPZ0F3SUJBZ0lRZlRqTkJTOTJYV3RlQnpOYUF3RE9KVEFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERUSXhNREV5TlRBME5EVXdNRm9YRFRNeE1ERXlNekEwTkRVd01Gb3dhVEVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4RkRBU0JnTlZCQW9UQzJWNFlXMXdiR1V1WTI5dE1SY3dGUVlEVlFRREV3NWpZUzVsZUdGdGNHeGxMbU52CmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJMzdkazZKLzRvMzV5WHViNDNjUG9NRUFHWDcKM0pCQ25iTlJyMFEyOVUxdXJlNEl2TTcxMXdERXI0d2xzV0RSN3NnOGlSdjFiWnVpZ2hqRlpvQnhxQmVqYlRCcgpNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBZ1lJS3dZQkJRVUhBd0V3CkR3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlZIUTRFSWdRZ0lZM01NUDEvR1FRQzFaVHpHUXpRMnpiS2VPbEMKTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaEFNNTZ2U2wvblN3QTRYZDY5QUNmTDhkWApBbHlQWC82QkJFVjdFVWRBMlA0WEFpQTdVdmhDNU5ETFdYN1BlSlhkVjg4YzRRV1hrUVJZVzlRQWFjV25ld2U5CjVnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + ], + "signing_identity": null, + "tls_intermediate_certs": [], + "tls_root_certs": [ + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNSVENDQWVxZ0F3SUJBZ0lSQUljb2F2TFpORW91WTNOOXNLalFsa3d3Q2dZSUtvWkl6ajBFQXdJd2JERUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhGREFTQmdOVkJBb1RDMlY0WVcxd2JHVXVZMjl0TVJvd0dBWURWUVFERXhGMGJITmpZUzVsCmVHRnRjR3hsTG1OdmJUQWVGdzB5TVRBeE1qVXdORFExTURCYUZ3MHpNVEF4TWpNd05EUTFNREJhTUd3eEN6QUoKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaApibU5wYzJOdk1SUXdFZ1lEVlFRS0V3dGxlR0Z0Y0d4bExtTnZiVEVhTUJnR0ExVUVBeE1SZEd4elkyRXVaWGhoCmJYQnNaUzVqYjIwd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFRSjJpVW41dS9ZOU5MZ1RzdFEKdXVTNXN1V0JPSEZ1Y0hIMnRzck9HY3FMdmJBUEVBbnVsOUZxWFlsRDFuMVZPdk9BQm9wRnNvN1JTaXpYMXVpTAp5M3M1bzIwd2F6QU9CZ05WSFE4QkFmOEVCQU1DQWFZd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3SUdDQ3NHCkFRVUZCd01CTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3S1FZRFZSME9CQ0lFSUVqVHJTN1JacUJ3MWlGeUtxMVEKcVFibEFSKzlHTWJZMTEvRS9WbHJSUmdkTUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDSVFDa2RFclpQdWtNcENoVApNWkZaTXdnUWc0ZjJuVEc1S0l4bUE3UzBFVXBqU1FJaEFLeC9ZZDNNZjU2MzBvZUZWcm9tN0R4ajFUMkp2aktCCjBod0FvcEE3VXdJNQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + ] + }, + "type": 0 + }, + "version": "0" + } + }, + "version": "0" + } + }, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + }, + "version": "0" + }, + "BlockValidation": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Readers" + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" + } + }, + "values": { + "BatchSize": { + "mod_policy": "Admins", + "value": { + "absolute_max_bytes": 103809024, + "max_message_count": 10, + "preferred_max_bytes": 524288 + }, + "version": "0" + }, + "BatchTimeout": { + "mod_policy": "Admins", + "value": { + "timeout": "2s" + }, + "version": "0" + }, + "Capabilities": { + "mod_policy": "Admins", + "value": { + "capabilities": { + "V2_0": {} + } + }, + "version": "0" + }, + "ChannelRestrictions": { + "mod_policy": "Admins", + "value": null, + "version": "0" + }, + "ConsensusType": { + "mod_policy": "Admins", + "value": { + "metadata": { + "consenters": [ + { + "client_tls_cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWw2Z0F3SUJBZ0lSQU1EWEJGYVBZZTRHYTNFbjNyVmpVM2N3Q2dZSUtvWkl6ajBFQXdJd2JERUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhGREFTQmdOVkJBb1RDMlY0WVcxd2JHVXVZMjl0TVJvd0dBWURWUVFERXhGMGJITmpZUzVsCmVHRnRjR3hsTG1OdmJUQWVGdzB5TVRBeE1qVXdORFExTURCYUZ3MHpNVEF4TWpNd05EUTFNREJhTUZneEN6QUoKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaApibU5wYzJOdk1Sd3dHZ1lEVlFRREV4TnZjbVJsY21WeUxtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDCkFRWUlLb1pJemowREFRY0RRZ0FFSGd2QnFWaks4MTFzSUxzdDgzMmJTQldIVFZEYWpHNHhBR1hxU05zVjRTUkIKdjBMQXVTaDAwOUk5S1B5QWk2ckRodCsxbk9yd1Ivakl2U015R3RDdjJxT0I5RENCOFRBT0JnTlZIUThCQWY4RQpCQU1DQmFBd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDCk1BQXdLd1lEVlIwakJDUXdJb0FnU05PdEx0Rm1vSERXSVhJcXJWQ3BCdVVCSDcwWXh0alhYOFQ5V1d0RkdCMHcKZ1lRR0ExVWRFUVI5TUh1Q0UyOXlaR1Z5WlhJdVpYaGhiWEJzWlM1amIyMkNCMjl5WkdWeVpYS0NDV3h2WTJGcwphRzl6ZElJVGIzSmtaWEpsY2k1bGVHRnRjR3hsTG1OdmJZSUhiM0prWlhKbGNvSUpiRzlqWVd4b2IzTjBnaE52CmNtUmxjbVZ5TG1WNFlXMXdiR1V1WTI5dGdnZHZjbVJsY21WeWdnbHNiMk5oYkdodmMzUXdDZ1lJS29aSXpqMEUKQXdJRFNBQXdSUUloQUkwRnhHOUlzZTRQbkZ2L2tGOU1QOTJxcVprT1hjeExWa1JYS0FUSkgyVGFBaUFVaFJTcgoyVDMreC9MMFJVa2lSWlJIYnZGTWZKeFZESFpUdlRZTDVwaENQdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "host": "orderer.example.com", + "port": 7050, + "server_tls_cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWw2Z0F3SUJBZ0lSQU1EWEJGYVBZZTRHYTNFbjNyVmpVM2N3Q2dZSUtvWkl6ajBFQXdJd2JERUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhGREFTQmdOVkJBb1RDMlY0WVcxd2JHVXVZMjl0TVJvd0dBWURWUVFERXhGMGJITmpZUzVsCmVHRnRjR3hsTG1OdmJUQWVGdzB5TVRBeE1qVXdORFExTURCYUZ3MHpNVEF4TWpNd05EUTFNREJhTUZneEN6QUoKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaApibU5wYzJOdk1Sd3dHZ1lEVlFRREV4TnZjbVJsY21WeUxtVjRZVzF3YkdVdVkyOXRNRmt3RXdZSEtvWkl6ajBDCkFRWUlLb1pJemowREFRY0RRZ0FFSGd2QnFWaks4MTFzSUxzdDgzMmJTQldIVFZEYWpHNHhBR1hxU05zVjRTUkIKdjBMQXVTaDAwOUk5S1B5QWk2ckRodCsxbk9yd1Ivakl2U015R3RDdjJxT0I5RENCOFRBT0JnTlZIUThCQWY4RQpCQU1DQmFBd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDCk1BQXdLd1lEVlIwakJDUXdJb0FnU05PdEx0Rm1vSERXSVhJcXJWQ3BCdVVCSDcwWXh0alhYOFQ5V1d0RkdCMHcKZ1lRR0ExVWRFUVI5TUh1Q0UyOXlaR1Z5WlhJdVpYaGhiWEJzWlM1amIyMkNCMjl5WkdWeVpYS0NDV3h2WTJGcwphRzl6ZElJVGIzSmtaWEpsY2k1bGVHRnRjR3hsTG1OdmJZSUhiM0prWlhKbGNvSUpiRzlqWVd4b2IzTjBnaE52CmNtUmxjbVZ5TG1WNFlXMXdiR1V1WTI5dGdnZHZjbVJsY21WeWdnbHNiMk5oYkdodmMzUXdDZ1lJS29aSXpqMEUKQXdJRFNBQXdSUUloQUkwRnhHOUlzZTRQbkZ2L2tGOU1QOTJxcVprT1hjeExWa1JYS0FUSkgyVGFBaUFVaFJTcgoyVDMreC9MMFJVa2lSWlJIYnZGTWZKeFZESFpUdlRZTDVwaENQdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + } + ], + "options": { + "election_tick": 10, + "heartbeat_tick": 1, + "max_inflight_blocks": 5, + "snapshot_interval_size": 16777216, + "tick_interval": "500ms" + } + }, + "state": "STATE_NORMAL", + "type": "etcdraft" + }, + "version": "0" + } + }, + "version": "0" + } + }, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Readers" + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" + } + }, + "values": { + "BlockDataHashingStructure": { + "mod_policy": "Admins", + "value": { + "width": 4294967295 + }, + "version": "0" + }, + "Capabilities": { + "mod_policy": "Admins", + "value": { + "capabilities": { + "V2_0": {} + } + }, + "version": "0" + }, + "Consortium": { + "mod_policy": "Admins", + "value": { + "name": "SampleConsortium" + }, + "version": "0" + }, + "HashingAlgorithm": { + "mod_policy": "Admins", + "value": { + "name": "SHA256" + }, + "version": "0" + }, + "OrdererAddresses": { + "mod_policy": "/Channel/Orderer/Admins", + "value": { + "addresses": ["127.0.0.1:7050"] + }, + "version": "0" + } + }, + "version": "0" + }, + "sequence": "3" + }, + "last_update": { + "payload": { + "data": { + "config_update": { + "channel_id": "mychannel", + "isolated_data": {}, + "read_set": { + "groups": { + "Application": { + "groups": { + "Org2MSP": { + "groups": {}, + "mod_policy": "", + "policies": { + "Admins": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Endorsement": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Readers": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Writers": { + "mod_policy": "", + "policy": null, + "version": "0" + } + }, + "values": { + "MSP": { + "mod_policy": "", + "value": null, + "version": "0" + } + }, + "version": "0" + } + }, + "mod_policy": "", + "policies": {}, + "values": {}, + "version": "1" + } + }, + "mod_policy": "", + "policies": {}, + "values": {}, + "version": "0" + }, + "write_set": { + "groups": { + "Application": { + "groups": { + "Org2MSP": { + "groups": {}, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Endorsement": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Readers": { + "mod_policy": "", + "policy": null, + "version": "0" + }, + "Writers": { + "mod_policy": "", + "policy": null, + "version": "0" + } + }, + "values": { + "AnchorPeers": { + "mod_policy": "Admins", + "value": { + "anchor_peers": [ + { + "host": "peer0.org2.example.com", + "port": 9051 + } + ] + }, + "version": "0" + }, + "MSP": { + "mod_policy": "", + "value": null, + "version": "0" + } + }, + "version": "1" + } + }, + "mod_policy": "", + "policies": {}, + "values": {}, + "version": "1" + } + }, + "mod_policy": "", + "policies": {}, + "values": {}, + "version": "0" + } + }, + "signatures": [ + { + "signature": "MEQCIBIJ6WHML7NirGlipfSjA2RfUtKvAvTy/nkPqCbMA5hlAiAPj0NkeMlPe6eMGWy3nypaixHmo6GNxrHIC7wqZVZSNg==", + "signature_header": { + "creator": { + "id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWMrZ0F3SUJBZ0lRU01uczcyc1h4U1pkKzdVQ215ZTl5REFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTWk1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NaTVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUdzeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVE0d0RBWURWUVFMRXdWaFpHMXBiakVmTUIwR0ExVUVBd3dXUVdSdGFXNUFiM0puCk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCUGxSczNtWXk2T3gKZGN6RXNiMVhGbklJaFB0QnBlTmZ4cWZsc0U4TDdhYTdsLzJxMjJXbGVrL3FsRHFHRXNtMWc2RFAyVU9OSFlhYgpyYVZLVktxZDY1bWpUVEJMTUE0R0ExVWREd0VCL3dRRUF3SUhnREFNQmdOVkhSTUJBZjhFQWpBQU1Dc0dBMVVkCkl3UWtNQ0tBSVBMalpJUUpIVW84T2tubTEzSjJWd3pNNWNaaWJ6c2NHL0tudTh2TkpTTnRNQW9HQ0NxR1NNNDkKQkFNQ0EwZ0FNRVVDSVFDdmZJV2FPRlB5Wm54RDZIeEgrMDVmTUlQUVl2VW9mSzhCY0FqdjNWb1hUQUlnWVRjYgo0NFczSFlzdXRpbE9PWWZmYUFVajMzTDhlOXZReW1ReGdIb3J5YW89Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "mspid": "Org2MSP" + }, + "nonce": "CQ+bqP1WmcEpP/R9xGDbd9gP4Z+3tYz7" + } + } + ] + }, + "header": { + "channel_header": { + "channel_id": "mychannel", + "epoch": "0", + "extension": null, + "timestamp": "2021-01-25T04:50:17Z", + "tls_cert_hash": null, + "tx_id": "", + "type": 2, + "typeString": "CONFIG_UPDATE", + "version": 0 + }, + "signature_header": { + "creator": { + "id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWMrZ0F3SUJBZ0lRU01uczcyc1h4U1pkKzdVQ215ZTl5REFLQmdncWhrak9QUVFEQWpCek1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTWk1bGVHRnRjR3hsTG1OdmJURWNNQm9HQTFVRUF4TVRZMkV1CmIzSm5NaTVsZUdGdGNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmEKTUdzeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVApZVzRnUm5KaGJtTnBjMk52TVE0d0RBWURWUVFMRXdWaFpHMXBiakVmTUIwR0ExVUVBd3dXUVdSdGFXNUFiM0puCk1pNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCUGxSczNtWXk2T3gKZGN6RXNiMVhGbklJaFB0QnBlTmZ4cWZsc0U4TDdhYTdsLzJxMjJXbGVrL3FsRHFHRXNtMWc2RFAyVU9OSFlhYgpyYVZLVktxZDY1bWpUVEJMTUE0R0ExVWREd0VCL3dRRUF3SUhnREFNQmdOVkhSTUJBZjhFQWpBQU1Dc0dBMVVkCkl3UWtNQ0tBSVBMalpJUUpIVW84T2tubTEzSjJWd3pNNWNaaWJ6c2NHL0tudTh2TkpTTnRNQW9HQ0NxR1NNNDkKQkFNQ0EwZ0FNRVVDSVFDdmZJV2FPRlB5Wm54RDZIeEgrMDVmTUlQUVl2VW9mSzhCY0FqdjNWb1hUQUlnWVRjYgo0NFczSFlzdXRpbE9PWWZmYUFVajMzTDhlOXZReW1ReGdIb3J5YW89Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "mspid": "Org2MSP" + }, + "nonce": "d9/GdSPkERQRz9QwORlH1PzUsTITgj5j" + } + } + }, + "signature": "MEUCIQDFFmfbBKea6NzA2QRbnyVnQdSGHEtAdK05BnIDG1tLwgIgGN5AB8joc+mM4iXUbYfx8HyqRg/wdJxAD7oCX3/vSXg=" + } + }, + "header": { + "channel_header": { + "channel_id": "mychannel", + "epoch": "0", + "extension": null, + "timestamp": "2021-01-25T04:50:17Z", + "tls_cert_hash": null, + "tx_id": "", + "type": 1, + "typeString": "CONFIG", + "version": 0 + }, + "signature_header": { + "creator": { + "id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNIekNDQWNXZ0F3SUJBZ0lSQUsxbG82ZUZXbWc3cmVoazZZdGQ4OGN3Q2dZSUtvWkl6ajBFQXdJd2FURUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhGREFTQmdOVkJBb1RDMlY0WVcxd2JHVXVZMjl0TVJjd0ZRWURWUVFERXc1allTNWxlR0Z0CmNHeGxMbU52YlRBZUZ3MHlNVEF4TWpVd05EUTFNREJhRncwek1UQXhNak13TkRRMU1EQmFNR294Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxVFlXNGdSbkpoYm1OcApjMk52TVJBd0RnWURWUVFMRXdkdmNtUmxjbVZ5TVJ3d0dnWURWUVFERXhOdmNtUmxjbVZ5TG1WNFlXMXdiR1V1ClkyOXRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUV0QlFQQ01QT0ZwWmk4UDE1bUpMcklPSEYKbzdjVUtSTVZOK2o1RHI0alQ2OGIwU3JZckZyQThDK0h3ZG8yT0g1KzRWU05adlNnRDNwYVJ4MHM1TmlIS0tOTgpNRXN3RGdZRFZSMFBBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0t3WURWUjBqQkNRd0lvQWdJWTNNCk1QMS9HUVFDMVpUekdRelEyemJLZU9sQ0w3SEpKQU5GWHV6ZnhhNHdDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWgKQUxnbnFhcFRvQU1oYlY5QW9pUVp5Sk9mR24yVmJpcE5qOTAxbFhKc203V3lBaUFqUStHRGVoblBuZkRVbndtQQpFRjZWRnVmeHQ1VlF5cVJFOE1sTmJJQWZWZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "mspid": "OrdererMSP" + }, + "nonce": "+1SRG3nvAbY1KONG4nC/hK+VWhwE/+oG" + } + } + }, + "signature": "MEUCIQDb2dG8zZDY5oSGv+KcJMHGUOSO4K7PC5cEEVorTLV0aQIgJto49dhZa8CsyZadJ4ERlQaAOnnbPwSWdIIP2XxmWp4=" + } + ] + }, + "header": { + "data_hash": "xcx3tVzEFY7FBk9DqAnksbargFRibl22tWmDULQBhMY=", + "number": "2", + "previous_hash": "OXd8OGybdOr6sD//we99Qi94Ox7BR5kX2tqZsQV3lfs=" + }, + "metadata": { + "metadata": [ + "Cg8KAggCEgkKBwoBARACGAQSlgcKygYKrQYKCk9yZGVyZXJNU1ASngYtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ0h6Q0NBY1dnQXdJQkFnSVJBSzFsbzZlRldtZzdyZWhrNll0ZDg4Y3dDZ1lJS29aSXpqMEVBd0l3YVRFTApNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdUQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjVERWTmhiaUJHCmNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMyVjRZVzF3YkdVdVkyOXRNUmN3RlFZRFZRUURFdzVqWVM1bGVHRnQKY0d4bExtTnZiVEFlRncweU1UQXhNalV3TkRRMU1EQmFGdzB6TVRBeE1qTXdORFExTURCYU1Hb3hDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSUV3cERZV3hwWm05eWJtbGhNUll3RkFZRFZRUUhFdzFUWVc0Z1JuSmhibU5wCmMyTnZNUkF3RGdZRFZRUUxFd2R2Y21SbGNtVnlNUnd3R2dZRFZRUURFeE52Y21SbGNtVnlMbVY0WVcxd2JHVXUKWTI5dE1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRXRCUVBDTVBPRnBaaThQMTVtSkxySU9IRgpvN2NVS1JNVk4rajVEcjRqVDY4YjBTcllyRnJBOEMrSHdkbzJPSDUrNFZTTlp2U2dEM3BhUngwczVOaUhLS05OCk1Fc3dEZ1lEVlIwUEFRSC9CQVFEQWdlQU1Bd0dBMVVkRXdFQi93UUNNQUF3S3dZRFZSMGpCQ1F3SW9BZ0lZM00KTVAxL0dRUUMxWlR6R1F6UTJ6YktlT2xDTDdISkpBTkZYdXpmeGE0d0NnWUlLb1pJemowRUF3SURTQUF3UlFJaApBTGducWFwVG9BTWhiVjlBb2lRWnlKT2ZHbjJWYmlwTmo5MDFsWEpzbTdXeUFpQWpRK0dEZWhuUG5mRFVud21BCkVGNlZGdWZ4dDVWUXlxUkU4TWxOYklBZlZnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoSGBnHiyvn/cA/HU/qYqSqpmnh5YqW+qR0HRJHMEUCIQCfyjmVn1+a6N3YUXjkic1OjasT+DQuqBacd7+YDmftpwIgT00CckRV10TmpkIbJmZ3ztVvRCIGdprmWh1xLtFBK/8=", + "CgIIAg==", + "AA==", + "", + "CiBfiLYUB7FJpIQTQz9GcMRlMeXEqP69wzmpU2/4cWpVng==" + ] + } +}