mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
Merge f6618ad85d into 406a852ec8
This commit is contained in:
commit
cf242e0de2
8 changed files with 53 additions and 7 deletions
|
|
@ -2936,3 +2936,8 @@ func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
|||
func (bc *BlockChain) StateSizer() *state.SizeTracker {
|
||||
return bc.stateSizer
|
||||
}
|
||||
|
||||
// FreezerTailBlock returns the block number of the oldest state in the freezer.
|
||||
func (bc *BlockChain) FreezerTailBlock() (uint64, error) {
|
||||
return bc.triedb.FreezerTailBlock()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package eth
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
|
|
@ -61,9 +62,16 @@ func (b *EthAPIBackend) CurrentBlock() *types.Header {
|
|||
return b.eth.blockchain.CurrentBlock()
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) SetHead(number uint64) {
|
||||
func (b *EthAPIBackend) SetHead(number uint64) error {
|
||||
tailBlock, err := b.eth.blockchain.FreezerTailBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if number < tailBlock {
|
||||
return fmt.Errorf("cannot rewind to block %d, oldest available state is at block %d", number, tailBlock)
|
||||
}
|
||||
b.eth.handler.downloader.Cancel()
|
||||
b.eth.blockchain.SetHead(number)
|
||||
return b.eth.blockchain.SetHead(number)
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
|
||||
|
|
|
|||
|
|
@ -2094,8 +2094,7 @@ func (api *DebugAPI) SetHead(number hexutil.Uint64) error {
|
|||
if header.Number.Uint64() <= uint64(number) {
|
||||
return errors.New("not allowed to rewind to a future block")
|
||||
}
|
||||
api.b.SetHead(uint64(number))
|
||||
return nil
|
||||
return api.b.SetHead(uint64(number))
|
||||
}
|
||||
|
||||
// NetAPI offers network related RPC methods
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ func (b testBackend) RPCGasCap() uint64 { return 10000000
|
|||
func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second }
|
||||
func (b testBackend) RPCTxFeeCap() float64 { return 0 }
|
||||
func (b testBackend) UnprotectedAllowed() bool { return false }
|
||||
func (b testBackend) SetHead(number uint64) {}
|
||||
func (b testBackend) SetHead(number uint64) error { return nil }
|
||||
func (b testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
|
||||
if number == rpc.LatestBlockNumber {
|
||||
return b.chain.CurrentBlock(), nil
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ type Backend interface {
|
|||
RPCTxSyncMaxTimeout() time.Duration
|
||||
|
||||
// Blockchain API
|
||||
SetHead(number uint64)
|
||||
SetHead(number uint64) error
|
||||
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
|
||||
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
|
||||
HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error)
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ func (b *backendMock) RPCGasCap() uint64 { return 0 }
|
|||
func (b *backendMock) RPCEVMTimeout() time.Duration { return time.Second }
|
||||
func (b *backendMock) RPCTxFeeCap() float64 { return 0 }
|
||||
func (b *backendMock) UnprotectedAllowed() bool { return false }
|
||||
func (b *backendMock) SetHead(number uint64) {}
|
||||
func (b *backendMock) SetHead(number uint64) error { return nil }
|
||||
func (b *backendMock) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,3 +393,12 @@ func (db *Database) SnapshotCompleted() bool {
|
|||
}
|
||||
return pdb.SnapshotCompleted()
|
||||
}
|
||||
|
||||
// FrezzerTailBlock returns the block number of the oldest state in the freezer.
|
||||
func (db *Database) FreezerTailBlock() (uint64, error) {
|
||||
pdb, ok := db.backend.(*pathdb.Database)
|
||||
if !ok {
|
||||
return 0, nil
|
||||
}
|
||||
return pdb.FreezerTailBlock()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -673,3 +673,28 @@ func (db *Database) SnapshotCompleted() bool {
|
|||
}
|
||||
return db.tree.bottom().genComplete()
|
||||
}
|
||||
|
||||
// FreezerTailBlock returns the block number of the oldest state in the freezer.
|
||||
func (db *Database) FreezerTailBlock() (uint64, error) {
|
||||
freezer := db.stateFreezer
|
||||
if freezer == nil {
|
||||
return 0, errors.New("freezer is not available")
|
||||
}
|
||||
|
||||
tailID, err := freezer.Tail()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// No state has been persistent, return the genesis block number.
|
||||
if tailID == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
blob := rawdb.ReadStateHistoryMeta(freezer, tailID+1)
|
||||
var m meta
|
||||
if err := m.decode(blob); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return m.block, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue