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