Skip to content

Commit

Permalink
peer: knownInventory, sentNonces - use generic lru
Browse files Browse the repository at this point in the history
While here, also rename and generalize limitMap and apply to
other maps which need to be bounded.
  • Loading branch information
tuxcanfly authored and jcvernaleo committed Jul 8, 2020
1 parent e2d9cf4 commit 875b51c
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 606 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792
github.com/btcsuite/winsvc v1.0.0
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/lru v1.0.0
github.com/jessevdk/go-flags v1.4.0
github.com/jrick/logrotate v1.0.0
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
Expand Down
50 changes: 24 additions & 26 deletions netsync/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,25 @@ type peerSyncState struct {
requestedBlocks map[chainhash.Hash]struct{}
}

// limitAdd is a helper function for maps that require a maximum limit by
// evicting a random value if adding the new value would cause it to
// overflow the maximum allowed.
func limitAdd(m map[chainhash.Hash]struct{}, hash chainhash.Hash, limit int) {
if len(m)+1 > limit {
// Remove a random entry from the map. For most compilers, Go's
// range statement iterates starting at a random item although
// that is not 100% guaranteed by the spec. The iteration order
// is not important here because an adversary would have to be
// able to pull off preimage attacks on the hashing function in
// order to target eviction of specific entries anyways.
for txHash := range m {
delete(m, txHash)
break
}
}
m[hash] = struct{}{}
}

// SyncManager is used to communicate block related messages with peers. The
// SyncManager is started as by executing Start() in a goroutine. Once started,
// it selects peers to sync from and starts the initial block download. Once the
Expand Down Expand Up @@ -579,8 +598,7 @@ func (sm *SyncManager) handleTxMsg(tmsg *txMsg) {
if err != nil {
// Do not request this transaction again until a new block
// has been processed.
sm.rejectedTxns[*txHash] = struct{}{}
sm.limitMap(sm.rejectedTxns, maxRejectedTxns)
limitAdd(sm.rejectedTxns, *txHash, maxRejectedTxns)

// When the error is a rule error, it means the transaction was
// simply rejected as opposed to something actually going wrong,
Expand Down Expand Up @@ -1202,9 +1220,8 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) {
// Request the block if there is not already a pending
// request.
if _, exists := sm.requestedBlocks[iv.Hash]; !exists {
sm.requestedBlocks[iv.Hash] = struct{}{}
sm.limitMap(sm.requestedBlocks, maxRequestedBlocks)
state.requestedBlocks[iv.Hash] = struct{}{}
limitAdd(sm.requestedBlocks, iv.Hash, maxRequestedBlocks)
limitAdd(state.requestedBlocks, iv.Hash, maxRequestedBlocks)

if peer.IsWitnessEnabled() {
iv.Type = wire.InvTypeWitnessBlock
Expand All @@ -1220,9 +1237,8 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) {
// Request the transaction if there is not already a
// pending request.
if _, exists := sm.requestedTxns[iv.Hash]; !exists {
sm.requestedTxns[iv.Hash] = struct{}{}
sm.limitMap(sm.requestedTxns, maxRequestedTxns)
state.requestedTxns[iv.Hash] = struct{}{}
limitAdd(sm.requestedTxns, iv.Hash, maxRequestedTxns)
limitAdd(state.requestedTxns, iv.Hash, maxRequestedTxns)

// If the peer is capable, request the txn
// including all witness data.
Expand All @@ -1245,24 +1261,6 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) {
}
}

// limitMap is a helper function for maps that require a maximum limit by
// evicting a random transaction if adding a new value would cause it to
// overflow the maximum allowed.
func (sm *SyncManager) limitMap(m map[chainhash.Hash]struct{}, limit int) {
if len(m)+1 > limit {
// Remove a random entry from the map. For most compilers, Go's
// range statement iterates starting at a random item although
// that is not 100% guaranteed by the spec. The iteration order
// is not important here because an adversary would have to be
// able to pull off preimage attacks on the hashing function in
// order to target eviction of specific entries anyways.
for txHash := range m {
delete(m, txHash)
return
}
}
}

// blockHandler is the main handler for the sync manager. It must be run as a
// goroutine. It processes block and inv messages in a separate goroutine
// from the peer handlers so the block (MsgBlock) messages are handled by a
Expand Down
127 changes: 0 additions & 127 deletions peer/mruinvmap.go

This file was deleted.

Loading

0 comments on commit 875b51c

Please sign in to comment.