@@ -75,12 +75,12 @@ type Peer struct {
75
75
head common.Hash // Latest advertised head block hash
76
76
td * big.Int // Latest advertised head block total difficulty
77
77
78
- knownBlocks mapset. Set // Set of block hashes known to be known by this peer
78
+ knownBlocks * knownCache // Set of block hashes known to be known by this peer
79
79
queuedBlocks chan * blockPropagation // Queue of blocks to broadcast to the peer
80
80
queuedBlockAnns chan * types.Block // Queue of blocks to announce to the peer
81
81
82
82
txpool TxPool // Transaction pool used by the broadcasters for liveness checks
83
- knownTxs mapset. Set // Set of transaction hashes known to be known by this peer
83
+ knownTxs * knownCache // Set of transaction hashes known to be known by this peer
84
84
txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
85
85
txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
86
86
@@ -96,8 +96,8 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Pe
96
96
Peer : p ,
97
97
rw : rw ,
98
98
version : version ,
99
- knownTxs : mapset . NewSet ( ),
100
- knownBlocks : mapset . NewSet ( ),
99
+ knownTxs : newKnownCache ( maxKnownTxs ),
100
+ knownBlocks : newKnownCache ( maxKnownBlocks ),
101
101
queuedBlocks : make (chan * blockPropagation , maxQueuedBlocks ),
102
102
queuedBlockAnns : make (chan * types.Block , maxQueuedBlockAnns ),
103
103
txBroadcast : make (chan []common.Hash ),
@@ -162,19 +162,13 @@ func (p *Peer) KnownTransaction(hash common.Hash) bool {
162
162
// never be propagated to this particular peer.
163
163
func (p * Peer ) markBlock (hash common.Hash ) {
164
164
// If we reached the memory allowance, drop a previously known block hash
165
- for p .knownBlocks .Cardinality () >= maxKnownBlocks {
166
- p .knownBlocks .Pop ()
167
- }
168
165
p .knownBlocks .Add (hash )
169
166
}
170
167
171
168
// markTransaction marks a transaction as known for the peer, ensuring that it
172
169
// will never be propagated to this particular peer.
173
170
func (p * Peer ) markTransaction (hash common.Hash ) {
174
171
// If we reached the memory allowance, drop a previously known transaction hash
175
- for p .knownTxs .Cardinality () >= maxKnownTxs {
176
- p .knownTxs .Pop ()
177
- }
178
172
p .knownTxs .Add (hash )
179
173
}
180
174
@@ -189,9 +183,6 @@ func (p *Peer) markTransaction(hash common.Hash) {
189
183
// tests that directly send messages without having to do the asyn queueing.
190
184
func (p * Peer ) SendTransactions (txs types.Transactions ) error {
191
185
// Mark all the transactions as known, but ensure we don't overflow our limits
192
- for p .knownTxs .Cardinality () > max (0 , maxKnownTxs - len (txs )) {
193
- p .knownTxs .Pop ()
194
- }
195
186
for _ , tx := range txs {
196
187
p .knownTxs .Add (tx .Hash ())
197
188
}
@@ -205,12 +196,7 @@ func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
205
196
select {
206
197
case p .txBroadcast <- hashes :
207
198
// Mark all the transactions as known, but ensure we don't overflow our limits
208
- for p .knownTxs .Cardinality () > max (0 , maxKnownTxs - len (hashes )) {
209
- p .knownTxs .Pop ()
210
- }
211
- for _ , hash := range hashes {
212
- p .knownTxs .Add (hash )
213
- }
199
+ p .knownTxs .Add (hashes ... )
214
200
case <- p .term :
215
201
p .Log ().Debug ("Dropping transaction propagation" , "count" , len (hashes ))
216
202
}
@@ -224,12 +210,7 @@ func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
224
210
// not be managed directly.
225
211
func (p * Peer ) sendPooledTransactionHashes (hashes []common.Hash ) error {
226
212
// Mark all the transactions as known, but ensure we don't overflow our limits
227
- for p .knownTxs .Cardinality () > max (0 , maxKnownTxs - len (hashes )) {
228
- p .knownTxs .Pop ()
229
- }
230
- for _ , hash := range hashes {
231
- p .knownTxs .Add (hash )
232
- }
213
+ p .knownTxs .Add (hashes ... )
233
214
return p2p .Send (p .rw , NewPooledTransactionHashesMsg , NewPooledTransactionHashesPacket (hashes ))
234
215
}
235
216
@@ -240,12 +221,7 @@ func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
240
221
select {
241
222
case p .txAnnounce <- hashes :
242
223
// Mark all the transactions as known, but ensure we don't overflow our limits
243
- for p .knownTxs .Cardinality () > max (0 , maxKnownTxs - len (hashes )) {
244
- p .knownTxs .Pop ()
245
- }
246
- for _ , hash := range hashes {
247
- p .knownTxs .Add (hash )
248
- }
224
+ p .knownTxs .Add (hashes ... )
249
225
case <- p .term :
250
226
p .Log ().Debug ("Dropping transaction announcement" , "count" , len (hashes ))
251
227
}
@@ -254,12 +230,8 @@ func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
254
230
// ReplyPooledTransactionsRLP is the eth/66 version of SendPooledTransactionsRLP.
255
231
func (p * Peer ) ReplyPooledTransactionsRLP (id uint64 , hashes []common.Hash , txs []rlp.RawValue ) error {
256
232
// Mark all the transactions as known, but ensure we don't overflow our limits
257
- for p .knownTxs .Cardinality () > max (0 , maxKnownTxs - len (hashes )) {
258
- p .knownTxs .Pop ()
259
- }
260
- for _ , hash := range hashes {
261
- p .knownTxs .Add (hash )
262
- }
233
+ p .knownTxs .Add (hashes ... )
234
+
263
235
// Not packed into PooledTransactionsPacket to avoid RLP decoding
264
236
return p2p .Send (p .rw , PooledTransactionsMsg , PooledTransactionsRLPPacket66 {
265
237
RequestId : id ,
@@ -271,12 +243,8 @@ func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs [
271
243
// a hash notification.
272
244
func (p * Peer ) SendNewBlockHashes (hashes []common.Hash , numbers []uint64 ) error {
273
245
// Mark all the block hashes as known, but ensure we don't overflow our limits
274
- for p .knownBlocks .Cardinality () > max (0 , maxKnownBlocks - len (hashes )) {
275
- p .knownBlocks .Pop ()
276
- }
277
- for _ , hash := range hashes {
278
- p .knownBlocks .Add (hash )
279
- }
246
+ p .knownBlocks .Add (hashes ... )
247
+
280
248
request := make (NewBlockHashesPacket , len (hashes ))
281
249
for i := 0 ; i < len (hashes ); i ++ {
282
250
request [i ].Hash = hashes [i ]
@@ -292,9 +260,6 @@ func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
292
260
select {
293
261
case p .queuedBlockAnns <- block :
294
262
// Mark all the block hash as known, but ensure we don't overflow our limits
295
- for p .knownBlocks .Cardinality () >= maxKnownBlocks {
296
- p .knownBlocks .Pop ()
297
- }
298
263
p .knownBlocks .Add (block .Hash ())
299
264
default :
300
265
p .Log ().Debug ("Dropping block announcement" , "number" , block .NumberU64 (), "hash" , block .Hash ())
@@ -304,9 +269,6 @@ func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
304
269
// SendNewBlock propagates an entire block to a remote peer.
305
270
func (p * Peer ) SendNewBlock (block * types.Block , td * big.Int ) error {
306
271
// Mark all the block hash as known, but ensure we don't overflow our limits
307
- for p .knownBlocks .Cardinality () >= maxKnownBlocks {
308
- p .knownBlocks .Pop ()
309
- }
310
272
p .knownBlocks .Add (block .Hash ())
311
273
return p2p .Send (p .rw , NewBlockMsg , & NewBlockPacket {
312
274
Block : block ,
@@ -320,9 +282,6 @@ func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) {
320
282
select {
321
283
case p .queuedBlocks <- & blockPropagation {block : block , td : td }:
322
284
// Mark all the block hash as known, but ensure we don't overflow our limits
323
- for p .knownBlocks .Cardinality () >= maxKnownBlocks {
324
- p .knownBlocks .Pop ()
325
- }
326
285
p .knownBlocks .Add (block .Hash ())
327
286
default :
328
287
p .Log ().Debug ("Dropping block propagation" , "number" , block .NumberU64 (), "hash" , block .Hash ())
@@ -465,3 +424,37 @@ func (p *Peer) RequestTxs(hashes []common.Hash) error {
465
424
GetPooledTransactionsPacket : hashes ,
466
425
})
467
426
}
427
+
428
+ // knownCache is a cache for known hashes.
429
+ type knownCache struct {
430
+ hashes mapset.Set
431
+ max int
432
+ }
433
+
434
+ // newKnownCache creates a new knownCache with a max capacity.
435
+ func newKnownCache (max int ) * knownCache {
436
+ return & knownCache {
437
+ max : max ,
438
+ hashes : mapset .NewSet (),
439
+ }
440
+ }
441
+
442
+ // Add adds a list of elements to the set.
443
+ func (k * knownCache ) Add (hashes ... common.Hash ) {
444
+ for k .hashes .Cardinality () > max (0 , k .max - len (hashes )) {
445
+ k .hashes .Pop ()
446
+ }
447
+ for _ , hash := range hashes {
448
+ k .hashes .Add (hash )
449
+ }
450
+ }
451
+
452
+ // Contains returns whether the given item is in the set.
453
+ func (k * knownCache ) Contains (hash common.Hash ) bool {
454
+ return k .hashes .Contains (hash )
455
+ }
456
+
457
+ // Cardinality returns the number of elements in the set.
458
+ func (k * knownCache ) Cardinality () int {
459
+ return k .hashes .Cardinality ()
460
+ }
0 commit comments