Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions eth/downloader/fetchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ import (
"github.com/ethereum/go-ethereum/eth/protocols/eth"
)

// masterPeerHeaderTimeout caps the timeout for blocking header requests on the
// critical sync path (fetchHead, findAncestor, skeleton). With BSC's 0.45s block
// interval, the dynamic TargetTimeout (10s+) causes excessive lag; this ensures
// we fail fast and switch peers instead.
const masterPeerHeaderTimeout = 5 * time.Second

// fetchHeadersByHash is a blocking version of Peer.RequestHeadersByHash which
// handles all the cancellation, interruption and timeout mechanisms of a data
// retrieval to allow blocking API calls.
Expand All @@ -38,13 +44,18 @@ func (d *Downloader) fetchHeadersByHash(p *peerConnection, hash common.Hash, amo
}
defer req.Close()

// Wait until the response arrives, the request is cancelled or times out
// Wait until the response arrives, the request is cancelled or times out.
ttl := d.peers.rates.TargetTimeout()

if ttl > masterPeerHeaderTimeout {
ttl = masterPeerHeaderTimeout
}
timeoutTimer := time.NewTimer(ttl)
defer timeoutTimer.Stop()

select {
case <-d.cancelCh:
return nil, nil, errCanceled

case <-timeoutTimer.C:
// Header retrieval timed out, update the metrics
p.log.Debug("Header request timed out", "elapsed", ttl)
Expand Down Expand Up @@ -80,9 +91,11 @@ func (d *Downloader) fetchHeadersByNumber(p *peerConnection, number uint64, amou
}
defer req.Close()

// Wait until the response arrives, the request is cancelled or times out
// Wait until the response arrives, the request is cancelled or times out.
ttl := d.peers.rates.TargetTimeout()

if ttl > masterPeerHeaderTimeout {
ttl = masterPeerHeaderTimeout
}
timeoutTimer := time.NewTimer(ttl)
defer timeoutTimer.Stop()

Expand Down
28 changes: 20 additions & 8 deletions eth/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,16 @@ func (cs *chainSyncer) loop() {
select {
case <-cs.peerEventCh:
// Peer information changed, recheck.
case <-cs.doneCh:
case err := <-cs.doneCh:
cs.doneCh = nil
cs.force.Reset(forceSyncCycle)
cs.forced = false
if err != nil {
// Sync failed, keep forced=true so nextSyncOp can immediately
// retry with minPeers=1 instead of waiting for the 10s force timer.
cs.forced = true
} else {
cs.force.Reset(forceSyncCycle)
cs.forced = false
}
case <-cs.force.C:
cs.forced = true

Expand Down Expand Up @@ -184,11 +190,17 @@ func (cs *chainSyncer) nextSyncOp() *chainSyncOp {
// log.Info("Disable transaction acceptance randomly for the delay exceeding 10 blocks.")
// }
} else if op.td.Cmp(new(big.Int).Add(ourTD, common.Big2)) <= 0 { // common.Big2: difficulty of an in-turn block
// On BSC, blocks are produced much faster than on Ethereum.
// If the node is only slightly behind (e.g., 1 block), syncing is unnecessary.
// It's likely still processing broadcasted blocks(such as including a big tx) or block hash announcements.
// In most cases, the node will catch up within 2 seconds.
time.Sleep(2 * time.Second)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just change it to time.Sleep(500 * time.Millisecond)

// Only slightly behind (~1 block). Wait briefly for block broadcast to
// catch up before starting a full sync. Use non-blocking select to stay
// responsive to quit signals and peer events.
waitTimer := time.NewTimer(500 * time.Millisecond)
defer waitTimer.Stop()
select {
case <-waitTimer.C:
case <-cs.handler.quitSync:
return nil
case <-cs.peerEventCh:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need trigger by this signal peerEventCh

}

// Re-check local head to see if it has caught up
if _, latestTD := cs.modeAndLocalHead(); ourTD.Cmp(latestTD) < 0 {
Expand Down
Loading