diff --git a/core/chaincode/chaincode_support_test.go b/core/chaincode/chaincode_support_test.go index dc41c8ed55e..bbc76dedd3f 100644 --- a/core/chaincode/chaincode_support_test.go +++ b/core/chaincode/chaincode_support_test.go @@ -41,12 +41,11 @@ import ( "github.com/hyperledger/fabric/core/peer" "github.com/hyperledger/fabric/core/policy" "github.com/hyperledger/fabric/core/scc" + mspmgmt "github.com/hyperledger/fabric/msp/mgmt" plgr "github.com/hyperledger/fabric/protos/ledger/queryresult" pb "github.com/hyperledger/fabric/protos/peer" putils "github.com/hyperledger/fabric/protos/utils" "golang.org/x/net/context" - - mspmgmt "github.com/hyperledger/fabric/msp/mgmt" ) var globalBlockNum map[string]uint64 @@ -342,7 +341,7 @@ func initializeCC(t *testing.T, chainID, ccname string, ccSide *mockpeer.MockCCC } chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop := startTx(t, chainID, cis) @@ -392,7 +391,7 @@ func invokeCC(t *testing.T, chainID, ccname string, ccSide *mockpeer.MockCCComm) } chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop := startTx(t, chainID, cis) @@ -439,7 +438,7 @@ func getQueryStateByRange(t *testing.T, chainID, ccname string, ccSide *mockpeer } chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop := startTx(t, chainID, cis) @@ -486,7 +485,7 @@ func cc2cc(t *testing.T, chainID, chainID2, ccname string, ccSide *mockpeer.Mock } chaincodeID := &pb.ChaincodeID{Name: calledCC, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("deploycc")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("deploycc")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} //first deploy the new cc to LSCC @@ -500,7 +499,7 @@ func cc2cc(t *testing.T, chainID, chainID2, ccname string, ccSide *mockpeer.Mock //now do the cc2cc chaincodeID = &pb.ChaincodeID{Name: ccname, Version: "0"} - ci = &pb.ChaincodeInput{[][]byte{[]byte("invokecc")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("invokecc")}, nil} cis = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop = startTx(t, chainID, cis) @@ -538,7 +537,7 @@ func getQueryResult(t *testing.T, chainID, ccname string, ccSide *mockpeer.MockC } chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop := startTx(t, chainID, cis) @@ -589,7 +588,7 @@ func getHistory(t *testing.T, chainID, ccname string, ccSide *mockpeer.MockCCCom } chaincodeID := &pb.ChaincodeID{Name: ccname, Version: "0"} - ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} cis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: ci}} ctxt, txsim, sprop, prop := startTx(t, chainID, cis) diff --git a/core/chaincode/exectransaction.go b/core/chaincode/exectransaction.go index c4460e36913..6bf7e4f1b1f 100644 --- a/core/chaincode/exectransaction.go +++ b/core/chaincode/exectransaction.go @@ -46,6 +46,8 @@ func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{} return nil, nil, fmt.Errorf("%s", err) } + cMsg.Decorations = cccid.ProposalDecorations + var ccMsg *pb.ChaincodeMessage ccMsg, err = createCCMessage(cctyp, cccid.TxID, cMsg) if err != nil { diff --git a/core/chaincode/shim/chaincode.go b/core/chaincode/shim/chaincode.go index ea917525592..0bb7c21fcba 100644 --- a/core/chaincode/shim/chaincode.go +++ b/core/chaincode/shim/chaincode.go @@ -67,6 +67,8 @@ type ChaincodeStub struct { creator []byte transient map[string][]byte binding []byte + + decorations map[string][]byte } // Peer address derived from command line or env var @@ -334,6 +336,7 @@ func (stub *ChaincodeStub) init(handler *Handler, txid string, input *pb.Chainco stub.args = input.Args stub.handler = handler stub.signedProposal = signedProposal + stub.decorations = input.Decorations // TODO: sanity check: verify that every call to init with a nil // signedProposal is a legitimate one, meaning it is an internal call @@ -366,6 +369,10 @@ func (stub *ChaincodeStub) GetTxID() string { return stub.TxID } +func (stub *ChaincodeStub) GetDecorations() map[string][]byte { + return stub.decorations +} + // --------- Security functions ---------- //CHAINCODE SEC INTERFACE FUNCS TOBE IMPLEMENTED BY ANGELO diff --git a/core/chaincode/shim/interfaces.go b/core/chaincode/shim/interfaces.go index a761d6dfa42..35033867801 100644 --- a/core/chaincode/shim/interfaces.go +++ b/core/chaincode/shim/interfaces.go @@ -179,6 +179,10 @@ type ChaincodeStubInterface interface { // GetBinding returns the transaction binding GetBinding() ([]byte, error) + // GetDecorations returns additional data (if applicable) + // about the proposal that originated from the peer + GetDecorations() map[string][]byte + // GetSignedProposal returns the SignedProposal object, which contains all // data elements part of a transaction proposal. GetSignedProposal() (*pb.SignedProposal, error) diff --git a/core/chaincode/shim/mockstub.go b/core/chaincode/shim/mockstub.go index 440da7a415d..69f635821cb 100644 --- a/core/chaincode/shim/mockstub.go +++ b/core/chaincode/shim/mockstub.go @@ -134,6 +134,10 @@ func (stub *MockStub) MockInvoke(uuid string, args [][]byte) pb.Response { return res } +func (stub *MockStub) GetDecorations() map[string][]byte { + return nil +} + // Invoke this chaincode, also starts and ends a transaction. func (stub *MockStub) MockInvokeWithSignedProposal(uuid string, args [][]byte, sp *pb.SignedProposal) pb.Response { stub.args = args diff --git a/core/chaincode/shim/shim_test.go b/core/chaincode/shim/shim_test.go index 8aefb759b79..e86648fe0fa 100644 --- a/core/chaincode/shim/shim_test.go +++ b/core/chaincode/shim/shim_test.go @@ -24,13 +24,12 @@ import ( "testing" "time" + "github.com/hyperledger/fabric/common/flogging" mockpeer "github.com/hyperledger/fabric/common/mocks/peer" "github.com/hyperledger/fabric/common/util" lproto "github.com/hyperledger/fabric/protos/ledger/queryresult" pb "github.com/hyperledger/fabric/protos/peer" "github.com/hyperledger/fabric/protos/utils" - - "github.com/hyperledger/fabric/common/flogging" "github.com/op/go-logging" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -585,7 +584,7 @@ func TestInvoke(t *testing.T) { peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: "1"}) - ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}, nil} payload := utils.MarshalOrPanic(ci) respSet := &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{ &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}}, @@ -608,7 +607,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3"}) @@ -623,7 +622,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3a"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3a"}) @@ -636,7 +635,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3b"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("invoke"), []byte("A"), []byte("B"), []byte("10")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3b"}) @@ -649,7 +648,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "4"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "4"}) @@ -662,7 +661,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "4a"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("delete"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "4a"}) @@ -674,7 +673,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "5"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("badinvoke")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("badinvoke")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "5"}) @@ -700,7 +699,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6"}) @@ -715,7 +714,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6a"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6a"}) @@ -732,7 +731,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6b"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6b"}) @@ -749,7 +748,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "6c"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("rangeq"), []byte("A"), []byte("B")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "6c"}) @@ -771,7 +770,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "7"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "7"}) @@ -786,7 +785,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "7a"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("historyq"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "7a"}) @@ -812,7 +811,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "8"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "8"}) @@ -826,7 +825,7 @@ func TestInvoke(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "8a"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("richq"), []byte("A")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "8a"}) @@ -907,7 +906,7 @@ func TestCC2CC(t *testing.T) { peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: "1"}) - ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}} + ci := &pb.ChaincodeInput{[][]byte{[]byte("init"), []byte("A"), []byte("100"), []byte("B"), []byte("200")}, nil} payload := utils.MarshalOrPanic(ci) respSet := &mockpeer.MockResponseSet{errorFunc, errorFunc, []*mockpeer.MockResponse{ &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Txid: "2"}, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: "2"}}, @@ -929,7 +928,7 @@ func TestCC2CC(t *testing.T) { &mockpeer.MockResponse{&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Txid: "3"}, nil}}} peerSide.SetResponses(respSet) - ci = &pb.ChaincodeInput{[][]byte{[]byte("cc2cc"), []byte("othercc"), []byte("arg1"), []byte("arg2")}} + ci = &pb.ChaincodeInput{[][]byte{[]byte("cc2cc"), []byte("othercc"), []byte("arg1"), []byte("arg2")}, nil} payload = utils.MarshalOrPanic(ci) peerSide.Send(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: "3"}) diff --git a/core/common/ccprovider/ccinfocache_test.go b/core/common/ccprovider/ccinfocache_test.go index c95851a8059..07385aac630 100644 --- a/core/common/ccprovider/ccinfocache_test.go +++ b/core/common/ccprovider/ccinfocache_test.go @@ -21,11 +21,10 @@ import ( "bytes" "compress/gzip" "io/ioutil" + "os" "path/filepath" "testing" - "os" - "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/core/container/util" "github.com/hyperledger/fabric/protos/peer" @@ -221,7 +220,7 @@ func TestNewCCContext(t *testing.T) { NewCCContext("foo", "foo", "", "", false, nil, nil) }, "NewCCContext should have paniced if version is empty") - ccctx = &CCContext{"foo", "foo", "1.0", "", false, nil, nil, ""} + ccctx = &CCContext{"foo", "foo", "1.0", "", false, nil, nil, "", nil} assert.Panics(t, func() { ccctx.GetCanonicalName() }, "GetConnonicalName should have paniced if cannonical name is empty") diff --git a/core/common/ccprovider/ccprovider.go b/core/common/ccprovider/ccprovider.go index ce46eaddaaf..ac4cb02c450 100644 --- a/core/common/ccprovider/ccprovider.go +++ b/core/common/ccprovider/ccprovider.go @@ -17,6 +17,7 @@ limitations under the License. package ccprovider import ( + "bytes" "context" "fmt" "io/ioutil" @@ -25,9 +26,6 @@ import ( "strings" "github.com/golang/protobuf/proto" - - "bytes" - "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/core/ledger" pb "github.com/hyperledger/fabric/protos/peer" @@ -345,6 +343,9 @@ type CCContext struct { //this is not set but computed (note that this is not exported. use GetCanonicalName) canonicalName string + + // this is additional data passed to the chaincode + ProposalDecorations map[string][]byte } //NewCCContext just construct a new struct with whatever args @@ -358,7 +359,7 @@ func NewCCContext(cid, name, version, txid string, syscc bool, signedProp *pb.Si canName := name + ":" + version - cccid := &CCContext{cid, name, version, txid, syscc, signedProp, prop, canName} + cccid := &CCContext{cid, name, version, txid, syscc, signedProp, prop, canName, nil} ccproviderLogger.Debugf("NewCCCC (chain=%s,chaincode=%s,version=%s,txid=%s,syscc=%t,proposal=%p,canname=%s", cid, name, version, txid, syscc, prop, cccid.canonicalName) diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index 0cd4c778a3d..73da14d9919 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -21,6 +21,8 @@ import ( "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/validation" + "github.com/hyperledger/fabric/core/handlers/decoration" + "github.com/hyperledger/fabric/core/handlers/library" "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/peer" "github.com/hyperledger/fabric/core/policy" @@ -111,6 +113,12 @@ func (e *Endorser) callChaincode(ctxt context.Context, chainID string, version s cccid := ccprovider.NewCCContext(chainID, cid.Name, version, txid, scc, signedProp, prop) + // decorate the chaincode input + decorator := library.InitRegistry(library.Config{}).Lookup(library.DecoratorKey).(decoration.Decorator) + cis.ChaincodeSpec.Input.Decorations = make(map[string][]byte) + cis.ChaincodeSpec.Input = decorator.Decorate(cis.ChaincodeSpec.Input) + cccid.ProposalDecorations = cis.ChaincodeSpec.Input.Decorations + res, ccevent, err = chaincode.ExecuteChaincode(ctxt, cccid, cis.ChaincodeSpec.Input.Args) if err != nil { diff --git a/protos/peer/chaincode.pb.go b/protos/peer/chaincode.pb.go index c45f51aed73..d47607b7e5a 100644 --- a/protos/peer/chaincode.pb.go +++ b/protos/peer/chaincode.pb.go @@ -135,7 +135,8 @@ func (m *ChaincodeID) GetVersion() string { // UnmarshalJSON in transaction.go converts the string-based REST/JSON input to // the []byte-based current ChaincodeInput structure. type ChaincodeInput struct { - Args [][]byte `protobuf:"bytes,1,rep,name=args,proto3" json:"args,omitempty"` + Args [][]byte `protobuf:"bytes,1,rep,name=args,proto3" json:"args,omitempty"` + Decorations map[string][]byte `protobuf:"bytes,2,rep,name=decorations" json:"decorations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (m *ChaincodeInput) Reset() { *m = ChaincodeInput{} } @@ -150,6 +151,13 @@ func (m *ChaincodeInput) GetArgs() [][]byte { return nil } +func (m *ChaincodeInput) GetDecorations() map[string][]byte { + if m != nil { + return m.Decorations + } + return nil +} + // Carries the chaincode specification. This is the actual metadata required for // defining a chaincode. type ChaincodeSpec struct { @@ -281,42 +289,46 @@ func init() { func init() { proto.RegisterFile("peer/chaincode.proto", fileDescriptor1) } var fileDescriptor1 = []byte{ - // 591 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x93, 0x5d, 0x6f, 0xd3, 0x3e, - 0x14, 0xc6, 0x97, 0xb5, 0x7b, 0x3b, 0x7d, 0xf9, 0xe7, 0x6f, 0x06, 0x54, 0xbb, 0x61, 0x44, 0x5c, - 0x8c, 0x09, 0xa5, 0x52, 0x99, 0xb8, 0x42, 0x48, 0x59, 0x93, 0x4d, 0x81, 0xd2, 0x4c, 0x59, 0x87, - 0x04, 0x37, 0x95, 0x9b, 0x9c, 0xa6, 0x16, 0xa9, 0x1d, 0x25, 0x6e, 0xb4, 0x5e, 0xf3, 0xbd, 0xf8, - 0x6a, 0x20, 0x3b, 0x6b, 0xb7, 0xa9, 0xbb, 0xe4, 0x2a, 0xf6, 0x93, 0xe7, 0xd8, 0xcf, 0xf9, 0xe9, - 0x18, 0x0e, 0x33, 0xc4, 0xbc, 0x1b, 0xcd, 0x28, 0xe3, 0x91, 0x88, 0xd1, 0xce, 0x72, 0x21, 0x05, - 0xd9, 0xd5, 0x9f, 0xe2, 0xe8, 0x55, 0x22, 0x44, 0x92, 0x62, 0x57, 0x6f, 0x27, 0x8b, 0x69, 0x57, - 0xb2, 0x39, 0x16, 0x92, 0xce, 0xb3, 0xca, 0x68, 0x05, 0xd0, 0xe8, 0xaf, 0x6a, 0x7d, 0x97, 0x10, - 0xa8, 0x67, 0x54, 0xce, 0x3a, 0xc6, 0xb1, 0x71, 0x72, 0x10, 0xea, 0xb5, 0xd2, 0x38, 0x9d, 0x63, - 0x67, 0xbb, 0xd2, 0xd4, 0x9a, 0x74, 0x60, 0xaf, 0xc4, 0xbc, 0x60, 0x82, 0x77, 0x6a, 0x5a, 0x5e, - 0x6d, 0xad, 0x37, 0xd0, 0xbe, 0x3f, 0x90, 0x67, 0x0b, 0xa9, 0xea, 0x69, 0x9e, 0x14, 0x1d, 0xe3, - 0xb8, 0x76, 0xd2, 0x0c, 0xf5, 0xda, 0xfa, 0x63, 0x40, 0x6b, 0x6d, 0xbb, 0xce, 0x30, 0x22, 0x36, - 0xd4, 0xe5, 0x32, 0x43, 0x7d, 0x73, 0xbb, 0x77, 0x54, 0xc5, 0x2b, 0xec, 0x47, 0x26, 0x7b, 0xb4, - 0xcc, 0x30, 0xd4, 0x3e, 0xf2, 0x01, 0x9a, 0xeb, 0xa6, 0xc7, 0x2c, 0xd6, 0xe9, 0x1a, 0xbd, 0x67, - 0x1b, 0x75, 0xbe, 0x1b, 0x36, 0xd6, 0x46, 0x3f, 0x26, 0xef, 0x60, 0x87, 0xa9, 0x58, 0x3a, 0x77, - 0xa3, 0xf7, 0x62, 0xb3, 0x40, 0xfd, 0x0d, 0x2b, 0x93, 0xea, 0x53, 0x11, 0x13, 0x0b, 0xd9, 0xa9, - 0x1f, 0x1b, 0x27, 0x3b, 0xe1, 0x6a, 0x6b, 0x7d, 0x82, 0xba, 0x4a, 0x43, 0x5a, 0x70, 0x70, 0x33, - 0x74, 0xbd, 0x0b, 0x7f, 0xe8, 0xb9, 0xe6, 0x16, 0x01, 0xd8, 0xbd, 0x0c, 0x06, 0xce, 0xf0, 0xd2, - 0x34, 0xc8, 0x3e, 0xd4, 0x87, 0x81, 0xeb, 0x99, 0xdb, 0x64, 0x0f, 0x6a, 0x7d, 0x27, 0x34, 0x6b, - 0x4a, 0xfa, 0xec, 0x7c, 0x73, 0xcc, 0xba, 0xf5, 0x7b, 0x1b, 0x5e, 0xae, 0xef, 0x74, 0x31, 0x4b, - 0xc5, 0x72, 0x8e, 0x5c, 0x6a, 0x16, 0x1f, 0xa1, 0x7d, 0xdf, 0x5b, 0x91, 0x61, 0xa4, 0xa9, 0x34, - 0x7a, 0xcf, 0x9f, 0xa4, 0x12, 0xb6, 0xa2, 0x47, 0x24, 0x1d, 0x68, 0xe3, 0x74, 0x8a, 0x91, 0x64, - 0x25, 0x8e, 0x63, 0x2a, 0xf1, 0x8e, 0xcd, 0x91, 0x5d, 0x0d, 0x83, 0xbd, 0x1a, 0x06, 0x7b, 0xb4, - 0x1a, 0x86, 0xb0, 0xb5, 0xae, 0x70, 0xa9, 0x44, 0xf2, 0x1a, 0x9a, 0xfa, 0xee, 0x8c, 0x46, 0x3f, - 0x69, 0x82, 0x9a, 0x55, 0x33, 0x6c, 0x28, 0xed, 0xaa, 0x92, 0x48, 0x00, 0xfb, 0x78, 0x8b, 0xd1, - 0x18, 0x79, 0xa9, 0xd1, 0xb4, 0x7b, 0x67, 0x1b, 0xe9, 0x1e, 0xb7, 0x65, 0x7b, 0xb7, 0x18, 0x2d, - 0x24, 0x13, 0xdc, 0xe3, 0x25, 0xcb, 0x05, 0x57, 0x3f, 0xc2, 0x3d, 0x75, 0x8a, 0xc7, 0x4b, 0xcb, - 0x86, 0xc3, 0xa7, 0x0c, 0x8a, 0xa8, 0x1b, 0xf4, 0xbf, 0x78, 0x61, 0x45, 0xf7, 0xfa, 0xfb, 0xf5, - 0xc8, 0xfb, 0x6a, 0x1a, 0xd6, 0x2f, 0xe3, 0x01, 0x40, 0x9f, 0x97, 0x22, 0xa2, 0xaa, 0xf4, 0x1f, - 0x00, 0x3c, 0x85, 0xff, 0x59, 0x3c, 0x4e, 0x90, 0x63, 0xae, 0x8f, 0x1c, 0xd3, 0x34, 0xb9, 0x9b, - 0xfe, 0xff, 0x58, 0x7c, 0xb9, 0xd6, 0x9d, 0x34, 0x39, 0x3d, 0x83, 0xc3, 0xbe, 0xe0, 0x53, 0x16, - 0x23, 0x97, 0x8c, 0xa6, 0x4c, 0x2e, 0x07, 0x58, 0x62, 0xaa, 0x92, 0x5e, 0xdd, 0x9c, 0x0f, 0xfc, - 0xbe, 0xb9, 0x45, 0x4c, 0x68, 0xf6, 0x83, 0xe1, 0x85, 0xef, 0x7a, 0xc3, 0x91, 0xef, 0x0c, 0x4c, - 0xe3, 0x3c, 0x00, 0x4b, 0xe4, 0x89, 0x3d, 0x5b, 0x66, 0x98, 0xa7, 0x18, 0x27, 0x98, 0xdb, 0x53, - 0x3a, 0xc9, 0x59, 0xb4, 0xca, 0xa7, 0x1e, 0xf5, 0x8f, 0xb7, 0x09, 0x93, 0xb3, 0xc5, 0xc4, 0x8e, - 0xc4, 0xbc, 0xfb, 0xc0, 0xda, 0xad, 0xac, 0xd5, 0x9b, 0x2e, 0xba, 0xca, 0x3a, 0xa9, 0xde, 0xfb, - 0xfb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x05, 0x18, 0x06, 0x44, 0x0e, 0x04, 0x00, 0x00, + // 654 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x54, 0x4d, 0x6f, 0xda, 0x4a, + 0x14, 0x8d, 0x81, 0x7c, 0x5d, 0x03, 0xcf, 0x6f, 0x1e, 0xef, 0x3d, 0xc4, 0xa6, 0xd4, 0x9b, 0xd2, + 0xa8, 0x32, 0x12, 0x8d, 0xaa, 0xaa, 0xaa, 0x22, 0x11, 0xec, 0x44, 0x6e, 0x29, 0x44, 0x0e, 0xa9, + 0xd4, 0x6e, 0x90, 0xb1, 0x2f, 0x66, 0x14, 0x33, 0x63, 0xd9, 0x83, 0x15, 0xd6, 0xfd, 0x41, 0xfd, + 0x07, 0xfd, 0x6b, 0xad, 0x66, 0x1c, 0x48, 0xd2, 0x64, 0xd9, 0x15, 0x73, 0x0f, 0xe7, 0x7e, 0x9c, + 0x33, 0xd7, 0x03, 0x8d, 0x04, 0x31, 0xed, 0x06, 0x0b, 0x9f, 0xb2, 0x80, 0x87, 0x68, 0x25, 0x29, + 0x17, 0x9c, 0xec, 0xa9, 0x9f, 0xac, 0xf5, 0x2c, 0xe2, 0x3c, 0x8a, 0xb1, 0xab, 0xc2, 0xd9, 0x6a, + 0xde, 0x15, 0x74, 0x89, 0x99, 0xf0, 0x97, 0x49, 0x41, 0x34, 0xc7, 0xa0, 0x0f, 0x36, 0xb9, 0xae, + 0x4d, 0x08, 0x54, 0x12, 0x5f, 0x2c, 0x9a, 0x5a, 0x5b, 0xeb, 0x1c, 0x7a, 0xea, 0x2c, 0x31, 0xe6, + 0x2f, 0xb1, 0x59, 0x2a, 0x30, 0x79, 0x26, 0x4d, 0xd8, 0xcf, 0x31, 0xcd, 0x28, 0x67, 0xcd, 0xb2, + 0x82, 0x37, 0xa1, 0xf9, 0x5d, 0x83, 0xfa, 0x5d, 0x45, 0x96, 0xac, 0x84, 0x2c, 0xe0, 0xa7, 0x51, + 0xd6, 0xd4, 0xda, 0xe5, 0x4e, 0xd5, 0x53, 0x67, 0xe2, 0x82, 0x1e, 0x62, 0xc0, 0x53, 0x5f, 0x50, + 0xce, 0xb2, 0x66, 0xa9, 0x5d, 0xee, 0xe8, 0xbd, 0x17, 0xc5, 0x50, 0x99, 0xf5, 0xb0, 0x80, 0x65, + 0xdf, 0x31, 0x1d, 0x26, 0xd2, 0xb5, 0x77, 0x3f, 0xb7, 0x75, 0x02, 0xc6, 0xef, 0x04, 0x62, 0x40, + 0xf9, 0x1a, 0xd7, 0xb7, 0x32, 0xe4, 0x91, 0x34, 0x60, 0x37, 0xf7, 0xe3, 0x55, 0x21, 0xa3, 0xea, + 0x15, 0xc1, 0xbb, 0xd2, 0x5b, 0xcd, 0xfc, 0xa9, 0x41, 0x6d, 0xdb, 0xf0, 0x32, 0xc1, 0x80, 0x58, + 0x50, 0x11, 0xeb, 0x04, 0x55, 0x7a, 0xbd, 0xd7, 0x7a, 0x34, 0x95, 0x24, 0x59, 0x93, 0x75, 0x82, + 0x9e, 0xe2, 0x91, 0x37, 0x50, 0xdd, 0x5e, 0xc0, 0x94, 0x86, 0xaa, 0x85, 0xde, 0xfb, 0xe7, 0xb1, + 0x1a, 0xdb, 0xd3, 0xb7, 0x44, 0x37, 0x24, 0xaf, 0x60, 0x97, 0x4a, 0x81, 0xca, 0x43, 0xbd, 0xf7, + 0xdf, 0xd3, 0xf2, 0xbd, 0x82, 0x24, 0x3d, 0x97, 0xb7, 0xc7, 0x57, 0xa2, 0x59, 0x69, 0x6b, 0x9d, + 0x5d, 0x6f, 0x13, 0x9a, 0x27, 0x50, 0x91, 0xd3, 0x90, 0x1a, 0x1c, 0x5e, 0x8d, 0x6c, 0xe7, 0xcc, + 0x1d, 0x39, 0xb6, 0xb1, 0x43, 0x00, 0xf6, 0xce, 0xc7, 0xc3, 0xfe, 0xe8, 0xdc, 0xd0, 0xc8, 0x01, + 0x54, 0x46, 0x63, 0xdb, 0x31, 0x4a, 0x64, 0x1f, 0xca, 0x83, 0xbe, 0x67, 0x94, 0x25, 0xf4, 0xa1, + 0xff, 0xb9, 0x6f, 0x54, 0xcc, 0x1f, 0x25, 0xf8, 0x7f, 0xdb, 0xd3, 0xc6, 0x24, 0xe6, 0xeb, 0x25, + 0x32, 0xa1, 0xbc, 0x78, 0x0f, 0xf5, 0x3b, 0x6d, 0x59, 0x82, 0x81, 0x72, 0x45, 0xef, 0xfd, 0xfb, + 0xa4, 0x2b, 0x5e, 0x2d, 0x78, 0xe0, 0x64, 0x1f, 0xea, 0x38, 0x9f, 0x63, 0x20, 0x68, 0x8e, 0xd3, + 0xd0, 0x17, 0x78, 0xeb, 0x4d, 0xcb, 0x2a, 0x16, 0xd3, 0xda, 0x2c, 0xa6, 0x35, 0xd9, 0x2c, 0xa6, + 0x57, 0xdb, 0x66, 0xd8, 0xbe, 0x40, 0xf2, 0x1c, 0xaa, 0xaa, 0x77, 0xe2, 0x07, 0xd7, 0x7e, 0x84, + 0xca, 0xab, 0xaa, 0xa7, 0x4b, 0xec, 0xa2, 0x80, 0xc8, 0x18, 0x0e, 0xf0, 0x06, 0x83, 0x29, 0xb2, + 0x5c, 0x59, 0x53, 0xef, 0x1d, 0x3f, 0x9a, 0xee, 0xa1, 0x2c, 0xcb, 0xb9, 0xc1, 0x60, 0x25, 0x17, + 0xc6, 0x61, 0x39, 0x4d, 0x39, 0x93, 0x7f, 0x78, 0xfb, 0xb2, 0x8a, 0xc3, 0x72, 0xd3, 0x82, 0xc6, + 0x53, 0x04, 0xe9, 0xa8, 0x3d, 0x1e, 0x7c, 0x74, 0xbc, 0xc2, 0xdd, 0xcb, 0x2f, 0x97, 0x13, 0xe7, + 0x93, 0xa1, 0x99, 0xdf, 0xb4, 0x7b, 0x06, 0xba, 0x2c, 0xe7, 0x81, 0x5a, 0xc6, 0x3f, 0x60, 0xe0, + 0x11, 0xfc, 0x4d, 0xc3, 0x69, 0x84, 0x0c, 0x8b, 0xfd, 0x9e, 0xfa, 0x71, 0x74, 0xfb, 0x25, 0xfe, + 0x45, 0xc3, 0xf3, 0x2d, 0xde, 0x8f, 0xa3, 0xa3, 0x63, 0x68, 0x0c, 0x38, 0x9b, 0xd3, 0x10, 0x99, + 0xa0, 0x7e, 0x4c, 0xc5, 0x7a, 0x88, 0x39, 0xc6, 0x72, 0xd2, 0x8b, 0xab, 0xd3, 0xa1, 0x3b, 0x30, + 0x76, 0x88, 0x01, 0xd5, 0xc1, 0x78, 0x74, 0xe6, 0xda, 0xce, 0x68, 0xe2, 0xf6, 0x87, 0x86, 0x76, + 0x3a, 0x06, 0x93, 0xa7, 0x91, 0xb5, 0x58, 0x27, 0x98, 0xc6, 0x18, 0x46, 0x98, 0x5a, 0x73, 0x7f, + 0x96, 0xd2, 0x60, 0x33, 0x9f, 0x7c, 0x60, 0xbe, 0xbe, 0x8c, 0xa8, 0x58, 0xac, 0x66, 0x56, 0xc0, + 0x97, 0xdd, 0x7b, 0xd4, 0x6e, 0x41, 0x2d, 0xde, 0x97, 0xac, 0x2b, 0xa9, 0xb3, 0xe2, 0xed, 0x79, + 0xfd, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x66, 0x39, 0xf9, 0x9a, 0x04, 0x00, 0x00, } diff --git a/protos/peer/chaincode.proto b/protos/peer/chaincode.proto index ec6e1bb72f0..805762a60f8 100644 --- a/protos/peer/chaincode.proto +++ b/protos/peer/chaincode.proto @@ -53,6 +53,7 @@ message ChaincodeID { // the []byte-based current ChaincodeInput structure. message ChaincodeInput { repeated bytes args = 1; + map decorations = 2; } // Carries the chaincode specification. This is the actual metadata required for