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