mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-27 18:29:26 +00:00
Merge f7ed82b12c into 3d1e6aa6c3
This commit is contained in:
commit
a7942c8d55
5 changed files with 34 additions and 34 deletions
|
|
@ -53,17 +53,9 @@ func main() {
|
||||||
}
|
}
|
||||||
vmConfig := vm.Config{}
|
vmConfig := vm.Config{}
|
||||||
|
|
||||||
crossStateRoot, crossReceiptRoot, err := core.ExecuteStateless(context.Background(), chainConfig, vmConfig, payload.Block, payload.Witness)
|
_, _, err = core.ExecuteStateless(context.Background(), chainConfig, vmConfig, payload.Block, payload.Witness, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "stateless self-validation failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "stateless self-validation failed: %v\n", err)
|
||||||
os.Exit(10)
|
os.Exit(10)
|
||||||
}
|
}
|
||||||
if crossStateRoot != payload.Block.Root() {
|
|
||||||
fmt.Fprintf(os.Stderr, "stateless self-validation root mismatch (cross: %x local: %x)\n", crossStateRoot, payload.Block.Root())
|
|
||||||
os.Exit(11)
|
|
||||||
}
|
|
||||||
if crossReceiptRoot != payload.Block.ReceiptHash() {
|
|
||||||
fmt.Fprintf(os.Stderr, "stateless self-validation receipt root mismatch (cross: %x local: %x)\n", crossReceiptRoot, payload.Block.ReceiptHash())
|
|
||||||
os.Exit(12)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,19 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
||||||
if v.config.IsOsaka(block.Number(), block.Time()) && block.Size() > params.MaxBlockSize {
|
if v.config.IsOsaka(block.Number(), block.Time()) && block.Size() > params.MaxBlockSize {
|
||||||
return ErrBlockOversized
|
return ErrBlockOversized
|
||||||
}
|
}
|
||||||
// Check whether the block is already imported.
|
|
||||||
if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
|
|
||||||
return ErrKnownBlock
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header validity is known at this point. Here we verify that uncles, transactions
|
// Header validity is known at this point. Here we verify that uncles, transactions
|
||||||
// and withdrawals given in the block body match the header.
|
// and withdrawals given in the block body match the header.
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
if err := v.bc.engine.VerifyUncles(v.bc, block); err != nil {
|
|
||||||
return err
|
// Chain-dependent checks: skip in stateless mode (no blockchain available).
|
||||||
|
if v.bc != nil {
|
||||||
|
// Check whether the block is already imported.
|
||||||
|
if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
|
||||||
|
return ErrKnownBlock
|
||||||
|
}
|
||||||
|
if err := v.bc.engine.VerifyUncles(v.bc, block); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash {
|
if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash {
|
||||||
return fmt.Errorf("uncle root hash mismatch (header value %x, calculated %x)", header.UncleHash, hash)
|
return fmt.Errorf("uncle root hash mismatch (header value %x, calculated %x)", header.UncleHash, hash)
|
||||||
|
|
@ -111,12 +114,14 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ancestor block must be known.
|
// Ancestor block must be known (skip in stateless mode).
|
||||||
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
|
if v.bc != nil {
|
||||||
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
|
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
|
||||||
return consensus.ErrUnknownAncestor
|
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
|
||||||
|
return consensus.ErrUnknownAncestor
|
||||||
|
}
|
||||||
|
return consensus.ErrPrunedAncestor
|
||||||
}
|
}
|
||||||
return consensus.ErrPrunedAncestor
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2260,7 +2260,7 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash,
|
||||||
task := types.NewBlockWithHeader(context).WithBody(*block.Body())
|
task := types.NewBlockWithHeader(context).WithBody(*block.Body())
|
||||||
|
|
||||||
// Run the stateless self-cross-validation
|
// Run the stateless self-cross-validation
|
||||||
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(ctx, bc.chainConfig, bc.cfg.VmConfig, task, witness)
|
crossStateRoot, crossReceiptRoot, err := ExecuteStateless(ctx, bc.chainConfig, bc.cfg.VmConfig, task, witness, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
|
return nil, fmt.Errorf("stateless self-validation failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/lru"
|
"github.com/ethereum/go-ethereum/common/lru"
|
||||||
|
|
@ -27,7 +28,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/stateless"
|
"github.com/ethereum/go-ethereum/core/stateless"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
|
@ -42,15 +42,7 @@ import (
|
||||||
// - It cannot be placed outside of core, because it needs to construct a dud headerchain
|
// - It cannot be placed outside of core, because it needs to construct a dud headerchain
|
||||||
//
|
//
|
||||||
// TODO(karalabe): Would be nice to resolve both issues above somehow and move it.
|
// TODO(karalabe): Would be nice to resolve both issues above somehow and move it.
|
||||||
func ExecuteStateless(ctx context.Context, config *params.ChainConfig, vmconfig vm.Config, block *types.Block, witness *stateless.Witness) (common.Hash, common.Hash, error) {
|
func ExecuteStateless(ctx context.Context, config *params.ChainConfig, vmconfig vm.Config, block *types.Block, witness *stateless.Witness, validateHeader bool) (common.Hash, common.Hash, error) {
|
||||||
// Sanity check if the supplied block accidentally contains a set root or
|
|
||||||
// receipt hash. If so, be very loud, but still continue.
|
|
||||||
if block.Root() != (common.Hash{}) {
|
|
||||||
log.Error("stateless runner received state root it's expected to calculate (faulty consensus client)", "block", block.Number())
|
|
||||||
}
|
|
||||||
if block.ReceiptHash() != (common.Hash{}) {
|
|
||||||
log.Error("stateless runner received receipt root it's expected to calculate (faulty consensus client)", "block", block.Number())
|
|
||||||
}
|
|
||||||
// Create and populate the state database to serve as the stateless backend
|
// Create and populate the state database to serve as the stateless backend
|
||||||
memdb := witness.MakeHashDB()
|
memdb := witness.MakeHashDB()
|
||||||
db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), state.NewCodeDB(memdb)))
|
db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), state.NewCodeDB(memdb)))
|
||||||
|
|
@ -67,12 +59,23 @@ func ExecuteStateless(ctx context.Context, config *params.ChainConfig, vmconfig
|
||||||
processor := NewStateProcessor(chain)
|
processor := NewStateProcessor(chain)
|
||||||
validator := NewBlockValidator(config, nil) // No chain, we only validate the state, not the block
|
validator := NewBlockValidator(config, nil) // No chain, we only validate the state, not the block
|
||||||
|
|
||||||
|
if validateHeader {
|
||||||
|
if err := beacon.New(ethash.NewFaker()).VerifyHeader(chain, block.Header()); err != nil {
|
||||||
|
return common.Hash{}, common.Hash{}, fmt.Errorf("error verifying header in stateless validation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
validator := NewBlockValidator(config, nil)
|
||||||
|
if err := validator.ValidateBody(block); err != nil {
|
||||||
|
return common.Hash{}, common.Hash{}, fmt.Errorf("error validating body in stateless validation: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run the stateless blocks processing and self-validate certain fields
|
// Run the stateless blocks processing and self-validate certain fields
|
||||||
res, err := processor.Process(ctx, block, db, vmconfig)
|
res, err := processor.Process(ctx, block, db, vmconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, common.Hash{}, err
|
return common.Hash{}, common.Hash{}, err
|
||||||
}
|
}
|
||||||
if err = validator.ValidateState(block, db, res, true); err != nil {
|
if err = validator.ValidateState(block, db, res, validateHeader); err != nil {
|
||||||
return common.Hash{}, common.Hash{}, err
|
return common.Hash{}, common.Hash{}, err
|
||||||
}
|
}
|
||||||
// Almost everything validated, but receipt and state root needs to be returned
|
// Almost everything validated, but receipt and state root needs to be returned
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ func (api *ConsensusAPI) executeStatelessPayload(params engine.ExecutableData, v
|
||||||
api.lastNewPayloadUpdate.Store(time.Now().Unix())
|
api.lastNewPayloadUpdate.Store(time.Now().Unix())
|
||||||
|
|
||||||
log.Trace("Executing block statelessly", "number", block.Number(), "hash", params.BlockHash)
|
log.Trace("Executing block statelessly", "number", block.Number(), "hash", params.BlockHash)
|
||||||
stateRoot, receiptRoot, err := core.ExecuteStateless(context.Background(), api.config(), vm.Config{}, block, witness)
|
stateRoot, receiptRoot, err := core.ExecuteStateless(context.Background(), api.config(), vm.Config{}, block, witness, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("ExecuteStatelessPayload: execution failed", "err", err)
|
log.Warn("ExecuteStatelessPayload: execution failed", "err", err)
|
||||||
errorMsg := err.Error()
|
errorMsg := err.Error()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue