본문 바로가기
Hyperledger Fabric

[Hyperledger Fabric v2.x] 2장 Network 구축하기

by namho46 2021. 1. 12.

Hyperledger Fabric 은 허가형 블록체인이기 때문에 가장 먼저 시작 할 것은 어떤 네트워크를 구성 할 것인지에 대한 고민입니다.

네트워크 구성에는 Peer 와 Orderer 뿐만 아니라 Channel 도 고민해야한다

Hyperledger Fabric 네트워크 구성원에는 대표적으로 두 종류의 노드가 있습니다. (자세한 내용은 링크를 확인해주세요)

  • Peer: Peers are a fundamental element of the network because they host ledgers and smart contracts.
  • Orderer: In addition to their ordering role, orderers also maintain the list of organizations that are allowed to create channels.

아래 그림1. 은 이번 내용을 통해 궁극적으로 구축하고자 하는 네트워크 구성도입니다.

그림1. 네트워크 구성도

 

그림1 에서 각각의 심볼은 아래와 같습니다(상세 설명은 Hyperledger Fabric 공식 사이트에서 확인하시길 추천 드립니다):

위와 같은 구성은 두 가지 방법으로 구축 할 수 있습니다.

  1. 간편한 방법으로서, Hyperledger Fabric v2.x 에서 제공하는 sample-network/test-network 디렉토리에 network.sh 파일을 활용하여 구축
  2. 조금 번거로운 방법으로서, 네트워크 구축의 일련의 과정을 내려받은 binary 의 command 를 활용하여 구축

우선 간편한 방법을 먼저 소개 드리겠습니다.

간편하게 test-network 구축하기

저번 챕터에서 fabric-samples 를 $HOME/fabric-lecture/fabric-samples 경로에 내려받았습니다. 이제 아래의 커맨드를 실행합니다.

$ cd $HOME/fabric-lecture/fabric-samples/test-network
$ ./network.sh down
$ ./network.sh up

