Skip to content

Commit

Permalink
[FAB-5921] add channel to proposal contexts
Browse files Browse the repository at this point in the history
Proposal contexts are currently keyed of just transaction IDs.
This prevents CC-2-CC calls where the called CC is on a different
channel (we want to use the same TXID for the entire CC call chain).

This CR adds Channel ID to the context key. In addition to fixing the
above bug, this also has a couple of good side effects
    . Chaincode can now get the ChannelID of proposals (they could do
      it from the proposal header but that would not work when calling
      a CC on a different channel)
    . proposals with the SAME transaction id can now be sent to the
      SAME chaincode on multiple channels (this is different from the
      CC-2-CC issue the bug was raised on)

. patch-2 removed a check that should never have been there (forgot to
  remove it in previous checkin). Also found a bug that prevented that
  from kicking in.
. patch-4 rebuilt protos to pick up protos/common/collection.pb.go
  (hopefully will fix z built UT failures in protos/utils)
. patch-5 rebase and fix some "go vet" issues now that we are using go vet

Change-Id: I7e4333d4219a0927885ed787fda05e0dcaab25fd
Signed-off-by: Srinivasan Muralidharan <srinivasan.muralidharan99@gmail.com>
  • Loading branch information
muralisrini committed Nov 3, 2017
1 parent 25ce382 commit 92ca115
Show file tree
Hide file tree
Showing 14 changed files with 449 additions and 319 deletions.
8 changes: 4 additions & 4 deletions core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func (chaincodeSupport *ChaincodeSupport) sendReady(context context.Context, ccc
}

//if initOrReady succeeded, our responsibility to delete the context
chrte.handler.deleteTxContext(cccid.TxID)
chrte.handler.deleteTxContext(cccid.ChainID, cccid.TxID)

return err
}
Expand Down Expand Up @@ -784,13 +784,13 @@ func (chaincodeSupport *ChaincodeSupport) Register(stream pb.ChaincodeSupport_Re
}

// createCCMessage creates a transaction message.
func createCCMessage(typ pb.ChaincodeMessage_Type, txid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
func createCCMessage(typ pb.ChaincodeMessage_Type, cid string, txid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
payload, err := proto.Marshal(cMsg)
if err != nil {
fmt.Printf(err.Error())
return nil, err
}
return &pb.ChaincodeMessage{Type: typ, Payload: payload, Txid: txid}, nil
return &pb.ChaincodeMessage{Type: typ, Payload: payload, Txid: txid, ChannelId: cid}, nil
}

// Execute executes a transaction and waits for it to complete until a timeout value.
Expand Down Expand Up @@ -824,7 +824,7 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, cccid *c
}

//our responsibility to delete transaction context if sendExecuteMessage succeeded
chrte.handler.deleteTxContext(msg.Txid)
chrte.handler.deleteTxContext(msg.ChannelId, msg.Txid)

return ccresp, err
}
Expand Down
163 changes: 112 additions & 51 deletions core/chaincode/chaincode_support_test.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/chaincode/exectransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{}
cMsg.Decorations = cccid.ProposalDecorations

var ccMsg *pb.ChaincodeMessage
ccMsg, err = createCCMessage(cctyp, cccid.TxID, cMsg)
ccMsg, err = createCCMessage(cctyp, cccid.ChainID, cccid.TxID, cMsg)
if err != nil {
return nil, nil, errors.WithMessage(err, "failed to create chaincode message")
}
Expand Down
151 changes: 82 additions & 69 deletions core/chaincode/handler.go

Large diffs are not rendered by default.

