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  }