@@ -28,9 +28,11 @@ import (
28
28
"time"
29
29
30
30
"github.com/ethereum/go-ethereum/common"
31
- "gopkg.in/fatih/set.v0"
32
31
)
33
32
33
+ // Maximum number of entries allowed on the list or lacking items.
34
+ const maxLackingHashes = 4096
35
+
34
36
// Hash and block fetchers belonging to eth/61 and below
35
37
type relativeHashFetcherFn func (common.Hash ) error
36
38
type absoluteHashFetcherFn func (uint64 , int ) error
@@ -67,7 +69,8 @@ type peer struct {
67
69
receiptStarted time.Time // Time instance when the last receipt fetch was started
68
70
stateStarted time.Time // Time instance when the last node data fetch was started
69
71
70
- ignored * set.Set // Set of hashes not to request (didn't have previously)
72
+ lacking map [common.Hash ]struct {} // Set of hashes not to request (didn't have previously)
73
+ lackingLock sync.RWMutex // Lock protecting the lacking hashes list
71
74
72
75
getRelHashes relativeHashFetcherFn // [eth/61] Method to retrieve a batch of hashes from an origin hash
73
76
getAbsHashes absoluteHashFetcherFn // [eth/61] Method to retrieve a batch of hashes from an absolute position
@@ -95,7 +98,7 @@ func newPeer(id string, version int, head common.Hash,
95
98
blockCapacity : 1 ,
96
99
receiptCapacity : 1 ,
97
100
stateCapacity : 1 ,
98
- ignored : set . New ( ),
101
+ lacking : make ( map [common. Hash ] struct {} ),
99
102
100
103
getRelHashes : getRelHashes ,
101
104
getAbsHashes : getAbsHashes ,
@@ -119,7 +122,10 @@ func (p *peer) Reset() {
119
122
atomic .StoreInt32 (& p .blockCapacity , 1 )
120
123
atomic .StoreInt32 (& p .receiptCapacity , 1 )
121
124
atomic .StoreInt32 (& p .stateCapacity , 1 )
122
- p .ignored .Clear ()
125
+
126
+ p .lackingLock .Lock ()
127
+ p .lacking = make (map [common.Hash ]struct {})
128
+ p .lackingLock .Unlock ()
123
129
}
124
130
125
131
// Fetch61 sends a block retrieval request to the remote peer.
@@ -305,13 +311,42 @@ func (p *peer) Demote() {
305
311
}
306
312
}
307
313
314
+ // MarkLacking appends a new entity to the set of items (blocks, receipts, states)
315
+ // that a peer is known not to have (i.e. have been requested before). If the
316
+ // set reaches its maximum allowed capacity, items are randomly dropped off.
317
+ func (p * peer ) MarkLacking (hash common.Hash ) {
318
+ p .lackingLock .Lock ()
319
+ defer p .lackingLock .Unlock ()
320
+
321
+ for len (p .lacking ) >= maxLackingHashes {
322
+ for drop , _ := range p .lacking {
323
+ delete (p .lacking , drop )
324
+ break
325
+ }
326
+ }
327
+ p .lacking [hash ] = struct {}{}
328
+ }
329
+
330
+ // Lacks retrieves whether the hash of a blockchain item is on the peers lacking
331
+ // list (i.e. whether we know that the peer does not have it).
332
+ func (p * peer ) Lacks (hash common.Hash ) bool {
333
+ p .lackingLock .RLock ()
334
+ defer p .lackingLock .RUnlock ()
335
+
336
+ _ , ok := p .lacking [hash ]
337
+ return ok
338
+ }
339
+
308
340
// String implements fmt.Stringer.
309
341
func (p * peer ) String () string {
342
+ p .lackingLock .RLock ()
343
+ defer p .lackingLock .RUnlock ()
344
+
310
345
return fmt .Sprintf ("Peer %s [%s]" , p .id ,
311
346
fmt .Sprintf ("reputation %3d, " , atomic .LoadInt32 (& p .rep ))+
312
347
fmt .Sprintf ("block cap %3d, " , atomic .LoadInt32 (& p .blockCapacity ))+
313
348
fmt .Sprintf ("receipt cap %3d, " , atomic .LoadInt32 (& p .receiptCapacity ))+
314
- fmt .Sprintf ("ignored %4d" , p . ignored . Size ( )),
349
+ fmt .Sprintf ("lacking %4d" , len ( p . lacking )),
315
350
)
316
351
}
317
352
0 commit comments