github.com/kaituanwang/hyperledger@v2.0.1+incompatible/protoutil/txutils_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package protoutil_test
     8  
     9  import (
    10  	"encoding/hex"
    11  	"errors"
    12  	"strconv"
    13  	"testing"
    14  
    15  	"github.com/golang/protobuf/proto"
    16  	cb "github.com/hyperledger/fabric-protos-go/common"
    17  	pb "github.com/hyperledger/fabric-protos-go/peer"
    18  
    19  	"github.com/hyperledger/fabric/protoutil"
    20  	"github.com/hyperledger/fabric/protoutil/fakes"
    21  	"github.com/stretchr/testify/assert"
    22  )
    23  
    24  func TestGetPayloads(t *testing.T) {
    25  	var txAction *pb.TransactionAction
    26  	var err error
    27  
    28  	// good
    29  	ccActionBytes, _ := proto.Marshal(&pb.ChaincodeAction{
    30  		Results: []byte("results"),
    31  	})
    32  	proposalResponsePayload := &pb.ProposalResponsePayload{
    33  		Extension: ccActionBytes,
    34  	}
    35  	proposalResponseBytes, err := proto.Marshal(proposalResponsePayload)
    36  	ccActionPayload := &pb.ChaincodeActionPayload{
    37  		Action: &pb.ChaincodeEndorsedAction{
    38  			ProposalResponsePayload: proposalResponseBytes,
    39  		},
    40  	}
    41  	ccActionPayloadBytes, _ := proto.Marshal(ccActionPayload)
    42  	txAction = &pb.TransactionAction{
    43  		Payload: ccActionPayloadBytes,
    44  	}
    45  	_, _, err = protoutil.GetPayloads(txAction)
    46  	assert.NoError(t, err, "Unexpected error getting payload bytes")
    47  	t.Logf("error1 [%s]", err)
    48  
    49  	// nil proposal response extension
    50  	proposalResponseBytes, err = proto.Marshal(&pb.ProposalResponsePayload{
    51  		Extension: nil,
    52  	})
    53  	ccActionPayloadBytes, _ = proto.Marshal(&pb.ChaincodeActionPayload{
    54  		Action: &pb.ChaincodeEndorsedAction{
    55  			ProposalResponsePayload: proposalResponseBytes,
    56  		},
    57  	})
    58  	txAction = &pb.TransactionAction{
    59  		Payload: ccActionPayloadBytes,
    60  	}
    61  	_, _, err = protoutil.GetPayloads(txAction)
    62  	assert.Error(t, err, "Expected error with nil proposal response extension")
    63  	t.Logf("error2 [%s]", err)
    64  
    65  	// malformed proposal response payload
    66  	ccActionPayloadBytes, _ = proto.Marshal(&pb.ChaincodeActionPayload{
    67  		Action: &pb.ChaincodeEndorsedAction{
    68  			ProposalResponsePayload: []byte("bad payload"),
    69  		},
    70  	})
    71  	txAction = &pb.TransactionAction{
    72  		Payload: ccActionPayloadBytes,
    73  	}
    74  	_, _, err = protoutil.GetPayloads(txAction)
    75  	assert.Error(t, err, "Expected error with malformed proposal response payload")
    76  	t.Logf("error3 [%s]", err)
    77  
    78  	// malformed proposal response payload extension
    79  	proposalResponseBytes, _ = proto.Marshal(&pb.ProposalResponsePayload{
    80  		Extension: []byte("bad extension"),
    81  	})
    82  	ccActionPayloadBytes, _ = proto.Marshal(&pb.ChaincodeActionPayload{
    83  		Action: &pb.ChaincodeEndorsedAction{
    84  			ProposalResponsePayload: proposalResponseBytes,
    85  		},
    86  	})
    87  	txAction = &pb.TransactionAction{
    88  		Payload: ccActionPayloadBytes,
    89  	}
    90  	_, _, err = protoutil.GetPayloads(txAction)
    91  	assert.Error(t, err, "Expected error with malformed proposal response extension")
    92  	t.Logf("error4 [%s]", err)
    93  
    94  	// nil proposal response payload extension
    95  	proposalResponseBytes, _ = proto.Marshal(&pb.ProposalResponsePayload{
    96  		ProposalHash: []byte("hash"),
    97  	})
    98  	ccActionPayloadBytes, _ = proto.Marshal(&pb.ChaincodeActionPayload{
    99  		Action: &pb.ChaincodeEndorsedAction{
   100  			ProposalResponsePayload: proposalResponseBytes,
   101  		},
   102  	})
   103  	txAction = &pb.TransactionAction{
   104  		Payload: ccActionPayloadBytes,
   105  	}
   106  	_, _, err = protoutil.GetPayloads(txAction)
   107  	assert.Error(t, err, "Expected error with nil proposal response extension")
   108  	t.Logf("error5 [%s]", err)
   109  
   110  	// malformed transaction action payload
   111  	txAction = &pb.TransactionAction{
   112  		Payload: []byte("bad payload"),
   113  	}
   114  	_, _, err = protoutil.GetPayloads(txAction)
   115  	assert.Error(t, err, "Expected error with malformed transaction action payload")
   116  	t.Logf("error6 [%s]", err)
   117  
   118  }
   119  
   120  func TestCreateSignedTx(t *testing.T) {
   121  	var err error
   122  	prop := &pb.Proposal{}
   123  
   124  	signID := &fakes.SignerSerializer{}
   125  	signID.SerializeReturns([]byte("signer"), nil)
   126  	signerBytes, err := signID.Serialize()
   127  	assert.NoError(t, err, "Unexpected error serializing signing identity")
   128  
   129  	ccHeaderExtensionBytes := protoutil.MarshalOrPanic(&pb.ChaincodeHeaderExtension{})
   130  	chdrBytes := protoutil.MarshalOrPanic(&cb.ChannelHeader{
   131  		Extension: ccHeaderExtensionBytes,
   132  	})
   133  	shdrBytes := protoutil.MarshalOrPanic(&cb.SignatureHeader{
   134  		Creator: signerBytes,
   135  	})
   136  	responses := []*pb.ProposalResponse{{}}
   137  
   138  	// malformed signature header
   139  	headerBytes := protoutil.MarshalOrPanic(&cb.Header{
   140  		SignatureHeader: []byte("bad signature header"),
   141  	})
   142  	prop.Header = headerBytes
   143  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   144  	assert.Error(t, err, "Expected error with malformed signature header")
   145  
   146  	// set up the header bytes for the remaining tests
   147  	headerBytes, _ = proto.Marshal(&cb.Header{
   148  		ChannelHeader:   chdrBytes,
   149  		SignatureHeader: shdrBytes,
   150  	})
   151  	prop.Header = headerBytes
   152  
   153  	nonMatchingTests := []struct {
   154  		responses     []*pb.ProposalResponse
   155  		expectedError string
   156  	}{
   157  		// good responses, but different payloads
   158  		{
   159  			[]*pb.ProposalResponse{
   160  				{Payload: []byte("payload"), Response: &pb.Response{Status: int32(200)}},
   161  				{Payload: []byte("payload2"), Response: &pb.Response{Status: int32(200)}},
   162  			},
   163  			"ProposalResponsePayloads do not match",
   164  		},
   165  		// good response followed by bad response
   166  		{
   167  			[]*pb.ProposalResponse{
   168  				{Payload: []byte("payload"), Response: &pb.Response{Status: int32(200)}},
   169  				{Payload: []byte{}, Response: &pb.Response{Status: int32(500), Message: "failed to endorse"}},
   170  			},
   171  			"proposal response was not successful, error code 500, msg failed to endorse",
   172  		},
   173  		// bad response followed by good response
   174  		{
   175  			[]*pb.ProposalResponse{
   176  				{Payload: []byte{}, Response: &pb.Response{Status: int32(500), Message: "failed to endorse"}},
   177  				{Payload: []byte("payload"), Response: &pb.Response{Status: int32(200)}},
   178  			},
   179  			"proposal response was not successful, error code 500, msg failed to endorse",
   180  		},
   181  	}
   182  	for i, nonMatchingTest := range nonMatchingTests {
   183  		_, err = protoutil.CreateSignedTx(prop, signID, nonMatchingTest.responses...)
   184  		assert.EqualErrorf(t, err, nonMatchingTest.expectedError, "Expected non-matching response error '%v' for test %d", nonMatchingTest.expectedError, i)
   185  	}
   186  
   187  	// no endorsement
   188  	responses = []*pb.ProposalResponse{{
   189  		Payload: []byte("payload"),
   190  		Response: &pb.Response{
   191  			Status: int32(200),
   192  		},
   193  	}}
   194  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   195  	assert.Error(t, err, "Expected error with no endorsements")
   196  
   197  	// success
   198  	responses = []*pb.ProposalResponse{{
   199  		Payload:     []byte("payload"),
   200  		Endorsement: &pb.Endorsement{},
   201  		Response: &pb.Response{
   202  			Status: int32(200),
   203  		},
   204  	}}
   205  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   206  	assert.NoError(t, err, "Unexpected error creating signed transaction")
   207  	t.Logf("error: [%s]", err)
   208  
   209  	//
   210  	//
   211  	// additional failure cases
   212  	prop = &pb.Proposal{}
   213  	responses = []*pb.ProposalResponse{}
   214  	// no proposal responses
   215  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   216  	assert.Error(t, err, "Expected error with no proposal responses")
   217  
   218  	// missing proposal header
   219  	responses = append(responses, &pb.ProposalResponse{})
   220  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   221  	assert.Error(t, err, "Expected error with no proposal header")
   222  
   223  	// bad proposal payload
   224  	prop.Payload = []byte("bad payload")
   225  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   226  	assert.Error(t, err, "Expected error with malformed proposal payload")
   227  
   228  	// bad payload header
   229  	prop.Header = []byte("bad header")
   230  	_, err = protoutil.CreateSignedTx(prop, signID, responses...)
   231  	assert.Error(t, err, "Expected error with malformed proposal header")
   232  
   233  }
   234  
   235  func TestCreateSignedTxStatus(t *testing.T) {
   236  	serializedExtension, err := proto.Marshal(&pb.ChaincodeHeaderExtension{})
   237  	assert.NoError(t, err)
   238  	serializedChannelHeader, err := proto.Marshal(&cb.ChannelHeader{
   239  		Extension: serializedExtension,
   240  	})
   241  	assert.NoError(t, err)
   242  
   243  	signingID := &fakes.SignerSerializer{}
   244  	signingID.SerializeReturns([]byte("signer"), nil)
   245  	serializedSigningID, err := signingID.Serialize()
   246  	assert.NoError(t, err)
   247  	serializedSignatureHeader, err := proto.Marshal(&cb.SignatureHeader{
   248  		Creator: serializedSigningID,
   249  	})
   250  	assert.NoError(t, err)
   251  
   252  	header := &cb.Header{
   253  		ChannelHeader:   serializedChannelHeader,
   254  		SignatureHeader: serializedSignatureHeader,
   255  	}
   256  
   257  	serializedHeader, err := proto.Marshal(header)
   258  	assert.NoError(t, err)
   259  
   260  	proposal := &pb.Proposal{
   261  		Header: serializedHeader,
   262  	}
   263  
   264  	tests := []struct {
   265  		status      int32
   266  		expectedErr string
   267  	}{
   268  		{status: 0, expectedErr: "proposal response was not successful, error code 0, msg response-message"},
   269  		{status: 199, expectedErr: "proposal response was not successful, error code 199, msg response-message"},
   270  		{status: 200, expectedErr: ""},
   271  		{status: 201, expectedErr: ""},
   272  		{status: 399, expectedErr: ""},
   273  		{status: 400, expectedErr: "proposal response was not successful, error code 400, msg response-message"},
   274  	}
   275  	for _, tc := range tests {
   276  		t.Run(strconv.Itoa(int(tc.status)), func(t *testing.T) {
   277  			response := &pb.ProposalResponse{
   278  				Payload:     []byte("payload"),
   279  				Endorsement: &pb.Endorsement{},
   280  				Response: &pb.Response{
   281  					Status:  tc.status,
   282  					Message: "response-message",
   283  				},
   284  			}
   285  
   286  			_, err := protoutil.CreateSignedTx(proposal, signingID, response)
   287  			if tc.expectedErr == "" {
   288  				assert.NoError(t, err)
   289  			} else {
   290  				assert.EqualError(t, err, tc.expectedErr)
   291  			}
   292  		})
   293  	}
   294  }
   295  
   296  func TestCreateSignedEnvelope(t *testing.T) {
   297  	var env *cb.Envelope
   298  	channelID := "mychannelID"
   299  	msg := &cb.ConfigEnvelope{}
   300  
   301  	id := &fakes.SignerSerializer{}
   302  	id.SignReturnsOnCall(0, []byte("goodsig"), nil)
   303  	id.SignReturnsOnCall(1, nil, errors.New("bad signature"))
   304  	env, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID,
   305  		id, msg, int32(1), uint64(1))
   306  	assert.NoError(t, err, "Unexpected error creating signed envelope")
   307  	assert.NotNil(t, env, "Envelope should not be nil")
   308  	// mock sign returns the bytes to be signed
   309  	assert.Equal(t, []byte("goodsig"), env.Signature, "Unexpected signature returned")
   310  	payload := &cb.Payload{}
   311  	err = proto.Unmarshal(env.Payload, payload)
   312  	assert.NoError(t, err, "Failed to unmarshal payload")
   313  	data := &cb.ConfigEnvelope{}
   314  	err = proto.Unmarshal(payload.Data, data)
   315  	assert.NoError(t, err, "Expected payload data to be a config envelope")
   316  	assert.Equal(t, msg, data, "Payload data does not match expected value")
   317  
   318  	_, err = protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID,
   319  		id, &cb.ConfigEnvelope{}, int32(1), uint64(1))
   320  	assert.Error(t, err, "Expected sign error")
   321  }
   322  
   323  func TestCreateSignedEnvelopeNilSigner(t *testing.T) {
   324  	var env *cb.Envelope
   325  	channelID := "mychannelID"
   326  	msg := &cb.ConfigEnvelope{}
   327  
   328  	env, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID,
   329  		nil, msg, int32(1), uint64(1))
   330  	assert.NoError(t, err, "Unexpected error creating signed envelope")
   331  	assert.NotNil(t, env, "Envelope should not be nil")
   332  	assert.Empty(t, env.Signature, "Signature should have been empty")
   333  	payload := &cb.Payload{}
   334  	err = proto.Unmarshal(env.Payload, payload)
   335  	assert.NoError(t, err, "Failed to unmarshal payload")
   336  	data := &cb.ConfigEnvelope{}
   337  	err = proto.Unmarshal(payload.Data, data)
   338  	assert.NoError(t, err, "Expected payload data to be a config envelope")
   339  	assert.Equal(t, msg, data, "Payload data does not match expected value")
   340  }
   341  
   342  func TestGetSignedProposal(t *testing.T) {
   343  	var signedProp *pb.SignedProposal
   344  	var err error
   345  
   346  	sig := []byte("signature")
   347  
   348  	signID := &fakes.SignerSerializer{}
   349  	signID.SignReturns(sig, nil)
   350  
   351  	prop := &pb.Proposal{}
   352  	propBytes, _ := proto.Marshal(prop)
   353  	signedProp, err = protoutil.GetSignedProposal(prop, signID)
   354  	assert.NoError(t, err, "Unexpected error getting signed proposal")
   355  	assert.Equal(t, propBytes, signedProp.ProposalBytes,
   356  		"Proposal bytes did not match expected value")
   357  	assert.Equal(t, sig, signedProp.Signature,
   358  		"Signature did not match expected value")
   359  
   360  	_, err = protoutil.GetSignedProposal(nil, signID)
   361  	assert.Error(t, err, "Expected error with nil proposal")
   362  	_, err = protoutil.GetSignedProposal(prop, nil)
   363  	assert.Error(t, err, "Expected error with nil signing identity")
   364  
   365  }
   366  
   367  func TestMockSignedEndorserProposalOrPanic(t *testing.T) {
   368  	var prop *pb.Proposal
   369  	var signedProp *pb.SignedProposal
   370  
   371  	ccProposal := &pb.ChaincodeProposalPayload{}
   372  	cis := &pb.ChaincodeInvocationSpec{}
   373  	chainID := "testchannelid"
   374  	sig := []byte("signature")
   375  	creator := []byte("creator")
   376  	cs := &pb.ChaincodeSpec{
   377  		ChaincodeId: &pb.ChaincodeID{
   378  			Name: "mychaincode",
   379  		},
   380  	}
   381  
   382  	signedProp, prop = protoutil.MockSignedEndorserProposalOrPanic(chainID, cs,
   383  		creator, sig)
   384  	assert.Equal(t, sig, signedProp.Signature,
   385  		"Signature did not match expected result")
   386  	propBytes, _ := proto.Marshal(prop)
   387  	assert.Equal(t, propBytes, signedProp.ProposalBytes,
   388  		"Proposal bytes do not match expected value")
   389  	err := proto.Unmarshal(prop.Payload, ccProposal)
   390  	assert.NoError(t, err, "Expected ChaincodeProposalPayload")
   391  	err = proto.Unmarshal(ccProposal.Input, cis)
   392  	assert.NoError(t, err, "Expected ChaincodeInvocationSpec")
   393  	assert.Equal(t, cs.ChaincodeId.Name, cis.ChaincodeSpec.ChaincodeId.Name,
   394  		"Chaincode name did not match expected value")
   395  }
   396  
   397  func TestMockSignedEndorserProposal2OrPanic(t *testing.T) {
   398  	var prop *pb.Proposal
   399  	var signedProp *pb.SignedProposal
   400  
   401  	ccProposal := &pb.ChaincodeProposalPayload{}
   402  	cis := &pb.ChaincodeInvocationSpec{}
   403  	chainID := "testchannelid"
   404  	sig := []byte("signature")
   405  	signID := &fakes.SignerSerializer{}
   406  	signID.SignReturns(sig, nil)
   407  
   408  	signedProp, prop = protoutil.MockSignedEndorserProposal2OrPanic(chainID,
   409  		&pb.ChaincodeSpec{}, signID)
   410  	assert.Equal(t, sig, signedProp.Signature,
   411  		"Signature did not match expected result")
   412  	propBytes, _ := proto.Marshal(prop)
   413  	assert.Equal(t, propBytes, signedProp.ProposalBytes,
   414  		"Proposal bytes do not match expected value")
   415  	err := proto.Unmarshal(prop.Payload, ccProposal)
   416  	assert.NoError(t, err, "Expected ChaincodeProposalPayload")
   417  	err = proto.Unmarshal(ccProposal.Input, cis)
   418  	assert.NoError(t, err, "Expected ChaincodeInvocationSpec")
   419  }
   420  
   421  func TestGetBytesProposalPayloadForTx(t *testing.T) {
   422  	input := &pb.ChaincodeProposalPayload{
   423  		Input:        []byte("input"),
   424  		TransientMap: make(map[string][]byte),
   425  	}
   426  	expected, _ := proto.Marshal(&pb.ChaincodeProposalPayload{
   427  		Input: []byte("input"),
   428  	})
   429  
   430  	result, err := protoutil.GetBytesProposalPayloadForTx(input)
   431  	assert.NoError(t, err, "Unexpected error getting proposal payload")
   432  	assert.Equal(t, expected, result, "Payload does not match expected value")
   433  
   434  	_, err = protoutil.GetBytesProposalPayloadForTx(nil)
   435  	assert.Error(t, err, "Expected error with nil proposal payload")
   436  }
   437  
   438  func TestGetProposalHash2(t *testing.T) {
   439  	expectedHashHex := "7b622ef4e1ab9b7093ec3bbfbca17d5d6f14a437914a6839319978a7034f7960"
   440  	expectedHash, _ := hex.DecodeString(expectedHashHex)
   441  	hdr := &cb.Header{
   442  		ChannelHeader:   []byte("chdr"),
   443  		SignatureHeader: []byte("shdr"),
   444  	}
   445  	propHash, err := protoutil.GetProposalHash2(hdr, []byte("ccproppayload"))
   446  	assert.NoError(t, err, "Unexpected error getting hash2 for proposal")
   447  	t.Logf("%x", propHash)
   448  	assert.Equal(t, expectedHash, propHash,
   449  		"Proposal hash did not match expected hash")
   450  
   451  	propHash, err = protoutil.GetProposalHash2(&cb.Header{},
   452  		[]byte("ccproppayload"))
   453  	assert.Error(t, err, "Expected error with nil arguments")
   454  }
   455  
   456  func TestGetProposalHash1(t *testing.T) {
   457  	expectedHashHex := "d4c1e3cac2105da5fddc2cfe776d6ec28e4598cf1e6fa51122c7f70d8076437b"
   458  	expectedHash, _ := hex.DecodeString(expectedHashHex)
   459  	hdr := &cb.Header{
   460  		ChannelHeader:   []byte("chdr"),
   461  		SignatureHeader: []byte("shdr"),
   462  	}
   463  
   464  	ccProposal, _ := proto.Marshal(&pb.ChaincodeProposalPayload{})
   465  
   466  	propHash, err := protoutil.GetProposalHash1(hdr, ccProposal)
   467  	assert.NoError(t, err, "Unexpected error getting hash for proposal")
   468  	t.Logf("%x", propHash)
   469  	assert.Equal(t, expectedHash, propHash,
   470  		"Proposal hash did not match expected hash")
   471  
   472  	propHash, err = protoutil.GetProposalHash1(hdr, []byte("ccproppayload"))
   473  	assert.Error(t, err,
   474  		"Expected error with malformed chaincode proposal payload")
   475  
   476  	propHash, err = protoutil.GetProposalHash1(&cb.Header{}, []byte("ccproppayload"))
   477  	assert.Error(t, err, "Expected error with nil arguments")
   478  }
   479  
   480  func TestCreateProposalResponseFailure(t *testing.T) {
   481  	// create a proposal from a ChaincodeInvocationSpec
   482  	prop, _, err := protoutil.CreateChaincodeProposal(cb.HeaderType_ENDORSER_TRANSACTION, testChannelID, createCIS(), signerSerialized)
   483  	if err != nil {
   484  		t.Fatalf("Could not create chaincode proposal, err %s\n", err)
   485  		return
   486  	}
   487  
   488  	response := &pb.Response{Status: 502, Payload: []byte("Invalid function name")}
   489  	result := []byte("res")
   490  
   491  	prespFailure, err := protoutil.CreateProposalResponseFailure(prop.Header, prop.Payload, response, result, nil, "foo")
   492  	if err != nil {
   493  		t.Fatalf("Could not create proposal response failure, err %s\n", err)
   494  		return
   495  	}
   496  
   497  	assert.Equal(t, int32(502), prespFailure.Response.Status)
   498  	// drilldown into the response to find the chaincode response
   499  	pRespPayload, err := protoutil.UnmarshalProposalResponsePayload(prespFailure.Payload)
   500  	assert.NoError(t, err, "Error while unmarshaling proposal response payload: %s", err)
   501  	ca, err := protoutil.UnmarshalChaincodeAction(pRespPayload.Extension)
   502  	assert.NoError(t, err, "Error while unmarshaling chaincode action: %s", err)
   503  
   504  	assert.Equal(t, int32(502), ca.Response.Status)
   505  	assert.Equal(t, "Invalid function name", string(ca.Response.Payload))
   506  }
   507  
   508  func TestGetorComputeTxIDFromEnvelope(t *testing.T) {
   509  	t.Run("txID is present in the envelope", func(t *testing.T) {
   510  		txID := "709184f9d24f6ade8fcd4d6521a6eef295fef6c2e67216c58b68ac15e8946492"
   511  		envelopeBytes := createSampleTxEnvelopeBytes(txID)
   512  		actualTxID, err := protoutil.GetOrComputeTxIDFromEnvelope(envelopeBytes)
   513  		assert.Nil(t, err)
   514  		assert.Equal(t, "709184f9d24f6ade8fcd4d6521a6eef295fef6c2e67216c58b68ac15e8946492", actualTxID)
   515  	})
   516  
   517  	t.Run("txID is not present in the envelope", func(t *testing.T) {
   518  		txID := ""
   519  		envelopeBytes := createSampleTxEnvelopeBytes(txID)
   520  		actualTxID, err := protoutil.GetOrComputeTxIDFromEnvelope(envelopeBytes)
   521  		assert.Nil(t, err)
   522  		assert.Equal(t, "709184f9d24f6ade8fcd4d6521a6eef295fef6c2e67216c58b68ac15e8946492", actualTxID)
   523  
   524  	})
   525  }
   526  
   527  func createSampleTxEnvelopeBytes(txID string) []byte {
   528  	chdr := &cb.ChannelHeader{
   529  		TxId: "709184f9d24f6ade8fcd4d6521a6eef295fef6c2e67216c58b68ac15e8946492",
   530  	}
   531  	chdrBytes := protoutil.MarshalOrPanic(chdr)
   532  
   533  	shdr := &cb.SignatureHeader{
   534  		Nonce:   []byte("nonce"),
   535  		Creator: []byte("creator"),
   536  	}
   537  	shdrBytes := protoutil.MarshalOrPanic(shdr)
   538  
   539  	hdr := &cb.Header{
   540  		ChannelHeader:   chdrBytes,
   541  		SignatureHeader: shdrBytes,
   542  	}
   543  
   544  	payload := &cb.Payload{
   545  		Header: hdr,
   546  	}
   547  	payloadBytes := protoutil.MarshalOrPanic(payload)
   548  
   549  	envelope := &cb.Envelope{
   550  		Payload: payloadBytes,
   551  	}
   552  	return protoutil.MarshalOrPanic(envelope)
   553  
   554  }