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