github.com/Hnampk/fabric@v2.1.1+incompatible/core/chaincode/transaction_contexts.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  	"sync"
    11  
    12  	pb "github.com/hyperledger/fabric-protos-go/peer"
    13  	commonledger "github.com/hyperledger/fabric/common/ledger"
    14  	"github.com/hyperledger/fabric/core/common/ccprovider"
    15  	"github.com/pkg/errors"
    16  )
    17  
    18  // TransactionContexts maintains active transaction contexts for a Handler.
    19  type TransactionContexts struct {
    20  	mutex    sync.Mutex
    21  	contexts map[string]*TransactionContext
    22  }
    23  
    24  // NewTransactionContexts creates a registry for active transaction contexts.
    25  func NewTransactionContexts() *TransactionContexts {
    26  	return &TransactionContexts{
    27  		contexts: map[string]*TransactionContext{},
    28  	}
    29  }
    30  
    31  // contextID creates a transaction identifier that is scoped to a channel.
    32  func contextID(channelID, txID string) string {
    33  	return channelID + txID
    34  }
    35  
    36  // Create creates a new TransactionContext for the specified channel and
    37  // transaction ID. An error is returned when a transaction context has already
    38  // been created for the specified channel and transaction ID.
    39  func (c *TransactionContexts) Create(txParams *ccprovider.TransactionParams) (*TransactionContext, error) {
    40  	c.mutex.Lock()
    41  	defer c.mutex.Unlock()
    42  
    43  	ctxID := contextID(txParams.ChannelID, txParams.TxID)
    44  	if c.contexts[ctxID] != nil {
    45  		return nil, errors.Errorf("txid: %s(%s) exists", txParams.TxID, txParams.ChannelID)
    46  	}
    47  
    48  	txctx := &TransactionContext{
    49  		NamespaceID:          txParams.NamespaceID,
    50  		ChannelID:            txParams.ChannelID,
    51  		SignedProp:           txParams.SignedProp,
    52  		Proposal:             txParams.Proposal,
    53  		ResponseNotifier:     make(chan *pb.ChaincodeMessage, 1),
    54  		TXSimulator:          txParams.TXSimulator,
    55  		HistoryQueryExecutor: txParams.HistoryQueryExecutor,
    56  		CollectionStore:      txParams.CollectionStore,
    57  		IsInitTransaction:    txParams.IsInitTransaction,
    58  
    59  		queryIteratorMap:    map[string]commonledger.ResultsIterator{},
    60  		pendingQueryResults: map[string]*PendingQueryResult{},
    61  	}
    62  	txctx.InitializeCollectionACLCache()
    63  
    64  	c.contexts[ctxID] = txctx
    65  
    66  	return txctx, nil
    67  }
    68  
    69  // Get retrieves the transaction context associated with the channel and
    70  // transaction ID.
    71  func (c *TransactionContexts) Get(channelID, txID string) *TransactionContext {
    72  	ctxID := contextID(channelID, txID)
    73  	c.mutex.Lock()
    74  	tc := c.contexts[ctxID]
    75  	c.mutex.Unlock()
    76  	return tc
    77  }
    78  
    79  // Delete removes the transaction context associated with the specified channel
    80  // and transaction ID.
    81  func (c *TransactionContexts) Delete(channelID, txID string) {
    82  	ctxID := contextID(channelID, txID)
    83  	c.mutex.Lock()
    84  	delete(c.contexts, ctxID)
    85  	c.mutex.Unlock()
    86  }
    87  
    88  // Close closes all query iterators assocated with the context.
    89  func (c *TransactionContexts) Close() {
    90  	c.mutex.Lock()
    91  	defer c.mutex.Unlock()
    92  
    93  	for _, txctx := range c.contexts {
    94  		txctx.CloseQueryIterators()
    95  	}
    96  }