github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/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 18 19 import ( 20 "bytes" 21 "testing" 22 23 "reflect" 24 25 "fmt" 26 "os" 27 28 "crypto/sha256" 29 "encoding/hex" 30 31 "github.com/hyperledger/fabric/common/util" 32 "github.com/hyperledger/fabric/msp" 33 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 34 "github.com/hyperledger/fabric/msp/mgmt/testtools" 35 "github.com/hyperledger/fabric/protos/common" 36 pb "github.com/hyperledger/fabric/protos/peer" 37 "github.com/stretchr/testify/assert" 38 ) 39 40 func createCIS() *pb.ChaincodeInvocationSpec { 41 return &pb.ChaincodeInvocationSpec{ 42 ChaincodeSpec: &pb.ChaincodeSpec{ 43 Type: pb.ChaincodeSpec_GOLANG, 44 ChaincodeId: &pb.ChaincodeID{Name: "chaincode_name"}, 45 Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("arg1"), []byte("arg2")}}}} 46 } 47 48 func TestProposal(t *testing.T) { 49 // create a proposal from a ChaincodeInvocationSpec 50 prop, _, err := CreateChaincodeProposalWithTransient( 51 common.HeaderType_ENDORSER_TRANSACTION, 52 util.GetTestChainID(), createCIS(), 53 []byte("creator"), 54 map[string][]byte{"certx": []byte("transient")}) 55 if err != nil { 56 t.Fatalf("Could not create chaincode proposal, err %s\n", err) 57 return 58 } 59 60 // serialize the proposal 61 pBytes, err := GetBytesProposal(prop) 62 if err != nil { 63 t.Fatalf("Could not serialize the chaincode proposal, err %s\n", err) 64 return 65 } 66 67 // deserialize it and expect it to be the same 68 propBack, err := GetProposal(pBytes) 69 if err != nil { 70 t.Fatalf("Could not deserialize the chaincode proposal, err %s\n", err) 71 return 72 } 73 if !reflect.DeepEqual(prop, propBack) { 74 t.Fatalf("Proposal and deserialized proposals don't match\n") 75 return 76 } 77 78 // get back the header 79 hdr, err := GetHeader(prop.Header) 80 if err != nil { 81 t.Fatalf("Could not extract the header from the proposal, err %s\n", err) 82 } 83 84 hdrBytes, err := GetBytesHeader(hdr) 85 if err != nil { 86 t.Fatalf("Could not marshal the header, err %s\n", err) 87 } 88 89 hdr, err = GetHeader(hdrBytes) 90 if err != nil { 91 t.Fatalf("Could not unmarshal the header, err %s\n", err) 92 } 93 94 chdr, err := UnmarshalChannelHeader(hdr.ChannelHeader) 95 if err != nil { 96 t.Fatalf("Could not unmarshal channel header, err %s", err) 97 } 98 99 shdr, err := GetSignatureHeader(hdr.SignatureHeader) 100 if err != nil { 101 t.Fatalf("Could not unmarshal signature header, err %s", err) 102 } 103 104 // sanity check on header 105 if chdr.Type != int32(common.HeaderType_ENDORSER_TRANSACTION) || 106 shdr.Nonce == nil || 107 string(shdr.Creator) != "creator" { 108 t.Fatalf("Invalid header after unmarshalling\n") 109 return 110 } 111 112 // get back the header extension 113 hdrExt, err := GetChaincodeHeaderExtension(hdr) 114 if err != nil { 115 t.Fatalf("Could not extract the header extensions from the proposal, err %s\n", err) 116 return 117 } 118 119 // sanity check on header extension 120 if string(hdrExt.ChaincodeId.Name) != "chaincode_name" { 121 t.Fatalf("Invalid header extension after unmarshalling\n") 122 return 123 } 124 125 // get back the ChaincodeInvocationSpec 126 cis, err := GetChaincodeInvocationSpec(prop) 127 if err != nil { 128 t.Fatalf("Could not extract chaincode invocation spec from header, err %s\n", err) 129 return 130 } 131 132 // sanity check on cis 133 if cis.ChaincodeSpec.Type != pb.ChaincodeSpec_GOLANG || 134 cis.ChaincodeSpec.ChaincodeId.Name != "chaincode_name" || 135 len(cis.ChaincodeSpec.Input.Args) != 2 || 136 string(cis.ChaincodeSpec.Input.Args[0]) != "arg1" || 137 string(cis.ChaincodeSpec.Input.Args[1]) != "arg2" { 138 t.Fatalf("Invalid chaincode invocation spec after unmarshalling\n") 139 return 140 } 141 142 creator, transient, err := GetChaincodeProposalContext(prop) 143 if err != nil { 144 t.Fatalf("Failed getting chaincode proposal context [%s]", err) 145 } 146 if string(creator) != "creator" { 147 t.Fatalf("Failed checking Creator field. Invalid value, expectext 'creator', got [%s]", string(creator)) 148 return 149 } 150 value, ok := transient["certx"] 151 if !ok || string(value) != "transient" { 152 t.Fatalf("Failed checking Transient field. Invalid value, expectext 'transient', got [%s]", string(value)) 153 return 154 } 155 } 156 157 func TestProposalResponse(t *testing.T) { 158 events := &pb.ChaincodeEvent{ 159 ChaincodeId: "ccid", 160 EventName: "EventName", 161 Payload: []byte("EventPayload"), 162 TxId: "TxID"} 163 164 pHashBytes := []byte("proposal_hash") 165 pResponse := &pb.Response{Status: 200} 166 results := []byte("results") 167 eventBytes, err := GetBytesChaincodeEvent(events) 168 if err != nil { 169 t.Fatalf("Failure while marshalling the ProposalResponsePayload") 170 return 171 } 172 173 // get the bytes of the ProposalResponsePayload 174 prpBytes, err := GetBytesProposalResponsePayload(pHashBytes, pResponse, results, eventBytes) 175 if err != nil { 176 t.Fatalf("Failure while marshalling the ProposalResponsePayload") 177 return 178 } 179 180 // get the ProposalResponsePayload message 181 prp, err := GetProposalResponsePayload(prpBytes) 182 if err != nil { 183 t.Fatalf("Failure while unmarshalling the ProposalResponsePayload") 184 return 185 } 186 187 // get the ChaincodeAction message 188 act, err := GetChaincodeAction(prp.Extension) 189 if err != nil { 190 t.Fatalf("Failure while unmarshalling the ChaincodeAction") 191 return 192 } 193 194 // sanity check on the action 195 if string(act.Results) != "results" { 196 t.Fatalf("Invalid actions after unmarshalling") 197 return 198 } 199 200 event, err := GetChaincodeEvents(act.Events) 201 if err != nil { 202 t.Fatalf("Failure while unmarshalling the ChainCodeEvents") 203 return 204 } 205 206 // sanity check on the event 207 if string(event.ChaincodeId) != "ccid" { 208 t.Fatalf("Invalid actions after unmarshalling") 209 return 210 } 211 212 pr := &pb.ProposalResponse{ 213 Payload: prpBytes, 214 Endorsement: &pb.Endorsement{Endorser: []byte("endorser"), Signature: []byte("signature")}, 215 Version: 1, // TODO: pick right version number 216 Response: &pb.Response{Status: 200, Message: "OK"}} 217 218 // create a proposal response 219 prBytes, err := GetBytesProposalResponse(pr) 220 if err != nil { 221 t.Fatalf("Failure while marshalling the ProposalResponse") 222 return 223 } 224 225 // get the proposal response message back 226 prBack, err := GetProposalResponse(prBytes) 227 if err != nil { 228 t.Fatalf("Failure while unmarshalling the ProposalResponse") 229 return 230 } 231 232 // sanity check on pr 233 if prBack.Response.Status != 200 || 234 string(prBack.Endorsement.Signature) != "signature" || 235 string(prBack.Endorsement.Endorser) != "endorser" || 236 bytes.Compare(prBack.Payload, prpBytes) != 0 { 237 t.Fatalf("Invalid ProposalResponse after unmarshalling") 238 return 239 } 240 } 241 242 func TestEnvelope(t *testing.T) { 243 // create a proposal from a ChaincodeInvocationSpec 244 prop, _, err := CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), createCIS(), signerSerialized) 245 if err != nil { 246 t.Fatalf("Could not create chaincode proposal, err %s\n", err) 247 return 248 } 249 250 response := &pb.Response{Status: 200, Payload: []byte("payload")} 251 result := []byte("res") 252 253 presp, err := CreateProposalResponse(prop.Header, prop.Payload, response, result, nil, nil, signer) 254 if err != nil { 255 t.Fatalf("Could not create proposal response, err %s\n", err) 256 return 257 } 258 259 tx, err := CreateSignedTx(prop, signer, presp) 260 if err != nil { 261 t.Fatalf("Could not create signed tx, err %s\n", err) 262 return 263 } 264 265 envBytes, err := GetBytesEnvelope(tx) 266 if err != nil { 267 t.Fatalf("Could not marshal envelope, err %s\n", err) 268 return 269 } 270 271 tx, err = GetEnvelopeFromBlock(envBytes) 272 if err != nil { 273 t.Fatalf("Could not unmarshal envelope, err %s\n", err) 274 return 275 } 276 277 act2, err := GetActionFromEnvelope(envBytes) 278 if err != nil { 279 t.Fatalf("Could not extract actions from envelop, err %s\n", err) 280 return 281 } 282 283 if act2.Response.Status != response.Status { 284 t.Fatalf("response staus don't match") 285 return 286 } 287 if bytes.Compare(act2.Response.Payload, response.Payload) != 0 { 288 t.Fatalf("response payload don't match") 289 return 290 } 291 292 if bytes.Compare(act2.Results, result) != 0 { 293 t.Fatalf("results don't match") 294 return 295 } 296 297 txpayl, err := GetPayload(tx) 298 if err != nil { 299 t.Fatalf("Could not unmarshal payload, err %s\n", err) 300 return 301 } 302 303 tx2, err := GetTransaction(txpayl.Data) 304 if err != nil { 305 t.Fatalf("Could not unmarshal Transaction, err %s\n", err) 306 return 307 } 308 309 sh, err := GetSignatureHeader(tx2.Actions[0].Header) 310 if err != nil { 311 t.Fatalf("Could not unmarshal SignatureHeader, err %s\n", err) 312 return 313 } 314 315 if bytes.Compare(sh.Creator, signerSerialized) != 0 { 316 t.Fatalf("creator does not match") 317 return 318 } 319 320 cap, err := GetChaincodeActionPayload(tx2.Actions[0].Payload) 321 if err != nil { 322 t.Fatalf("Could not unmarshal ChaincodeActionPayload, err %s\n", err) 323 return 324 } 325 assert.NotNil(t, cap) 326 327 prp, err := GetProposalResponsePayload(cap.Action.ProposalResponsePayload) 328 if err != nil { 329 t.Fatalf("Could not unmarshal ProposalResponsePayload, err %s\n", err) 330 return 331 } 332 333 ca, err := GetChaincodeAction(prp.Extension) 334 if err != nil { 335 t.Fatalf("Could not unmarshal ChaincodeAction, err %s\n", err) 336 return 337 } 338 339 if ca.Response.Status != response.Status { 340 t.Fatalf("response staus don't match") 341 return 342 } 343 if bytes.Compare(ca.Response.Payload, response.Payload) != 0 { 344 t.Fatalf("response payload don't match") 345 return 346 } 347 348 if bytes.Compare(ca.Results, result) != 0 { 349 t.Fatalf("results don't match") 350 return 351 } 352 } 353 354 func TestProposalTxID(t *testing.T) { 355 nonce := []byte{1} 356 creator := []byte{2} 357 358 txid, err := ComputeProposalTxID(nonce, creator) 359 assert.NotEmpty(t, txid, "TxID cannot be empty.") 360 assert.NoError(t, err, "Failed computing txID") 361 assert.Nil(t, CheckProposalTxID(txid, nonce, creator)) 362 assert.Error(t, CheckProposalTxID("", nonce, creator)) 363 364 txid, err = ComputeProposalTxID(nil, nil) 365 assert.NotEmpty(t, txid, "TxID cannot be empty.") 366 assert.NoError(t, err, "Failed computing txID") 367 } 368 369 func TestComputeProposalTxID(t *testing.T) { 370 txid, err := ComputeProposalTxID([]byte{1}, []byte{1}) 371 assert.NoError(t, err, "Failed computing TxID") 372 373 // Compute the function computed by ComputeProposalTxID, 374 // namely, base64(sha256(nonce||creator)) 375 hf := sha256.New() 376 hf.Write([]byte{1}) 377 hf.Write([]byte{1}) 378 hashOut := hf.Sum(nil) 379 txid2 := hex.EncodeToString(hashOut) 380 381 t.Logf("% x\n", hashOut) 382 t.Logf("% s\n", txid) 383 t.Logf("% s\n", txid2) 384 385 assert.Equal(t, txid, txid2) 386 } 387 388 var signer msp.SigningIdentity 389 var signerSerialized []byte 390 391 func TestMain(m *testing.M) { 392 // setup the MSP manager so that we can sign/verify 393 mspMgrConfigFile := "../../msp/sampleconfig/" 394 err := msptesttools.LoadMSPSetupForTesting(mspMgrConfigFile) 395 if err != nil { 396 os.Exit(-1) 397 fmt.Printf("Could not initialize msp") 398 return 399 } 400 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 401 if err != nil { 402 os.Exit(-1) 403 fmt.Printf("Could not get signer") 404 return 405 } 406 407 signerSerialized, err = signer.Serialize() 408 if err != nil { 409 os.Exit(-1) 410 fmt.Printf("Could not serialize identity") 411 return 412 } 413 414 os.Exit(m.Run()) 415 }