github.com/yimialmonte/fabric@v2.1.1+incompatible/core/tx/endorser/parser_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package endorsertx_test
     8  
     9  import (
    10  	"encoding/hex"
    11  
    12  	"github.com/hyperledger/fabric-protos-go/common"
    13  	"github.com/hyperledger/fabric-protos-go/peer"
    14  	"github.com/hyperledger/fabric/common/configtx"
    15  	endorsertx "github.com/hyperledger/fabric/core/tx/endorser"
    16  	"github.com/hyperledger/fabric/pkg/tx"
    17  	"github.com/hyperledger/fabric/protoutil"
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  )
    21  
    22  var _ = Describe("Parser", func() {
    23  	var (
    24  		txenv     *tx.Envelope
    25  		chHeader  *common.ChannelHeader
    26  		sigHeader *common.SignatureHeader
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		chHeader = &common.ChannelHeader{
    31  			ChannelId: "my-channel",
    32  			Epoch:     0,
    33  		}
    34  
    35  		sigHeader = &common.SignatureHeader{
    36  			Nonce:   []byte("1234"),
    37  			Creator: []byte("creator"),
    38  		}
    39  	})
    40  
    41  	Context("the tx envelope bytes contain valid data", func() {
    42  		BeforeEach(func() {
    43  			txenv = genTxEnvelope(nil, nil, nil, nil, chHeader, sigHeader)
    44  		})
    45  
    46  		It("returns an instance of EndorserTx", func() {
    47  			pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
    48  			Expect(err).NotTo(HaveOccurred())
    49  			Expect(pe).To(Equal(&endorsertx.EndorserTx{
    50  				Response: &peer.Response{
    51  					Status: 200,
    52  				},
    53  				Results:      []byte("results"),
    54  				Events:       []byte("events"),
    55  				ComputedTxID: "0befbaa99e45fb676a54d6df7e44a52a0594d524d696d9f77e8ee21bbfb554f0",
    56  				Endorsements: []*peer.Endorsement{
    57  					{
    58  						Endorser:  []byte("endorser"),
    59  						Signature: []byte("signature"),
    60  					},
    61  				},
    62  				ChannelID:   "my-channel",
    63  				Creator:     []byte("creator"),
    64  				ChaincodeID: &peer.ChaincodeID{Name: "my-called-cc"},
    65  				Type:        0,
    66  				Version:     0,
    67  				Epoch:       0,
    68  				Nonce:       []byte("1234"),
    69  			}))
    70  		})
    71  	})
    72  
    73  	Context("the tx envelope bytes contain invalid data", func() {
    74  		var (
    75  			hdrExtOverride      []byte
    76  			payloadDataOverride []byte
    77  			prpExtOverride      []byte
    78  			prpOverride         []byte
    79  		)
    80  
    81  		BeforeEach(func() {
    82  			// reset the overrides to nil, so that each test case can set its own
    83  			hdrExtOverride, payloadDataOverride, prpExtOverride, prpOverride = nil, nil, nil, nil
    84  		})
    85  
    86  		JustBeforeEach(func() {
    87  			// use the overrides to generate the envelope right before every test case starts
    88  			txenv = genTxEnvelope(hdrExtOverride, payloadDataOverride, prpExtOverride, prpOverride, chHeader, sigHeader)
    89  		})
    90  
    91  		When("there is no payload data", func() {
    92  			BeforeEach(func() {
    93  				payloadDataOverride = []byte{}
    94  			})
    95  
    96  			It("returns an error", func() {
    97  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
    98  				Expect(err).To(MatchError("nil payload data"))
    99  				Expect(pe).To(BeNil())
   100  			})
   101  		})
   102  
   103  		When("there is bad payload data", func() {
   104  			BeforeEach(func() {
   105  				payloadDataOverride = []byte("barf")
   106  			})
   107  
   108  			It("returns an error", func() {
   109  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   110  				Expect(err).To(MatchError("error unmarshaling Transaction: unexpected EOF"))
   111  				Expect(pe).To(BeNil())
   112  			})
   113  		})
   114  
   115  		When("there is bad payload data", func() {
   116  			BeforeEach(func() {
   117  				payloadDataOverride = protoutil.MarshalOrPanic(&peer.Transaction{
   118  					Actions: []*peer.TransactionAction{{}, {}},
   119  				})
   120  			})
   121  
   122  			It("returns an error", func() {
   123  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   124  				Expect(err).To(MatchError("only one transaction action is supported, 2 were present"))
   125  				Expect(pe).To(BeNil())
   126  			})
   127  		})
   128  
   129  		When("the transaction action has no payload", func() {
   130  			BeforeEach(func() {
   131  				payloadDataOverride = protoutil.MarshalOrPanic(&peer.Transaction{
   132  					Actions: []*peer.TransactionAction{{}},
   133  				})
   134  			})
   135  
   136  			It("returns an error", func() {
   137  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   138  				Expect(err).To(MatchError("empty ChaincodeActionPayload"))
   139  				Expect(pe).To(BeNil())
   140  			})
   141  		})
   142  
   143  		When("the transaction action has a bad payload", func() {
   144  			BeforeEach(func() {
   145  				payloadDataOverride = protoutil.MarshalOrPanic(&peer.Transaction{
   146  					Actions: []*peer.TransactionAction{{Payload: []byte("barf")}},
   147  				})
   148  			})
   149  
   150  			It("returns an error", func() {
   151  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   152  				Expect(err).To(MatchError("error unmarshaling ChaincodeActionPayload: unexpected EOF"))
   153  				Expect(pe).To(BeNil())
   154  			})
   155  		})
   156  
   157  		When("the transaction action has a bad payload", func() {
   158  			BeforeEach(func() {
   159  				payloadDataOverride = protoutil.MarshalOrPanic(&peer.Transaction{
   160  					Actions: []*peer.TransactionAction{
   161  						{
   162  							Payload: protoutil.MarshalOrPanic(
   163  								&peer.ChaincodeActionPayload{
   164  									ChaincodeProposalPayload: []byte("some proposal payload"),
   165  									Action:                   nil,
   166  								},
   167  							),
   168  						},
   169  					},
   170  				})
   171  			})
   172  
   173  			It("returns an error", func() {
   174  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   175  				Expect(err).To(MatchError("nil ChaincodeEndorsedAction"))
   176  				Expect(pe).To(BeNil())
   177  			})
   178  		})
   179  
   180  		When("there is no header extension", func() {
   181  			BeforeEach(func() {
   182  				hdrExtOverride = []byte{}
   183  			})
   184  
   185  			It("returns an error", func() {
   186  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   187  				Expect(err).To(MatchError("empty header extension"))
   188  				Expect(pe).To(BeNil())
   189  			})
   190  		})
   191  
   192  		When("there is a bad header extension", func() {
   193  			BeforeEach(func() {
   194  				hdrExtOverride = []byte("barf")
   195  			})
   196  
   197  			It("returns an error", func() {
   198  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   199  				Expect(err).To(MatchError("error unmarshaling ChaincodeHeaderExtension: unexpected EOF"))
   200  				Expect(pe).To(BeNil())
   201  			})
   202  		})
   203  
   204  		When("there is no ProposalResponsePayload", func() {
   205  			BeforeEach(func() {
   206  				prpOverride = []byte{}
   207  			})
   208  
   209  			It("returns an error", func() {
   210  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   211  				Expect(err).To(MatchError("empty ProposalResponsePayload"))
   212  				Expect(pe).To(BeNil())
   213  			})
   214  		})
   215  
   216  		When("there is a bad ProposalResponsePayload", func() {
   217  			BeforeEach(func() {
   218  				prpOverride = []byte("barf")
   219  			})
   220  
   221  			It("returns an error", func() {
   222  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   223  				Expect(err).To(MatchError("error unmarshaling ProposalResponsePayload: unexpected EOF"))
   224  				Expect(pe).To(BeNil())
   225  			})
   226  		})
   227  
   228  		When("there is no ProposalResponsePayload", func() {
   229  			BeforeEach(func() {
   230  				prpExtOverride = []byte{}
   231  			})
   232  
   233  			It("returns an error", func() {
   234  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   235  				Expect(err).To(MatchError("nil Extension"))
   236  				Expect(pe).To(BeNil())
   237  			})
   238  		})
   239  
   240  		When("there is a bad ProposalResponsePayload", func() {
   241  			BeforeEach(func() {
   242  				prpExtOverride = []byte("barf")
   243  			})
   244  
   245  			It("returns an error", func() {
   246  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   247  				Expect(err).To(MatchError("error unmarshaling ChaincodeAction: unexpected EOF"))
   248  				Expect(pe).To(BeNil())
   249  			})
   250  		})
   251  
   252  		When("there is a bad epoch", func() {
   253  			BeforeEach(func() {
   254  				chHeader = &common.ChannelHeader{
   255  					ChannelId: "my-channel",
   256  					Epoch:     35,
   257  				}
   258  			})
   259  
   260  			It("returns an error", func() {
   261  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   262  				Expect(err).To(MatchError("invalid epoch in ChannelHeader. Expected 0, got [35]"))
   263  				Expect(pe).To(BeNil())
   264  			})
   265  		})
   266  
   267  		When("there is a bad version", func() {
   268  			BeforeEach(func() {
   269  				chHeader = &common.ChannelHeader{
   270  					ChannelId: "my-channel",
   271  					Version:   35,
   272  				}
   273  			})
   274  
   275  			It("returns an error", func() {
   276  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   277  				Expect(err).To(MatchError("invalid version in ChannelHeader. Expected 0, got [35]"))
   278  				Expect(pe).To(BeNil())
   279  			})
   280  		})
   281  
   282  		When("there is an empty channel name", func() {
   283  			BeforeEach(func() {
   284  				chHeader = &common.ChannelHeader{
   285  					ChannelId: "",
   286  				}
   287  			})
   288  
   289  			It("returns an error", func() {
   290  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   291  				Expect(err).To(MatchError("channel ID illegal, cannot be empty"))
   292  				Expect(pe).To(BeNil())
   293  			})
   294  		})
   295  
   296  		When("there is an invalid channel name", func() {
   297  			BeforeEach(func() {
   298  				chHeader = &common.ChannelHeader{
   299  					ChannelId: ".foo",
   300  				}
   301  			})
   302  
   303  			It("returns an error", func() {
   304  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   305  				Expect(err).To(MatchError("'.foo' contains illegal characters"))
   306  				Expect(pe).To(BeNil())
   307  			})
   308  		})
   309  
   310  		When("there is an empty nonce", func() {
   311  			BeforeEach(func() {
   312  				sigHeader = &common.SignatureHeader{
   313  					Creator: []byte("creator"),
   314  				}
   315  			})
   316  
   317  			It("returns an error", func() {
   318  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   319  				Expect(err).To(MatchError("empty nonce"))
   320  				Expect(pe).To(BeNil())
   321  			})
   322  		})
   323  
   324  		When("there is an empty creator", func() {
   325  			BeforeEach(func() {
   326  				sigHeader = &common.SignatureHeader{
   327  					Nonce: []byte("1234"),
   328  				}
   329  			})
   330  
   331  			It("returns an error", func() {
   332  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   333  				Expect(err).To(MatchError("empty creator"))
   334  				Expect(pe).To(BeNil())
   335  			})
   336  		})
   337  
   338  		When("there is no chaincode ID", func() {
   339  			BeforeEach(func() {
   340  				// annoyingly, it's not easy to get a nonzero length
   341  				// marshalling of a proto message with zero values
   342  				// everywhere. We simulate this condition by adding
   343  				// extra bytes for a non-existent second field that
   344  				// our unmarshaler will skip. Still, the presence of
   345  				// an extraneous field will get the unmarshaler to
   346  				// return a non-nil struct
   347  				bytes, err := hex.DecodeString("1a046369616f")
   348  				Expect(err).To(BeNil())
   349  				hdrExtOverride = bytes
   350  			})
   351  
   352  			It("returns an error", func() {
   353  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   354  				Expect(err).To(MatchError("nil ChaincodeId"))
   355  				Expect(pe).To(BeNil())
   356  			})
   357  		})
   358  
   359  		When("there is an empty chaincode name", func() {
   360  			BeforeEach(func() {
   361  				hdrExtOverride = protoutil.MarshalOrPanic(
   362  					&peer.ChaincodeHeaderExtension{
   363  						ChaincodeId: &peer.ChaincodeID{},
   364  					},
   365  				)
   366  			})
   367  
   368  			It("returns an error", func() {
   369  				pe, err := endorsertx.UnmarshalEndorserTxAndValidate(txenv)
   370  				Expect(err).To(MatchError("empty chaincode name in chaincode id"))
   371  				Expect(pe).To(BeNil())
   372  			})
   373  		})
   374  	})
   375  
   376  	Describe("Validation of the channel ID", func() {
   377  		Context("the used constants", func() {
   378  			It("ensures that are kept in sync", func() {
   379  				Expect(endorsertx.ChannelAllowedChars).To(Equal(configtx.ChannelAllowedChars))
   380  				Expect(endorsertx.MaxLength).To(Equal(configtx.MaxLength))
   381  			})
   382  		})
   383  
   384  		Context("the validation function", func() {
   385  			It("behaves as the one in the configtx package", func() {
   386  				err1 := endorsertx.ValidateChannelID(randomLowerAlphaString(endorsertx.MaxLength + 1))
   387  				err2 := configtx.ValidateChannelID(randomLowerAlphaString(endorsertx.MaxLength + 1))
   388  				Expect(err1).To(HaveOccurred())
   389  				Expect(err2).To(HaveOccurred())
   390  				Expect(err1.Error()).To(Equal(err2.Error()))
   391  
   392  				err1 = endorsertx.ValidateChannelID("foo_bar")
   393  				err2 = configtx.ValidateChannelID("foo_bar")
   394  				Expect(err1).To(HaveOccurred())
   395  				Expect(err2).To(HaveOccurred())
   396  				Expect(err1.Error()).To(Equal(err2.Error()))
   397  
   398  				err1 = endorsertx.ValidateChannelID("8foo")
   399  				err2 = configtx.ValidateChannelID("8foo")
   400  				Expect(err1).To(HaveOccurred())
   401  				Expect(err2).To(HaveOccurred())
   402  				Expect(err1.Error()).To(Equal(err2.Error()))
   403  
   404  				err1 = endorsertx.ValidateChannelID(".foo")
   405  				err2 = configtx.ValidateChannelID(".foo")
   406  				Expect(err1).To(HaveOccurred())
   407  				Expect(err2).To(HaveOccurred())
   408  				Expect(err1.Error()).To(Equal(err2.Error()))
   409  
   410  				err1 = endorsertx.ValidateChannelID("")
   411  				err2 = configtx.ValidateChannelID("")
   412  				Expect(err1).To(HaveOccurred())
   413  				Expect(err2).To(HaveOccurred())
   414  				Expect(err1.Error()).To(Equal(err2.Error()))
   415  
   416  				err1 = endorsertx.ValidateChannelID("f-oo.bar")
   417  				err2 = configtx.ValidateChannelID("f-oo.bar")
   418  				Expect(err1).NotTo(HaveOccurred())
   419  				Expect(err2).NotTo(HaveOccurred())
   420  			})
   421  		})
   422  	})
   423  })