38 changes: 23 additions & 15 deletions core/chaincode/shim/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const (
// APIs.
type ChaincodeStub struct {
TxID string
ChannelId string
chaincodeEvent *pb.ChaincodeEvent
args [][]byte
handler *Handler
Expand Down Expand Up @@ -346,8 +347,9 @@ func chatWithPeer(chaincodename string, stream PeerChaincodeStream, cc Chaincode
// -- init stub ---
// ChaincodeInvocation functionality

func (stub *ChaincodeStub) init(handler *Handler, txid string, input *pb.ChaincodeInput, signedProposal *pb.SignedProposal) error {
func (stub *ChaincodeStub) init(handler *Handler, channelId string, txid string, input *pb.ChaincodeInput, signedProposal *pb.SignedProposal) error {
stub.TxID = txid
stub.ChannelId = channelId
stub.args = input.Args
stub.handler = handler
stub.signedProposal = signedProposal
Expand Down Expand Up @@ -379,11 +381,16 @@ func (stub *ChaincodeStub) init(handler *Handler, txid string, input *pb.Chainco
return nil
}

// GetTxID returns the transaction ID
// GetTxID returns the transaction ID for the proposal
func (stub *ChaincodeStub) GetTxID() string {
return stub.TxID
}

// GetChannelID returns the channel for the proposal
func (stub *ChaincodeStub) GetChannelID() string {
return stub.ChannelId
}

func (stub *ChaincodeStub) GetDecorations() map[string][]byte {
return stub.decorations
}
Expand All @@ -396,7 +403,7 @@ func (stub *ChaincodeStub) InvokeChaincode(chaincodeName string, args [][]byte,
if channel != "" {
chaincodeName = chaincodeName + "/" + channel
}
return stub.handler.handleInvokeChaincode(chaincodeName, args, stub.TxID)
return stub.handler.handleInvokeChaincode(chaincodeName, args, stub.ChannelId, stub.TxID)
}

// --------- State functions ----------
Expand All @@ -405,7 +412,7 @@ func (stub *ChaincodeStub) InvokeChaincode(chaincodeName string, args [][]byte,
func (stub *ChaincodeStub) GetState(key string) ([]byte, error) {
// Access public data by setting the collection to empty string
collection := ""
return stub.handler.handleGetState(collection, key, stub.TxID)
return stub.handler.handleGetState(collection, key, stub.ChannelId, stub.TxID)
}

// PutState documentation can be found in interfaces.go
Expand All @@ -415,31 +422,32 @@ func (stub *ChaincodeStub) PutState(key string, value []byte) error {
}
// Access public data by setting the collection to empty string
collection := ""
return stub.handler.handlePutState(collection, key, value, stub.TxID)
return stub.handler.handlePutState(collection, key, value, stub.ChannelId, stub.TxID)
}

// GetQueryResult documentation can be found in interfaces.go
func (stub *ChaincodeStub) GetQueryResult(query string) (StateQueryIteratorInterface, error) {
// Access public data by setting the collection to empty string
collection := ""
response, err := stub.handler.handleGetQueryResult(collection, query, stub.TxID)
response, err := stub.handler.handleGetQueryResult(collection, query, stub.ChannelId, stub.TxID)
if err != nil {
return nil, err
}
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.TxID, response, 0}}, nil
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.ChannelId, stub.TxID, response, 0}}, nil
}

// DelState documentation can be found in interfaces.go
func (stub *ChaincodeStub) DelState(key string) error {
// Access public data by setting the collection to empty string
collection := ""
return stub.handler.handleDelState(collection, key, stub.TxID)
return stub.handler.handleDelState(collection, key, stub.ChannelId, stub.TxID)
}

// CommonIterator documentation can be found in interfaces.go
type CommonIterator struct {
handler *Handler
uuid string
channelId string
txid string
response *pb.QueryResponse
currentLoc int
}
Expand All @@ -462,11 +470,11 @@ const (
)

func (stub *ChaincodeStub) handleGetStateByRange(collection, startKey, endKey string) (StateQueryIteratorInterface, error) {
response, err := stub.handler.handleGetStateByRange(collection, startKey, endKey, stub.TxID)
response, err := stub.handler.handleGetStateByRange(collection, startKey, endKey, stub.ChannelId, stub.TxID)
if err != nil {
return nil, err
}
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.TxID, response, 0}}, nil
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.ChannelId, stub.TxID, response, 0}}, nil
}

