You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

77 lines
1.8 KiB

package mempool
import (
"fmt"
tmsync "github.com/tendermint/tendermint/internal/libs/sync"
"github.com/tendermint/tendermint/p2p"
)
// nolint: golint
// TODO: Rename type.
type MempoolIDs struct {
mtx tmsync.RWMutex
peerMap map[p2p.NodeID]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
}
func NewMempoolIDs() *MempoolIDs {
return &MempoolIDs{
peerMap: make(map[p2p.NodeID]uint16),
// reserve UnknownPeerID for mempoolReactor.BroadcastTx
activeIDs: map[uint16]struct{}{UnknownPeerID: {}},
nextID: 1,
}
}
// ReserveForPeer searches for the next unused ID and assigns it to the provided
// peer.
func (ids *MempoolIDs) ReserveForPeer(peerID p2p.NodeID) {
ids.mtx.Lock()
defer ids.mtx.Unlock()
curID := ids.nextPeerID()
ids.peerMap[peerID] = curID
ids.activeIDs[curID] = struct{}{}
}
// Reclaim returns the ID reserved for the peer back to unused pool.
func (ids *MempoolIDs) Reclaim(peerID p2p.NodeID) {
ids.mtx.Lock()
defer ids.mtx.Unlock()
removedID, ok := ids.peerMap[peerID]
if ok {
delete(ids.activeIDs, removedID)
delete(ids.peerMap, peerID)
}
}
// GetForPeer returns an ID reserved for the peer.
func (ids *MempoolIDs) GetForPeer(peerID p2p.NodeID) uint16 {
ids.mtx.RLock()
defer ids.mtx.RUnlock()
return ids.peerMap[peerID]
}
// nextPeerID returns the next unused peer ID to use. We assume that the mutex
// is already held.
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
}