-
Notifications
You must be signed in to change notification settings - Fork 60
/
mempool.go
83 lines (69 loc) · 1.94 KB
/
mempool.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
package nodemempool
import (
"fmt"
"math"
"github.com/libp2p/go-libp2p/core/peer"
tmsync "github.com/tendermint/tendermint/libs/sync"
)
const (
maxActiveIDs = math.MaxUint16
)
type MempoolIDs struct {
mtx tmsync.RWMutex
peerMap map[peer.ID]uint16
nextID uint16 // assumes that a node will never have over 65536 active peers
activeIDs map[uint16]struct{} // used to check if a given peerID key is used, the value doesn't matter
}
// Reserve searches for the next unused ID and assigns it to the
// peer.
func (ids *MempoolIDs) ReserveForPeer(peer peer.ID) {
ids.mtx.Lock()
defer ids.mtx.Unlock()
curID := ids.nextPeerID()
ids.peerMap[peer] = curID
ids.activeIDs[curID] = struct{}{}
}
// nextPeerID returns the next unused peer ID to use.
// This assumes that ids's mutex is already locked.
func (ids *MempoolIDs) nextPeerID() uint16 {
if len(ids.activeIDs) == maxActiveIDs {
panic(fmt.Sprintf("node has maximum %d active IDs and wanted to get one more", maxActiveIDs))
}
_, idExists := ids.activeIDs[ids.nextID]
for idExists {
ids.nextID++
_, idExists = ids.activeIDs[ids.nextID]
}
curID := ids.nextID
ids.nextID++
return curID
}
// Reclaim returns the ID reserved for the peer back to unused pool.
func (ids *MempoolIDs) Reclaim(peer peer.ID) {
ids.mtx.Lock()
defer ids.mtx.Unlock()
removedID, ok := ids.peerMap[peer]
if ok {
delete(ids.activeIDs, removedID)
delete(ids.peerMap, peer)
}
}
// GetForPeer returns an ID for the peer. ID is generated if required.
func (ids *MempoolIDs) GetForPeer(peer peer.ID) uint16 {
ids.mtx.Lock()
defer ids.mtx.Unlock()
id, ok := ids.peerMap[peer]
if !ok {
id = ids.nextPeerID()
ids.peerMap[peer] = id
ids.activeIDs[id] = struct{}{}
}
return id
}
func NewMempoolIDs() *MempoolIDs {
return &MempoolIDs{
peerMap: make(map[peer.ID]uint16),
activeIDs: map[uint16]struct{}{0: {}},
nextID: 1, // reserve unknownPeerID(0) for mempoolReactor.BroadcastTx
}
}