Skip to content

Commit 9095d9e

Browse files
Saad Karimsykesm
Saad Karim
authored andcommitted
[FAB-9591] Make active transactions an object
Change-Id: I5e8dd612ae2744da843479ec4d5b7c59e7a1780f Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
1 parent f2f4b3d commit 9095d9e

File tree

4 files changed

+107
-31
lines changed

4 files changed

+107
-31
lines changed

core/chaincode/active_transactions.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package chaincode
8+
9+
import "sync"
10+
11+
func NewTxKey(channelID, txID string) string { return channelID + txID }
12+
13+
type ActiveTransactions struct {
14+
mutex sync.Mutex
15+
ids map[string]struct{}
16+
}
17+
18+
func NewActiveTransactions() *ActiveTransactions {
19+
return &ActiveTransactions{
20+
ids: map[string]struct{}{},
21+
}
22+
}
23+
24+
func (a *ActiveTransactions) Add(channelID, txID string) bool {
25+
key := NewTxKey(channelID, txID)
26+
a.mutex.Lock()
27+
defer a.mutex.Unlock()
28+
if _, ok := a.ids[key]; ok {
29+
return false
30+
}
31+
32+
a.ids[key] = struct{}{}
33+
return true
34+
}
35+
36+
func (a *ActiveTransactions) Remove(channelID, txID string) {
37+
key := NewTxKey(channelID, txID)
38+
a.mutex.Lock()
39+
delete(a.ids, key)
40+
a.mutex.Unlock()
41+
}
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package chaincode_test
8+
9+
import (
10+
"testing"
11+
12+
"github.com/hyperledger/fabric/core/chaincode"
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestActiveTransactions(t *testing.T) {
17+
activeTx := chaincode.NewActiveTransactions()
18+
assert.NotNil(t, activeTx)
19+
20+
// Add unique transactions
21+
ok := activeTx.Add("channel-id", "tx-id")
22+
assert.True(t, ok, "a new transaction should return true")
23+
ok = activeTx.Add("channel-id", "tx-id-2")
24+
assert.True(t, ok, "adding a different transaction id should return true")
25+
ok = activeTx.Add("channel-id-2", "tx-id")
26+
assert.True(t, ok, "adding a different channel-id should return true")
27+
28+
// Attempt to add a transaction that already exists
29+
ok = activeTx.Add("channel-id", "tx-id")
30+
assert.False(t, ok, "attempting to an existing transaction should return false")
31+
32+
// Remove existing and make sure the ID can be reused
33+
activeTx.Remove("channel-id", "tx-id")
34+
ok = activeTx.Add("channel-id", "tx-id")
35+
assert.True(t, ok, "using a an id that has been removed should return true")
36+
}
37+
38+
func TestNewTxKey(t *testing.T) {
39+
tests := []struct {
40+
channelID string
41+
txID string
42+
result string
43+
}{
44+
{"", "", ""},
45+
{"", "tx-1", "tx-1"},
46+
{"chan-1", "", "chan-1"},
47+
{"chan-1", "tx-1", "chan-1tx-1"},
48+
}
49+
for _, tc := range tests {
50+
result := chaincode.NewTxKey(tc.channelID, tc.txID)
51+
assert.Equal(t, tc.result, result)
52+
}
53+
}

core/chaincode/chaincode_support.go

-5
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,6 @@ func (chaincodeSupport *ChaincodeSupport) registerHandler(chaincodehandler *Hand
211211

212212
chaincodehandler.registered = true
213213

214-
//now we are ready to receive messages and send back responses
215-
// TODO: Should we move these to the handler constructor?
216-
chaincodehandler.txCtxs = NewTransactionContexts()
217-
chaincodehandler.txidMap = make(map[string]bool)
218-
219214
chaincodeLogger.Debugf("registered handler complete for chaincode %s", key)
220215

221216
return nil

core/chaincode/handler.go

+13-26
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,13 @@ type Handler struct {
8888

8989
//chan to pass error in sync and nonsync mode
9090
errChan chan error
91+
9192
// Map of tx txid to either invoke tx. Each tx will be
9293
// added prior to execute and remove when done execute
9394
txCtxs *TransactionContexts
9495

95-
txidMap map[string]bool
96+
// set of active transaction identifiers
97+
activeTransactions *ActiveTransactions
9698

9799
//handlers for each state of the handler
98100
readyStateHandlers stateHandlers
@@ -358,12 +360,14 @@ func HandleChaincodeStream(chaincodeSupport *ChaincodeSupport, ctxt context.Cont
358360

359361
func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStream ccintf.ChaincodeStream) *Handler {
360362
v := &Handler{
361-
ChatStream: peerChatStream,
362-
handlerSupport: chaincodeSupport,
363-
state: created,
364-
errChan: make(chan error, 1),
365-
keepalive: chaincodeSupport.keepalive,
366-
userRunsCC: chaincodeSupport.userRunsCC,
363+
ChatStream: peerChatStream,
364+
handlerSupport: chaincodeSupport,
365+
state: created,
366+
errChan: make(chan error, 1),
367+
txCtxs: NewTransactionContexts(),
368+
activeTransactions: NewActiveTransactions(),
369+
keepalive: chaincodeSupport.keepalive,
370+
userRunsCC: chaincodeSupport.userRunsCC,
367371
}
368372

369373
v.readyStateHandlers = stateHandlers{
@@ -392,28 +396,11 @@ func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStre
392396
}
393397

394398
func (handler *Handler) createTXIDEntry(channelID, txid string) bool {
395-
if handler.txidMap == nil {
396-
return false
397-
}
398-
handler.Lock()
399-
defer handler.Unlock()
400-
txCtxID := handler.getTxCtxId(channelID, txid)
401-
if handler.txidMap[txCtxID] {
402-
return false
403-
}
404-
handler.txidMap[txCtxID] = true
405-
return handler.txidMap[txCtxID]
399+
return handler.activeTransactions.Add(channelID, txid)
406400
}
407401

408402
func (handler *Handler) deleteTXIDEntry(channelID, txid string) {
409-
handler.Lock()
410-
defer handler.Unlock()
411-
txCtxID := handler.getTxCtxId(channelID, txid)
412-
if handler.txidMap != nil {
413-
delete(handler.txidMap, txCtxID)
414-
} else {
415-
chaincodeLogger.Warningf("TXID %s not found!", txCtxID)
416-
}
403+
handler.activeTransactions.Remove(channelID, txid)
417404
}
418405

419406
//sendReady sends READY to chaincode serially (just like REGISTER)

0 commit comments

Comments
 (0)