use interface instead of concrete state type

This commit is contained in:
codchen 2023-10-20 13:03:53 +08:00
parent ff86dbf72a
commit 16a8208f36
33 changed files with 473 additions and 107 deletions

View file

@ -180,7 +180,7 @@ func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
} }
// stateByBlockNumber retrieves a state by a given blocknumber. // stateByBlockNumber retrieves a state by a given blocknumber.
func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) { func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (vm.StateDB, error) {
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number) == 0 { if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number) == 0 {
return b.blockchain.State() return b.blockchain.State()
} }
@ -640,7 +640,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
// callContract implements common code between normal and pending contract calls. // callContract implements common code between normal and pending contract calls.
// state is modified during execution, make sure to copy it if necessary. // state is modified during execution, make sure to copy it if necessary.
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, header *types.Header, stateDB *state.StateDB) (*core.ExecutionResult, error) { func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, header *types.Header, stateDB vm.StateDB) (*core.ExecutionResult, error) {
// Gas prices post 1559 need to be initialized // Gas prices post 1559 need to be initialized
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) { if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
@ -680,7 +680,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
} }
// Set infinite balance to the fake caller account. // Set infinite balance to the fake caller account.
from := stateDB.GetOrNewStateObject(call.From) from := stateDB.(*state.StateDB).GetOrNewStateObject(call.From)
from.SetBalance(math.MaxBig256) from.SetBalance(math.MaxBig256)
// Execute the call. // Execute the call.
@ -739,7 +739,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
return err return err
} }
b.pendingBlock = blocks[0] b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.(*state.StateDB).Database(), nil)
b.pendingReceipts = receipts[0] b.pendingReceipts = receipts[0]
return nil return nil
} }
@ -862,7 +862,7 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
return err return err
} }
b.pendingBlock = blocks[0] b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.(*state.StateDB).Database(), nil)
return nil return nil
} }

View file

