diff --git a/core/headerchain.go b/core/headerchain.go index b8ddc4ad9b..478a55bc08 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -174,6 +174,9 @@ func (hc *HeaderChain) Reorg(headers []*types.Header) error { ) for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash { + if frozen, _ := hc.chainDb.Ancients(); frozen == headNumber { + break + } rawdb.WriteCanonicalHash(batch, headHash, headNumber) if headNumber == 0 { diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go index a3f21c920a..d6d5fd675b 100644 --- a/core/rawdb/chain_iterator.go +++ b/core/rawdb/chain_iterator.go @@ -106,8 +106,10 @@ func iterateTransactions(db ethdb.Database, from uint64, to uint64, reverse bool number uint64 rlp rlp.RawValue } - - if to == from { + if offset := db.AncientOffSet(); offset > from { + from = offset + } + if to <= from { return nil } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index b0016e15cc..47c08972f7 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -76,6 +76,9 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u // The optional base statedb is given, mark the start point as parent block statedb, database, triedb, report = base, base.Database(), base.Database().TrieDB(), false current = eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) + if current == nil { + return nil, nil, fmt.Errorf("missing parent block %v %d", block.ParentHash(), block.NumberU64()-1) + } } else { // Otherwise, try to reexec blocks until we find a state or reach our limit current = block diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2d988ac94e..2781c1a19d 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -678,6 +678,9 @@ func (s *BlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context, block if err != nil { return nil, err } + if receipts == nil { + return nil, fmt.Errorf("block %d receipts not found", block.NumberU64()) + } txs := block.Transactions()