core: use headers only where blocks are unnecessary #19261 (#984)

This commit is contained in:
Daniel Liu 2025-04-28 06:46:40 +08:00 committed by GitHub
parent 80547a50d9
commit c02ab17b17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 24 additions and 23 deletions

View file

@ -84,7 +84,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
// transition, such as amount of used gas, the receipt roots and the state root // transition, such as amount of used gas, the receipt roots and the state root
// itself. ValidateState returns a database batch if the validation was a success // itself. ValidateState returns a database batch if the validation was a success
// otherwise nil and an error is returned. // otherwise nil and an error is returned.
func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error {
header := block.Header() header := block.Header()
if block.GasUsed() != usedGas { if block.GasUsed() != usedGas {
return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas) return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas)

View file

@ -1726,10 +1726,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
parent := it.previous() parent := it.previous()
if parent == nil { if parent == nil {
parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
} }
// Create a new statedb using the parent block and report an error if it fails. // Create a new statedb using the parent block and report an error if it fails.
statedb, err := state.New(parent.Root(), bc.stateCache) statedb, err := state.New(parent.Root, bc.stateCache)
if err != nil { if err != nil {
return it.index, events, coalescedLogs, err return it.index, events, coalescedLogs, err
} }
@ -1741,7 +1741,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
bc.reportBlock(block, nil, err) bc.reportBlock(block, nil, err)
return it.index, events, coalescedLogs, err return it.index, events, coalescedLogs, err
} }
feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root(), statedb) feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root, statedb)
receipts, logs, usedGas, err := bc.processor.Process(block, statedb, tradingState, bc.vmConfig, feeCapacity) receipts, logs, usedGas, err := bc.processor.Process(block, statedb, tradingState, bc.vmConfig, feeCapacity)
t1 := time.Now() t1 := time.Now()
if err != nil { if err != nil {
@ -1749,7 +1749,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
return it.index, events, coalescedLogs, err return it.index, events, coalescedLogs, err
} }
// Validate the state using the default validator // Validate the state using the default validator
err = bc.Validator().ValidateState(block, parent, statedb, receipts, usedGas) err = bc.Validator().ValidateState(block, statedb, receipts, usedGas)
if err != nil { if err != nil {
bc.reportBlock(block, receipts, err) bc.reportBlock(block, receipts, err)
return it.index, events, coalescedLogs, err return it.index, events, coalescedLogs, err
@ -1907,7 +1907,7 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i
// blocks to regenerate the required state // blocks to regenerate the required state
localTd := bc.GetTd(bc.CurrentBlock().Hash(), current) localTd := bc.GetTd(bc.CurrentBlock().Hash(), current)
if localTd.Cmp(externTd) > 0 { if localTd.Cmp(externTd) > 0 {
log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().NumberU64(), "sidetd", externTd, "localtd", localTd) log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd)
return it.index, nil, nil, err return it.index, nil, nil, err
} }
// Gather all the sidechain hashes (full blocks may be memory heavy) // Gather all the sidechain hashes (full blocks may be memory heavy)
@ -1915,7 +1915,7 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i
hashes []common.Hash hashes []common.Hash
numbers []uint64 numbers []uint64
) )
parent := bc.GetHeader(it.previous().Hash(), it.previous().NumberU64()) parent := it.previous()
for parent != nil && !bc.HasState(parent.Root) { for parent != nil && !bc.HasState(parent.Root) {
hashes = append(hashes, parent.Hash()) hashes = append(hashes, parent.Hash())
numbers = append(numbers, parent.Number.Uint64()) numbers = append(numbers, parent.Number.Uint64())
@ -2060,9 +2060,9 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
bc.reportBlock(block, nil, err) bc.reportBlock(block, nil, err)
return nil, err return nil, err
} }
var parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) var parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
// Create a new statedb using the parent block and report an error if it fails. // Create a new statedb using the parent block and report an error if it fails.
statedb, err := state.New(parent.Root(), bc.stateCache) statedb, err := state.New(parent.Root, bc.stateCache)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2073,7 +2073,7 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
bc.reportBlock(block, nil, err) bc.reportBlock(block, nil, err)
return nil, err return nil, err
} }
feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root(), statedb) feeCapacity := state.GetTRC21FeeCapacityFromStateWithCache(parent.Root, statedb)
receipts, logs, usedGas, err := bc.processor.ProcessBlockNoValidator(calculatedBlock, statedb, tradingState, bc.vmConfig, feeCapacity) receipts, logs, usedGas, err := bc.processor.ProcessBlockNoValidator(calculatedBlock, statedb, tradingState, bc.vmConfig, feeCapacity)
process := time.Since(bstart) process := time.Since(bstart)
if err != nil { if err != nil {
@ -2083,7 +2083,7 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
return nil, err return nil, err
} }
// Validate the state using the default validator // Validate the state using the default validator
err = bc.Validator().ValidateState(block, parent, statedb, receipts, usedGas) err = bc.Validator().ValidateState(block, statedb, receipts, usedGas)
if err != nil { if err != nil {
bc.reportBlock(block, receipts, err) bc.reportBlock(block, receipts, err)
return nil, err return nil, err
@ -2904,7 +2904,7 @@ func (bc *BlockChain) AddFinalizedTrades(txHash common.Hash, trades map[common.H
// 6. Validates trading and lending orders using the block's transactions and state. // 6. Validates trading and lending orders using the block's transactions and state.
// 7. Processes liquidation data for lending trades if the block is a liquidation block. // 7. Processes liquidation data for lending trades if the block is a liquidation block.
// 8. Verifies the integrity of the trading and lending state roots by comparing the computed roots with the expected roots. // 8. Verifies the integrity of the trading and lending state roots by comparing the computed roots with the expected roots.
func (bc *BlockChain) processTradingAndLendingStates(isValidBlockNumber bool, block *types.Block, parent *types.Block, statedb *state.StateDB) (*tradingstate.TradingStateDB, *lendingstate.LendingStateDB, error) { func (bc *BlockChain) processTradingAndLendingStates(isValidBlockNumber bool, block *types.Block, parent *types.Header, statedb *state.StateDB) (*tradingstate.TradingStateDB, *lendingstate.LendingStateDB, error) {
if !isValidBlockNumber || bc.chainConfig.XDPoS == nil || block.NumberU64() <= bc.chainConfig.XDPoS.Epoch { if !isValidBlockNumber || bc.chainConfig.XDPoS == nil || block.NumberU64() <= bc.chainConfig.XDPoS.Epoch {
return nil, nil, nil return nil, nil, nil
} }
@ -2925,12 +2925,13 @@ func (bc *BlockChain) processTradingAndLendingStates(isValidBlockNumber bool, bl
return nil, nil, nil return nil, nil, nil
} }
parentAuthor, _ := bc.Engine().Author(parent.Header()) parentAuthor, _ := bc.Engine().Author(parent)
tradingState, err := tradingService.GetTradingState(parent, parentAuthor) parentBlock := bc.GetBlock(parent.Hash(), parent.Number.Uint64())
tradingState, err := tradingService.GetTradingState(parentBlock, parentAuthor)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
lendingState, err := lendingService.GetLendingState(parent, parentAuthor) lendingState, err := lendingService.GetLendingState(parentBlock, parentAuthor)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -2987,7 +2988,7 @@ func (bc *BlockChain) processTradingAndLendingStates(isValidBlockNumber bool, bl
if tradingState != nil { if tradingState != nil {
gotRoot := tradingState.IntermediateRoot() gotRoot := tradingState.IntermediateRoot()
expectRoot, _ := tradingService.GetTradingStateRoot(block, author) expectRoot, _ := tradingService.GetTradingStateRoot(block, author)
parentRoot, _ := tradingService.GetTradingStateRoot(parent, parentAuthor) parentRoot, _ := tradingService.GetTradingStateRoot(parentBlock, parentAuthor)
if gotRoot != expectRoot { if gotRoot != expectRoot {
err = fmt.Errorf("invalid XDCx trading state merke trie got : %s , expect : %s ,parent : %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex()) err = fmt.Errorf("invalid XDCx trading state merke trie got : %s , expect : %s ,parent : %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
return tradingState, lendingState, err return tradingState, lendingState, err
@ -2998,7 +2999,7 @@ func (bc *BlockChain) processTradingAndLendingStates(isValidBlockNumber bool, bl
if lendingState != nil && tradingState != nil { if lendingState != nil && tradingState != nil {
gotRoot := lendingState.IntermediateRoot() gotRoot := lendingState.IntermediateRoot()
expectRoot, _ := lendingService.GetLendingStateRoot(block, author) expectRoot, _ := lendingService.GetLendingStateRoot(block, author)
parentRoot, _ := lendingService.GetLendingStateRoot(parent, parentAuthor) parentRoot, _ := lendingService.GetLendingStateRoot(parentBlock, parentAuthor)
if gotRoot != expectRoot { if gotRoot != expectRoot {
err = fmt.Errorf("invalid lending state merke trie got: %s, expect: %s, parent: %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex()) err = fmt.Errorf("invalid lending state merke trie got: %s, expect: %s, parent: %s", gotRoot.Hex(), expectRoot.Hex(), parentRoot.Hex())
return tradingState, lendingState, err return tradingState, lendingState, err

View file

@ -111,12 +111,12 @@ func (it *insertIterator) next() (*types.Block, error) {
return it.chain[it.index], it.validator.ValidateBody(it.chain[it.index]) return it.chain[it.index], it.validator.ValidateBody(it.chain[it.index])
} }
// previous returns the previous block was being processed, or nil // previous returns the previous header that was being processed, or nil.
func (it *insertIterator) previous() *types.Block { func (it *insertIterator) previous() *types.Header {
if it.index < 1 { if it.index < 1 {
return nil return nil
} }
return it.chain[it.index-1] return it.chain[it.index-1].Header()
} }
// first returns the first block in the it. // first returns the first block in the it.

View file

@ -159,7 +159,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
blockchain.reportBlock(block, receipts, err) blockchain.reportBlock(block, receipts, err)
return err return err
} }
err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas) err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
if err != nil { if err != nil {
blockchain.reportBlock(block, receipts, err) blockchain.reportBlock(block, receipts, err)
return err return err

View file

@ -30,14 +30,13 @@ import (
// Validator is an interface which defines the standard for block validation. It // Validator is an interface which defines the standard for block validation. It
// is only responsible for validating block contents, as the header validation is // is only responsible for validating block contents, as the header validation is
// done by the specific consensus engines. // done by the specific consensus engines.
//
type Validator interface { type Validator interface {
// ValidateBody validates the given block's content. // ValidateBody validates the given block's content.
ValidateBody(block *types.Block) error ValidateBody(block *types.Block) error
// ValidateState validates the given statedb and optionally the receipts and // ValidateState validates the given statedb and optionally the receipts and
// gas used. // gas used.
ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error ValidateState(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error
ValidateTradingOrder(statedb *state.StateDB, XDCxStatedb *tradingstate.TradingStateDB, txMatchBatch tradingstate.TxMatchBatch, coinbase common.Address, header *types.Header) error ValidateTradingOrder(statedb *state.StateDB, XDCxStatedb *tradingstate.TradingStateDB, txMatchBatch tradingstate.TxMatchBatch, coinbase common.Address, header *types.Header) error
@ -52,5 +51,6 @@ type Validator interface {
// failed. // failed.
type Processor interface { type Processor interface {
Process(block *types.Block, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) Process(block *types.Block, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
ProcessBlockNoValidator(block *CalculatedBlock, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error) ProcessBlockNoValidator(block *CalculatedBlock, statedb *state.StateDB, tradingState *tradingstate.TradingStateDB, cfg vm.Config, balanceFee map[common.Address]*big.Int) (types.Receipts, []*types.Log, uint64, error)
} }