@ -25,8 +25,8 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -347,7 +347,7 @@ func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.H
} }
// Finalize implements consensus.Engine and processes withdrawals on top. // Finalize implements consensus.Engine and processes withdrawals on top.
func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) { func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
if !beacon.IsPoSHeader(header) { if !beacon.IsPoSHeader(header) {
beacon.ethone.Finalize(chain, header, state, txs, uncles, nil) beacon.ethone.Finalize(chain, header, state, txs, uncles, nil)
return return
@ -364,7 +364,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
// FinalizeAndAssemble implements consensus.Engine, setting the final state and // FinalizeAndAssemble implements consensus.Engine, setting the final state and
// assembling the block. // assembling the block.
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) { func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
if !beacon.IsPoSHeader(header) { if !beacon.IsPoSHeader(header) {
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil) return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil)
} }

View file

@ -34,8 +34,8 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@ -580,13 +580,13 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
// Finalize implements consensus.Engine. There is no post-transaction // Finalize implements consensus.Engine. There is no post-transaction
// consensus rules in clique, do nothing here. // consensus rules in clique, do nothing here.
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) { func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
// No block rewards in PoA, so the state remains as is // No block rewards in PoA, so the state remains as is
} }
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block. // nor block rewards given, and returns the final block.
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) { func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
if len(withdrawals) > 0 { if len(withdrawals) > 0 {
return nil, errors.New("clique does not support withdrawals") return nil, errors.New("clique does not support withdrawals")
} }

View file

@ -21,8 +21,8 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
@ -88,7 +88,7 @@ type Engine interface {
// //
// Note: The state database might be updated to reflect any consensus rules // Note: The state database might be updated to reflect any consensus rules
// that happen at finalization (e.g. block rewards). // that happen at finalization (e.g. block rewards).
Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, Finalize(chain ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction,
uncles []*types.Header, withdrawals []*types.Withdrawal) uncles []*types.Header, withdrawals []*types.Withdrawal)
// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
@ -96,7 +96,7 @@ type Engine interface {
// //
// Note: The block header and state database might be updated to reflect any // Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards). // consensus rules that happen at finalization (e.g. block rewards).
FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error)
// Seal generates a new sealing request for the given input block and pushes // Seal generates a new sealing request for the given input block and pushes

View file

@ -28,8 +28,8 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -500,14 +500,14 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
} }
// Finalize implements consensus.Engine, accumulating the block and uncle rewards. // Finalize implements consensus.Engine, accumulating the block and uncle rewards.
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) { func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
// Accumulate any block and uncle rewards // Accumulate any block and uncle rewards
accumulateRewards(chain.Config(), state, header, uncles) accumulateRewards(chain.Config(), state, header, uncles)
} }
// FinalizeAndAssemble implements consensus.Engine, accumulating the block and // FinalizeAndAssemble implements consensus.Engine, accumulating the block and
// uncle rewards, setting the final state and assembling the block. // uncle rewards, setting the final state and assembling the block.
func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) { func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
if len(withdrawals) > 0 { if len(withdrawals) > 0 {
return nil, errors.New("ethash does not support withdrawals") return nil, errors.New("ethash does not support withdrawals")
} }
@ -569,7 +569,7 @@ var (
// AccumulateRewards credits the coinbase of the given block with the mining // AccumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for // reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded. // included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { func accumulateRewards(config *params.ChainConfig, state vm.StateDB, header *types.Header, uncles []*types.Header) {
// Select the correct block reward based on chain progression // Select the correct block reward based on chain progression
blockReward := FrontierBlockReward blockReward := FrontierBlockReward
if config.IsByzantium(header.Number) { if config.IsByzantium(header.Number) {

View file

@ -21,8 +21,8 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
) )
@ -72,7 +72,7 @@ func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header)
// ApplyDAOHardFork modifies the state database according to the DAO hard-fork // ApplyDAOHardFork modifies the state database according to the DAO hard-fork
// rules, transferring all balances of a set of DAO accounts to a single refund // rules, transferring all balances of a set of DAO accounts to a single refund
// contract. // contract.
func ApplyDAOHardFork(statedb *state.StateDB) { func ApplyDAOHardFork(statedb vm.StateDB) {
// Retrieve the contract to refund balances into // Retrieve the contract to refund balances into
if !statedb.Exist(params.DAORefundContract) { if !statedb.Exist(params.DAORefundContract) {
statedb.CreateAccount(params.DAORefundContract) statedb.CreateAccount(params.DAORefundContract)

View file

@ -1385,7 +1385,7 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error {
// writeBlockWithState writes block, metadata and corresponding state data to the // writeBlockWithState writes block, metadata and corresponding state data to the
// database. // database.
func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) error { func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state vm.StateDB) error {
// Calculate the total difficulty of the block // Calculate the total difficulty of the block
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
if ptd == nil { if ptd == nil {
@ -1473,7 +1473,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
// WriteBlockAndSetHead writes the given block and all associated state to the database, // WriteBlockAndSetHead writes the given block and all associated state to the database,
// and applies the block as the new chain head. // and applies the block as the new chain head.
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state vm.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
if !bc.chainmu.TryLock() { if !bc.chainmu.TryLock() {
return NonStatTy, errChainStopped return NonStatTy, errChainStopped
} }
@ -1484,7 +1484,7 @@ func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead. // writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
// This function expects the chain mutex to be held. // This function expects the chain mutex to be held.
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state vm.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
if err := bc.writeBlockWithState(block, receipts, state); err != nil { if err := bc.writeBlockWithState(block, receipts, state); err != nil {
return NonStatTy, err return NonStatTy, err
} }

View file

@ -320,12 +320,12 @@ func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
} }
// State returns a new mutable state based on the current HEAD block. // State returns a new mutable state based on the current HEAD block.
func (bc *BlockChain) State() (*state.StateDB, error) { func (bc *BlockChain) State() (vm.StateDB, error) {
return bc.StateAt(bc.CurrentBlock().Root) return bc.StateAt(bc.CurrentBlock().Root)
} }
// StateAt returns a new mutable state based on a particular point in time. // StateAt returns a new mutable state based on a particular point in time.
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { func (bc *BlockChain) StateAt(root common.Hash) (vm.StateDB, error) {
return state.New(root, bc.stateCache, bc.snaps) return state.New(root, bc.stateCache, bc.snaps)
} }

View file

@ -24,7 +24,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -57,7 +56,7 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
// Process returns the receipts and logs accumulated during the process and // Process returns the receipts and logs accumulated during the process and
// returns the amount of gas that was used in the process. If any of the // returns the amount of gas that was used in the process. If any of the
// transactions failed to execute due to insufficient gas it will return an error. // transactions failed to execute due to insufficient gas it will return an error.
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { func (p *StateProcessor) Process(block *types.Block, statedb vm.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
var ( var (
receipts types.Receipts receipts types.Receipts
usedGas = new(uint64) usedGas = new(uint64)
@ -104,7 +103,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return receipts, allLogs, *usedGas, nil return receipts, allLogs, *usedGas, nil
} }
func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) { func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
// Create a new context to be used in the EVM environment. // Create a new context to be used in the EVM environment.
txContext := NewEVMTxContext(msg) txContext := NewEVMTxContext(msg)
evm.Reset(txContext, statedb) evm.Reset(txContext, statedb)
@ -158,7 +157,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
// and uses the input parameters for its environment. It returns the receipt // and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed, // for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid. // indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb vm.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee) msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee)
if err != nil { if err != nil {
return nil, err return nil, err
@ -172,7 +171,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root // ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
// contract. This method is exported to be used in tests. // contract. This method is exported to be used in tests.
func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *state.StateDB) { func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb vm.StateDB) {
// If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with // If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with
// the new root // the new root
msg := &Message{ msg := &Message{

View file

@ -33,9 +33,9 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
@ -302,9 +302,9 @@ type BlobPool struct {
signer types.Signer // Transaction signer to use for sender recovery signer types.Signer // Transaction signer to use for sender recovery
chain BlockChain // Chain object to access the state through chain BlockChain // Chain object to access the state through
head *types.Header // Current head of the chain head *types.Header // Current head of the chain
state *state.StateDB // Current state at the head of the chain state vm.StateDB // Current state at the head of the chain
gasTip *uint256.Int // Currently accepted minimum gas tip gasTip *uint256.Int // Currently accepted minimum gas tip
lookup map[common.Hash]uint64 // Lookup table mapping hashes to tx billy entries lookup map[common.Hash]uint64 // Lookup table mapping hashes to tx billy entries
index map[common.Address][]*blobTxMeta // Blob transactions grouped by accounts, sorted by nonce index map[common.Address][]*blobTxMeta // Blob transactions grouped by accounts, sorted by nonce

View file

@ -37,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/ethdb/memorydb"
@ -84,7 +85,7 @@ type testBlockChain struct {
config *params.ChainConfig config *params.ChainConfig
basefee *uint256.Int basefee *uint256.Int
blobfee *uint256.Int blobfee *uint256.Int
statedb *state.StateDB statedb vm.StateDB
} }
func (bc *testBlockChain) Config() *params.ChainConfig { func (bc *testBlockChain) Config() *params.ChainConfig {
@ -158,7 +159,7 @@ func (bt *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return nil return nil
} }
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { func (bc *testBlockChain) StateAt(common.Hash) (vm.StateDB, error) {
return bc.statedb, nil return bc.statedb, nil
} }

View file

@ -18,8 +18,8 @@ package blobpool
import ( import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
) )
@ -40,5 +40,5 @@ type BlockChain interface {
GetBlock(hash common.Hash, number uint64) *types.Block GetBlock(hash common.Hash, number uint64) *types.Block
// StateAt returns a state database for a given root hash (generally the head). // StateAt returns a state database for a given root hash (generally the head).
StateAt(root common.Hash) (*state.StateDB, error) StateAt(root common.Hash) (vm.StateDB, error)
} }

View file

@ -30,9 +30,9 @@ import (
"github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
@ -115,7 +115,7 @@ type BlockChain interface {
GetBlock(hash common.Hash, number uint64) *types.Block GetBlock(hash common.Hash, number uint64) *types.Block
// StateAt returns a state database for a given root hash (generally the head). // StateAt returns a state database for a given root hash (generally the head).
StateAt(root common.Hash) (*state.StateDB, error) StateAt(root common.Hash) (vm.StateDB, error)
} }
// Config are the configuration parameters of the transaction pool. // Config are the configuration parameters of the transaction pool.
@ -208,7 +208,7 @@ type LegacyPool struct {
mu sync.RWMutex mu sync.RWMutex
currentHead atomic.Pointer[types.Header] // Current head of the blockchain currentHead atomic.Pointer[types.Header] // Current head of the blockchain
currentState *state.StateDB // Current state in the blockchain head currentState vm.StateDB // Current state in the blockchain head
pendingNonces *noncer // Pending state tracking virtual nonces pendingNonces *noncer // Pending state tracking virtual nonces
locals *accountSet // Set of local transaction to exempt from eviction rules locals *accountSet // Set of local transaction to exempt from eviction rules

View file

@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -63,7 +64,7 @@ func init() {
type testBlockChain struct { type testBlockChain struct {
config *params.ChainConfig config *params.ChainConfig
gasLimit atomic.Uint64 gasLimit atomic.Uint64
statedb *state.StateDB statedb vm.StateDB
chainHeadFeed *event.Feed chainHeadFeed *event.Feed
} }
@ -88,7 +89,7 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil))
} }
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { func (bc *testBlockChain) StateAt(common.Hash) (vm.StateDB, error) {
return bc.statedb, nil return bc.statedb, nil
} }
@ -246,7 +247,7 @@ type testChain struct {
// testChain.State() is used multiple times to reset the pending state. // testChain.State() is used multiple times to reset the pending state.
// when simulate is true it will create a state that indicates // when simulate is true it will create a state that indicates
// that tx0 and tx1 are included in the chain. // that tx0 and tx1 are included in the chain.
func (c *testChain) State() (*state.StateDB, error) { func (c *testChain) State() (vm.StateDB, error) {
// delay "state change" by one. The tx pool fetches the // delay "state change" by one. The tx pool fetches the
// state multiple times and by delaying it a bit we simulate // state multiple times and by delaying it a bit we simulate
// a state change between those fetches. // a state change between those fetches.

View file

@ -20,20 +20,20 @@ import (
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm"
) )
// noncer is a tiny virtual state database to manage the executable nonces of // noncer is a tiny virtual state database to manage the executable nonces of
// accounts in the pool, falling back to reading from a real state database if // accounts in the pool, falling back to reading from a real state database if
// an account is unknown. // an account is unknown.
type noncer struct { type noncer struct {
fallback *state.StateDB fallback vm.StateDB
nonces map[common.Address]uint64 nonces map[common.Address]uint64
lock sync.Mutex lock sync.Mutex
} }
// newNoncer creates a new virtual state database to track the pool nonces. // newNoncer creates a new virtual state database to track the pool nonces.
func newNoncer(statedb *state.StateDB) *noncer { func newNoncer(statedb vm.StateDB) *noncer {
return &noncer{ return &noncer{
fallback: statedb.Copy(), fallback: statedb.Copy(),
nonces: make(map[common.Address]uint64), nonces: make(map[common.Address]uint64),

View file

@ -23,8 +23,8 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -169,7 +169,7 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
// ValidationOptionsWithState define certain differences between stateful transaction // ValidationOptionsWithState define certain differences between stateful transaction
// validation across the different pools without having to duplicate those checks. // validation across the different pools without having to duplicate those checks.
type ValidationOptionsWithState struct { type ValidationOptionsWithState struct {
State *state.StateDB // State database to check nonces and balances against State vm.StateDB // State database to check nonces and balances against
// FirstNonceGap is an optional callback to retrieve the first nonce gap in // FirstNonceGap is an optional callback to retrieve the first nonce gap in
// the list of pooled transactions of a specific account. If this method is // the list of pooled transactions of a specific account. If this method is

View file

@ -49,5 +49,5 @@ type Processor interface {
// Process processes the state changes according to the Ethereum rules by running // Process processes the state changes according to the Ethereum rules by running
// the transaction messages using the statedb and applying any rewards to both // the transaction messages using the statedb and applying any rewards to both
// the processor (coinbase) and any included uncles. // the processor (coinbase) and any included uncles.
Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) Process(block *types.Block, statedb vm.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error)
} }

View file

@ -20,6 +20,7 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
@ -78,6 +79,20 @@ type StateDB interface {
AddLog(*types.Log) AddLog(*types.Log)
AddPreimage(common.Hash, []byte) AddPreimage(common.Hash, []byte)
// new methods
Error() error
GetStorageRoot(common.Address) common.Hash
SetBalance(common.Address, *big.Int)
SetStorage(common.Address, map[common.Hash]common.Hash)
Finalise(deleteEmptyObjects bool)
Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error)
SetTxContext(thash common.Hash, ti int)
Copy() *state.StateDB
IntermediateRoot(deleteEmptyObjects bool) common.Hash
GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log
TxIndex() int
Preimages() map[common.Hash][]byte
} }
// CallContext provides a basic interface for the EVM calling conventions. The EVM // CallContext provides a basic interface for the EVM calling conventions. The EVM

View file

@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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"
@ -186,7 +185,7 @@ func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts)
return b.eth.miner.PendingBlockAndReceipts() return b.eth.miner.PendingBlockAndReceipts()
} }
func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error) {
// Pending state is only known by the miner // Pending state is only known by the miner
if number == rpc.PendingBlockNumber { if number == rpc.PendingBlockNumber {
block, state := b.eth.miner.Pending() block, state := b.eth.miner.Pending()
@ -210,7 +209,7 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.B
return stateDb, header, nil return stateDb, header, nil
} }
func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok { if blockNr, ok := blockNrOrHash.Number(); ok {
return b.StateAndHeaderByNumber(ctx, blockNr) return b.StateAndHeaderByNumber(ctx, blockNr)
} }
@ -249,7 +248,7 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
return nil return nil
} }
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM { func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state vm.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM {
if vmConfig == nil { if vmConfig == nil {
vmConfig = b.eth.blockchain.GetVMConfig() vmConfig = b.eth.blockchain.GetVMConfig()
} }
@ -408,10 +407,10 @@ func (b *EthAPIBackend) StartMining() error {
return b.eth.StartMining() return b.eth.StartMining()
} }
func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, tracers.StateReleaseFunc, error) { func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (vm.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtBlock(ctx, block, reexec, base, readOnly, preferDisk) return b.eth.stateAtBlock(ctx, block, reexec, base, readOnly, preferDisk)
} }
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, vm.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
} }

View file

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@ -60,7 +61,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if stateDb == nil { if stateDb == nil {
return state.Dump{}, errors.New("pending state is not available") return state.Dump{}, errors.New("pending state is not available")
} }
return stateDb.RawDump(opts), nil return stateDb.(*state.StateDB).RawDump(opts), nil
} }
var header *types.Header var header *types.Header
switch blockNr { switch blockNr {
@ -84,7 +85,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if err != nil { if err != nil {
return state.Dump{}, err return state.Dump{}, err
} }
return stateDb.RawDump(opts), nil return stateDb.(*state.StateDB).RawDump(opts), nil
} }
// Preimage is a debug API function that returns the preimage for a sha3 hash, if known. // Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
@ -134,7 +135,7 @@ const AccountRangeMaxResults = 256
// AccountRange enumerates all accounts in the given block and start point in paging request // AccountRange enumerates all accounts in the given block and start point in paging request
func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hexutil.Bytes, maxResults int, nocode, nostorage, incompletes bool) (state.Dump, error) { func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hexutil.Bytes, maxResults int, nocode, nostorage, incompletes bool) (state.Dump, error) {
var stateDb *state.StateDB var stateDb vm.StateDB
var err error var err error
if number, ok := blockNrOrHash.Number(); ok { if number, ok := blockNrOrHash.Number(); ok {
@ -229,13 +230,13 @@ func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockNrOrHash rpc.Block
return storageRangeAt(statedb, block.Root(), contractAddress, keyStart, maxResult) return storageRangeAt(statedb, block.Root(), contractAddress, keyStart, maxResult)
} }
func storageRangeAt(statedb *state.StateDB, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) { func storageRangeAt(statedb vm.StateDB, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) {
storageRoot := statedb.GetStorageRoot(address) storageRoot := statedb.GetStorageRoot(address)
if storageRoot == types.EmptyRootHash || storageRoot == (common.Hash{}) { if storageRoot == types.EmptyRootHash || storageRoot == (common.Hash{}) {
return StorageRangeResult{}, nil // empty storage return StorageRangeResult{}, nil // empty storage
} }
id := trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), storageRoot) id := trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
tr, err := trie.NewStateTrie(id, statedb.Database().TrieDB()) tr, err := trie.NewStateTrie(id, statedb.(*state.StateDB).Database().TrieDB())
if err != nil { if err != nil {
return StorageRangeResult{}, err return StorageRangeResult{}, err
} }

View file

@ -37,7 +37,7 @@ import (
// for releasing state. // for releasing state.
var noopReleaser = tracers.StateReleaseFunc(func() {}) var noopReleaser = tracers.StateReleaseFunc(func() {})
func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (statedb vm.StateDB, release tracers.StateReleaseFunc, err error) {
var ( var (
current *types.Block current *types.Block
database state.Database database state.Database
@ -74,7 +74,7 @@ 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 // The optional base statedb is given, mark the start point as parent block
statedb, database, triedb, report = base, base.Database(), base.Database().TrieDB(), false statedb, database, triedb, report = base, base.(*state.StateDB).Database(), base.(*state.StateDB).Database().TrieDB(), false
current = eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) current = eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
} else { } else {
// Otherwise, try to reexec blocks until we find a state or reach our limit // Otherwise, try to reexec blocks until we find a state or reach our limit
@ -174,7 +174,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
return statedb, func() { triedb.Dereference(block.Root()) }, nil return statedb, func() { triedb.Dereference(block.Root()) }, nil
} }
func (eth *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) { func (eth *Ethereum) pathState(block *types.Block) (vm.StateDB, func(), error) {
// Check if the requested state is available in the live chain. // Check if the requested state is available in the live chain.
statedb, err := eth.blockchain.StateAt(block.Root()) statedb, err := eth.blockchain.StateAt(block.Root())
if err == nil { if err == nil {
@ -208,7 +208,7 @@ func (eth *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), erro
// - preferDisk: This arg can be used by the caller to signal that even though the 'base' is // - preferDisk: This arg can be used by the caller to signal that even though the 'base' is
// provided, it would be preferable to start from a fresh state, if we have it // provided, it would be preferable to start from a fresh state, if we have it
// on disk. // on disk.
func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (statedb vm.StateDB, release tracers.StateReleaseFunc, err error) {
if eth.blockchain.TrieDB().Scheme() == rawdb.HashScheme { if eth.blockchain.TrieDB().Scheme() == rawdb.HashScheme {
return eth.hashState(ctx, block, reexec, base, readOnly, preferDisk) return eth.hashState(ctx, block, reexec, base, readOnly, preferDisk)
} }
@ -216,7 +216,7 @@ func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexe
} }
// stateAtTransaction returns the execution environment of a certain transaction. // stateAtTransaction returns the execution environment of a certain transaction.
func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, vm.StateDB, tracers.StateReleaseFunc, error) {
// Short circuit if it's genesis block. // Short circuit if it's genesis block.
if block.NumberU64() == 0 { if block.NumberU64() == 0 {
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis") return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")

View file

@ -85,8 +85,8 @@ type Backend interface {
ChainConfig() *params.ChainConfig ChainConfig() *params.ChainConfig
Engine() consensus.Engine Engine() consensus.Engine
ChainDb() ethdb.Database ChainDb() ethdb.Database
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (vm.StateDB, StateReleaseFunc, error)
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, vm.StateDB, StateReleaseFunc, error)
} }
// API is the collection of tracing APIs exposed over the private debugging endpoint. // API is the collection of tracing APIs exposed over the private debugging endpoint.
@ -309,7 +309,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
number uint64 number uint64
traced uint64 traced uint64
failed error failed error
statedb *state.StateDB statedb vm.StateDB
release StateReleaseFunc release StateReleaseFunc
) )
// Ensure everything is properly cleaned up on any exit path // Ensure everything is properly cleaned up on any exit path
@ -369,7 +369,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
// if the relevant state is available in disk. // if the relevant state is available in disk.
var preferDisk bool var preferDisk bool
if statedb != nil { if statedb != nil {
s1, s2, s3 := statedb.Database().TrieDB().Size() s1, s2, s3 := statedb.(*state.StateDB).Database().TrieDB().Size()
preferDisk = s1+s2+s3 > defaultTracechainMemLimit preferDisk = s1+s2+s3 > defaultTracechainMemLimit
} }
statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk) statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk)
@ -627,7 +627,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
// traceBlockParallel is for tracers that have a high overhead (read JS tracers). One thread // traceBlockParallel is for tracers that have a high overhead (read JS tracers). One thread
// runs along and executes txes without tracing enabled to generate their prestate. // runs along and executes txes without tracing enabled to generate their prestate.
// Worker threads take the tasks and the prestate and trace them. // Worker threads take the tasks and the prestate and trace them.
func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, statedb *state.StateDB, config *TraceConfig) ([]*txTraceResult, error) { func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, statedb vm.StateDB, config *TraceConfig) ([]*txTraceResult, error) {
// Execute all the transaction contained within the block concurrently // Execute all the transaction contained within the block concurrently
var ( var (
txs = block.Transactions() txs = block.Transactions()
@ -934,7 +934,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
// traceTx configures a new tracer according to the provided configuration, and // traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will // executes the given message in the provided environment. The return value will
// be tracer dependent. // be tracer dependent.
func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) { func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb vm.StateDB, config *TraceConfig) (interface{}, error) {
var ( var (
tracer Tracer tracer Tracer
err error err error

View file

@ -34,7 +34,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -139,7 +138,7 @@ func (b *testBackend) teardown() {
b.chain.Stop() b.chain.Stop()
} }
func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) { func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (vm.StateDB, StateReleaseFunc, error) {
statedb, err := b.chain.StateAt(block.Root()) statedb, err := b.chain.StateAt(block.Root())
if err != nil { if err != nil {
return nil, nil, errStateNotFound return nil, nil, errStateNotFound
@ -155,7 +154,7 @@ func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reex
return statedb, release, nil return statedb, release, nil
} }
func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) { func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, vm.StateDB, StateReleaseFunc, error) {
parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1) parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil { if parent == nil {
return nil, vm.BlockContext{}, nil, nil, errBlockNotFound return nil, vm.BlockContext{}, nil, nil, errBlockNotFound

View file

@ -32,8 +32,8 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core/state"
"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/eth/filters" "github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@ -86,7 +86,7 @@ type Account struct {
} }
// getState fetches the StateDB object for an account. // getState fetches the StateDB object for an account.
func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { func (a *Account) getState(ctx context.Context) (vm.StateDB, error) {
state, _, err := a.r.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash) state, _, err := a.r.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
return state, err return state, err
} }

View file

@ -950,7 +950,7 @@ type OverrideAccount struct {
type StateOverride map[common.Address]OverrideAccount type StateOverride map[common.Address]OverrideAccount
// Apply overrides the fields of specified accounts into the given state. // Apply overrides the fields of specified accounts into the given state.
func (diff *StateOverride) Apply(state *state.StateDB) error { func (diff *StateOverride) Apply(state vm.StateDB) error {
if diff == nil { if diff == nil {
return nil return nil
} }
@ -1063,7 +1063,7 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H
return header return header
} }
func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { func doCall(ctx context.Context, b Backend, args TransactionArgs, state vm.StateDB, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
if err := overrides.Apply(state); err != nil { if err := overrides.Apply(state); err != nil {
return nil, err return nil, err
} }
@ -1178,6 +1178,24 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO
return result.Return(), result.Err return result.Return(), result.Err
} }
<<<<<<< HEAD
=======
// executeEstimate is a helper that executes the transaction under a given gas limit and returns
// true if the transaction fails for a reason that might be related to not enough gas. A non-nil
// error means execution failed due to reasons unrelated to the gas limit.
func executeEstimate(ctx context.Context, b Backend, args TransactionArgs, state vm.StateDB, header *types.Header, gasCap uint64, gasLimit uint64) (bool, *core.ExecutionResult, error) {
args.Gas = (*hexutil.Uint64)(&gasLimit)
result, err := doCall(ctx, b, args, state, header, nil, nil, 0, gasCap)
if err != nil {
if errors.Is(err, core.ErrIntrinsicGas) {
return true, nil, nil // Special case, raise gas limit
}
return true, nil, err // Bail out
}
return result.Failed(), result, nil
}
>>>>>>> 6c86d947d (use interface instead of concrete state type)
// DoEstimateGas returns the lowest possible gas limit that allows the transaction to run // DoEstimateGas returns the lowest possible gas limit that allows the transaction to run
// successfully at block `blockNrOrHash`. It returns error if the transaction would revert, or if // successfully at block `blockNrOrHash`. It returns error if the transaction would revert, or if
// there are unexpected failures. The gas limit is capped by both `args.Gas` (if non-nil & // there are unexpected failures. The gas limit is capped by both `args.Gas` (if non-nil &

View file

@ -39,7 +39,6 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -501,7 +500,7 @@ func (b testBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.
func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) { func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil
} }
func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error) {
if number == rpc.PendingBlockNumber { if number == rpc.PendingBlockNumber {
panic("pending state not implemented") panic("pending state not implemented")
} }
@ -515,7 +514,7 @@ func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.Bloc
stateDb, err := b.chain.StateAt(header.Root) stateDb, err := b.chain.StateAt(header.Root)
return stateDb, header, err return stateDb, header, err
} }
func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok { if blockNr, ok := blockNrOrHash.Number(); ok {
return b.StateAndHeaderByNumber(ctx, blockNr) return b.StateAndHeaderByNumber(ctx, blockNr)
} }
@ -536,7 +535,8 @@ func (b testBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
} }
return big.NewInt(1) return big.NewInt(1)
} }
func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM { func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state vm.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM {
vmError := func() error { return nil }
if vmConfig == nil { if vmConfig == nil {
vmConfig = b.chain.GetVMConfig() vmConfig = b.chain.GetVMConfig()
} }

View file

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state"
"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/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -63,12 +62,12 @@ type Backend interface {
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error)
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error)
PendingBlockAndReceipts() (*types.Block, types.Receipts) PendingBlockAndReceipts() (*types.Block, types.Receipts)
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
GetTd(ctx context.Context, hash common.Hash) *big.Int GetTd(ctx context.Context, hash common.Hash) *big.Int
GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM GetEVM(ctx context.Context, msg *core.Message, state vm.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription

View file

@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state"
"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/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -291,10 +290,10 @@ func (b *backendMock) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc
func (b *backendMock) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) { func (b *backendMock) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
return nil, nil return nil, nil
} }
func (b *backendMock) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { func (b *backendMock) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error) {
return nil, nil, nil return nil, nil, nil
} }
func (b *backendMock) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { func (b *backendMock) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error) {
return nil, nil, nil return nil, nil, nil
} }
func (b *backendMock) PendingBlockAndReceipts() (*types.Block, types.Receipts) { return nil, nil } func (b *backendMock) PendingBlockAndReceipts() (*types.Block, types.Receipts) { return nil, nil }
@ -305,8 +304,8 @@ func (b *backendMock) GetLogs(ctx context.Context, blockHash common.Hash, number
return nil, nil return nil, nil
} }
func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int { return nil } func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int { return nil }
func (b *backendMock) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM { func (b *backendMock) GetEVM(ctx context.Context, msg *core.Message, state vm.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM {
return nil return nil, nil
} }
func (b *backendMock) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return nil } func (b *backendMock) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return nil }
func (b *backendMock) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { func (b *backendMock) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {

336
les/api_backend.go Normal file
View file

@ -0,0 +1,336 @@
// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package les
import (
"context"
"errors"
"math/big"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
type LesApiBackend struct {
extRPCEnabled bool
allowUnprotectedTxs bool
eth *LightEthereum
gpo *gasprice.Oracle
}
func (b *LesApiBackend) ChainConfig() *params.ChainConfig {
return b.eth.chainConfig
}
func (b *LesApiBackend) CurrentBlock() *types.Header {
return b.eth.BlockChain().CurrentHeader()
}
func (b *LesApiBackend) SetHead(number uint64) {
b.eth.blockchain.SetHead(number)
}
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
// Return the latest current as the pending one since there
// is no pending notion in the light client. TODO(rjl493456442)
// unify the behavior of `HeaderByNumber` and `PendingBlockAndReceipts`.
if number == rpc.PendingBlockNumber {
return b.eth.blockchain.CurrentHeader(), nil
}
if number == rpc.LatestBlockNumber {
return b.eth.blockchain.CurrentHeader(), nil
}
return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(number))
}
func (b *LesApiBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok {
return b.HeaderByNumber(ctx, blockNr)
}
if hash, ok := blockNrOrHash.Hash(); ok {
header, err := b.HeaderByHash(ctx, hash)
if err != nil {
return nil, err
}
if header == nil {
return nil, errors.New("header for hash not found")
}
if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
return nil, errors.New("hash is not currently canonical")
}
return header, nil
}
return nil, errors.New("invalid arguments; neither block nor hash specified")
}
func (b *LesApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
return b.eth.blockchain.GetHeaderByHash(hash), nil
}
func (b *LesApiBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
header, err := b.HeaderByNumber(ctx, number)
if header == nil || err != nil {
return nil, err
}
return b.BlockByHash(ctx, header.Hash())
}
func (b *LesApiBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
return b.eth.blockchain.GetBlockByHash(ctx, hash)
}
func (b *LesApiBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) {
if blockNr, ok := blockNrOrHash.Number(); ok {
return b.BlockByNumber(ctx, blockNr)
}
if hash, ok := blockNrOrHash.Hash(); ok {
block, err := b.BlockByHash(ctx, hash)
if err != nil {
return nil, err
}
if block == nil {
return nil, errors.New("header found, but block body is missing")
}
if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(block.NumberU64()) != hash {
return nil, errors.New("hash is not currently canonical")
}
return block, nil
}
return nil, errors.New("invalid arguments; neither block nor hash specified")
}
func (b *LesApiBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
return light.GetBody(ctx, b.eth.odr, hash, uint64(number))
}
func (b *LesApiBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
return nil, nil
}
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error) {
header, err := b.HeaderByNumber(ctx, number)
if err != nil {
return nil, nil, err
}
if header == nil {
return nil, nil, errors.New("header not found")
}
return light.NewState(ctx, header, b.eth.odr), header, nil
}
func (b *LesApiBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok {
return b.StateAndHeaderByNumber(ctx, blockNr)
}
if hash, ok := blockNrOrHash.Hash(); ok {
header := b.eth.blockchain.GetHeaderByHash(hash)
if header == nil {
return nil, nil, errors.New("header for hash not found")
}
if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
return nil, nil, errors.New("hash is not currently canonical")
}
return light.NewState(ctx, header, b.eth.odr), header, nil
}
return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
}
func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number)
}
return nil, nil
}
func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
return light.GetBlockLogs(ctx, b.eth.odr, hash, number)
}
func (b *LesApiBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
return b.eth.blockchain.GetTdOdr(ctx, hash, *number)
}
return nil
}
func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state vm.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
if vmConfig == nil {
vmConfig = new(vm.Config)
}
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(header, b.eth.blockchain, nil)
if blockCtx != nil {
context = *blockCtx
}
return vm.NewEVM(context, txContext, state, b.eth.chainConfig, *vmConfig), state.Error
}
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
return b.eth.txPool.Add(ctx, signedTx)
}
func (b *LesApiBackend) RemoveTx(txHash common.Hash) {
b.eth.txPool.RemoveTx(txHash)
}
func (b *LesApiBackend) GetPoolTransactions() (types.Transactions, error) {
return b.eth.txPool.GetTransactions()
}
func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction {
return b.eth.txPool.GetTransaction(txHash)
}
func (b *LesApiBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
return light.GetTransaction(ctx, b.eth.odr, txHash)
}
func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.GetNonce(ctx, addr)
}
func (b *LesApiBackend) Stats() (pending int, queued int) {
return b.eth.txPool.Stats(), 0
}
func (b *LesApiBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
return b.eth.txPool.Content()
}
func (b *LesApiBackend) TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
return b.eth.txPool.ContentFrom(addr)
}
func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
return b.eth.txPool.SubscribeNewTxsEvent(ch)
}
func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
return b.eth.blockchain.SubscribeChainEvent(ch)
}
func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
return b.eth.blockchain.SubscribeChainHeadEvent(ch)
}
func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
return b.eth.blockchain.SubscribeChainSideEvent(ch)
}
func (b *LesApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
return b.eth.blockchain.SubscribeLogsEvent(ch)
}
func (b *LesApiBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
return event.NewSubscription(func(quit <-chan struct{}) error {
<-quit
return nil
})
}
func (b *LesApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
return b.eth.blockchain.SubscribeRemovedLogsEvent(ch)
}
func (b *LesApiBackend) SyncProgress() ethereum.SyncProgress {
return ethereum.SyncProgress{}
}
func (b *LesApiBackend) ProtocolVersion() int {
return b.eth.LesVersion() + 10000
}
func (b *LesApiBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
return b.gpo.SuggestTipCap(ctx)
}
func (b *LesApiBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
}
func (b *LesApiBackend) ChainDb() ethdb.Database {
return b.eth.chainDb
}
func (b *LesApiBackend) AccountManager() *accounts.Manager {
return b.eth.accountManager
}
func (b *LesApiBackend) ExtRPCEnabled() bool {
return b.extRPCEnabled
}
func (b *LesApiBackend) UnprotectedAllowed() bool {
return b.allowUnprotectedTxs
}
func (b *LesApiBackend) RPCGasCap() uint64 {
return b.eth.config.RPCGasCap
}
func (b *LesApiBackend) RPCEVMTimeout() time.Duration {
return b.eth.config.RPCEVMTimeout
}
func (b *LesApiBackend) RPCTxFeeCap() float64 {
return b.eth.config.RPCTxFeeCap
}
func (b *LesApiBackend) BloomStatus() (uint64, uint64) {
if b.eth.bloomIndexer == nil {
return 0, 0
}
sections, _, _ := b.eth.bloomIndexer.Sections()
return params.BloomBitsBlocksClient, sections
}
func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
for i := 0; i < bloomFilterThreads; i++ {
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
}
}
func (b *LesApiBackend) Engine() consensus.Engine {
return b.eth.engine
}
func (b *LesApiBackend) CurrentHeader() *types.Header {
return b.eth.blockchain.CurrentHeader()
}
func (b *LesApiBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base vm.StateDB, readOnly bool, preferDisk bool) (vm.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtBlock(ctx, block, reexec)
}
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, vm.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
}

