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  }