mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
eth: quick canceling block inserting when debug_setHead is invoked (#32067)
If Geth is engaged in a long-run block synchronization, such as a full syncing over a large number of blocks, invoking `debug_setHead` will cause `downloader.Cancel` to wait for all fetchers to stop first. This can be time-consuming, particularly for the block processing thread. To address this, we manually call `blockchain.StopInsert` to interrupt the blocking processing thread and allow it to exit immediately, and after that call `blockchain.ResumeInsert` to resume the block downloading process. Additionally, we add a sanity check for the input block number of `debug_setHead` to ensure its validity. --------- Signed-off-by: jsvisa <delweng@gmail.com> Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This commit is contained in:
parent
21920207e4
commit
78b6059341
3 changed files with 23 additions and 12 deletions
|
|
@ -1244,7 +1244,7 @@ func (bc *BlockChain) stopWithoutSaving() {
|
|||
bc.scope.Close()
|
||||
|
||||
// Signal shutdown to all goroutines.
|
||||
bc.StopInsert()
|
||||
bc.InterruptInsert(true)
|
||||
|
||||
// Now wait for all chain modifications to end and persistent goroutines to exit.
|
||||
//
|
||||
|
|
@ -1318,11 +1318,15 @@ func (bc *BlockChain) Stop() {
|
|||
log.Info("Blockchain stopped")
|
||||
}
|
||||
|
||||
// StopInsert interrupts all insertion methods, causing them to return
|
||||
// errInsertionInterrupted as soon as possible. Insertion is permanently disabled after
|
||||
// calling this method.
|
||||
func (bc *BlockChain) StopInsert() {
|
||||
bc.procInterrupt.Store(true)
|
||||
// InterruptInsert interrupts all insertion methods, causing them to return
|
||||
// errInsertionInterrupted as soon as possible, or resume the chain insertion
|
||||
// if required.
|
||||
func (bc *BlockChain) InterruptInsert(on bool) {
|
||||
if on {
|
||||
bc.procInterrupt.Store(true)
|
||||
} else {
|
||||
bc.procInterrupt.Store(false)
|
||||
}
|
||||
}
|
||||
|
||||
// insertStopped returns true after StopInsert has been called.
|
||||
|
|
|
|||
|
|
@ -199,8 +199,8 @@ type BlockChain interface {
|
|||
// InsertChain inserts a batch of blocks into the local chain.
|
||||
InsertChain(types.Blocks) (int, error)
|
||||
|
||||
// StopInsert interrupts the inserting process.
|
||||
StopInsert()
|
||||
// InterruptInsert whether disables the chain insertion.
|
||||
InterruptInsert(on bool)
|
||||
|
||||
// InsertReceiptChain inserts a batch of blocks along with their receipts
|
||||
// into the local chain. Blocks older than the specified `ancientLimit`
|
||||
|
|
@ -630,16 +630,15 @@ func (d *Downloader) cancel() {
|
|||
// Cancel aborts all of the operations and waits for all download goroutines to
|
||||
// finish before returning.
|
||||
func (d *Downloader) Cancel() {
|
||||
d.blockchain.InterruptInsert(true)
|
||||
d.cancel()
|
||||
d.cancelWg.Wait()
|
||||
d.blockchain.InterruptInsert(false)
|
||||
}
|
||||
|
||||
// Terminate interrupts the downloader, canceling all pending operations.
|
||||
// The downloader cannot be reused after calling Terminate.
|
||||
func (d *Downloader) Terminate() {
|
||||
// Signal to stop inserting in-flight blocks
|
||||
d.blockchain.StopInsert()
|
||||
|
||||
// Close the termination channel (make sure double close is allowed)
|
||||
d.quitLock.Lock()
|
||||
select {
|
||||
|
|
|
|||
|
|
@ -1831,8 +1831,16 @@ func (api *DebugAPI) ChaindbCompact() error {
|
|||
}
|
||||
|
||||
// SetHead rewinds the head of the blockchain to a previous block.
|
||||
func (api *DebugAPI) SetHead(number hexutil.Uint64) {
|
||||
func (api *DebugAPI) SetHead(number hexutil.Uint64) error {
|
||||
header := api.b.CurrentHeader()
|
||||
if header == nil {
|
||||
return errors.New("current header is not available")
|
||||
}
|
||||
if header.Number.Uint64() <= uint64(number) {
|
||||
return errors.New("not allowed to rewind to a future block")
|
||||
}
|
||||
api.b.SetHead(uint64(number))
|
||||
return nil
|
||||
}
|
||||
|
||||
// NetAPI offers network related RPC methods
|
||||
|
|
|
|||
Loading…
Reference in a new issue