github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/protos/utils/proputils_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package utils_test
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/sha256"
    22  	"encoding/hex"
    23  	"fmt"
    24  	"os"
    25  	"reflect"
    26  	"testing"
    27  
    28  	"github.com/golang/protobuf/proto"
    29  	"github.com/hyperledger/fabric/common/util"
    30  	"github.com/hyperledger/fabric/msp"
    31  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    32  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    33  	"github.com/hyperledger/fabric/protos/common"
    34  	pb "github.com/hyperledger/fabric/protos/peer"
    35  	"github.com/hyperledger/fabric/protos/utils"
    36  	"github.com/stretchr/testify/assert"
    37  )
    38  
    39  func createCIS() *pb.ChaincodeInvocationSpec {
    40  	return &pb.ChaincodeInvocationSpec{
    41  		ChaincodeSpec: &pb.ChaincodeSpec{
    42  			Type:        pb.ChaincodeSpec_GOLANG,
    43  			ChaincodeId: &pb.ChaincodeID{Name: "chaincode_name"},
    44  			Input:       &pb.ChaincodeInput{Args: [][]byte{[]byte("arg1"), []byte("arg2")}}}}
    45  }
    46  
    47  func TestNilProposal(t *testing.T) {
    48  	// pass nil to all function which accept *peer.Proposal
    49  	_, err := utils.GetChaincodeInvocationSpec(nil)
    50  	assert.Error(t, err, "Expected error with nil proposal")
    51  	_, _, err = utils.GetChaincodeProposalContext(nil)
    52  	assert.Error(t, err, "Expected error with nil proposal")
    53  	_, err = utils.GetNonce(nil)
    54  	assert.Error(t, err, "Expected error with nil proposal")
    55  	_, err = utils.GetBytesProposal(nil)
    56  	assert.Error(t, err, "Expected error with nil proposal")
    57  	_, err = utils.ComputeProposalBinding(nil)
    58  	assert.Error(t, err, "Expected error with nil proposal")
    59  }
    60  
    61  func TestBadProposalHeaders(t *testing.T) {
    62  	// NOTE:  There is a lot of repetitive proposal validation code
    63  	// in multiple functions which should be refactored in the future.
    64  	// For now, simply consolidating the test cases
    65  
    66  	// emty header
    67  	prop := &pb.Proposal{
    68  		Header: []byte{},
    69  	}
    70  	_, _, err := utils.GetChaincodeProposalContext(prop)
    71  	assert.Error(t, err, "Expected error with empty proposal header")
    72  	_, err = utils.ComputeProposalBinding(prop)
    73  	assert.Error(t, err, "Expected error with empty proposal header")
    74  
    75  	// malformed proposal header
    76  	prop = &pb.Proposal{
    77  		Header:  []byte("bad header"),
    78  		Payload: []byte("payload"),
    79  	}
    80  	_, err = utils.GetHeader(prop.Header)
    81  	assert.Error(t, err, "Expected error with malformed proposal header")
    82  	_, err = utils.GetChaincodeInvocationSpec(prop)
    83  	assert.Error(t, err, "Expected error with malformed proposal header")
    84  	_, _, err = utils.GetChaincodeProposalContext(prop)
    85  	assert.Error(t, err, "Expected error with malformed proposal header")
    86  	_, err = utils.GetNonce(prop)
    87  	assert.Error(t, err, "Expected error with malformed proposal header")
    88  	_, err = utils.ComputeProposalBinding(prop)
    89  	assert.Error(t, err, "Expected error with malformed proposal header")
    90  
    91  	// malformed signature header
    92  	chdr, _ := proto.Marshal(&common.ChannelHeader{
    93  		Type: int32(common.HeaderType_ENDORSER_TRANSACTION),
    94  	})
    95  	hdr := &common.Header{
    96  		ChannelHeader:   chdr,
    97  		SignatureHeader: []byte("bad signature header"),
    98  	}
    99  	_, err = utils.GetSignatureHeader(hdr.SignatureHeader)
   100  	assert.Error(t, err, "Expected error with malformed signature header")
   101  	hdrBytes, _ := proto.Marshal(hdr)
   102  	prop.Header = hdrBytes
   103  	_, err = utils.GetChaincodeInvocationSpec(prop)
   104  	assert.Error(t, err, "Expected error with malformed signature header")
   105  	_, _, err = utils.GetChaincodeProposalContext(prop)
   106  	assert.Error(t, err, "Expected error with malformed signature header")
   107  	_, err = utils.GetNonce(prop)
   108  	assert.Error(t, err, "Expected error with malformed signature header")
   109  	_, err = utils.ComputeProposalBinding(prop)
   110  	assert.Error(t, err, "Expected error with malformed signature header")
   111  
   112  	// wrong channel header type
   113  	chdr, _ = proto.Marshal(&common.ChannelHeader{
   114  		Type: int32(common.HeaderType_DELIVER_SEEK_INFO),
   115  	})
   116  	hdr.ChannelHeader = chdr
   117  	hdrBytes, _ = proto.Marshal(hdr)
   118  	prop.Header = hdrBytes
   119  	_, _, err = utils.GetChaincodeProposalContext(prop)
   120  	assert.Error(t, err, "Expected error with wrong header type")
   121  	_, err = utils.GetNonce(prop)
   122  	assert.Error(t, err, "Expected error with wrong header type")
   123  
   124  	// malformed channel header
   125  	hdr.ChannelHeader = []byte("bad channel header")
   126  	hdrBytes, _ = proto.Marshal(hdr)
   127  	prop.Header = hdrBytes
   128  	_, _, err = utils.GetChaincodeProposalContext(prop)
   129  	assert.Error(t, err, "Expected error with malformed channel header")
   130  	_, err = utils.GetNonce(prop)
   131  	assert.Error(t, err, "Expected error with malformed channel header")
   132  	_, err = utils.GetChaincodeHeaderExtension(hdr)
   133  	assert.Error(t, err, "Expected error with malformed channel header")
   134  	_, err = utils.ComputeProposalBinding(prop)
   135  	assert.Error(t, err, "Expected error with malformed channel header")
   136  
   137  }
   138  
   139  func TestGetNonce(t *testing.T) {
   140  	chdr, _ := proto.Marshal(&common.ChannelHeader{
   141  		Type: int32(common.HeaderType_ENDORSER_TRANSACTION),
   142  	})
   143  	hdr, _ := proto.Marshal(&common.Header{
   144  		ChannelHeader:   chdr,
   145  		SignatureHeader: []byte{},
   146  	})
   147  	prop := &pb.Proposal{
   148  		Header: hdr,
   149  	}
   150  	_, err := utils.GetNonce(prop)
   151  	assert.Error(t, err, "Expected error with nil signature header")
   152  
   153  	shdr, _ := proto.Marshal(&common.SignatureHeader{
   154  		Nonce: []byte("nonce"),
   155  	})
   156  	hdr, _ = proto.Marshal(&common.Header{
   157  		ChannelHeader:   chdr,
   158  		SignatureHeader: shdr,
   159  	})
   160  	prop = &pb.Proposal{
   161  		Header: hdr,
   162  	}
   163  	nonce, err := utils.GetNonce(prop)
   164  	assert.NoError(t, err, "Unexpected error getting nonce")
   165  	assert.Equal(t, "nonce", string(nonce), "Failed to return the expected nonce")
   166  
   167  }
   168  
   169  func TestGetChaincodeDeploymentSpec(t *testing.T) {
   170  	_, err := utils.GetChaincodeDeploymentSpec([]byte("bad spec"))
   171  	assert.Error(t, err, "Expected error with malformed spec")
   172  
   173  	cds, _ := proto.Marshal(&pb.ChaincodeDeploymentSpec{
   174  		ChaincodeSpec: &pb.ChaincodeSpec{
   175  			Type: pb.ChaincodeSpec_GOLANG,
   176  		},
   177  	})
   178  	_, err = utils.GetChaincodeDeploymentSpec(cds)
   179  	assert.NoError(t, err, "Unexpected error getting deployment spec")
   180  
   181  	cds, _ = proto.Marshal(&pb.ChaincodeDeploymentSpec{
   182  		ChaincodeSpec: &pb.ChaincodeSpec{
   183  			Type: pb.ChaincodeSpec_UNDEFINED,
   184  		},
   185  	})
   186  	_, err = utils.GetChaincodeDeploymentSpec(cds)
   187  	assert.Error(t, err, "Expected error with invalid spec type")
   188  
   189  }
   190  
   191  func TestCDSProposals(t *testing.T) {
   192  	var prop *pb.Proposal
   193  	var err error
   194  	var txid string
   195  	creator := []byte("creator")
   196  	cds := &pb.ChaincodeDeploymentSpec{
   197  		ChaincodeSpec: &pb.ChaincodeSpec{
   198  			Type: pb.ChaincodeSpec_GOLANG,
   199  		},
   200  	}
   201  	policy := []byte("policy")
   202  	escc := []byte("escc")
   203  	vscc := []byte("vscc")
   204  	chainID := "testchainid"
   205  
   206  	// install
   207  	prop, txid, err = utils.CreateInstallProposalFromCDS(cds, creator)
   208  	assert.NotNil(t, prop, "Install proposal should not be nil")
   209  	assert.NoError(t, err, "Unexpected error creating install proposal")
   210  	assert.NotEqual(t, "", txid, "txid should not be empty")
   211  
   212  	// deploy
   213  	prop, txid, err = utils.CreateDeployProposalFromCDS(chainID, cds, creator, policy, escc, vscc)
   214  	assert.NotNil(t, prop, "Deploy proposal should not be nil")
   215  	assert.NoError(t, err, "Unexpected error creating deploy proposal")
   216  	assert.NotEqual(t, "", txid, "txid should not be empty")
   217  
   218  	// upgrade
   219  	prop, txid, err = utils.CreateUpgradeProposalFromCDS(chainID, cds, creator, policy, escc, vscc)
   220  	assert.NotNil(t, prop, "Upgrade proposal should not be nil")
   221  	assert.NoError(t, err, "Unexpected error creating upgrade proposal")
   222  	assert.NotEqual(t, "", txid, "txid should not be empty")
   223  
   224  }
   225  
   226  func TestComputeProposalBinding(t *testing.T) {
   227  	expectedDigestHex := "5093dd4f4277e964da8f4afbde0a9674d17f2a6a5961f0670fc21ae9b67f2983"
   228  	expectedDigest, _ := hex.DecodeString(expectedDigestHex)
   229  	chdr, _ := proto.Marshal(&common.ChannelHeader{
   230  		Epoch: uint64(10),
   231  	})
   232  	shdr, _ := proto.Marshal(&common.SignatureHeader{
   233  		Nonce:   []byte("nonce"),
   234  		Creator: []byte("creator"),
   235  	})
   236  	hdr, _ := proto.Marshal(&common.Header{
   237  		ChannelHeader:   chdr,
   238  		SignatureHeader: shdr,
   239  	})
   240  	prop := &pb.Proposal{
   241  		Header: hdr,
   242  	}
   243  	binding, _ := utils.ComputeProposalBinding(prop)
   244  	assert.Equal(t, expectedDigest, binding, "Binding does not match expected digest")
   245  }
   246  
   247  func TestProposal(t *testing.T) {
   248  	// create a proposal from a ChaincodeInvocationSpec
   249  	prop, _, err := utils.CreateChaincodeProposalWithTransient(
   250  		common.HeaderType_ENDORSER_TRANSACTION,
   251  		util.GetTestChainID(), createCIS(),
   252  		[]byte("creator"),
   253  		map[string][]byte{"certx": []byte("transient")})
   254  	if err != nil {
   255  		t.Fatalf("Could not create chaincode proposal, err %s\n", err)
   256  		return
   257  	}
   258  
   259  	// serialize the proposal
   260  	pBytes, err := utils.GetBytesProposal(prop)
   261  	if err != nil {
   262  		t.Fatalf("Could not serialize the chaincode proposal, err %s\n", err)
   263  		return
   264  	}
   265  
   266  	// deserialize it and expect it to be the same
   267  	propBack, err := utils.GetProposal(pBytes)
   268  	if err != nil {
   269  		t.Fatalf("Could not deserialize the chaincode proposal, err %s\n", err)
   270  		return
   271  	}
   272  	if !reflect.DeepEqual(prop, propBack) {
   273  		t.Fatalf("Proposal and deserialized proposals don't match\n")
   274  		return
   275  	}
   276  
   277  	// get back the header
   278  	hdr, err := utils.GetHeader(prop.Header)
   279  	if err != nil {
   280  		t.Fatalf("Could not extract the header from the proposal, err %s\n", err)
   281  	}
   282  
   283  	hdrBytes, err := utils.GetBytesHeader(hdr)
   284  	if err != nil {
   285  		t.Fatalf("Could not marshal the header, err %s\n", err)
   286  	}
   287  
   288  	hdr, err = utils.GetHeader(hdrBytes)
   289  	if err != nil {
   290  		t.Fatalf("Could not unmarshal the header, err %s\n", err)
   291  	}
   292  
   293  	chdr, err := utils.UnmarshalChannelHeader(hdr.ChannelHeader)
   294  	if err != nil {
   295  		t.Fatalf("Could not unmarshal channel header, err %s", err)
   296  	}
   297  
   298  	shdr, err := utils.GetSignatureHeader(hdr.SignatureHeader)
   299  	if err != nil {
   300  		t.Fatalf("Could not unmarshal signature header, err %s", err)
   301  	}
   302  
   303  	_, err = utils.GetBytesSignatureHeader(shdr)
   304  	if err != nil {
   305  		t.Fatalf("Could not marshal signature header, err %s", err)
   306  	}
   307  
   308  	// sanity check on header
   309  	if chdr.Type != int32(common.HeaderType_ENDORSER_TRANSACTION) ||
   310  		shdr.Nonce == nil ||
   311  		string(shdr.Creator) != "creator" {
   312  		t.Fatalf("Invalid header after unmarshalling\n")
   313  		return
   314  	}
   315  
   316  	// get back the header extension
   317  	hdrExt, err := utils.GetChaincodeHeaderExtension(hdr)
   318  	if err != nil {
   319  		t.Fatalf("Could not extract the header extensions from the proposal, err %s\n", err)
   320  		return
   321  	}
   322  
   323  	// sanity check on header extension
   324  	if string(hdrExt.ChaincodeId.Name) != "chaincode_name" {
   325  		t.Fatalf("Invalid header extension after unmarshalling\n")
   326  		return
   327  	}
   328  
   329  	// get back the ChaincodeInvocationSpec
   330  	cis, err := utils.GetChaincodeInvocationSpec(prop)
   331  	if err != nil {
   332  		t.Fatalf("Could not extract chaincode invocation spec from header, err %s\n", err)
   333  		return
   334  	}
   335  
   336  	// sanity check on cis
   337  	if cis.ChaincodeSpec.Type != pb.ChaincodeSpec_GOLANG ||
   338  		cis.ChaincodeSpec.ChaincodeId.Name != "chaincode_name" ||
   339  		len(cis.ChaincodeSpec.Input.Args) != 2 ||
   340  		string(cis.ChaincodeSpec.Input.Args[0]) != "arg1" ||
   341  		string(cis.ChaincodeSpec.Input.Args[1]) != "arg2" {
   342  		t.Fatalf("Invalid chaincode invocation spec after unmarshalling\n")
   343  		return
   344  	}
   345  
   346  	creator, transient, err := utils.GetChaincodeProposalContext(prop)
   347  	if err != nil {
   348  		t.Fatalf("Failed getting chaincode proposal context [%s]", err)
   349  	}
   350  	if string(creator) != "creator" {
   351  		t.Fatalf("Failed checking Creator field. Invalid value, expectext 'creator', got [%s]", string(creator))
   352  		return
   353  	}
   354  	value, ok := transient["certx"]
   355  	if !ok || string(value) != "transient" {
   356  		t.Fatalf("Failed checking Transient field. Invalid value, expectext 'transient', got [%s]", string(value))
   357  		return
   358  	}
   359  }
   360  
   361  func TestProposalResponse(t *testing.T) {
   362  	events := &pb.ChaincodeEvent{
   363  		ChaincodeId: "ccid",
   364  		EventName:   "EventName",
   365  		Payload:     []byte("EventPayload"),
   366  		TxId:        "TxID"}
   367  	ccid := &pb.ChaincodeID{
   368  		Name:    "ccid",
   369  		Version: "v1",
   370  	}
   371  
   372  	pHashBytes := []byte("proposal_hash")
   373  	pResponse := &pb.Response{Status: 200}
   374  	results := []byte("results")
   375  	eventBytes, err := utils.GetBytesChaincodeEvent(events)
   376  	if err != nil {
   377  		t.Fatalf("Failure while marshalling the ProposalResponsePayload")
   378  		return
   379  	}
   380  
   381  	// get the bytes of the response
   382  	pResponseBytes, err := utils.GetBytesResponse(pResponse)
   383  	if err != nil {
   384  		t.Fatalf("Failure while marshalling the Response")
   385  		return
   386  	}
   387  
   388  	// get the response from bytes
   389  	_, err = utils.GetResponse(pResponseBytes)
   390  	if err != nil {
   391  		t.Fatalf("Failure while unmarshalling the Response")
   392  		return
   393  	}
   394  
   395  	// get the bytes of the ProposalResponsePayload
   396  	prpBytes, err := utils.GetBytesProposalResponsePayload(pHashBytes, pResponse, results, eventBytes, ccid)
   397  	if err != nil {
   398  		t.Fatalf("Failure while marshalling the ProposalResponsePayload")
   399  		return
   400  	}
   401  
   402  	// get the ProposalResponsePayload message
   403  	prp, err := utils.GetProposalResponsePayload(prpBytes)
   404  	if err != nil {
   405  		t.Fatalf("Failure while unmarshalling the ProposalResponsePayload")
   406  		return
   407  	}
   408  
   409  	// get the ChaincodeAction message
   410  	act, err := utils.GetChaincodeAction(prp.Extension)
   411  	if err != nil {
   412  		t.Fatalf("Failure while unmarshalling the ChaincodeAction")
   413  		return
   414  	}
   415  
   416  	// sanity check on the action
   417  	if string(act.Results) != "results" {
   418  		t.Fatalf("Invalid actions after unmarshalling")
   419  		return
   420  	}
   421  
   422  	event, err := utils.GetChaincodeEvents(act.Events)
   423  	if err != nil {
   424  		t.Fatalf("Failure while unmarshalling the ChainCodeEvents")
   425  		return
   426  	}
   427  
   428  	// sanity check on the event
   429  	if string(event.ChaincodeId) != "ccid" {
   430  		t.Fatalf("Invalid actions after unmarshalling")
   431  		return
   432  	}
   433  
   434  	pr := &pb.ProposalResponse{
   435  		Payload:     prpBytes,
   436  		Endorsement: &pb.Endorsement{Endorser: []byte("endorser"), Signature: []byte("signature")},
   437  		Version:     1, // TODO: pick right version number
   438  		Response:    &pb.Response{Status: 200, Message: "OK"}}
   439  
   440  	// create a proposal response
   441  	prBytes, err := utils.GetBytesProposalResponse(pr)
   442  	if err != nil {
   443  		t.Fatalf("Failure while marshalling the ProposalResponse")
   444  		return
   445  	}
   446  
   447  	// get the proposal response message back
   448  	prBack, err := utils.GetProposalResponse(prBytes)
   449  	if err != nil {
   450  		t.Fatalf("Failure while unmarshalling the ProposalResponse")
   451  		return
   452  	}
   453  
   454  	// sanity check on pr
   455  	if prBack.Response.Status != 200 ||
   456  		string(prBack.Endorsement.Signature) != "signature" ||
   457  		string(prBack.Endorsement.Endorser) != "endorser" ||
   458  		bytes.Compare(prBack.Payload, prpBytes) != 0 {
   459  		t.Fatalf("Invalid ProposalResponse after unmarshalling")
   460  		return
   461  	}
   462  }
   463  
   464  func TestEnvelope(t *testing.T) {
   465  	// create a proposal from a ChaincodeInvocationSpec
   466  	prop, _, err := utils.CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), createCIS(), signerSerialized)
   467  	if err != nil {
   468  		t.Fatalf("Could not create chaincode proposal, err %s\n", err)
   469  		return
   470  	}
   471  
   472  	response := &pb.Response{Status: 200, Payload: []byte("payload")}
   473  	result := []byte("res")
   474  	ccid := &pb.ChaincodeID{Name: "foo", Version: "v1"}
   475  
   476  	presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response, result, nil, ccid, nil, signer)
   477  	if err != nil {
   478  		t.Fatalf("Could not create proposal response, err %s\n", err)
   479  		return
   480  	}
   481  
   482  	tx, err := utils.CreateSignedTx(prop, signer, presp)
   483  	if err != nil {
   484  		t.Fatalf("Could not create signed tx, err %s\n", err)
   485  		return
   486  	}
   487  
   488  	envBytes, err := utils.GetBytesEnvelope(tx)
   489  	if err != nil {
   490  		t.Fatalf("Could not marshal envelope, err %s\n", err)
   491  		return
   492  	}
   493  
   494  	tx, err = utils.GetEnvelopeFromBlock(envBytes)
   495  	if err != nil {
   496  		t.Fatalf("Could not unmarshal envelope, err %s\n", err)
   497  		return
   498  	}
   499  
   500  	act2, err := utils.GetActionFromEnvelope(envBytes)
   501  	if err != nil {
   502  		t.Fatalf("Could not extract actions from envelop, err %s\n", err)
   503  		return
   504  	}
   505  
   506  	if act2.Response.Status != response.Status {
   507  		t.Fatalf("response staus don't match")
   508  		return
   509  	}
   510  	if bytes.Compare(act2.Response.Payload, response.Payload) != 0 {
   511  		t.Fatalf("response payload don't match")
   512  		return
   513  	}
   514  
   515  	if bytes.Compare(act2.Results, result) != 0 {
   516  		t.Fatalf("results don't match")
   517  		return
   518  	}
   519  
   520  	txpayl, err := utils.GetPayload(tx)
   521  	if err != nil {
   522  		t.Fatalf("Could not unmarshal payload, err %s\n", err)
   523  		return
   524  	}
   525  
   526  	tx2, err := utils.GetTransaction(txpayl.Data)
   527  	if err != nil {
   528  		t.Fatalf("Could not unmarshal Transaction, err %s\n", err)
   529  		return
   530  	}
   531  
   532  	sh, err := utils.GetSignatureHeader(tx2.Actions[0].Header)
   533  	if err != nil {
   534  		t.Fatalf("Could not unmarshal SignatureHeader, err %s\n", err)
   535  		return
   536  	}
   537  
   538  	if bytes.Compare(sh.Creator, signerSerialized) != 0 {
   539  		t.Fatalf("creator does not match")
   540  		return
   541  	}
   542  
   543  	cap, err := utils.GetChaincodeActionPayload(tx2.Actions[0].Payload)
   544  	if err != nil {
   545  		t.Fatalf("Could not unmarshal ChaincodeActionPayload, err %s\n", err)
   546  		return
   547  	}
   548  	assert.NotNil(t, cap)
   549  
   550  	prp, err := utils.GetProposalResponsePayload(cap.Action.ProposalResponsePayload)
   551  	if err != nil {
   552  		t.Fatalf("Could not unmarshal ProposalResponsePayload, err %s\n", err)
   553  		return
   554  	}
   555  
   556  	ca, err := utils.GetChaincodeAction(prp.Extension)
   557  	if err != nil {
   558  		t.Fatalf("Could not unmarshal ChaincodeAction, err %s\n", err)
   559  		return
   560  	}
   561  
   562  	if ca.Response.Status != response.Status {
   563  		t.Fatalf("response staus don't match")
   564  		return
   565  	}
   566  	if bytes.Compare(ca.Response.Payload, response.Payload) != 0 {
   567  		t.Fatalf("response payload don't match")
   568  		return
   569  	}
   570  
   571  	if bytes.Compare(ca.Results, result) != 0 {
   572  		t.Fatalf("results don't match")
   573  		return
   574  	}
   575  }
   576  
   577  func TestProposalTxID(t *testing.T) {
   578  	nonce := []byte{1}
   579  	creator := []byte{2}
   580  
   581  	txid, err := utils.ComputeProposalTxID(nonce, creator)
   582  	assert.NotEmpty(t, txid, "TxID cannot be empty.")
   583  	assert.NoError(t, err, "Failed computing txID")
   584  	assert.Nil(t, utils.CheckProposalTxID(txid, nonce, creator))
   585  	assert.Error(t, utils.CheckProposalTxID("", nonce, creator))
   586  
   587  	txid, err = utils.ComputeProposalTxID(nil, nil)
   588  	assert.NotEmpty(t, txid, "TxID cannot be empty.")
   589  	assert.NoError(t, err, "Failed computing txID")
   590  }
   591  
   592  func TestComputeProposalTxID(t *testing.T) {
   593  	txid, err := utils.ComputeProposalTxID([]byte{1}, []byte{1})
   594  	assert.NoError(t, err, "Failed computing TxID")
   595  
   596  	// Compute the function computed by ComputeProposalTxID,
   597  	// namely, base64(sha256(nonce||creator))
   598  	hf := sha256.New()
   599  	hf.Write([]byte{1})
   600  	hf.Write([]byte{1})
   601  	hashOut := hf.Sum(nil)
   602  	txid2 := hex.EncodeToString(hashOut)
   603  
   604  	t.Logf("% x\n", hashOut)
   605  	t.Logf("% s\n", txid)
   606  	t.Logf("% s\n", txid2)
   607  
   608  	assert.Equal(t, txid, txid2)
   609  }
   610  
   611  var signer msp.SigningIdentity
   612  var signerSerialized []byte
   613  
   614  func TestMain(m *testing.M) {
   615  	// setup the MSP manager so that we can sign/verify
   616  	err := msptesttools.LoadMSPSetupForTesting()
   617  	if err != nil {
   618  		os.Exit(-1)
   619  		fmt.Printf("Could not initialize msp")
   620  		return
   621  	}
   622  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   623  	if err != nil {
   624  		os.Exit(-1)
   625  		fmt.Printf("Could not get signer")
   626  		return
   627  	}
   628  
   629  	signerSerialized, err = signer.Serialize()
   630  	if err != nil {
   631  		os.Exit(-1)
   632  		fmt.Printf("Could not serialize identity")
   633  		return
   634  	}
   635  
   636  	os.Exit(m.Run())
   637  }