이제 우리가 뭘 한 것인지 코드 한 줄 씩 보겠다.

  • ./network.sh down - 현재 구동중인 fabric network 의 docker container 를 중지 및 삭제 함과 동시에 관련 있는 디렉토리를 삭제합니다. 혹시라도 구동중일 수 있는 노드를 사전에 내리기 위함 입니다. 실행 결과는 아래와 같이 나오면 정상입니다.

    Stopping network
    Removing network net_test
    WARNING: Network net_test not found.
    Removing volume net_orderer.example.com
    WARNING: Volume net_orderer.example.com not found.
    Removing volume net_peer0.org1.example.com
    WARNING: Volume net_peer0.org1.example.com not found.
    Removing volume net_peer0.org2.example.com
    WARNING: Volume net_peer0.org2.example.com not found.
    Removing network net_test
    WARNING: Network net_test not found.
    Removing volume net_peer0.org3.example.com
    WARNING: Volume net_peer0.org3.example.com not found.
    No containers available for deletion
    No images available for deletion
  • ./network.sh up - Peer 노드들과 Orderer 노드로 구성된 네트워크를 docker-compose 를 통해 띄웁니다. 실행 결과는 아래와 같이 나오면 정상입니다.

    Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen'
    LOCAL_VERSION=2.3.0
    DOCKER_IMAGE_VERSION=2.3.0
    /home/fabric-lecture/fabric-samples/test-network/../bin/cryptogen
    Generating certificates using cryptogen tool
    Creating Org1 Identities
    + cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
    org1.example.com
    + res=0
    Creating Org2 Identities
    + cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
    org2.example.com
    + res=0
    Creating Orderer Org Identities
    + cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
    + res=0
    Generating CCP files for Org1 and Org2
    /Users/namho46/fabric-lecture/fabric-samples/test-network/../bin/configtxgen
    Generating Orderer Genesis block
    + configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
    2021-01-12 00:29:54.021 KST [common.tools.configtxgen] main -> INFO 001 Loading configuration
    2021-01-12 00:29:54.026 KST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
    2021-01-12 00:29:54.026 KST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216 
    2021-01-12 00:29:54.026 KST [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /home/fabric-lecture/fabric-samples/test-network/configtx/configtx.yaml
    2021-01-12 00:29:54.028 KST [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
    2021-01-12 00:29:54.028 KST [common.tools.configtxgen] doOutputBlock -> INFO 006 Creating system channel genesis block
    2021-01-12 00:29:54.028 KST [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
    + res=0
    Creating network "net_test" with the default driver
    Creating volume "net_orderer.example.com" with default driver
    Creating volume "net_peer0.org1.example.com" with default driver
    Creating volume "net_peer0.org2.example.com" with default driver
    Creating peer0.org1.example.com ... done
    Creating orderer.example.com    ... done
    Creating peer0.org2.example.com ... done
    Creating cli                    ... done
    CONTAINER ID   IMAGE                               COMMAND             CREATED                  STATUS                  PORTS                              NAMES
    981263e7f987   hyperledger/fabric-tools:latest     "/bin/bash"         Less than a second ago   Up Less than a second                                      cli
    7be4c3784daf   hyperledger/fabric-orderer:latest   "orderer"           1 second ago             Up Less than a second   0.0.0.0:7050->7050/tcp             orderer.example.com
    ed4929869db0   hyperledger/fabric-peer:latest      "peer node start"   1 second ago             Up Less than a second   7051/tcp, 0.0.0.0:9051->9051/tcp   peer0.org2.example.com
    18b9c8c36ffe   hyperledger/fabric-peer:latest      "peer node start"   1 second ago             Up Less than a second   0.0.0.0:7051->7051/tcp             peer0.org1.example.com

docker 프로세스를 확인해보면 hyperledger/fabric-peer 이미지를 사용하는 컨테이너 두개(peer0.org1.example.com, peer0.org2.example.com)와 hyperledger/fabric-orderer (orderer.example.com) 그리고 hyperledger/fabric-tools 이미지를 사용하는 컨테이너가 구동 중이 것을 확인 할 수 있습니다.

이제 현 상황에서 나중에 비교를 위해 peer 중 하나의 컨테이너의 로그를 확인해보겠습니다. 저는 peer0.org1.example.com 의 로그를 확인하겠습니다.

$ docker logs peer0.org1.example.com

아래는 해당 Peer 의 로그 결과 입니다. 정상적으로 구동 되었다면 비슷한 결과가 나올 것 입니다:

2021-01-11 15:29:55.496 UTC [nodeCmd] serve -> INFO 001 Starting peer:
 Version: 2.3.0
 Commit SHA: ec81f3e
 Go version: go1.14.12
 OS/Arch: linux/amd64
 Chaincode:
  Base Docker Label: org.hyperledger.fabric
  Docker Namespace: hyperledger
2021-01-11 15:29:55.497 UTC [peer] getLocalAddress -> INFO 002 Auto-detected peer address: 172.19.0.2:7051
2021-01-11 15:29:55.498 UTC [peer] getLocalAddress -> INFO 003 Returning peer0.org1.example.com:7051
2021-01-11 15:29:55.517 UTC [nodeCmd] initGrpcSemaphores -> INFO 004 concurrency limit for endorser service is 2500
2021-01-11 15:29:55.517 UTC [nodeCmd] initGrpcSemaphores -> INFO 005 concurrency limit for deliver service is 2500
2021-01-11 15:29:55.517 UTC [nodeCmd] serve -> INFO 006 Starting peer with TLS enabled
2021-01-11 15:29:55.533 UTC [certmonitor] trackCertExpiration -> INFO 007 The enrollment certificate will expire on 2031-01-09 15:25:00 +0000 UTC
2021-01-11 15:29:55.534 UTC [certmonitor] trackCertExpiration -> INFO 008 The server TLS certificate will expire on 2031-01-09 15:25:00 +0000 UTC
2021-01-11 15:29:55.535 UTC [ledgermgmt] NewLedgerMgr -> INFO 009 Initializing LedgerMgr
2021-01-11 15:29:55.567 UTC [leveldbhelper] openDBAndCheckFormat -> INFO 00a DB is empty Setting db format as 2.0
2021-01-11 15:29:55.582 UTC [blkstorage] NewProvider -> INFO 00b Creating new file ledger directory at /var/hyperledger/production/ledgersData/chains/chains
2021-01-11 15:29:55.736 UTC [leveldbhelper] openDBAndCheckFormat -> INFO 00c DB is empty Setting db format as 2.0
2021-01-11 15:29:55.833 UTC [leveldbhelper] openDBAndCheckFormat -> INFO 00d DB is empty Setting db format as 2.0
2021-01-11 15:29:55.835 UTC [ledgermgmt] NewLedgerMgr -> INFO 00e Initialized LedgerMgr
2021-01-11 15:29:55.838 UTC [gossip.service] New -> INFO 00f Initialize gossip with endpoint peer0.org1.example.com:7051
2021-01-11 15:29:55.840 UTC [gossip.gossip] New -> INFO 010 Creating gossip service with self membership of Endpoint: peer0.org1.example.com:7051, InternalEndpoint: peer0.org1.example.com:7051, PKI-ID: 45df79d8445577d5a55c26f3f6bac8db4f7fbd8b302af52a4f960b2df0fb1366, Metadata: 
2021-01-11 15:29:55.841 UTC [gossip.gossip] start -> INFO 011 Gossip instance peer0.org1.example.com:7051 started
2021-01-11 15:29:55.840 UTC [lifecycle] InitializeLocalChaincodes -> INFO 012 Initialized lifecycle cache with 0 already installed chaincodes
2021-01-11 15:29:55.842 UTC [nodeCmd] computeChaincodeEndpoint -> INFO 013 Entering computeChaincodeEndpoint with peerHostname: peer0.org1.example.com
2021-01-11 15:29:55.842 UTC [nodeCmd] computeChaincodeEndpoint -> INFO 014 Exit with ccEndpoint: peer0.org1.example.com:7052
2021-01-11 15:29:55.848 UTC [sccapi] DeploySysCC -> INFO 015 deploying system chaincode 'lscc'
2021-01-11 15:29:55.850 UTC [sccapi] DeploySysCC -> INFO 016 deploying system chaincode 'cscc'
2021-01-11 15:29:55.850 UTC [sccapi] DeploySysCC -> INFO 017 deploying system chaincode 'qscc'
2021-01-11 15:29:55.851 UTC [sccapi] DeploySysCC -> INFO 018 deploying system chaincode '_lifecycle'
2021-01-11 15:29:55.851 UTC [nodeCmd] serve -> INFO 019 Deployed system chaincodes
2021-01-11 15:29:55.851 UTC [discovery] NewService -> INFO 01a Created with config TLS: true, authCacheMaxSize: 1000, authCachePurgeRatio: 0.750000
2021-01-11 15:29:55.851 UTC [nodeCmd] registerDiscoveryService -> INFO 01b Discovery service activated
2021-01-11 15:29:55.851 UTC [nodeCmd] serve -> INFO 01c Starting peer with ID=[peer0.org1.example.com], network ID=[dev], address=[peer0.org1.example.com:7051]
2021-01-11 15:29:55.851 UTC [nodeCmd] func6 -> INFO 01d Starting profiling server with listenAddress = 0.0.0.0:6060
2021-01-11 15:29:55.852 UTC [nodeCmd] serve -> INFO 01e Started peer with ID=[peer0.org1.example.com], network ID=[dev], address=[peer0.org1.example.com:7051]
2021-01-11 15:29:55.852 UTC [kvledger] LoadPreResetHeight -> INFO 01f Loading prereset height from path [/var/hyperledger/production/ledgersData/chains]
2021-01-11 15:29:55.852 UTC [blkstorage] preResetHtFiles -> INFO 020 No active channels passed

로그의 마지막 라인을 보시면, No active channels passed 라는 내용을 확인 할 수 있습니다. 이는 현재가 orderer 노드와 peer 노드가 실행 중이긴 하지만 아직 channel 에 참여하고 있지 않다는 것을 알 수 있습니다.

이제 그러면 채널을 생성하고 생성한 채널에 peer 노드가 참여하도록 하기 위해 아래 커맨드를 실행하겠습니다.

$ ./network.sh createChannel -c channel1

아래는 실행시 출력되는 로그 입니다. 이제부터는 필요한 로그만 편집하기 때문에 실제 출력 내용과 다를 수 있습니다.

Creating channel 'channel1'.
Generating channel create transaction 'channel1.tx'
2021-01-12 00:46:13.699 KST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-01-12 00:46:13.705 KST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/fabric-lecture/fabric-samples/test-network/configtx/configtx.yaml
2021-01-12 00:46:13.705 KST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-01-12 00:46:13.710 KST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
Creating channel channel1
Using organization 1
Channel 'channel1' created
Joining org1 peer to the channel...
Using organization 1
2021-01-12 00:46:21.207 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-12 00:46:21.233 KST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Joining org2 peer to the channel...
Using organization 2
2021-01-12 00:46:24.290 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-12 00:46:24.316 KST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel channel1
Using organization 1
Fetching the most recent configuration block for the channel
2021-01-11 15:46:24.665 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-11 15:46:24.666 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2021-01-11 15:46:24.666 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2021-01-11 15:46:24.667 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel channel1
2021-01-11 15:46:24.915 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-11 15:46:24.929 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'channel1'
Setting anchor peer for org2...
Using organization 2
Fetching channel config for channel channel1
Using organization 2
Fetching the most recent configuration block for the channel
2021-01-11 15:46:25.154 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-11 15:46:25.157 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2021-01-11 15:46:25.158 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2021-01-11 15:46:25.159 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
Generating anchor peer update transaction for Org2 on channel channel1
2021-01-11 15:46:25.329 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-01-11 15:46:25.347 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'channel1'
Channel 'channel1' joined

굳이 로그를 편집하여 보여드리는 이유는 위의 로그의 내용에서 키워드들을 확인 후 지금의 간편한 방법이 아닌 커맨드를 활용하여 네트워크 구축시 익숙해지기 위해서 입니다. 위의 로그를 간략히 해석하면 아래와 같습니다.

  1. 채널 생성 요청 받음
  2. 채널 생성 트랜잭션 생성
    1. configtx.yaml 을 읽어서 채널 트랜잭션 생성 트랜잭션 생성
  3. Org1 으로 사용자 변경하여 생성한 채널에 참여
    1. Endorser 와 Orderer 사이에 통신
    2. 채널 참가 요청 전송
  4. Org2 으로 사용자 변경하여 생성한 채널에 참여
    1. Endorer 와 Orderer 사이에 통신
    2. 채널 참가 요청 전송
  5. Org1 으로 사용자 변경하여 채널1 에 대한 채널 구성 파일 가져옴
  6. 그 채널의 가장 최신 블록 가져옴
    1. Endorser 와 Orderer 통신
    2. 최신 블록 수신
  7. 가져온 블록 구성 정보를 복호화하여 json 파일로 변환
    1. Endorser 와 Orderer 통신
    2. 채널 변경 내용 전송
  8. Org1MSP 를 채널1 에 등록
  9. Org2 에 대해서도 동일하게 진행...
  10. 최종적으로 채널1 에 참여 완료

위의 단계는 다음 장에서 자세히 다룰테니 지금은 저런 내용들이 createChannel 커맨드를 통해 진행 된다는 것을 알아두기만 하면 될 것 같습니다.

아까 채널 생성 전에 peer0.org1.example.com 의 컨테이너 로그를 확인 했는데, 이번에는 채널을 생성 후 참여를 완료 했으니 다시 확인해보도록 하겠습니다. 커맨드는 아래와 같습니다.

$ docker logs peer0.org1.example.com

아까 확인 했던 로그 마지막 라인이었던 No active channel passed 이후의 로그 출력 내용만 확인하면 아래와 같습니다.

2021-01-11 15:46:21.216 UTC [ledgermgmt] CreateLedger -> INFO 021 Creating ledger [channel1] with genesis block
2021-01-11 15:46:21.218 UTC [blkstorage] newBlockfileMgr -> INFO 022 Getting block information from block storage
2021-01-11 15:46:21.225 UTC [kvledger] commit -> INFO 023 [channel1] Committed block [0] with 1 transaction(s) in 3ms (state_validation=0ms block_and_pvtdata_commit=1ms state_commit=1ms) commitHash=[]
2021-01-11 15:46:21.225 UTC [kvledger] updateLedgerStatus -> INFO 024 Updating ledger [channel1] status to [ACTIVE]
2021-01-11 15:46:21.226 UTC [ledgermgmt] CreateLedger -> INFO 025 Created ledger [channel1] with genesis block
2021-01-11 15:46:21.230 UTC [peer.orderers] Update -> WARN 026 Config defines both orderer org specific endpoints and global endpoints, global endpoints will be ignored channel=channel1
2021-01-11 15:46:21.230 UTC [gossip.gossip] JoinChan -> INFO 027 Joining gossip network of channel channel1 with 2 organizations
2021-01-11 15:46:21.230 UTC [gossip.gossip] learnAnchorPeers -> INFO 028 No configured anchor peers of Org1MSP for channel channel1 to learn about
2021-01-11 15:46:21.230 UTC [gossip.gossip] learnAnchorPeers -> INFO 029 No configured anchor peers of Org2MSP for channel channel1 to learn about
2021-01-11 15:46:21.231 UTC [gossip.state] NewGossipStateProvider -> INFO 02a Updating metadata information for channel channel1, current ledger sequence is at = 0, next expected block is = 1
2021-01-11 15:46:21.231 UTC [deliveryClient] StartDeliverForChannel -> INFO 02b This peer will retrieve blocks from ordering service and disseminate to other peers in the organization for channel channel1
2021-01-11 15:46:21.232 UTC [endorser] callChaincode -> INFO 02c finished chaincode: cscc duration: 20ms channel= txID=13ff55aa
2021-01-11 15:46:21.232 UTC [comm.grpc.server] 1 -> INFO 02d unary call completed grpc.service=protos.Endorser grpc.method=ProcessProposal grpc.peer_address=172.19.0.1:60744 grpc.code=OK grpc.call_duration=21.914344ms
2021-01-11 15:46:24.952 UTC [gossip.privdata] StoreBlock -> INFO 02e Received block [1] from buffer channel=channel1
2021-01-11 15:46:24.954 UTC [comm.grpc.server] 1 -> INFO 02f unary call completed grpc.service=gossip.Gossip grpc.method=Ping grpc.request_deadline=2021-01-11T15:46:26.953Z grpc.peer_address=172.19.0.4:41964 grpc.peer_subject="CN=peer0.org2.example.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=118.46µs
2021-01-11 15:46:24.958 UTC [gossip.comm] GossipStream -> INFO 030 Peer 97512c2cb740626693874a1d426945f897faa0e3d122ff7be18acf177d52fe5c (172.19.0.4:41964) probed us
2021-01-11 15:46:24.958 UTC [comm.grpc.server] 1 -> INFO 031 streaming call completed grpc.service=gossip.Gossip grpc.method=GossipStream grpc.request_deadline=2021-01-11T15:46:34.955Z grpc.peer_address=172.19.0.4:41964 grpc.peer_subject="CN=peer0.org2.example.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=2.512375ms
2021-01-11 15:46:24.961 UTC [comm.grpc.server] 1 -> INFO 032 unary call completed grpc.service=gossip.Gossip grpc.method=Ping grpc.request_deadline=2021-01-11T15:46:26.961Z grpc.peer_address=172.19.0.4:41966 grpc.peer_subject="CN=peer0.org2.example.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=38.789µs
2021-01-11 15:46:24.963 UTC [peer.orderers] Update -> WARN 033 Config defines both orderer org specific endpoints and global endpoints, global endpoints will be ignored channel=channel1
2021-01-11 15:46:24.963 UTC [gossip.gossip] JoinChan -> INFO 034 Joining gossip network of channel channel1 with 2 organizations
2021-01-11 15:46:24.963 UTC [gossip.gossip] learnAnchorPeers -> INFO 035 Learning about the configured anchor peers of Org1MSP for channel channel1: [{peer0.org1.example.com 7051}]
2021-01-11 15:46:24.963 UTC [gossip.gossip] learnAnchorPeers -> INFO 036 Anchor peer for channel channel1 with same endpoint, skipping connecting to myself
2021-01-11 15:46:24.963 UTC [gossip.gossip] learnAnchorPeers -> INFO 037 No configured anchor peers of Org2MSP for channel channel1 to learn about
2021-01-11 15:46:24.964 UTC [committer.txvalidator] Validate -> INFO 038 [channel1] Validated block [1] in 11ms
2021-01-11 15:46:24.971 UTC [kvledger] commit -> INFO 039 [channel1] Committed block [1] with 1 transaction(s) in 6ms (state_validation=0ms block_and_pvtdata_commit=3ms state_commit=1ms) commitHash=[47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254]
2021-01-11 15:46:25.363 UTC [gossip.privdata] StoreBlock -> INFO 03a Received block [2] from buffer channel=channel1
2021-01-11 15:46:25.368 UTC [peer.orderers] Update -> WARN 03b Config defines both orderer org specific endpoints and global endpoints, global endpoints will be ignored channel=channel1
2021-01-11 15:46:25.368 UTC [gossip.gossip] JoinChan -> INFO 03c Joining gossip network of channel channel1 with 2 organizations
2021-01-11 15:46:25.368 UTC [gossip.gossip] learnAnchorPeers -> INFO 03d Learning about the configured anchor peers of Org2MSP for channel channel1: [{peer0.org2.example.com 9051}]
2021-01-11 15:46:25.368 UTC [gossip.gossip] learnAnchorPeers -> INFO 03e Learning about the configured anchor peers of Org1MSP for channel channel1: [{peer0.org1.example.com 7051}]
2021-01-11 15:46:25.368 UTC [gossip.gossip] learnAnchorPeers -> INFO 03f Anchor peer for channel channel1 with same endpoint, skipping connecting to myself
2021-01-11 15:46:25.369 UTC [committer.txvalidator] Validate -> INFO 040 [channel1] Validated block [2] in 5ms
2021-01-11 15:46:25.373 UTC [comm.grpc.server] 1 -> INFO 041 unary call completed grpc.service=gossip.Gossip grpc.method=Ping grpc.request_deadline=2021-01-11T15:46:27.373Z grpc.peer_address=172.19.0.4:41974 grpc.peer_subject="CN=peer0.org2.example.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=38.693µs
2021-01-11 15:46:25.374 UTC [gossip.comm] GossipStream -> INFO 042 Peer 97512c2cb740626693874a1d426945f897faa0e3d122ff7be18acf177d52fe5c (172.19.0.4:41974) probed us
2021-01-11 15:46:25.375 UTC [comm.grpc.server] 1 -> INFO 043 streaming call completed grpc.service=gossip.Gossip grpc.method=GossipStream grpc.request_deadline=2021-01-11T15:46:35.373Z grpc.peer_address=172.19.0.4:41974 grpc.peer_subject="CN=peer0.org2.example.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=1.280896ms
2021-01-11 15:46:25.376 UTC [kvledger] commit -> INFO 044 [channel1] Committed block [2] with 1 transaction(s) in 7ms (state_validation=0ms block_and_pvtdata_commit=5ms state_commit=0ms) commitHash=[5f88b61407b149a48413433f4670c46531e5c4a8febdc339a9536ff8716a559e]
2021-01-11 15:46:26.232 UTC [gossip.channel] reportMembershipChanges -> INFO 045 [[channel1] Membership view has changed. peers went online:  [[peer0.org2.example.com:9051 ]] , current view:  [[peer0.org2.example.com:9051 ]]]

로그 내용을 하나씩 살펴보다보면 이전에 createChannel 커맨드의 출력 내용과 비슷한 것을 알 수 있습니다. 이는 peer 의 로그를 network.sh 내부에서 명령 실행시 같이 출력하기 때문입니다. 하지만 지금 살펴보고자 하는 것은 다음과 같은 내용입니다.

[ledgermgmt] CreateLedger -> Creating ledger [channel1] with genesis block
[kvledger] commit -> [channel1] Committed block [0] with 1 transaction(s)
[kvledger] updateLedgerStatus -> Updating ledger [channel1] status to [ACTIVE]
[ledgermgmt] CreateLedger -> Created ledger [channel1] with genesis block
[gossip.privdata] StoreBlock -> Received block [1] from buffer channel=channel1
[kvledger] commit -> [channel1] Validated block [1]
[kvledger] commit -> [channel1] Committed block [1] with 1 transaction(s)
[gossip.privdata] StoreBlock -> Received block [2] from buffer channel=channel1
[committer.txvalidator] Validate -> [channel1] Validated block [2]
Committed block [2] with 1 transaction(s)
[[channel1] Membership view has changed. peers went online:  [[peer0.org2.example.com:9051 ]] , current view:  [[peer0.org2.example.com:9051 ]]]

이는 채널 생성 트랜잭션의 생성과 그 이후 합의 과정을 보여주고 있습니다. 이러한 과정을 통해 최종적으로 채널1 에 두 peer 노드가 참여하고 있다는 것을 확인 할 수 있습니다.

지금까지 간단한 ./network.sh 쉘 스크립트를 활용한 네트워크 구축을 실습해보았습니다. 다음 장에서는 실제 커맨드 실행을 통해 하나씩 그 과정을 짚어보도록 하겠습니다.

댓글