// GetStateByRange documentation can be found in interfaces.go
Expand All @@ -483,11 +491,11 @@ func (stub *ChaincodeStub) GetStateByRange(startKey, endKey string) (StateQueryI

// GetHistoryForKey documentation can be found in interfaces.go
func (stub *ChaincodeStub) GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error) {
response, err := stub.handler.handleGetHistoryForKey(key, stub.TxID)
response, err := stub.handler.handleGetHistoryForKey(key, stub.ChannelId, stub.TxID)
if err != nil {
return nil, err
}
return &HistoryQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.TxID, response, 0}}, nil
return &HistoryQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.ChannelId, stub.TxID, response, 0}}, nil
}

//CreateCompositeKey documentation can be found in interfaces.go
Expand Down Expand Up @@ -616,7 +624,7 @@ func (iter *CommonIterator) getResultFromBytes(queryResultBytes *pb.QueryResultB
}

func (iter *CommonIterator) fetchNextQueryResult() error {
if response, err := iter.handler.handleQueryStateNext(iter.response.Id, iter.uuid); err == nil {
if response, err := iter.handler.handleQueryStateNext(iter.response.Id, iter.channelId, iter.txid); err == nil {
iter.currentLoc = 0
iter.response = response
return nil
Expand Down Expand Up @@ -659,7 +667,7 @@ func (iter *CommonIterator) nextResult(rType resultType) (commonledger.QueryResu

// Close documentation can be found in interfaces.go
func (iter *CommonIterator) Close() error {
_, err := iter.handler.handleQueryStateClose(iter.response.Id, iter.uuid)
_, err := iter.handler.handleQueryStateClose(iter.response.Id, iter.channelId, iter.txid)
return err
}

Expand Down
10 changes: 5 additions & 5 deletions core/chaincode/shim/chaincode_experimental.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (stub *ChaincodeStub) GetPrivateData(collection string, key string) ([]byte
if collection == "" {
return nil, fmt.Errorf("collection must not be an empty string")
}
return stub.handler.handleGetState(collection, key, stub.TxID)
return stub.handler.handleGetState(collection, key, stub.ChannelId, stub.TxID)
}

// PutPrivateData documentation can be found in interfaces.go
Expand All @@ -30,15 +30,15 @@ func (stub *ChaincodeStub) PutPrivateData(collection string, key string, value [
if key == "" {
return fmt.Errorf("key must not be an empty string")
}
return stub.handler.handlePutState(collection, key, value, stub.TxID)
return stub.handler.handlePutState(collection, key, value, stub.ChannelId, stub.TxID)
}

// DelPrivateData documentation can be found in interfaces.go
func (stub *ChaincodeStub) DelPrivateData(collection string, key string) error {
if collection == "" {
return fmt.Errorf("collection must not be an empty string")
}
return stub.handler.handleDelState(collection, key, stub.TxID)
return stub.handler.handleDelState(collection, key, stub.ChannelId, stub.TxID)
}

// GetPrivateDataByRange documentation can be found in interfaces.go
Expand Down Expand Up @@ -72,9 +72,9 @@ func (stub *ChaincodeStub) GetPrivateDataQueryResult(collection, query string) (
if collection == "" {
return nil, fmt.Errorf("collection must not be an empty string")
}
response, err := stub.handler.handleGetQueryResult(collection, query, stub.TxID)
response, err := stub.handler.handleGetQueryResult(collection, query, stub.ChannelId, stub.TxID)
if err != nil {
return nil, err
}
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.TxID, response, 0}}, nil
return &StateQueryIterator{CommonIterator: &CommonIterator{stub.handler, stub.TxID, stub.ChannelId, response, 0}}, nil
}
Loading

0 comments on commit 92ca115

Please sign in to comment.