github.com/yimialmonte/fabric@v2.1.1+incompatible/core/chaincode/transaction_context.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/privdata"
    15  	"github.com/hyperledger/fabric/core/ledger"
    16  )
    17  
    18  type TransactionContext struct {
    19  	ChannelID            string
    20  	NamespaceID          string
    21  	SignedProp           *pb.SignedProposal
    22  	Proposal             *pb.Proposal
    23  	ResponseNotifier     chan *pb.ChaincodeMessage
    24  	TXSimulator          ledger.TxSimulator
    25  	HistoryQueryExecutor ledger.HistoryQueryExecutor
    26  	CollectionStore      privdata.CollectionStore
    27  	IsInitTransaction    bool
    28  
    29  	// tracks open iterators used for range queries
    30  	queryMutex          sync.Mutex
    31  	queryIteratorMap    map[string]commonledger.ResultsIterator
    32  	pendingQueryResults map[string]*PendingQueryResult
    33  	totalReturnCount    map[string]*int32
    34  
    35  	// cache used to save the result of collection acl
    36  	// as a transactionContext is created for every chaincode
    37  	// invoke (even in case of chaincode-calling-chaincode,
    38  	// we do not need to store the namespace in the map and
    39  	// collection alone is sufficient.
    40  	CollectionACLCache CollectionACLCache
    41  }
    42  
    43  // CollectionACLCache encapsulates a cache that stores read
    44  // write permission on a collection
    45  type CollectionACLCache map[string]*readWritePermission
    46  
    47  type readWritePermission struct {
    48  	read, write bool
    49  }
    50  
    51  func (c CollectionACLCache) put(collection string, rwPermission *readWritePermission) {
    52  	c[collection] = rwPermission
    53  }
    54  
    55  func (c CollectionACLCache) get(collection string) *readWritePermission {
    56  	return c[collection]
    57  }
    58  
    59  func (t *TransactionContext) InitializeCollectionACLCache() {
    60  	t.CollectionACLCache = make(CollectionACLCache)
    61  }
    62  
    63  func (t *TransactionContext) InitializeQueryContext(queryID string, iter commonledger.ResultsIterator) {
    64  	t.queryMutex.Lock()
    65  	if t.queryIteratorMap == nil {
    66  		t.queryIteratorMap = map[string]commonledger.ResultsIterator{}
    67  	}
    68  	if t.pendingQueryResults == nil {
    69  		t.pendingQueryResults = map[string]*PendingQueryResult{}
    70  	}
    71  	if t.totalReturnCount == nil {
    72  		t.totalReturnCount = map[string]*int32{}
    73  	}
    74  	t.queryIteratorMap[queryID] = iter
    75  	t.pendingQueryResults[queryID] = &PendingQueryResult{}
    76  	zeroValue := int32(0)
    77  	t.totalReturnCount[queryID] = &zeroValue
    78  	t.queryMutex.Unlock()
    79  }
    80  
    81  func (t *TransactionContext) GetQueryIterator(queryID string) commonledger.ResultsIterator {
    82  	t.queryMutex.Lock()
    83  	iter := t.queryIteratorMap[queryID]
    84  	t.queryMutex.Unlock()
    85  	return iter
    86  }
    87  
    88  func (t *TransactionContext) GetPendingQueryResult(queryID string) *PendingQueryResult {
    89  	t.queryMutex.Lock()
    90  	result := t.pendingQueryResults[queryID]
    91  	t.queryMutex.Unlock()
    92  	return result
    93  }
    94  
    95  func (t *TransactionContext) GetTotalReturnCount(queryID string) *int32 {
    96  	t.queryMutex.Lock()
    97  	result := t.totalReturnCount[queryID]
    98  	t.queryMutex.Unlock()
    99  	return result
   100  }
   101  
   102  func (t *TransactionContext) CleanupQueryContext(queryID string) {
   103  	t.queryMutex.Lock()
   104  	defer t.queryMutex.Unlock()
   105  	iter := t.queryIteratorMap[queryID]
   106  	if iter != nil {
   107  		iter.Close()
   108  	}
   109  	delete(t.queryIteratorMap, queryID)
   110  	delete(t.pendingQueryResults, queryID)
   111  	delete(t.totalReturnCount, queryID)
   112  }
   113  
   114  func (t *TransactionContext) CleanupQueryContextWithBookmark(queryID string) string {
   115  	t.queryMutex.Lock()
   116  	defer t.queryMutex.Unlock()
   117  	iter := t.queryIteratorMap[queryID]
   118  	bookmark := ""
   119  	if iter != nil {
   120  		if queryResultIterator, ok := iter.(commonledger.QueryResultsIterator); ok {
   121  			bookmark = queryResultIterator.GetBookmarkAndClose()
   122  		}
   123  	}
   124  	delete(t.queryIteratorMap, queryID)
   125  	delete(t.pendingQueryResults, queryID)
   126  	delete(t.totalReturnCount, queryID)
   127  	return bookmark
   128  }
   129  
   130  func (t *TransactionContext) CloseQueryIterators() {
   131  	t.queryMutex.Lock()
   132  	defer t.queryMutex.Unlock()
   133  	for _, iter := range t.queryIteratorMap {
   134  		iter.Close()
   135  	}
   136  }