github.com/kaituanwang/hyperledger@v2.0.1+incompatible/common/ledger/blkstorage/fsblkstorage/block_serialization_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 SPDX-License-Identifier: Apache-2.0 4 */ 5 6 package fsblkstorage 7 8 import ( 9 "testing" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/hyperledger/fabric-protos-go/common" 13 "github.com/hyperledger/fabric/common/ledger/testutil" 14 "github.com/hyperledger/fabric/protoutil" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func TestBlockSerialization(t *testing.T) { 19 block := testutil.ConstructTestBlock(t, 1, 10, 100) 20 21 // malformed Payload 22 block.Data.Data[1] = protoutil.MarshalOrPanic(&common.Envelope{ 23 Payload: []byte("Malformed Payload"), 24 }) 25 26 // empty TxID 27 block.Data.Data[2] = protoutil.MarshalOrPanic(&common.Envelope{ 28 Payload: protoutil.MarshalOrPanic(&common.Payload{ 29 Header: &common.Header{ 30 ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{ 31 TxId: "", 32 }), 33 }, 34 }), 35 }) 36 37 bb, _, err := serializeBlock(block) 38 assert.NoError(t, err) 39 deserializedBlock, err := deserializeBlock(bb) 40 assert.NoError(t, err) 41 assert.Equal(t, block, deserializedBlock) 42 } 43 44 func TestSerializedBlockInfo(t *testing.T) { 45 c := &testutilTxIDComputator{ 46 t: t, 47 malformedTxNums: map[int]struct{}{}, 48 } 49 50 t.Run("txID is present in all transaction", func(t *testing.T) { 51 block := testutil.ConstructTestBlock(t, 1, 10, 100) 52 testSerializedBlockInfo(t, block, c) 53 }) 54 55 t.Run("txID is not present in one of the transactions", func(t *testing.T) { 56 block := testutil.ConstructTestBlock(t, 1, 10, 100) 57 // empty txid for txNum 2 58 block.Data.Data[1] = protoutil.MarshalOrPanic(&common.Envelope{ 59 Payload: protoutil.MarshalOrPanic(&common.Payload{ 60 Header: &common.Header{ 61 ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{ 62 TxId: "", 63 }), 64 SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{ 65 Creator: []byte("fake user"), 66 Nonce: []byte("fake nonce"), 67 }), 68 }, 69 }), 70 }) 71 testSerializedBlockInfo(t, block, c) 72 }) 73 74 t.Run("malformed tx-envelop for one of the transactions", func(t *testing.T) { 75 block := testutil.ConstructTestBlock(t, 1, 10, 100) 76 // malformed Payload for 77 block.Data.Data[1] = protoutil.MarshalOrPanic(&common.Envelope{ 78 Payload: []byte("Malformed Payload"), 79 }) 80 c.reset() 81 c.malformedTxNums[1] = struct{}{} 82 testSerializedBlockInfo(t, block, c) 83 }) 84 } 85 86 func testSerializedBlockInfo(t *testing.T, block *common.Block, c *testutilTxIDComputator) { 87 bb, info, err := serializeBlock(block) 88 assert.NoError(t, err) 89 infoFromBB, err := extractSerializedBlockInfo(bb) 90 assert.NoError(t, err) 91 assert.Equal(t, info, infoFromBB) 92 assert.Equal(t, len(block.Data.Data), len(info.txOffsets)) 93 for txIndex, txEnvBytes := range block.Data.Data { 94 txid := c.computeExpectedTxID(txIndex, txEnvBytes) 95 indexInfo := info.txOffsets[txIndex] 96 indexTxID := indexInfo.txID 97 indexOffset := indexInfo.loc 98 99 assert.Equal(t, indexTxID, txid) 100 b := bb[indexOffset.offset:] 101 length, num := proto.DecodeVarint(b) 102 txEnvBytesFromBB := b[num : num+int(length)] 103 assert.Equal(t, txEnvBytes, txEnvBytesFromBB) 104 } 105 } 106 107 type testutilTxIDComputator struct { 108 t *testing.T 109 malformedTxNums map[int]struct{} 110 } 111 112 func (c *testutilTxIDComputator) computeExpectedTxID(txNum int, txEnvBytes []byte) string { 113 txid, err := protoutil.GetOrComputeTxIDFromEnvelope(txEnvBytes) 114 if _, ok := c.malformedTxNums[txNum]; ok { 115 assert.Error(c.t, err) 116 } else { 117 assert.NoError(c.t, err) 118 } 119 return txid 120 } 121 122 func (c *testutilTxIDComputator) reset() { 123 c.malformedTxNums = map[int]struct{}{} 124 }