View file

@ -27,9 +27,9 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"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/eth/downloader" "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@ -204,7 +204,7 @@ func (miner *Miner) SetRecommitInterval(interval time.Duration) {
// Pending returns the currently pending block and associated state. The returned // Pending returns the currently pending block and associated state. The returned
// values can be nil in case the pending block is not initialized // values can be nil in case the pending block is not initialized
func (miner *Miner) Pending() (*types.Block, *state.StateDB) { func (miner *Miner) Pending() (*types.Block, vm.StateDB) {
return miner.worker.pending() return miner.worker.pending()
} }

View file

@ -66,7 +66,7 @@ func (m *mockBackend) StateAtBlock(block *types.Block, reexec uint64, base *stat
type testBlockChain struct { type testBlockChain struct {
root common.Hash root common.Hash
config *params.ChainConfig config *params.ChainConfig
statedb *state.StateDB statedb vm.StateDB
gasLimit uint64 gasLimit uint64
chainHeadFeed *event.Feed chainHeadFeed *event.Feed
} }
@ -86,7 +86,7 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil))
} }
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { func (bc *testBlockChain) StateAt(common.Hash) (vm.StateDB, error) {
return bc.statedb, nil return bc.statedb, nil
} }

View file

@ -83,9 +83,9 @@ var (
// information of the sealing block generation. // information of the sealing block generation.
type environment struct { type environment struct {
signer types.Signer signer types.Signer
state *state.StateDB // apply state changes here state vm.StateDB // apply state changes here
tcount int // tx count in cycle tcount int // tx count in cycle
gasPool *core.GasPool // available gas used to pack transactions gasPool *core.GasPool // available gas used to pack transactions
coinbase common.Address coinbase common.Address
header *types.Header header *types.Header
@ -125,13 +125,13 @@ func (env *environment) discard() {
if env.state == nil { if env.state == nil {
return return
} }
env.state.StopPrefetcher() env.state.(*state.StateDB).StopPrefetcher()
} }
// task contains all information for consensus engine sealing and result submitting. // task contains all information for consensus engine sealing and result submitting.
type task struct { type task struct {
receipts []*types.Receipt receipts []*types.Receipt
state *state.StateDB state vm.StateDB
block *types.Block block *types.Block
createdAt time.Time createdAt time.Time
} }
@ -337,7 +337,7 @@ func (w *worker) setRecommitInterval(interval time.Duration) {
// pending returns the pending state and corresponding block. The returned // pending returns the pending state and corresponding block. The returned
// values can be nil in case the pending block is not initialized. // values can be nil in case the pending block is not initialized.
func (w *worker) pending() (*types.Block, *state.StateDB) { func (w *worker) pending() (*types.Block, vm.StateDB) {
w.snapshotMu.RLock() w.snapshotMu.RLock()
defer w.snapshotMu.RUnlock() defer w.snapshotMu.RUnlock()
if w.snapshotState == nil { if w.snapshotState == nil {
@ -707,16 +707,16 @@ func (w *worker) resultLoop() {
func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address) (*environment, error) { func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address) (*environment, error) {
// Retrieve the parent state to execute on top and start a prefetcher for // Retrieve the parent state to execute on top and start a prefetcher for
// the miner to speed block sealing up a bit. // the miner to speed block sealing up a bit.
state, err := w.chain.StateAt(parent.Root) stateDB, err := w.chain.StateAt(parent.Root)
if err != nil { if err != nil {
return nil, err return nil, err
} }
state.StartPrefetcher("miner") stateDB.(*state.StateDB).StartPrefetcher("miner")
// Note the passed coinbase may be different with header.Coinbase. // Note the passed coinbase may be different with header.Coinbase.
env := &environment{ env := &environment{
signer: types.MakeSigner(w.chainConfig, header.Number, header.Time), signer: types.MakeSigner(w.chainConfig, header.Number, header.Time),
state: state, state: stateDB,
coinbase: coinbase, coinbase: coinbase,
header: header, header: header,
} }

View file

@ -33,7 +33,6 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/params" "github.com/ethereum/go-ethereum/params"
@ -321,7 +320,7 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
return nil return nil
} }
func (t *BlockTest) validatePostState(statedb *state.StateDB) error { func (t *BlockTest) validatePostState(statedb vm.StateDB) error {
// validate post state accounts in test file against what we have in state db // validate post state accounts in test file against what we have in state db
for addr, acct := range t.json.Post { for addr, acct := range t.json.Post {
// address is indirectly verified by the other fields, as it's the db key // address is indirectly verified by the other fields, as it's the db key