Skip to content

Commit 7f61b8b

Browse files
committed
check first
Signed-off-by: Delweng <[email protected]>
1 parent 8788d37 commit 7f61b8b

File tree

8 files changed

+34
-27
lines changed

8 files changed

+34
-27
lines changed

core/blockchain.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -735,14 +735,6 @@ func (bc *BlockChain) initializeHistoryPruning(latest uint64) error {
735735
// was snap synced or full synced and in which state, the method will try to
736736
// delete minimal data from disk whilst retaining chain consistency.
737737
func (bc *BlockChain) SetHead(head uint64) error {
738-
// Only allowed to rewind to a block that is later than the oldest state block.
739-
firstStateBlock, err := bc.triedb.FirstStateBlock()
740-
if err != nil {
741-
return err
742-
}
743-
if head < firstStateBlock {
744-
return fmt.Errorf("cannot rewind to block %d, oldest available state is at block %d", head, firstStateBlock)
745-
}
746738
if _, err := bc.setHeadBeyondRoot(head, 0, common.Hash{}, false); err != nil {
747739
return err
748740
}
@@ -2827,3 +2819,8 @@ func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
28272819
func (bc *BlockChain) StateSizer() *state.SizeTracker {
28282820
return bc.stateSizer
28292821
}
2822+
2823+
// FirstStateBlock returns the first available state block number that is stored in the database.
2824+
func (bc *BlockChain) FirstStateBlock() (uint64, error) {
2825+
return bc.triedb.FirstStateBlock()
2826+
}

eth/api_backend.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package eth
1919
import (
2020
"context"
2121
"errors"
22+
"fmt"
2223
"math/big"
2324
"time"
2425

@@ -61,9 +62,16 @@ func (b *EthAPIBackend) CurrentBlock() *types.Header {
6162
return b.eth.blockchain.CurrentBlock()
6263
}
6364

64-
func (b *EthAPIBackend) SetHead(number uint64) {
65+
func (b *EthAPIBackend) SetHead(number uint64) error {
66+
firstStateBlock, err := b.eth.blockchain.FirstStateBlock()
67+
if err != nil {
68+
return err
69+
}
70+
if number < firstStateBlock {
71+
return fmt.Errorf("cannot rewind to block %d, oldest available state is at block %d", number, firstStateBlock)
72+
}
6573
b.eth.handler.downloader.Cancel()
66-
b.eth.blockchain.SetHead(number)
74+
return b.eth.blockchain.SetHead(number)
6775
}
6876

6977
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {

internal/ethapi/api.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,8 +1933,7 @@ func (api *DebugAPI) SetHead(number hexutil.Uint64) error {
19331933
if header.Number.Uint64() <= uint64(number) {
19341934
return errors.New("not allowed to rewind to a future block")
19351935
}
1936-
api.b.SetHead(uint64(number))
1937-
return nil
1936+
return api.b.SetHead(uint64(number))
19381937
}
19391938

19401939
// NetAPI offers network related RPC methods

internal/ethapi/api_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ func (b testBackend) RPCGasCap() uint64 { return 10000000
487487
func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second }
488488
func (b testBackend) RPCTxFeeCap() float64 { return 0 }
489489
func (b testBackend) UnprotectedAllowed() bool { return false }
490-
func (b testBackend) SetHead(number uint64) {}
490+
func (b testBackend) SetHead(number uint64) error { return nil }
491491
func (b testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
492492
if number == rpc.LatestBlockNumber {
493493
return b.chain.CurrentBlock(), nil

internal/ethapi/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type Backend interface {
5555
UnprotectedAllowed() bool // allows only for EIP155 transactions.
5656

5757
// Blockchain API
58-
SetHead(number uint64)
58+
SetHead(number uint64) error
5959
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
6060
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
6161
HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error)

internal/ethapi/transaction_args_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ func (b *backendMock) RPCGasCap() uint64 { return 0 }
336336
func (b *backendMock) RPCEVMTimeout() time.Duration { return time.Second }
337337
func (b *backendMock) RPCTxFeeCap() float64 { return 0 }
338338
func (b *backendMock) UnprotectedAllowed() bool { return false }
339-
func (b *backendMock) SetHead(number uint64) {}
339+
func (b *backendMock) SetHead(number uint64) error { return nil }
340340
func (b *backendMock) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
341341
return nil, nil
342342
}

triedb/database.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ func (db *Database) SnapshotCompleted() bool {
385385
return pdb.SnapshotCompleted()
386386
}
387387

388-
// FirstStateBlock
388+
// FirstStateBlock returns the first available state block number that is stored in the database.
389389
func (db *Database) FirstStateBlock() (uint64, error) {
390390
pdb, ok := db.backend.(*pathdb.Database)
391391
if !ok {

triedb/pathdb/database.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -695,20 +695,23 @@ func (db *Database) SnapshotCompleted() bool {
695695

696696
// FirstStateBlock returns the block number of the oldest state snapshot in the freezer or disk layer.
697697
func (db *Database) FirstStateBlock() (uint64, error) {
698-
var (
699-
m meta
700-
err error
701-
tailID = db.tree.bottom().stateID()
702-
)
698+
freezer := db.stateFreezer
699+
if freezer == nil {
700+
return 0, errors.New("freezer is not available")
701+
}
703702

704-
if db.stateFreezer != nil {
705-
tailID, err = db.stateFreezer.Tail()
706-
if err != nil {
707-
return 0, err
708-
}
703+
tailID, err := freezer.Tail()
704+
if err != nil {
705+
return 0, err
706+
}
707+
708+
// No state has been persistent
709+
if tailID == 0 {
710+
return 0, nil
709711
}
710712

711-
blob := rawdb.ReadStateHistoryMeta(db.diskdb, tailID)
713+
blob := rawdb.ReadStateHistoryMeta(freezer, tailID+1)
714+
var m meta
712715
if err := m.decode(blob); err != nil {
713716
return 0, err
714717
}

0 commit comments

Comments
 (0)