mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
eth/fetcher: use iter.seq in blobfetcher
This commit is contained in:
parent
999e6013a3
commit
294ac215af
1 changed files with 55 additions and 42 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
package fetcher
|
package fetcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"iter"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
@ -750,15 +751,15 @@ func (f *BlobFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}
|
||||||
wasIdle := len(f.requests) == 0
|
wasIdle := len(f.requests) == 0
|
||||||
|
|
||||||
// For each active peer, try to schedule some payload fetches.
|
// For each active peer, try to schedule some payload fetches.
|
||||||
f.forEachPeer(actives, func(peer string) {
|
for peer := range f.peers(actives) {
|
||||||
if len(f.announces[peer]) == 0 || len(f.requests[peer]) != 0 {
|
if len(f.announces[peer]) == 0 || len(f.requests[peer]) != 0 {
|
||||||
return // continue
|
continue
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
hashes []common.Hash
|
hashes []common.Hash
|
||||||
custodies []types.CustodyBitmap
|
custodies []types.CustodyBitmap
|
||||||
)
|
)
|
||||||
f.forEachAnnounce(f.announces[peer], func(hash common.Hash, cells types.CustodyBitmap) bool {
|
for hash, cells := range f.announcesByArrival(f.announces[peer]) {
|
||||||
var unfetched types.CustodyBitmap
|
var unfetched types.CustodyBitmap
|
||||||
if f.fetches[hash] == nil {
|
if f.fetches[hash] == nil {
|
||||||
// tx is not being fetched
|
// tx is not being fetched
|
||||||
|
|
@ -793,8 +794,11 @@ func (f *BlobFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}
|
||||||
f.alternates[hash][peer] = cells
|
f.alternates[hash][peer] = cells
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(hashes) < maxPayloadRetrievals
|
// Stop once we've accumulated enough hashes for this peer
|
||||||
})
|
if len(hashes) >= maxPayloadRetrievals {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If any hashes were allocated, request them from the peer
|
// If any hashes were allocated, request them from the peer
|
||||||
if len(hashes) > 0 {
|
if len(hashes) > 0 {
|
||||||
|
|
@ -829,7 +833,7 @@ func (f *BlobFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
// If a new request was fired, schedule a timeout timer
|
// If a new request was fired, schedule a timeout timer
|
||||||
if wasIdle && len(f.requests) > 0 {
|
if wasIdle && len(f.requests) > 0 {
|
||||||
|
|
@ -837,11 +841,13 @@ func (f *BlobFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachAnnounce loops over the given announcements in arrival order, invoking
|
// announcesByArrival returns an iterator over the given announcements
|
||||||
// the do function for each until it returns false. We enforce an arrival
|
// in arrival order. We enforce an arrival ordering to minimize
|
||||||
// ordering to minimize the chances of transaction nonce-gaps, which result in
|
// the chances of transaction nonce-gaps, which result in
|
||||||
// transactions being rejected by the txpool.
|
// transactions being rejected by the txpool.
|
||||||
func (f *BlobFetcher) forEachAnnounce(announces map[common.Hash]*cellWithSeq, do func(hash common.Hash, cells types.CustodyBitmap) bool) {
|
|
||||||
|
func (f *BlobFetcher) announcesByArrival(announces map[common.Hash]*cellWithSeq) iter.Seq2[common.Hash, types.CustodyBitmap] {
|
||||||
|
return func(yield func(hash common.Hash, cells types.CustodyBitmap) bool) {
|
||||||
type announcement struct {
|
type announcement struct {
|
||||||
hash common.Hash
|
hash common.Hash
|
||||||
cells types.CustodyBitmap
|
cells types.CustodyBitmap
|
||||||
|
|
@ -856,19 +862,23 @@ func (f *BlobFetcher) forEachAnnounce(announces map[common.Hash]*cellWithSeq, do
|
||||||
return list[i].seq < list[j].seq
|
return list[i].seq < list[j].seq
|
||||||
})
|
})
|
||||||
for i := range list {
|
for i := range list {
|
||||||
if !do(list[i].hash, list[i].cells) {
|
if !yield(list[i].hash, list[i].cells) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachPeer does a range loop over a map of peers in production, but during
|
// peers returns an iterator over a map of peers in production, but during
|
||||||
// testing it does a deterministic sorted random to allow reproducing issues.
|
// testing it does a deterministic sorted random to allow reproducing issues.
|
||||||
func (f *BlobFetcher) forEachPeer(peers map[string]struct{}, do func(peer string)) {
|
func (f *BlobFetcher) peers(peers map[string]struct{}) iter.Seq[string] {
|
||||||
|
return func(yield func(peer string) bool) {
|
||||||
// If we're running production(step == nil), use whatever Go's map gives us
|
// If we're running production(step == nil), use whatever Go's map gives us
|
||||||
if f.step == nil {
|
if f.step == nil {
|
||||||
for peer := range peers {
|
for peer := range peers {
|
||||||
do(peer)
|
if !yield(peer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -879,6 +889,9 @@ func (f *BlobFetcher) forEachPeer(peers map[string]struct{}, do func(peer string
|
||||||
}
|
}
|
||||||
sort.Strings(list)
|
sort.Strings(list)
|
||||||
for _, peer := range list {
|
for _, peer := range list {
|
||||||
do(peer)
|
if !yield(peer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue