eth: request id dispatcher and direct req/reply APIs (#23576)
* eth: request ID based message dispatcher * eth: fix dispatcher cancellation, rework fetchers idleness tracker * eth/downloader: drop peers who refuse to serve advertised chains
This commit is contained in:
@ -26,6 +26,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/prque"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
@ -74,10 +75,10 @@ type HeaderRetrievalFn func(common.Hash) *types.Header
|
||||
type blockRetrievalFn func(common.Hash) *types.Block
|
||||
|
||||
// headerRequesterFn is a callback type for sending a header retrieval request.
|
||||
type headerRequesterFn func(common.Hash) error
|
||||
type headerRequesterFn func(common.Hash, chan *eth.Response) (*eth.Request, error)
|
||||
|
||||
// bodyRequesterFn is a callback type for sending a body retrieval request.
|
||||
type bodyRequesterFn func([]common.Hash) error
|
||||
type bodyRequesterFn func([]common.Hash, chan *eth.Response) (*eth.Request, error)
|
||||
|
||||
// headerVerifierFn is a callback type to verify a block's header for fast propagation.
|
||||
type headerVerifierFn func(header *types.Header) error
|
||||
@ -461,15 +462,28 @@ func (f *BlockFetcher) loop() {
|
||||
|
||||
// Create a closure of the fetch and schedule in on a new thread
|
||||
fetchHeader, hashes := f.fetching[hashes[0]].fetchHeader, hashes
|
||||
go func() {
|
||||
go func(peer string) {
|
||||
if f.fetchingHook != nil {
|
||||
f.fetchingHook(hashes)
|
||||
}
|
||||
for _, hash := range hashes {
|
||||
headerFetchMeter.Mark(1)
|
||||
fetchHeader(hash) // Suboptimal, but protocol doesn't allow batch header retrievals
|
||||
go func(hash common.Hash) {
|
||||
resCh := make(chan *eth.Response)
|
||||
|
||||
req, err := fetchHeader(hash, resCh)
|
||||
if err != nil {
|
||||
return // Legacy code, yolo
|
||||
}
|
||||
defer req.Close()
|
||||
|
||||
res := <-resCh
|
||||
res.Done <- nil
|
||||
|
||||
f.FilterHeaders(peer, *res.Res.(*eth.BlockHeadersPacket), time.Now().Add(res.Time))
|
||||
}(hash)
|
||||
}
|
||||
}()
|
||||
}(peer)
|
||||
}
|
||||
// Schedule the next fetch if blocks are still pending
|
||||
f.rescheduleFetch(fetchTimer)
|
||||
@ -497,8 +511,24 @@ func (f *BlockFetcher) loop() {
|
||||
if f.completingHook != nil {
|
||||
f.completingHook(hashes)
|
||||
}
|
||||
fetchBodies := f.completing[hashes[0]].fetchBodies
|
||||
bodyFetchMeter.Mark(int64(len(hashes)))
|
||||
go f.completing[hashes[0]].fetchBodies(hashes)
|
||||
|
||||
go func(peer string, hashes []common.Hash) {
|
||||
resCh := make(chan *eth.Response)
|
||||
|
||||
req, err := fetchBodies(hashes, resCh)
|
||||
if err != nil {
|
||||
return // Legacy code, yolo
|
||||
}
|
||||
defer req.Close()
|
||||
|
||||
res := <-resCh
|
||||
res.Done <- nil
|
||||
|
||||
txs, uncles := res.Res.(*eth.BlockBodiesPacket).Unpack()
|
||||
f.FilterBodies(peer, txs, uncles, time.Now())
|
||||
}(peer, hashes)
|
||||
}
|
||||
// Schedule the next fetch if blocks are still pending
|
||||
f.rescheduleComplete(completeTimer)
|
||||
|
Reference in New Issue
Block a user