github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/core/chaincode/exectransaction_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package chaincode 8 9 import ( 10 "bytes" 11 "encoding/json" 12 "errors" 13 "flag" 14 "fmt" 15 "io/ioutil" 16 "net" 17 "os" 18 "path/filepath" 19 "reflect" 20 "strconv" 21 "strings" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/hyperledger/fabric/core/ledger/ledgermgmt/ledgermgmttest" 27 28 docker "github.com/fsouza/go-dockerclient" 29 "github.com/golang/protobuf/proto" 30 "github.com/hyperledger/fabric-chaincode-go/shim" 31 "github.com/hyperledger/fabric-protos-go/common" 32 pb "github.com/hyperledger/fabric-protos-go/peer" 33 "github.com/hyperledger/fabric/bccsp/factory" 34 "github.com/hyperledger/fabric/bccsp/sw" 35 "github.com/hyperledger/fabric/common/channelconfig" 36 "github.com/hyperledger/fabric/common/crypto/tlsgen" 37 "github.com/hyperledger/fabric/common/flogging" 38 "github.com/hyperledger/fabric/common/metrics/disabled" 39 40 "github.com/hyperledger/fabric/common/policies" 41 "github.com/hyperledger/fabric/common/util" 42 "github.com/hyperledger/fabric/core/aclmgmt" 43 "github.com/hyperledger/fabric/core/chaincode/lifecycle" 44 "github.com/hyperledger/fabric/core/chaincode/mock" 45 cm "github.com/hyperledger/fabric/core/chaincode/mock" 46 "github.com/hyperledger/fabric/core/chaincode/persistence" 47 "github.com/hyperledger/fabric/core/chaincode/platforms" 48 "github.com/hyperledger/fabric/core/chaincode/platforms/golang" 49 "github.com/hyperledger/fabric/core/comm" 50 "github.com/hyperledger/fabric/core/common/ccprovider" 51 "github.com/hyperledger/fabric/core/config" 52 "github.com/hyperledger/fabric/core/container" 53 "github.com/hyperledger/fabric/core/container/dockercontroller" 54 "github.com/hyperledger/fabric/core/ledger" 55 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 56 ledgermock "github.com/hyperledger/fabric/core/ledger/mock" 57 cut "github.com/hyperledger/fabric/core/ledger/util" 58 "github.com/hyperledger/fabric/core/peer" 59 "github.com/hyperledger/fabric/core/policy" 60 policymocks "github.com/hyperledger/fabric/core/policy/mocks" 61 "github.com/hyperledger/fabric/core/scc" 62 "github.com/hyperledger/fabric/core/scc/lscc" 63 "github.com/hyperledger/fabric/internal/peer/packaging" 64 "github.com/hyperledger/fabric/msp" 65 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 66 msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools" 67 "github.com/hyperledger/fabric/protoutil" 68 "github.com/spf13/viper" 69 "github.com/stretchr/testify/assert" 70 "github.com/stretchr/testify/require" 71 "google.golang.org/grpc" 72 ) 73 74 //initialize peer and start up. If security==enabled, login as vp 75 func initPeer(channelIDs ...string) (*cm.Lifecycle, net.Listener, *ChaincodeSupport, func(), error) { 76 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 77 if err != nil { 78 return nil, nil, nil, nil, fmt.Errorf("failed to create cryptoProvider %s", err) 79 } 80 81 peerInstance := &peer.Peer{CryptoProvider: cryptoProvider} 82 grpcServer := grpc.NewServer() 83 84 lis, err := net.Listen("tcp", ":0") 85 if err != nil { 86 return nil, nil, nil, nil, fmt.Errorf("failed to start peer listener %s", err) 87 } 88 _, localPort, err := net.SplitHostPort(lis.Addr().String()) 89 if err != nil { 90 return nil, nil, nil, nil, fmt.Errorf("failed to get port: %s", err) 91 } 92 localIP, err := comm.GetLocalIP() 93 if err != nil { 94 return nil, nil, nil, nil, fmt.Errorf("failed to get local IP: %s", err) 95 } 96 97 peerAddress := net.JoinHostPort(localIP, localPort) 98 99 tempdir, err := ioutil.TempDir("", "chaincode") 100 if err != nil { 101 panic(fmt.Sprintf("failed to create temporary directory: %s", err)) 102 } 103 104 lgrInitializer := ledgermgmttest.NewInitializer(filepath.Join(tempdir, "ledgersData")) 105 lgrInitializer.Config.HistoryDBConfig = &ledger.HistoryDBConfig{ 106 Enabled: true, 107 } 108 peerInstance.LedgerMgr = ledgermgmt.NewLedgerMgr(lgrInitializer) 109 ccprovider.SetChaincodesPath(tempdir) 110 ca, _ := tlsgen.NewCA() 111 pr := platforms.NewRegistry(&golang.Platform{}) 112 mockAclProvider := &mock.ACLProvider{} 113 builtinSCCs := map[string]struct{}{"lscc": {}} 114 115 client, err := docker.NewClientFromEnv() 116 if err != nil { 117 return nil, nil, nil, nil, err 118 } 119 120 containerRouter := &container.Router{ 121 DockerVM: &dockercontroller.DockerVM{ 122 PeerID: "", 123 NetworkID: "", 124 BuildMetrics: dockercontroller.NewBuildMetrics(&disabled.Provider{}), 125 Client: client, 126 PlatformBuilder: &platforms.Builder{ 127 Registry: pr, 128 Client: client, 129 }, 130 }, 131 PackageProvider: &persistence.FallbackPackageLocator{ 132 ChaincodePackageLocator: &persistence.ChaincodePackageLocator{}, 133 LegacyCCPackageLocator: &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider}, 134 }, 135 } 136 137 buildRegistry := &container.BuildRegistry{} 138 139 lsccImpl := &lscc.SCC{ 140 BuiltinSCCs: map[string]struct{}{"lscc": {}}, 141 Support: &lscc.SupportImpl{ 142 GetMSPIDs: peerInstance.GetMSPIDs, 143 }, 144 SCCProvider: &lscc.PeerShim{Peer: peerInstance}, 145 ACLProvider: mockAclProvider, 146 GetMSPIDs: peerInstance.GetMSPIDs, 147 PolicyChecker: newPolicyChecker(peerInstance), 148 BCCSP: cryptoProvider, 149 BuildRegistry: buildRegistry, 150 ChaincodeBuilder: containerRouter, 151 } 152 153 ml := &cm.Lifecycle{} 154 ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) { 155 switch name { 156 case "lscc": 157 return &lifecycle.ChaincodeEndorsementInfo{ 158 ChaincodeID: "lscc.syscc", 159 }, nil 160 default: 161 return &lifecycle.ChaincodeEndorsementInfo{ 162 ChaincodeID: name + ":0", 163 }, nil 164 } 165 } 166 globalConfig := &Config{ 167 TLSEnabled: false, 168 Keepalive: time.Second, 169 StartupTimeout: 3 * time.Minute, 170 ExecuteTimeout: 30 * time.Second, 171 LogLevel: "info", 172 ShimLogLevel: "warning", 173 LogFormat: "TEST: [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}", 174 TotalQueryLimit: 10000, 175 } 176 containerRuntime := &ContainerRuntime{ 177 BuildRegistry: buildRegistry, 178 ContainerRouter: containerRouter, 179 } 180 userRunsCC := false 181 metricsProviders := &disabled.Provider{} 182 chaincodeHandlerRegistry := NewHandlerRegistry(userRunsCC) 183 chaincodeLauncher := &RuntimeLauncher{ 184 Metrics: NewLaunchMetrics(metricsProviders), 185 Registry: chaincodeHandlerRegistry, 186 Runtime: containerRuntime, 187 StartupTimeout: globalConfig.StartupTimeout, 188 CACert: ca.CertBytes(), 189 PeerAddress: peerAddress, 190 } 191 chaincodeSupport := &ChaincodeSupport{ 192 ACLProvider: aclmgmt.NewACLProvider( 193 func(string) channelconfig.Resources { return nil }, 194 newPolicyChecker(peerInstance), 195 ), 196 AppConfig: peerInstance, 197 DeployedCCInfoProvider: &ledgermock.DeployedChaincodeInfoProvider{}, 198 ExecuteTimeout: globalConfig.ExecuteTimeout, 199 HandlerMetrics: NewHandlerMetrics(metricsProviders), 200 HandlerRegistry: chaincodeHandlerRegistry, 201 Keepalive: globalConfig.Keepalive, 202 Launcher: chaincodeLauncher, 203 Lifecycle: ml, 204 Peer: peerInstance, 205 Runtime: containerRuntime, 206 BuiltinSCCs: builtinSCCs, 207 TotalQueryLimit: globalConfig.TotalQueryLimit, 208 UserRunsCC: userRunsCC, 209 } 210 pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport) 211 212 scc.DeploySysCC(lsccImpl, chaincodeSupport) 213 214 go grpcServer.Serve(lis) 215 216 cleanup := func() { 217 finitPeer(peerInstance, lis, channelIDs...) 218 os.RemoveAll(tempdir) 219 } 220 221 return ml, lis, chaincodeSupport, cleanup, nil 222 } 223 224 func finitPeer(peerInstance *peer.Peer, lis net.Listener, chainIDs ...string) { 225 if lis != nil { 226 closeListenerAndSleep(lis) 227 } 228 for _, c := range chainIDs { 229 if lgr := peerInstance.GetLedger(c); lgr != nil { 230 lgr.Close() 231 } 232 } 233 peerInstance.LedgerMgr.Close() 234 ledgerPath := config.GetPath("peer.fileSystemPath") 235 os.RemoveAll(ledgerPath) 236 os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger")) 237 } 238 239 func startTxSimulation(peerInstance *peer.Peer, channelID string, txid string) (ledger.TxSimulator, ledger.HistoryQueryExecutor, error) { 240 lgr := peerInstance.GetLedger(channelID) 241 txsim, err := lgr.NewTxSimulator(txid) 242 if err != nil { 243 return nil, nil, err 244 } 245 historyQueryExecutor, err := lgr.NewHistoryQueryExecutor() 246 if err != nil { 247 return nil, nil, err 248 } 249 250 return txsim, historyQueryExecutor, nil 251 } 252 253 func endTxSimulationCDS(peerInstance *peer.Peer, channelID string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error { 254 // get serialized version of the signer 255 ss, err := signer.Serialize() 256 if err != nil { 257 return err 258 } 259 260 // get lscc ChaincodeID 261 lsccid := &pb.ChaincodeID{ 262 Name: "lscc", 263 } 264 265 // get a proposal - we need it to get a transaction 266 prop, _, err := protoutil.CreateDeployProposalFromCDS(channelID, cds, ss, nil, nil, nil, nil) 267 if err != nil { 268 return err 269 } 270 271 return endTxSimulation(peerInstance, channelID, lsccid, txsim, payload, commit, prop, blockNumber) 272 } 273 274 func endTxSimulationCIS(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error { 275 // get serialized version of the signer 276 ss, err := signer.Serialize() 277 if err != nil { 278 return err 279 } 280 281 // get a proposal - we need it to get a transaction 282 prop, returnedTxid, err := protoutil.CreateProposalFromCISAndTxid(txid, common.HeaderType_ENDORSER_TRANSACTION, channelID, cis, ss) 283 if err != nil { 284 return err 285 } 286 if returnedTxid != txid { 287 return errors.New("txids are not same") 288 } 289 290 return endTxSimulation(peerInstance, channelID, ccid, txsim, payload, commit, prop, blockNumber) 291 } 292 293 //getting a crash from ledger.Commit when doing concurrent invokes 294 //It is likely intentional that ledger.Commit is serial (ie, the real 295 //Committer will invoke this serially on each block). Mimic that here 296 //by forcing serialization of the ledger.Commit call. 297 // 298 //NOTE-this should NOT have any effect on the older serial tests. 299 //This affects only the tests in concurrent_test.go which call these 300 //concurrently (100 concurrent invokes followed by 100 concurrent queries) 301 var _commitLock_ sync.Mutex 302 303 func endTxSimulation(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error { 304 txsim.Done() 305 if lgr := peerInstance.GetLedger(channelID); lgr != nil { 306 if commit { 307 var txSimulationResults *ledger.TxSimulationResults 308 var txSimulationBytes []byte 309 var err error 310 311 txsim.Done() 312 313 //get simulation results 314 if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil { 315 return err 316 } 317 if txSimulationBytes, err = txSimulationResults.GetPubSimulationBytes(); err != nil { 318 return err 319 } 320 // assemble a (signed) proposal response message 321 resp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200}, 322 txSimulationBytes, nil, ccid, signer) 323 if err != nil { 324 return err 325 } 326 327 // get the envelope 328 env, err := protoutil.CreateSignedTx(prop, signer, resp) 329 if err != nil { 330 return err 331 } 332 333 envBytes, err := protoutil.GetBytesEnvelope(env) 334 if err != nil { 335 return err 336 } 337 338 //create the block with 1 transaction 339 bcInfo, err := lgr.GetBlockchainInfo() 340 if err != nil { 341 return err 342 } 343 block := protoutil.NewBlock(blockNumber, bcInfo.CurrentBlockHash) 344 block.Data.Data = [][]byte{envBytes} 345 txsFilter := cut.NewTxValidationFlagsSetValue(len(block.Data.Data), pb.TxValidationCode_VALID) 346 block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter 347 348 //commit the block 349 350 //see comment on _commitLock_ 351 _commitLock_.Lock() 352 defer _commitLock_.Unlock() 353 354 blockAndPvtData := &ledger.BlockAndPvtData{ 355 Block: block, 356 PvtData: make(ledger.TxPvtDataMap), 357 } 358 359 // All tests are performed with just one transaction in a block. 360 // Hence, we can simiplify the procedure of constructing the 361 // block with private data. There is not enough need to 362 // add more than one transaction in a block for testing chaincode 363 // API. 364 365 // ASSUMPTION: Only one transaction in a block. 366 seqInBlock := uint64(0) 367 368 if txSimulationResults.PvtSimulationResults != nil { 369 blockAndPvtData.PvtData[seqInBlock] = &ledger.TxPvtData{ 370 SeqInBlock: seqInBlock, 371 WriteSet: txSimulationResults.PvtSimulationResults, 372 } 373 } 374 375 if err := lgr.CommitLegacy(blockAndPvtData, &ledger.CommitOptions{}); err != nil { 376 return err 377 } 378 } 379 } 380 381 return nil 382 } 383 384 // Build a chaincode. 385 func getDeploymentSpec(spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 386 fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec) 387 codePackageBytes, err := packaging.NewRegistry(&golang.Platform{}).GetDeploymentPayload(spec.Type.String(), spec.ChaincodeId.Path) 388 if err != nil { 389 return nil, err 390 } 391 392 cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 393 return cdDeploymentSpec, nil 394 } 395 396 //getDeployLSCCSpec gets the spec for the chaincode deployment to be sent to LSCC 397 func getDeployLSCCSpec(channelID string, cds *pb.ChaincodeDeploymentSpec, ccp *pb.CollectionConfigPackage) (*pb.ChaincodeInvocationSpec, error) { 398 b, err := proto.Marshal(cds) 399 if err != nil { 400 return nil, err 401 } 402 403 var ccpBytes []byte 404 if ccp != nil { 405 if ccpBytes, err = proto.Marshal(ccp); err != nil { 406 return nil, err 407 } 408 } 409 invokeInput := &pb.ChaincodeInput{Args: [][]byte{ 410 []byte("deploy"), // function name 411 []byte(channelID), // chaincode name to deploy 412 b, // chaincode deployment spec 413 }} 414 415 if ccpBytes != nil { 416 // SignaturePolicyEnvelope, escc, vscc, CollectionConfigPackage 417 invokeInput.Args = append(invokeInput.Args, nil, nil, nil, ccpBytes) 418 } 419 420 //wrap the deployment in an invocation spec to lscc... 421 lsccSpec := &pb.ChaincodeInvocationSpec{ 422 ChaincodeSpec: &pb.ChaincodeSpec{ 423 Type: pb.ChaincodeSpec_GOLANG, 424 ChaincodeId: &pb.ChaincodeID{Name: "lscc"}, 425 Input: invokeInput, 426 }} 427 428 return lsccSpec, nil 429 } 430 431 // Deploy a chaincode - i.e., build and initialize. 432 func deploy(channelID string, ccContext *CCContext, spec *pb.ChaincodeSpec, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) { 433 // First build and get the deployment spec 434 cdDeploymentSpec, err := getDeploymentSpec(spec) 435 if err != nil { 436 return nil, err 437 } 438 return deploy2(channelID, ccContext, cdDeploymentSpec, nil, blockNumber, chaincodeSupport) 439 } 440 441 func deployWithCollectionConfigs(channelID string, ccContext *CCContext, spec *pb.ChaincodeSpec, 442 collectionConfigPkg *pb.CollectionConfigPackage, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) { 443 // First build and get the deployment spec 444 cdDeploymentSpec, err := getDeploymentSpec(spec) 445 if err != nil { 446 return nil, err 447 } 448 return deploy2(channelID, ccContext, cdDeploymentSpec, collectionConfigPkg, blockNumber, chaincodeSupport) 449 } 450 451 func deploy2(channelID string, ccContext *CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, 452 collectionConfigPkg *pb.CollectionConfigPackage, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) { 453 cis, err := getDeployLSCCSpec(channelID, chaincodeDeploymentSpec, collectionConfigPkg) 454 if err != nil { 455 return nil, fmt.Errorf("Error creating lscc spec : %s\n", err) 456 } 457 458 uuid := util.GenerateUUID() 459 txsim, hqe, err := startTxSimulation(chaincodeSupport.Peer, channelID, uuid) 460 sprop, prop := protoutil.MockSignedEndorserProposal2OrPanic(channelID, cis.ChaincodeSpec, signer) 461 txParams := &ccprovider.TransactionParams{ 462 TxID: uuid, 463 ChannelID: channelID, 464 TXSimulator: txsim, 465 HistoryQueryExecutor: hqe, 466 SignedProp: sprop, 467 Proposal: prop, 468 } 469 if err != nil { 470 return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 471 } 472 473 defer func() { 474 //no error, lets try commit 475 if err == nil { 476 //capture returned error from commit 477 err = endTxSimulationCDS(chaincodeSupport.Peer, channelID, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber) 478 } else { 479 //there was an error, just close simulation and return that 480 endTxSimulationCDS(chaincodeSupport.Peer, channelID, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber) 481 } 482 }() 483 484 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 485 if err != nil { 486 return nil, fmt.Errorf("Failed to create default cryptoProvider: %s ", err) 487 } 488 ccinfoFSImpl := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider} 489 //ignore existence errors 490 ccinfoFSImpl.PutChaincode(chaincodeDeploymentSpec) 491 492 //write to lscc 493 if _, _, err = chaincodeSupport.Execute(txParams, "lscc", cis.ChaincodeSpec.Input); err != nil { 494 return nil, fmt.Errorf("Error deploying chaincode (1): %s", err) 495 } 496 497 if resp, _, err = chaincodeSupport.ExecuteLegacyInit(txParams, ccContext.Name, ccContext.Version, chaincodeDeploymentSpec.ChaincodeSpec.Input); err != nil { 498 return nil, fmt.Errorf("Error deploying chaincode(2): %s", err) 499 } 500 501 return resp, nil 502 } 503 504 // Invoke a chaincode. 505 func invoke(channelID string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte, chaincodeSupport *ChaincodeSupport) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 506 return invokeWithVersion(channelID, spec.GetChaincodeId().Version, spec, blockNumber, creator, chaincodeSupport) 507 } 508 509 // Invoke a chaincode with version (needed for upgrade) 510 func invokeWithVersion(channelID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte, chaincodeSupport *ChaincodeSupport) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 511 cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 512 513 // Now create the Transactions message and send to Peer. 514 uuid = util.GenerateUUID() 515 516 txsim, hqe, err := startTxSimulation(chaincodeSupport.Peer, channelID, uuid) 517 if err != nil { 518 return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 519 } 520 521 defer func() { 522 //no error, lets try commit 523 if err == nil { 524 //capture returned error from commit 525 err = endTxSimulationCIS(chaincodeSupport.Peer, channelID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber) 526 } else { 527 //there was an error, just close simulation and return that 528 endTxSimulationCIS(chaincodeSupport.Peer, channelID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber) 529 } 530 }() 531 532 if len(creator) == 0 { 533 creator = []byte("Admin") 534 } 535 sprop, prop := protoutil.MockSignedEndorserProposalOrPanic(channelID, spec, creator, []byte("msg1")) 536 var resp *pb.Response 537 txParams := &ccprovider.TransactionParams{ 538 TxID: uuid, 539 ChannelID: channelID, 540 TXSimulator: txsim, 541 HistoryQueryExecutor: hqe, 542 SignedProp: sprop, 543 Proposal: prop, 544 } 545 546 resp, ccevt, err = chaincodeSupport.Execute(txParams, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, cdInvocationSpec.ChaincodeSpec.Input) 547 if err != nil { 548 return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err) 549 } 550 if resp.Status != shim.OK { 551 return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", resp.Message) 552 } 553 554 return ccevt, uuid, resp.Payload, err 555 } 556 557 func closeListenerAndSleep(l net.Listener) { 558 if l != nil { 559 l.Close() 560 time.Sleep(2 * time.Second) 561 } 562 } 563 564 // Check the correctness of the final state after transaction execution. 565 func checkFinalState(peerInstance *peer.Peer, channelID string, ccContext *CCContext, a int, b int) error { 566 txid := util.GenerateUUID() 567 txsim, _, err := startTxSimulation(peerInstance, channelID, txid) 568 if err != nil { 569 return fmt.Errorf("Failed to get handle to simulator: %s ", err) 570 } 571 572 defer txsim.Done() 573 574 cName := ccContext.Name + ":" + ccContext.Version 575 576 // Invoke ledger to get state 577 var Aval, Bval int 578 resbytes, resErr := txsim.GetState(ccContext.Name, "a") 579 if resErr != nil { 580 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 581 } 582 Aval, resErr = strconv.Atoi(string(resbytes)) 583 if resErr != nil { 584 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 585 } 586 if Aval != a { 587 return fmt.Errorf("Incorrect result. Aval %d != %d <%s>", Aval, a, cName) 588 } 589 590 resbytes, resErr = txsim.GetState(ccContext.Name, "b") 591 if resErr != nil { 592 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 593 } 594 Bval, resErr = strconv.Atoi(string(resbytes)) 595 if resErr != nil { 596 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 597 } 598 if Bval != b { 599 return fmt.Errorf("Incorrect result. Bval %d != %d <%s>", Bval, b, cName) 600 } 601 602 // Success 603 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 604 return nil 605 } 606 607 const ( 608 chaincodeExample02GolangPath = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/example02" 609 chaincodePassthruGolangPath = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/passthru" 610 ) 611 612 // Test the execution of a chaincode that invokes another chaincode. 613 func TestChaincodeInvokeChaincode(t *testing.T) { 614 channel1 := "testchannelid" 615 channel2 := channel1 + "2" 616 ml, lis, chaincodeSupport, cleanup, err := initPeer(channel1, channel2) 617 if err != nil { 618 t.Fail() 619 t.Logf("Error creating peer: %s", err) 620 } 621 defer cleanup() 622 defer closeListenerAndSleep(lis) 623 624 mockPolicy := &mock.Policy{} 625 mockPolicy.EvaluateSignedDataReturns(nil) 626 627 polMgrChannel1 := &mock.PolicyManager{} 628 polMgrChannel1.GetPolicyReturns(mockPolicy, true) 629 err = peer.CreateMockChannel(chaincodeSupport.Peer, channel1, polMgrChannel1) 630 if err != nil { 631 t.Fatalf("Failed to create mock channel: %s", err) 632 } 633 634 polMgrChannel2 := &mock.PolicyManager{} 635 polMgrChannel2.GetPolicyReturns(mockPolicy, true) 636 err = peer.CreateMockChannel(chaincodeSupport.Peer, channel2, polMgrChannel2) 637 if err != nil { 638 t.Fatalf("Failed to create mock channel: %s", err) 639 } 640 641 peerInstance := chaincodeSupport.Peer 642 643 var nextBlockNumber1 uint64 = 1 644 var nextBlockNumber2 uint64 = 1 645 646 chaincode1Name := "cc_go_" + util.GenerateUUID() 647 chaincode2Name := "cc_go_" + util.GenerateUUID() 648 649 initialA, initialB := 100, 200 650 651 // Deploy first chaincode 652 ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) { 653 switch name { 654 case "lscc": 655 return &lifecycle.ChaincodeEndorsementInfo{ 656 ChaincodeID: "lscc.syscc", 657 }, nil 658 default: 659 return &lifecycle.ChaincodeEndorsementInfo{ 660 ChaincodeID: name + ":0", 661 }, nil 662 } 663 } 664 _, ccContext1, err := deployChaincode( 665 chaincode1Name, 666 "0", 667 pb.ChaincodeSpec_GOLANG, 668 chaincodeExample02GolangPath, 669 util.ToChaincodeArgs("init", "a", strconv.Itoa(initialA), "b", strconv.Itoa(initialB)), 670 channel1, 671 nextBlockNumber1, 672 chaincodeSupport, 673 ) 674 defer stopChaincode(ccContext1, chaincodeSupport) 675 require.NoErrorf(t, err, "error initializing chaincode %s: %s", chaincode1Name, err) 676 nextBlockNumber1++ 677 time.Sleep(time.Second) 678 679 // chaincode2: the chaincode that will call by chaincode1 680 chaincode2Version := "0" 681 chaincode2Type := pb.ChaincodeSpec_GOLANG 682 chaincode2Path := chaincodePassthruGolangPath 683 684 // deploy second chaincode on channel 685 _, ccContext2, err := deployChaincode( 686 chaincode2Name, 687 chaincode2Version, 688 chaincode2Type, 689 chaincode2Path, 690 util.ToChaincodeArgs("init"), 691 channel1, 692 nextBlockNumber1, 693 chaincodeSupport, 694 ) 695 defer stopChaincode(ccContext2, chaincodeSupport) 696 require.NoErrorf(t, err, "Error initializing chaincode %s: %s", chaincode2Name, err) 697 nextBlockNumber1++ 698 time.Sleep(time.Second) 699 700 // Invoke second chaincode passing the first chaincode's name as first param, 701 // which will inturn invoke the first chaincode 702 chaincode2InvokeSpec := &pb.ChaincodeSpec{ 703 Type: chaincode2Type, 704 ChaincodeId: &pb.ChaincodeID{ 705 Name: chaincode2Name, 706 Version: chaincode2Version, 707 }, 708 Input: &pb.ChaincodeInput{ 709 Args: util.ToChaincodeArgs(ccContext1.Name, "invoke", "a", "b", "10", ""), 710 }, 711 } 712 _, _, _, err = invoke(channel1, chaincode2InvokeSpec, nextBlockNumber1, []byte("Alice"), chaincodeSupport) 713 require.NoErrorf(t, err, "error invoking %s: %s", chaincode2Name, err) 714 nextBlockNumber1++ 715 716 // Check the state in the ledger 717 err = checkFinalState(peerInstance, channel1, ccContext1, initialA-10, initialB+10) 718 require.NoErrorf(t, err, "incorrect final state after transaction for %s: %s", chaincode1Name, err) 719 720 // Change the policies of the two channels in such a way: 721 // 1. Alice has reader access to both the channels. 722 // 2. Bob has access only to chainID2. 723 // Therefore the chaincode invocation should fail. 724 725 polMgrChannel1.GetPolicyReturns(&CreatorPolicy{Creators: [][]byte{[]byte("Alice")}}, true) 726 polMgrChannel2.GetPolicyReturns(&CreatorPolicy{Creators: [][]byte{[]byte("Alice"), []byte("Bob")}}, true) 727 728 // deploy chaincode2 on channel2 729 _, ccContext3, err := deployChaincode( 730 chaincode2Name, 731 chaincode2Version, 732 chaincode2Type, 733 chaincode2Path, 734 util.ToChaincodeArgs("init"), 735 channel2, 736 nextBlockNumber2, 737 chaincodeSupport, 738 ) 739 defer stopChaincode(ccContext3, chaincodeSupport) 740 require.NoErrorf(t, err, "error initializing chaincode %s/%s: %s", chaincode2Name, channel2, err) 741 nextBlockNumber2++ 742 time.Sleep(time.Second) 743 744 chaincode2InvokeSpec = &pb.ChaincodeSpec{ 745 Type: chaincode2Type, 746 ChaincodeId: &pb.ChaincodeID{ 747 Name: chaincode2Name, 748 Version: chaincode2Version, 749 }, 750 Input: &pb.ChaincodeInput{ 751 Args: util.ToChaincodeArgs(ccContext1.Name, "invoke", "a", "b", "10", channel1), 752 }, 753 } 754 755 // as Bob, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel 756 _, _, _, err = invoke(channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Bob"), chaincodeSupport) 757 require.Errorf(t, err, "as Bob, invoking <%s/%s> via <%s/%s> should fail, but it succeeded.", ccContext1.Name, channel1, chaincode2Name, channel2) 758 assert.True(t, strings.Contains(err.Error(), "[Creator not recognized [Bob]]")) 759 760 // as Alice, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel 761 _, _, _, err = invoke(channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Alice"), chaincodeSupport) 762 require.NoError(t, err, "as Alice, invoking <%s/%s> via <%s/%s> should should of succeeded, but it failed: %s", ccContext1.Name, channel1, chaincode2Name, channel2, err) 763 nextBlockNumber2++ 764 } 765 766 func stopChaincode(chaincodeCtx *CCContext, chaincodeSupport *ChaincodeSupport) { 767 chaincodeSupport.Runtime.Stop(chaincodeCtx.Name + ":" + chaincodeCtx.Version) 768 } 769 770 // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from 771 // from the called chaincode 772 func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { 773 channelID := "testchannelid" 774 775 ml, _, chaincodeSupport, cleanup, err := initPeer(channelID) 776 if err != nil { 777 t.Fail() 778 t.Logf("Error creating peer: %s", err) 779 } 780 defer cleanup() 781 782 polMgr := &mock.PolicyManager{} 783 mockPolicy := &mock.Policy{} 784 mockPolicy.EvaluateIdentitiesReturns(nil) 785 mockPolicy.EvaluateSignedDataReturns(nil) 786 polMgr.GetPolicyReturns(mockPolicy, true) 787 788 peer.CreateMockChannel(chaincodeSupport.Peer, channelID, polMgr) 789 790 ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) { 791 switch name { 792 case "lscc": 793 return &lifecycle.ChaincodeEndorsementInfo{ 794 ChaincodeID: "lscc.syscc", 795 }, nil 796 default: 797 return &lifecycle.ChaincodeEndorsementInfo{ 798 ChaincodeID: name + ":0", 799 }, nil 800 } 801 } 802 803 // Deploy first chaincode 804 cID1 := &pb.ChaincodeID{Name: "example02", Path: chaincodeExample02GolangPath, Version: "0"} 805 f := "init" 806 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 807 808 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 809 810 ccContext1 := &CCContext{ 811 Name: "example02", 812 Version: "0", 813 } 814 815 var nextBlockNumber uint64 = 1 816 defer chaincodeSupport.Runtime.Stop(cID1.Name + ":" + cID1.Version) 817 818 _, err = deploy(channelID, ccContext1, spec1, nextBlockNumber, chaincodeSupport) 819 nextBlockNumber++ 820 ccID1 := spec1.ChaincodeId.Name 821 if err != nil { 822 t.Fail() 823 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 824 return 825 } 826 827 time.Sleep(time.Second) 828 829 // Deploy second chaincode 830 cID2 := &pb.ChaincodeID{Name: "pthru", Path: chaincodePassthruGolangPath, Version: "0"} 831 f = "init" 832 args = util.ToChaincodeArgs(f) 833 834 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 835 836 ccContext2 := &CCContext{ 837 Name: "pthru", 838 Version: "0", 839 } 840 841 defer chaincodeSupport.Runtime.Stop(cID2.Name + ":" + cID2.Version) 842 _, err = deploy(channelID, ccContext2, spec2, nextBlockNumber, chaincodeSupport) 843 nextBlockNumber++ 844 ccID2 := spec2.ChaincodeId.Name 845 if err != nil { 846 t.Fail() 847 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 848 return 849 } 850 851 time.Sleep(time.Second) 852 853 // Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params 854 f = ccID1 855 args = util.ToChaincodeArgs(f, "invoke", "a", "") 856 857 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 858 // Invoke chaincode 859 _, _, _, err = invoke(channelID, spec2, nextBlockNumber, []byte("Alice"), chaincodeSupport) 860 861 if err == nil { 862 t.Fail() 863 t.Logf("Error invoking <%s>: %s", ccID2, err) 864 return 865 } 866 867 if !strings.Contains(err.Error(), "Incorrect number of arguments. Expecting 3") { 868 t.Fail() 869 t.Logf("Unexpected error %s", err) 870 return 871 } 872 } 873 874 func TestChaincodeInit(t *testing.T) { 875 channelID := "testchannelid" 876 877 _, _, chaincodeSupport, cleanup, err := initPeer(channelID) 878 if err != nil { 879 t.Fail() 880 t.Logf("Error creating peer: %s", err) 881 } 882 883 defer cleanup() 884 885 peer.CreateMockChannel(chaincodeSupport.Peer, channelID, nil) 886 887 url := "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/init_private_data" 888 cID := &pb.ChaincodeID{Name: "init_pvtdata", Path: url, Version: "0"} 889 890 f := "init" 891 args := util.ToChaincodeArgs(f) 892 893 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 894 895 ccContext := &CCContext{ 896 Name: "init_pvtdata", 897 Version: "0", 898 } 899 900 defer chaincodeSupport.Runtime.Stop(cID.Name + ":" + cID.Version) 901 902 var nextBlockNumber uint64 = 1 903 _, err = deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport) 904 assert.Contains(t, err.Error(), "private data APIs are not allowed in chaincode Init") 905 906 url = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/init_public_data" 907 cID = &pb.ChaincodeID{Name: "init_public_data", Path: url, Version: "0"} 908 909 f = "init" 910 args = util.ToChaincodeArgs(f) 911 912 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 913 914 ccContext = &CCContext{ 915 Name: "init_public_data", 916 Version: "0", 917 } 918 919 resp, err := deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport) 920 assert.NoError(t, err) 921 // why response status is defined as int32 when the status codes are 922 // defined as int (i.e., constant) 923 assert.Equal(t, int32(shim.OK), resp.Status) 924 } 925 926 // Test the invocation of a transaction. 927 func TestQueries(t *testing.T) { 928 // Allow queries test alone so that end to end test can be performed. It takes less than 5 seconds. 929 //testForSkip(t) 930 931 channelID := "testchannelid" 932 933 _, _, chaincodeSupport, cleanup, err := initPeer(channelID) 934 if err != nil { 935 t.Fail() 936 t.Logf("Error creating peer: %s", err) 937 } 938 939 defer cleanup() 940 941 peer.CreateMockChannel(chaincodeSupport.Peer, channelID, nil) 942 943 url := "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/map" 944 cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"} 945 946 f := "init" 947 args := util.ToChaincodeArgs(f) 948 949 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 950 951 ccContext := &CCContext{ 952 Name: "tmap", 953 Version: "0", 954 } 955 956 defer chaincodeSupport.Runtime.Stop(cID.Name + ":" + cID.Version) 957 958 var nextBlockNumber uint64 = 1 959 _, err = deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport) 960 nextBlockNumber++ 961 ccID := spec.ChaincodeId.Name 962 if err != nil { 963 t.Fail() 964 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 965 return 966 } 967 968 var keys []interface{} 969 // Add 101 marbles for testing range queries and rich queries (for capable ledgers) 970 // The tests will test both range and rich queries and queries with query limits 971 for i := 1; i <= 101; i++ { 972 f = "put" 973 974 // 51 owned by tom, 50 by jerry 975 owner := "tom" 976 if i%2 == 0 { 977 owner = "jerry" 978 } 979 980 // one marble color is red, 100 are blue 981 color := "blue" 982 if i == 12 { 983 color = "red" 984 } 985 986 key := fmt.Sprintf("marble%03d", i) 987 argsString := fmt.Sprintf("{\"docType\":\"marble\",\"name\":\"%s\",\"color\":\"%s\",\"size\":35,\"owner\":\"%s\"}", key, color, owner) 988 args = util.ToChaincodeArgs(f, key, argsString) 989 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 990 _, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 991 nextBlockNumber++ 992 993 if err != nil { 994 t.Fail() 995 t.Logf("Error invoking <%s>: %s", ccID, err) 996 return 997 } 998 999 } 1000 1001 //The following range query for "marble001" to "marble011" should return 10 marbles 1002 f = "keys" 1003 args = util.ToChaincodeArgs(f, "marble001", "marble011") 1004 1005 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1006 _, _, retval, err := invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1007 nextBlockNumber++ 1008 if err != nil { 1009 t.Fail() 1010 t.Logf("Error invoking <%s>: %s", ccID, err) 1011 return 1012 } 1013 1014 err = json.Unmarshal(retval, &keys) 1015 assert.NoError(t, err) 1016 if len(keys) != 10 { 1017 t.Fail() 1018 t.Logf("Error detected with the range query, should have returned 10 but returned %v", len(keys)) 1019 return 1020 } 1021 1022 //FAB-1163- The following range query should timeout and produce an error 1023 //the peer should handle this gracefully and not die 1024 1025 //save the original timeout and set a new timeout of 1 sec 1026 origTimeout := chaincodeSupport.ExecuteTimeout 1027 chaincodeSupport.ExecuteTimeout = time.Duration(1) * time.Second 1028 1029 //chaincode to sleep for 2 secs with timeout 1 1030 args = util.ToChaincodeArgs(f, "marble001", "marble002", "2000") 1031 1032 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1033 _, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1034 if err == nil { 1035 t.Fail() 1036 t.Logf("expected timeout error but succeeded") 1037 return 1038 } 1039 1040 //restore timeout 1041 chaincodeSupport.ExecuteTimeout = origTimeout 1042 1043 // querying for all marbles will return 101 marbles 1044 // this query should return exactly 101 results (one call to Next()) 1045 //The following range query for "marble001" to "marble102" should return 101 marbles 1046 f = "keys" 1047 args = util.ToChaincodeArgs(f, "marble001", "marble102") 1048 1049 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1050 _, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1051 nextBlockNumber++ 1052 if err != nil { 1053 t.Fail() 1054 t.Logf("Error invoking <%s>: %s", ccID, err) 1055 return 1056 } 1057 1058 //unmarshal the results 1059 err = json.Unmarshal(retval, &keys) 1060 assert.NoError(t, err) 1061 1062 //check to see if there are 101 values 1063 //default query limit of 10000 is used, this query is effectively unlimited 1064 if len(keys) != 101 { 1065 t.Fail() 1066 t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys)) 1067 return 1068 } 1069 1070 // querying for all simple key. This query should return exactly 101 simple keys (one 1071 // call to Next()) no composite keys. 1072 //The following open ended range query for "" to "" should return 101 marbles 1073 f = "keys" 1074 args = util.ToChaincodeArgs(f, "", "") 1075 1076 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1077 _, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1078 nextBlockNumber++ 1079 if err != nil { 1080 t.Fail() 1081 t.Logf("Error invoking <%s>: %s", ccID, err) 1082 return 1083 } 1084 1085 //unmarshal the results 1086 err = json.Unmarshal(retval, &keys) 1087 assert.NoError(t, err) 1088 1089 //check to see if there are 101 values 1090 //default query limit of 10000 is used, this query is effectively unlimited 1091 if len(keys) != 101 { 1092 t.Fail() 1093 t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys)) 1094 return 1095 } 1096 1097 type PageResponse struct { 1098 Bookmark string `json:"bookmark"` 1099 Keys []string `json:"keys"` 1100 } 1101 1102 //The following range query for "marble001" to "marble011" should return 10 marbles, in pages of 2 1103 f = "keysByPage" 1104 args = util.ToChaincodeArgs(f, "marble001", "marble011", "2", "") 1105 1106 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1107 _, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1108 nextBlockNumber++ 1109 if err != nil { 1110 t.Fail() 1111 t.Logf("Error invoking <%s>: %s", ccID, err) 1112 return 1113 } 1114 queryPage := &PageResponse{} 1115 1116 json.Unmarshal(retval, &queryPage) 1117 1118 expectedResult := []string{"marble001", "marble002"} 1119 1120 if !reflect.DeepEqual(expectedResult, queryPage.Keys) { 1121 t.Fail() 1122 t.Logf("Error detected with the paginated range query. Returned: %v should have returned: %v", queryPage.Keys, expectedResult) 1123 return 1124 } 1125 1126 // query for the next page 1127 args = util.ToChaincodeArgs(f, "marble001", "marble011", "2", queryPage.Bookmark) 1128 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1129 _, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1130 nextBlockNumber++ 1131 if err != nil { 1132 t.Fail() 1133 t.Logf("Error invoking <%s>: %s", ccID, err) 1134 return 1135 } 1136 1137 json.Unmarshal(retval, &queryPage) 1138 1139 expectedResult = []string{"marble003", "marble004"} 1140 1141 if !reflect.DeepEqual(expectedResult, queryPage.Keys) { 1142 t.Fail() 1143 t.Logf("Error detected with the paginated range query second page. Returned: %v should have returned: %v %v", queryPage.Keys, expectedResult, queryPage.Bookmark) 1144 return 1145 } 1146 1147 // modifications for history query 1148 f = "put" 1149 args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}") 1150 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1151 _, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1152 nextBlockNumber++ 1153 if err != nil { 1154 t.Fail() 1155 t.Logf("Error invoking <%s>: %s", ccID, err) 1156 return 1157 } 1158 1159 f = "put" 1160 args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}") 1161 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1162 _, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1163 nextBlockNumber++ 1164 if err != nil { 1165 t.Fail() 1166 t.Logf("Error invoking <%s>: %s", ccID, err) 1167 return 1168 } 1169 1170 //The following history query for "marble12" should return 3 records 1171 f = "history" 1172 args = util.ToChaincodeArgs(f, "marble012") 1173 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1174 _, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport) 1175 nextBlockNumber++ 1176 if err != nil { 1177 t.Fail() 1178 t.Logf("Error invoking <%s>: %s", ccID, err) 1179 return 1180 } 1181 1182 var history []interface{} 1183 err = json.Unmarshal(retval, &history) 1184 assert.NoError(t, err) 1185 if len(history) != 3 { 1186 t.Fail() 1187 t.Logf("Error detected with the history query, should have returned 3 but returned %v", len(history)) 1188 return 1189 } 1190 } 1191 1192 func TestMain(m *testing.M) { 1193 var err error 1194 1195 msptesttools.LoadMSPSetupForTesting() 1196 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 1197 if err != nil { 1198 fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err) 1199 os.Exit(-1) 1200 return 1201 } 1202 signer, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity() 1203 if err != nil { 1204 fmt.Print("Could not initialize msp/signer") 1205 os.Exit(-1) 1206 return 1207 } 1208 1209 setupTestConfig() 1210 flogging.ActivateSpec("chaincode=debug") 1211 os.Exit(m.Run()) 1212 } 1213 1214 func setupTestConfig() { 1215 flag.Parse() 1216 1217 // Now set the configuration file 1218 viper.SetEnvPrefix("CORE") 1219 viper.AutomaticEnv() 1220 replacer := strings.NewReplacer(".", "_") 1221 viper.SetEnvKeyReplacer(replacer) 1222 viper.SetConfigName("chaincodetest") // name of config file (without extension) 1223 viper.AddConfigPath("./") // path to look for the config file in 1224 err := viper.ReadInConfig() // Find and read the config file 1225 if err != nil { // Handle errors reading the config file 1226 panic(fmt.Errorf("Fatal error config file: %s \n", err)) 1227 } 1228 1229 // Init the BCCSP 1230 err = factory.InitFactories(nil) 1231 if err != nil { 1232 panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err)) 1233 } 1234 } 1235 1236 func deployChaincode(name string, version string, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, channel string, nextBlockNumber uint64, chaincodeSupport *ChaincodeSupport) (*pb.Response, *CCContext, error) { 1237 chaincodeSpec := &pb.ChaincodeSpec{ 1238 ChaincodeId: &pb.ChaincodeID{ 1239 Name: name, 1240 Version: version, 1241 Path: path, 1242 }, 1243 Type: chaincodeType, 1244 Input: &pb.ChaincodeInput{ 1245 Args: args, 1246 }, 1247 } 1248 1249 chaincodeCtx := &CCContext{ 1250 Name: name, 1251 Version: version, 1252 } 1253 1254 result, err := deploy(channel, chaincodeCtx, chaincodeSpec, nextBlockNumber, chaincodeSupport) 1255 if err != nil { 1256 return nil, chaincodeCtx, fmt.Errorf("Error deploying <%s:%s>: %s", name, version, err) 1257 } 1258 return result, chaincodeCtx, nil 1259 } 1260 1261 var signer msp.SigningIdentity 1262 1263 type CreatorPolicy struct { 1264 Creators [][]byte 1265 } 1266 1267 // EvaluateSignedData takes a set of SignedData and evaluates whether this set of signatures satisfies the policy 1268 func (c *CreatorPolicy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error { 1269 for _, value := range c.Creators { 1270 if bytes.Equal(signatureSet[0].Identity, value) { 1271 return nil 1272 } 1273 } 1274 return fmt.Errorf("Creator not recognized [%s]", string(signatureSet[0].Identity)) 1275 } 1276 1277 // EvaluateIdentities takes an array of identities and evaluates whether 1278 // they satisfy the policy 1279 func (c *CreatorPolicy) EvaluateIdentities(identities []msp.Identity) error { 1280 return nil 1281 } 1282 1283 func newPolicyChecker(peerInstance *peer.Peer) policy.PolicyChecker { 1284 return policy.NewPolicyChecker( 1285 policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager), 1286 &policymocks.MockIdentityDeserializer{ 1287 Identity: []byte("Admin"), 1288 Msg: []byte("msg1"), 1289 }, 1290 &policymocks.MockMSPPrincipalGetter{Principal: []byte("Admin")}, 1291 ) 1292 }