github.com/lzy4123/fabric@v2.1.1+incompatible/orderer/consensus/etcdraft/blockpuller_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package etcdraft_test 8 9 import ( 10 "io/ioutil" 11 "testing" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hyperledger/fabric-protos-go/common" 15 "github.com/hyperledger/fabric/bccsp/sw" 16 "github.com/hyperledger/fabric/common/crypto/tlsgen" 17 "github.com/hyperledger/fabric/internal/pkg/comm" 18 "github.com/hyperledger/fabric/orderer/common/cluster" 19 "github.com/hyperledger/fabric/orderer/common/cluster/mocks" 20 "github.com/hyperledger/fabric/orderer/common/localconfig" 21 "github.com/hyperledger/fabric/orderer/consensus" 22 "github.com/hyperledger/fabric/orderer/consensus/etcdraft" 23 "github.com/hyperledger/fabric/orderer/mocks/common/multichannel" 24 "github.com/hyperledger/fabric/protoutil" 25 "github.com/stretchr/testify/assert" 26 ) 27 28 func TestEndpointconfigFromFromSupport(t *testing.T) { 29 blockBytes, err := ioutil.ReadFile("testdata/mychannel.block") 30 assert.NoError(t, err) 31 32 goodConfigBlock := &common.Block{} 33 assert.NoError(t, proto.Unmarshal(blockBytes, goodConfigBlock)) 34 35 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 36 assert.NoError(t, err) 37 38 for _, testCase := range []struct { 39 name string 40 height uint64 41 blockAtHeight *common.Block 42 lastConfigBlock *common.Block 43 expectedError string 44 }{ 45 { 46 name: "Block returns nil", 47 expectedError: "unable to retrieve block [99]", 48 height: 100, 49 }, 50 { 51 name: "Last config block number cannot be retrieved from last block", 52 blockAtHeight: &common.Block{}, 53 expectedError: "failed to retrieve metadata: no metadata in block", 54 height: 100, 55 }, 56 { 57 name: "Last config block cannot be retrieved", 58 blockAtHeight: &common.Block{ 59 Metadata: &common.BlockMetadata{ 60 Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{ 61 Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 42}), 62 })}, 63 }, 64 }, 65 expectedError: "unable to retrieve last config block [42]", 66 height: 100, 67 }, 68 { 69 name: "Last config block is retrieved but it is invalid", 70 blockAtHeight: &common.Block{ 71 Metadata: &common.BlockMetadata{ 72 Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{ 73 Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 42}), 74 })}, 75 }, 76 }, 77 lastConfigBlock: &common.Block{}, 78 expectedError: "block data is nil", 79 height: 100, 80 }, 81 { 82 name: "Last config block is retrieved and is valid", 83 blockAtHeight: &common.Block{ 84 Metadata: &common.BlockMetadata{ 85 Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{ 86 Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 42}), 87 })}, 88 }, 89 }, 90 lastConfigBlock: goodConfigBlock, 91 height: 100, 92 }, 93 } { 94 t.Run(testCase.name, func(t *testing.T) { 95 cs := &multichannel.ConsenterSupport{ 96 BlockByIndex: make(map[uint64]*common.Block), 97 } 98 cs.HeightVal = testCase.height 99 cs.BlockByIndex[cs.HeightVal-1] = testCase.blockAtHeight 100 cs.BlockByIndex[42] = testCase.lastConfigBlock 101 102 certs, err := etcdraft.EndpointconfigFromSupport(cs, cryptoProvider) 103 if testCase.expectedError == "" { 104 assert.NotNil(t, certs) 105 assert.NoError(t, err) 106 return 107 } 108 assert.EqualError(t, err, testCase.expectedError) 109 assert.Nil(t, certs) 110 }) 111 } 112 } 113 114 func TestNewBlockPuller(t *testing.T) { 115 ca, err := tlsgen.NewCA() 116 assert.NoError(t, err) 117 118 blockBytes, err := ioutil.ReadFile("testdata/mychannel.block") 119 assert.NoError(t, err) 120 121 goodConfigBlock := &common.Block{} 122 assert.NoError(t, proto.Unmarshal(blockBytes, goodConfigBlock)) 123 124 lastBlock := &common.Block{ 125 Metadata: &common.BlockMetadata{ 126 Metadata: [][]byte{{}, protoutil.MarshalOrPanic(&common.Metadata{ 127 Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: 42}), 128 })}, 129 }, 130 } 131 132 cs := &multichannel.ConsenterSupport{ 133 HeightVal: 100, 134 BlockByIndex: map[uint64]*common.Block{ 135 42: goodConfigBlock, 136 99: lastBlock, 137 }, 138 } 139 140 dialer := &cluster.PredicateDialer{ 141 Config: comm.ClientConfig{ 142 SecOpts: comm.SecureOptions{ 143 Certificate: ca.CertBytes(), 144 }, 145 }, 146 } 147 148 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 149 assert.NoError(t, err) 150 151 bp, err := etcdraft.NewBlockPuller(cs, dialer, localconfig.Cluster{}, cryptoProvider) 152 assert.NoError(t, err) 153 assert.NotNil(t, bp) 154 155 // From here on, we test failures. 156 for _, testCase := range []struct { 157 name string 158 expectedError string 159 cs consensus.ConsenterSupport 160 dialer *cluster.PredicateDialer 161 certificate []byte 162 }{ 163 { 164 name: "Unable to retrieve block", 165 cs: &multichannel.ConsenterSupport{ 166 HeightVal: 100, 167 }, 168 certificate: ca.CertBytes(), 169 expectedError: "unable to retrieve block [99]", 170 dialer: dialer, 171 }, 172 { 173 name: "Certificate is invalid", 174 cs: cs, 175 certificate: []byte{1, 2, 3}, 176 expectedError: "client certificate isn't in PEM format: \x01\x02\x03", 177 dialer: dialer, 178 }, 179 } { 180 t.Run(testCase.name, func(t *testing.T) { 181 testCase.dialer.Config.SecOpts.Certificate = testCase.certificate 182 bp, err := etcdraft.NewBlockPuller(testCase.cs, testCase.dialer, localconfig.Cluster{}, cryptoProvider) 183 assert.Nil(t, bp) 184 assert.EqualError(t, err, testCase.expectedError) 185 }) 186 } 187 } 188 189 func TestLedgerBlockPuller(t *testing.T) { 190 currHeight := func() uint64 { 191 return 1 192 } 193 194 genesisBlock := &common.Block{Header: &common.BlockHeader{Number: 0}} 195 notGenesisBlock := &common.Block{Header: &common.BlockHeader{Number: 1}} 196 197 blockRetriever := &mocks.BlockRetriever{} 198 blockRetriever.On("Block", uint64(0)).Return(genesisBlock) 199 200 puller := &mocks.ChainPuller{} 201 puller.On("PullBlock", uint64(1)).Return(notGenesisBlock) 202 203 lbp := &etcdraft.LedgerBlockPuller{ 204 Height: currHeight, 205 BlockRetriever: blockRetriever, 206 BlockPuller: puller, 207 } 208 209 assert.Equal(t, genesisBlock, lbp.PullBlock(0)) 210 assert.Equal(t, notGenesisBlock, lbp.PullBlock(1)) 211 }