mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
squash
This commit is contained in:
parent
dc34fe8291
commit
25ba0940d7
94 changed files with 794 additions and 406 deletions
|
|
@ -65,7 +65,7 @@ type SimulatedBackend struct {
|
|||
|
||||
mu sync.Mutex
|
||||
pendingBlock *types.Block // Currently pending block that will be imported on request
|
||||
pendingState *state.StateDB // Currently pending state that will be the active on request
|
||||
pendingState state.StateDBI // Currently pending state that will be the active on request
|
||||
pendingReceipts types.Receipts // Currently receipts for the pending block
|
||||
|
||||
events *filters.EventSystem // for filtering log events live
|
||||
|
|
@ -179,7 +179,7 @@ func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
|
|||
}
|
||||
|
||||
// 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) (state.StateDBI, error) {
|
||||
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number) == 0 {
|
||||
return b.blockchain.State()
|
||||
}
|
||||
|
|
@ -580,7 +580,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
}
|
||||
}
|
||||
// Reject the transaction as invalid if it still fails at the highest allowance
|
||||
if hi == cap {
|
||||
if hi >= cap {
|
||||
failed, result, err := executable(hi)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -601,7 +601,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
|
||||
// callContract implements common code between normal and pending contract calls.
|
||||
// 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 state.StateDBI) (*core.ExecutionResult, error) {
|
||||
// Gas prices post 1559 need to be initialized
|
||||
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
|
||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ type rejectedTx struct {
|
|||
// Apply applies a set of transactions to a pre-state
|
||||
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||
txs types.Transactions, miningReward int64,
|
||||
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, error) {
|
||||
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (state.StateDBI, *ExecutionResult, error) {
|
||||
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
||||
// required blockhashes
|
||||
var hashError error
|
||||
|
|
@ -335,7 +335,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
return statedb, execRs, nil
|
||||
}
|
||||
|
||||
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB {
|
||||
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) state.StateDBI {
|
||||
sdb := state.NewDatabaseWithConfig(db, &trie.Config{Preimages: true})
|
||||
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
|
||||
for addr, a := range accounts {
|
||||
|
|
|
|||
|
|
@ -116,14 +116,15 @@ func runCmd(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
var (
|
||||
tracer vm.EVMLogger
|
||||
debugLogger *logger.StructLogger
|
||||
statedb *state.StateDB
|
||||
chainConfig *params.ChainConfig
|
||||
sender = common.BytesToAddress([]byte("sender"))
|
||||
receiver = common.BytesToAddress([]byte("receiver"))
|
||||
preimages = ctx.Bool(DumpFlag.Name)
|
||||
blobHashes []common.Hash // TODO (MariusVanDerWijden) implement blob hashes in state tests
|
||||
tracer vm.EVMLogger
|
||||
debugLogger *logger.StructLogger
|
||||
statedb state.StateDBI
|
||||
chainConfig *params.ChainConfig
|
||||
sender = common.BytesToAddress([]byte("sender"))
|
||||
receiver = common.BytesToAddress([]byte("receiver"))
|
||||
genesisConfig *core.Genesis
|
||||
preimages = ctx.Bool(DumpFlag.Name)
|
||||
blobHashes []common.Hash // TODO (MariusVanDerWijden) implement blob hashes in state tests
|
||||
)
|
||||
if ctx.Bool(MachineFlag.Name) {
|
||||
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error {
|
|||
for _, st := range test.Subtests() {
|
||||
// Run the test and aggregate the result
|
||||
result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true}
|
||||
test.Run(st, cfg, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) {
|
||||
test.Run(st, cfg, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state state.StateDBI) {
|
||||
if state != nil {
|
||||
root := state.IntermediateRoot(false)
|
||||
result.Root = &root
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/internal/version"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/console/prompt"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/internal/debug"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ import (
|
|||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/ethdb/remotedb"
|
||||
"github.com/ethereum/go-ethereum/ethstats"
|
||||
"github.com/ethereum/go-ethereum/graphql"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/les"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -1962,8 +1962,12 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst
|
|||
}
|
||||
}
|
||||
|
||||
type NetworkingStack interface {
|
||||
RegisterAPIs([]rpc.API)
|
||||
}
|
||||
|
||||
// RegisterFilterAPI adds the eth log filtering RPC API to the node.
|
||||
func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem {
|
||||
func RegisterFilterAPI(stack NetworkingStack, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem {
|
||||
isLightClient := ethcfg.SyncMode == downloader.LightSync
|
||||
filterSystem := filters.NewFilterSystem(backend, filters.Config{
|
||||
LogCacheSize: ethcfg.FilterLogCacheSize,
|
||||
|
|
|
|||
|
|
@ -347,7 +347,9 @@ func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.H
|
|||
}
|
||||
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
|
||||
// Finalize is different with Prepare, it can be used in both block generation
|
||||
// and verification. So determine the consensus rules by header type.
|
||||
if !beacon.IsPoSHeader(header) {
|
||||
beacon.ethone.Finalize(chain, header, state, txs, uncles, nil)
|
||||
return
|
||||
|
|
@ -364,7 +366,9 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
|
|||
|
||||
// FinalizeAndAssemble implements consensus.Engine, setting the final state and
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
|
||||
// FinalizeAndAssemble is different with Prepare, it can be used in both block
|
||||
// generation and verification. So determine the consensus rules by header type.
|
||||
if !beacon.IsPoSHeader(header) {
|
||||
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,13 +567,15 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
|
|||
|
||||
// Finalize implements consensus.Engine. There is no post-transaction
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
|
||||
// No block rewards in PoA, so the state remains as is
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
header.UncleHash = types.CalcUncleHash(nil)
|
||||
}
|
||||
|
||||
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
|
||||
if len(withdrawals) > 0 {
|
||||
return nil, errors.New("clique does not support withdrawals")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ type Engine interface {
|
|||
//
|
||||
// Note: The state database might be updated to reflect any consensus rules
|
||||
// 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 state.StateDBI, txs []*types.Transaction,
|
||||
uncles []*types.Header, withdrawals []*types.Withdrawal)
|
||||
|
||||
// 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
|
||||
// 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 state.StateDBI, txs []*types.Transaction,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -487,14 +487,14 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
|
|||
}
|
||||
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
|
||||
// Accumulate any block and uncle rewards
|
||||
accumulateRewards(chain.Config(), state, header, uncles)
|
||||
}
|
||||
|
||||
// FinalizeAndAssemble implements consensus.Engine, accumulating the block and
|
||||
// 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 state.StateDBI, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
|
||||
if len(withdrawals) > 0 {
|
||||
return nil, errors.New("ethash does not support withdrawals")
|
||||
}
|
||||
|
|
@ -547,7 +547,7 @@ var (
|
|||
// AccumulateRewards credits the coinbase of the given block with the mining
|
||||
// reward. The total reward consists of the static block reward and rewards for
|
||||
// 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 state.StateDBI, header *types.Header, uncles []*types.Header) {
|
||||
// Select the correct block reward based on chain progression
|
||||
blockReward := FrontierBlockReward
|
||||
if config.IsByzantium(header.Number) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header)
|
|||
// 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
|
||||
// contract.
|
||||
func ApplyDAOHardFork(statedb *state.StateDB) {
|
||||
func ApplyDAOHardFork(statedb state.StateDBI) {
|
||||
// Retrieve the contract to refund balances into
|
||||
if !statedb.Exist(params.DAORefundContract) {
|
||||
statedb.CreateAccount(params.DAORefundContract)
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
|||
|
||||
// ValidateState validates the various changes that happen after a state transition,
|
||||
// such as amount of used gas, the receipt roots and the state root itself.
|
||||
func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error {
|
||||
func (v *BlockValidator) ValidateState(block *types.Block, statedb state.StateDBI, receipts types.Receipts, usedGas uint64) error {
|
||||
header := block.Header()
|
||||
if block.GasUsed() != usedGas {
|
||||
return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas)
|
||||
|
|
|
|||
|
|
@ -1385,7 +1385,7 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error {
|
|||
|
||||
// writeBlockWithState writes block, metadata and corresponding state data to the
|
||||
// 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 state.StateDBI) error {
|
||||
// Calculate the total difficulty of the block
|
||||
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
|
||||
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,
|
||||
// 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 state.StateDBI, emitHeadEvent bool) (status WriteStatus, err error) {
|
||||
if !bc.chainmu.TryLock() {
|
||||
return NonStatTy, errChainStopped
|
||||
}
|
||||
|
|
@ -1484,7 +1484,7 @@ func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types
|
|||
|
||||
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
|
||||
// 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 state.StateDBI, emitHeadEvent bool) (status WriteStatus, err error) {
|
||||
if err := bc.writeBlockWithState(block, receipts, state); err != nil {
|
||||
return NonStatTy, err
|
||||
}
|
||||
|
|
@ -1710,7 +1710,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||
return it.index, err
|
||||
}
|
||||
// No validation errors for the first block (or chain prefix skipped)
|
||||
var activeState *state.StateDB
|
||||
var activeState state.StateDBI
|
||||
defer func() {
|
||||
// The chain importer is starting and stopping trie prefetchers. If a bad
|
||||
// block or other error is hit however, an early return may not properly
|
||||
|
|
@ -1794,7 +1794,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||
if followup, err := it.peek(); followup != nil && err == nil {
|
||||
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
|
||||
|
||||
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
|
||||
go func(start time.Time, followup *types.Block, throwaway state.StateDBI) {
|
||||
bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt)
|
||||
|
||||
blockPrefetchExecuteTimer.Update(time.Since(start))
|
||||
|
|
|
|||
|
|
@ -320,15 +320,20 @@ func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
|
|||
}
|
||||
|
||||
// State returns a new mutable state based on the current HEAD block.
|
||||
func (bc *BlockChain) State() (*state.StateDB, error) {
|
||||
func (bc *BlockChain) State() (state.StateDBI, error) {
|
||||
return bc.StateAt(bc.CurrentBlock().Root)
|
||||
}
|
||||
|
||||
// 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) (state.StateDBI, error) {
|
||||
return state.New(root, bc.stateCache, bc.snaps)
|
||||
}
|
||||
|
||||
// StateAtBlockNumber returns a new mutable state based on a particular block number.
|
||||
func (bc *BlockChain) StateAtBlockNumber(number uint64) (state.StateDBI, error) {
|
||||
return bc.StateAt(bc.GetHeaderByNumber(number).Root)
|
||||
}
|
||||
|
||||
// Config retrieves the chain's fork configuration.
|
||||
func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ type BlockGen struct {
|
|||
parent *types.Block
|
||||
chain []*types.Block
|
||||
header *types.Header
|
||||
statedb *state.StateDB
|
||||
statedb state.StateDBI
|
||||
|
||||
gasPool *GasPool
|
||||
txs []*types.Transaction
|
||||
|
|
@ -289,7 +289,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
}
|
||||
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
|
||||
chainreader := &fakeChainReader{config: config}
|
||||
genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
||||
genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb state.StateDBI) (*types.Block, types.Receipts) {
|
||||
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
|
||||
b.header = makeHeader(chainreader, parent, statedb, b.engine)
|
||||
|
||||
|
|
@ -371,7 +371,7 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
|
|||
return db, blocks, receipts
|
||||
}
|
||||
|
||||
func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
||||
func makeHeader(chain consensus.ChainReader, parent *types.Block, state state.StateDBI, engine consensus.Engine) *types.Header {
|
||||
var time uint64
|
||||
if parent.Time() == 0 {
|
||||
time = 10
|
||||
|
|
|
|||
|
|
@ -20,20 +20,20 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type accessList struct {
|
||||
type AccessList struct {
|
||||
addresses map[common.Address]int
|
||||
slots []map[common.Hash]struct{}
|
||||
}
|
||||
|
||||
// ContainsAddress returns true if the address is in the access list.
|
||||
func (al *accessList) ContainsAddress(address common.Address) bool {
|
||||
func (al *AccessList) ContainsAddress(address common.Address) bool {
|
||||
_, ok := al.addresses[address]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Contains checks if a slot within an account is present in the access list, returning
|
||||
// separate flags for the presence of the account and the slot respectively.
|
||||
func (al *accessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
|
||||
func (al *AccessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
|
||||
idx, ok := al.addresses[address]
|
||||
if !ok {
|
||||
// no such address (and hence zero slots)
|
||||
|
|
@ -47,16 +47,16 @@ func (al *accessList) Contains(address common.Address, slot common.Hash) (addres
|
|||
return true, slotPresent
|
||||
}
|
||||
|
||||
// newAccessList creates a new accessList.
|
||||
func newAccessList() *accessList {
|
||||
return &accessList{
|
||||
// NewAccessList creates a new AccessList.
|
||||
func NewAccessList() *AccessList {
|
||||
return &AccessList{
|
||||
addresses: make(map[common.Address]int),
|
||||
}
|
||||
}
|
||||
|
||||
// Copy creates an independent copy of an accessList.
|
||||
func (a *accessList) Copy() *accessList {
|
||||
cp := newAccessList()
|
||||
// Copy creates an independent copy of an AccessList.
|
||||
func (a *AccessList) Copy() *AccessList {
|
||||
cp := NewAccessList()
|
||||
for k, v := range a.addresses {
|
||||
cp.addresses[k] = v
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ func (a *accessList) Copy() *accessList {
|
|||
|
||||
// AddAddress adds an address to the access list, and returns 'true' if the operation
|
||||
// caused a change (addr was not previously in the list).
|
||||
func (al *accessList) AddAddress(address common.Address) bool {
|
||||
func (al *AccessList) AddAddress(address common.Address) bool {
|
||||
if _, present := al.addresses[address]; present {
|
||||
return false
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ func (al *accessList) AddAddress(address common.Address) bool {
|
|||
// - address added
|
||||
// - slot added
|
||||
// For any 'true' value returned, a corresponding journal entry must be made.
|
||||
func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrChange bool, slotChange bool) {
|
||||
func (al *AccessList) AddSlot(address common.Address, slot common.Hash) (addrChange bool, slotChange bool) {
|
||||
idx, addrPresent := al.addresses[address]
|
||||
if !addrPresent || idx == -1 {
|
||||
// Address not present, or addr present but no slots there
|
||||
|
|
@ -110,7 +110,7 @@ func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrCha
|
|||
// This operation needs to be performed in the same order as the addition happened.
|
||||
// This method is meant to be used by the journal, which maintains ordering of
|
||||
// operations.
|
||||
func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
|
||||
func (al *AccessList) DeleteSlot(address common.Address, slot common.Hash) {
|
||||
idx, addrOk := al.addresses[address]
|
||||
// There are two ways this can fail
|
||||
if !addrOk {
|
||||
|
|
@ -131,6 +131,6 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
|
|||
// needs to be performed in the same order as the addition happened.
|
||||
// This method is meant to be used by the journal, which maintains ordering of
|
||||
// operations.
|
||||
func (al *accessList) DeleteAddress(address common.Address) {
|
||||
func (al *AccessList) DeleteAddress(address common.Address) {
|
||||
delete(al.addresses, address)
|
||||
}
|
||||
|
|
|
|||
107
core/state/interface.go
Normal file
107
core/state/interface.go
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright 2014 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 state provides a caching layer atop the Ethereum state trie.
|
||||
|
||||
package state
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// StateDBI is an EVM database for full state querying.
|
||||
type StateDBI interface {
|
||||
CreateAccount(common.Address)
|
||||
SubBalance(common.Address, *big.Int)
|
||||
AddBalance(common.Address, *big.Int)
|
||||
GetBalance(common.Address) *big.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
SetNonce(common.Address, uint64)
|
||||
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
GetCode(common.Address) []byte
|
||||
SetCode(common.Address, []byte)
|
||||
GetCodeSize(common.Address) int
|
||||
|
||||
AddRefund(uint64)
|
||||
SubRefund(uint64)
|
||||
GetRefund() uint64
|
||||
|
||||
GetCommittedState(common.Address, common.Hash) common.Hash
|
||||
GetState(common.Address, common.Hash) common.Hash
|
||||
SetState(common.Address, common.Hash, common.Hash)
|
||||
|
||||
GetTransientState(addr common.Address, key common.Hash) common.Hash
|
||||
SetTransientState(addr common.Address, key, value common.Hash)
|
||||
|
||||
SelfDestruct(common.Address)
|
||||
HasSelfDestructed(common.Address) bool
|
||||
|
||||
Selfdestruct6780(common.Address)
|
||||
|
||||
// Exist reports whether the given account exists in state.
|
||||
// Notably this should also return true for self-destructed accounts.
|
||||
Exist(common.Address) bool
|
||||
// Empty returns whether the given account is empty. Empty
|
||||
// is defined according to EIP161 (balance = nonce = code = 0).
|
||||
Empty(common.Address) bool
|
||||
|
||||
AddressInAccessList(addr common.Address) bool
|
||||
SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool)
|
||||
// AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddAddressToAccessList(addr common.Address)
|
||||
// AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddSlotToAccessList(addr common.Address, slot common.Hash)
|
||||
Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList)
|
||||
|
||||
RevertToSnapshot(int)
|
||||
Snapshot() int
|
||||
|
||||
AddLog(*types.Log)
|
||||
AddPreimage(common.Hash, []byte)
|
||||
|
||||
Logs() []*types.Log
|
||||
GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log
|
||||
TxIndex() int
|
||||
Preimages() map[common.Hash][]byte
|
||||
|
||||
GetOrNewStateObject(addr common.Address) *StateObject
|
||||
|
||||
DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []byte)
|
||||
Dump(opts *DumpConfig) []byte
|
||||
RawDump(opts *DumpConfig) Dump
|
||||
IteratorDump(opts *DumpConfig) IteratorDump
|
||||
Database() Database
|
||||
Error() error
|
||||
SetBalance(addr common.Address, amount *big.Int)
|
||||
SetStorage(addr common.Address, storage map[common.Hash]common.Hash)
|
||||
GetStorageRoot(addr common.Address) common.Hash
|
||||
Finalise(deleteEmptyObjects bool)
|
||||
Commit(uint64, bool) (common.Hash, error)
|
||||
Copy() StateDBI
|
||||
SetTxContext(thash common.Hash, ti int)
|
||||
StopPrefetcher()
|
||||
StartPrefetcher(namespace string)
|
||||
IntermediateRoot(deleteEmptyObjects bool) common.Hash
|
||||
GetPrecompileManager() any
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ type (
|
|||
}
|
||||
resetObjectChange struct {
|
||||
account *common.Address
|
||||
prev *stateObject
|
||||
prev *StateObject
|
||||
prevdestruct bool
|
||||
prevAccount []byte
|
||||
prevStorage map[common.Hash][]byte
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ func (s Storage) Copy() Storage {
|
|||
return cpy
|
||||
}
|
||||
|
||||
// stateObject represents an Ethereum account which is being modified.
|
||||
// StateObject represents an Ethereum account which is being modified.
|
||||
//
|
||||
// The usage pattern is as follows:
|
||||
// - First you need to obtain a state object.
|
||||
// - Account values as well as storages can be accessed and modified through the object.
|
||||
// - Finally, call commit to return the changes of storage trie and update account data.
|
||||
type stateObject struct {
|
||||
type StateObject struct {
|
||||
db *StateDB
|
||||
address common.Address // address of ethereum account
|
||||
addrHash common.Hash // hash of ethereum address of the account
|
||||
|
|
@ -92,17 +92,17 @@ type stateObject struct {
|
|||
}
|
||||
|
||||
// empty returns whether the account is considered empty.
|
||||
func (s *stateObject) empty() bool {
|
||||
func (s *StateObject) empty() bool {
|
||||
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes())
|
||||
}
|
||||
|
||||
// newObject creates a state object.
|
||||
func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject {
|
||||
func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *StateObject {
|
||||
origin := acct
|
||||
if acct == nil {
|
||||
acct = types.NewEmptyStateAccount()
|
||||
}
|
||||
return &stateObject{
|
||||
return &StateObject{
|
||||
db: db,
|
||||
address: address,
|
||||
addrHash: crypto.Keccak256Hash(address[:]),
|
||||
|
|
@ -115,15 +115,15 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s
|
|||
}
|
||||
|
||||
// EncodeRLP implements rlp.Encoder.
|
||||
func (s *stateObject) EncodeRLP(w io.Writer) error {
|
||||
func (s *StateObject) EncodeRLP(w io.Writer) error {
|
||||
return rlp.Encode(w, &s.data)
|
||||
}
|
||||
|
||||
func (s *stateObject) markSelfdestructed() {
|
||||
func (s *StateObject) markSelfdestructed() {
|
||||
s.selfDestructed = true
|
||||
}
|
||||
|
||||
func (s *stateObject) touch() {
|
||||
func (s *StateObject) touch() {
|
||||
s.db.journal.append(touchChange{
|
||||
account: &s.address,
|
||||
})
|
||||
|
|
@ -137,7 +137,7 @@ func (s *stateObject) touch() {
|
|||
// getTrie returns the associated storage trie. The trie will be opened
|
||||
// if it's not loaded previously. An error will be returned if trie can't
|
||||
// be loaded.
|
||||
func (s *stateObject) getTrie() (Trie, error) {
|
||||
func (s *StateObject) getTrie() (Trie, error) {
|
||||
if s.trie == nil {
|
||||
// Try fetching from prefetcher first
|
||||
if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
|
||||
|
|
@ -156,7 +156,7 @@ func (s *stateObject) getTrie() (Trie, error) {
|
|||
}
|
||||
|
||||
// GetState retrieves a value from the account storage trie.
|
||||
func (s *stateObject) GetState(key common.Hash) common.Hash {
|
||||
func (s *StateObject) GetState(key common.Hash) common.Hash {
|
||||
// If we have a dirty value for this state entry, return it
|
||||
value, dirty := s.dirtyStorage[key]
|
||||
if dirty {
|
||||
|
|
@ -167,7 +167,7 @@ func (s *stateObject) GetState(key common.Hash) common.Hash {
|
|||
}
|
||||
|
||||
// GetCommittedState retrieves a value from the committed account storage trie.
|
||||
func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||
func (s *StateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||
// If we have a pending write or clean cached, return that
|
||||
if value, pending := s.pendingStorage[key]; pending {
|
||||
return value
|
||||
|
|
@ -227,7 +227,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
|||
}
|
||||
|
||||
// SetState updates a value in account storage.
|
||||
func (s *stateObject) SetState(key, value common.Hash) {
|
||||
func (s *StateObject) SetState(key, value common.Hash) {
|
||||
// If the new value is the same as old, don't set
|
||||
prev := s.GetState(key)
|
||||
if prev == value {
|
||||
|
|
@ -242,13 +242,13 @@ func (s *stateObject) SetState(key, value common.Hash) {
|
|||
s.setState(key, value)
|
||||
}
|
||||
|
||||
func (s *stateObject) setState(key, value common.Hash) {
|
||||
func (s *StateObject) setState(key, value common.Hash) {
|
||||
s.dirtyStorage[key] = value
|
||||
}
|
||||
|
||||
// finalise moves all dirty storage slots into the pending area to be hashed or
|
||||
// committed later. It is invoked at the end of every transaction.
|
||||
func (s *stateObject) finalise(prefetch bool) {
|
||||
func (s *StateObject) finalise(prefetch bool) {
|
||||
slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage))
|
||||
for key, value := range s.dirtyStorage {
|
||||
s.pendingStorage[key] = value
|
||||
|
|
@ -270,7 +270,7 @@ func (s *stateObject) finalise(prefetch bool) {
|
|||
// loading or updating of the trie, an error will be returned. Furthermore,
|
||||
// this function will return the mutated storage trie, or nil if there is no
|
||||
// storage change at all.
|
||||
func (s *stateObject) updateTrie() (Trie, error) {
|
||||
func (s *StateObject) updateTrie() (Trie, error) {
|
||||
// Make sure all dirty slots are finalized into the pending storage area
|
||||
s.finalise(false)
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ func (s *stateObject) updateTrie() (Trie, error) {
|
|||
|
||||
// updateRoot flushes all cached storage mutations to trie, recalculating the
|
||||
// new storage trie root.
|
||||
func (s *stateObject) updateRoot() {
|
||||
func (s *StateObject) updateRoot() {
|
||||
// Flush cached storage mutations into trie, short circuit if any error
|
||||
// is occurred or there is not change in the trie.
|
||||
tr, err := s.updateTrie()
|
||||
|
|
@ -375,7 +375,7 @@ func (s *stateObject) updateRoot() {
|
|||
// commit obtains a set of dirty storage trie nodes and updates the account data.
|
||||
// The returned set can be nil if nothing to commit. This function assumes all
|
||||
// storage mutations have already been flushed into trie by updateRoot.
|
||||
func (s *stateObject) commit() (*trienode.NodeSet, error) {
|
||||
func (s *StateObject) commit() (*trienode.NodeSet, error) {
|
||||
// Short circuit if trie is not even loaded, don't bother with committing anything
|
||||
if s.trie == nil {
|
||||
s.origin = s.data.Copy()
|
||||
|
|
@ -401,7 +401,7 @@ func (s *stateObject) commit() (*trienode.NodeSet, error) {
|
|||
|
||||
// AddBalance adds amount to s's balance.
|
||||
// It is used to add funds to the destination account of a transfer.
|
||||
func (s *stateObject) AddBalance(amount *big.Int) {
|
||||
func (s *StateObject) AddBalance(amount *big.Int) {
|
||||
// EIP161: We must check emptiness for the objects such that the account
|
||||
// clearing (0,0,0 objects) can take effect.
|
||||
if amount.Sign() == 0 {
|
||||
|
|
@ -415,14 +415,14 @@ func (s *stateObject) AddBalance(amount *big.Int) {
|
|||
|
||||
// SubBalance removes amount from s's balance.
|
||||
// It is used to remove funds from the origin account of a transfer.
|
||||
func (s *stateObject) SubBalance(amount *big.Int) {
|
||||
func (s *StateObject) SubBalance(amount *big.Int) {
|
||||
if amount.Sign() == 0 {
|
||||
return
|
||||
}
|
||||
s.SetBalance(new(big.Int).Sub(s.Balance(), amount))
|
||||
}
|
||||
|
||||
func (s *stateObject) SetBalance(amount *big.Int) {
|
||||
func (s *StateObject) SetBalance(amount *big.Int) {
|
||||
s.db.journal.append(balanceChange{
|
||||
account: &s.address,
|
||||
prev: new(big.Int).Set(s.data.Balance),
|
||||
|
|
@ -430,12 +430,12 @@ func (s *stateObject) SetBalance(amount *big.Int) {
|
|||
s.setBalance(amount)
|
||||
}
|
||||
|
||||
func (s *stateObject) setBalance(amount *big.Int) {
|
||||
func (s *StateObject) setBalance(amount *big.Int) {
|
||||
s.data.Balance = amount
|
||||
}
|
||||
|
||||
func (s *stateObject) deepCopy(db *StateDB) *stateObject {
|
||||
obj := &stateObject{
|
||||
func (s *StateObject) deepCopy(db *StateDB) *StateObject {
|
||||
obj := &StateObject{
|
||||
db: db,
|
||||
address: s.address,
|
||||
addrHash: s.addrHash,
|
||||
|
|
@ -460,12 +460,12 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject {
|
|||
//
|
||||
|
||||
// Address returns the address of the contract/account
|
||||
func (s *stateObject) Address() common.Address {
|
||||
func (s *StateObject) Address() common.Address {
|
||||
return s.address
|
||||
}
|
||||
|
||||
// Code returns the contract code associated with this object, if any.
|
||||
func (s *stateObject) Code() []byte {
|
||||
func (s *StateObject) Code() []byte {
|
||||
if s.code != nil {
|
||||
return s.code
|
||||
}
|
||||
|
|
@ -483,7 +483,7 @@ func (s *stateObject) Code() []byte {
|
|||
// CodeSize returns the size of the contract code associated with this object,
|
||||
// or zero if none. This method is an almost mirror of Code, but uses a cache
|
||||
// inside the database to avoid loading codes seen recently.
|
||||
func (s *stateObject) CodeSize() int {
|
||||
func (s *StateObject) CodeSize() int {
|
||||
if s.code != nil {
|
||||
return len(s.code)
|
||||
}
|
||||
|
|
@ -497,7 +497,7 @@ func (s *stateObject) CodeSize() int {
|
|||
return size
|
||||
}
|
||||
|
||||
func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||
func (s *StateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||
prevcode := s.Code()
|
||||
s.db.journal.append(codeChange{
|
||||
account: &s.address,
|
||||
|
|
@ -507,13 +507,13 @@ func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
|
|||
s.setCode(codeHash, code)
|
||||
}
|
||||
|
||||
func (s *stateObject) setCode(codeHash common.Hash, code []byte) {
|
||||
func (s *StateObject) setCode(codeHash common.Hash, code []byte) {
|
||||
s.code = code
|
||||
s.data.CodeHash = codeHash[:]
|
||||
s.dirtyCode = true
|
||||
}
|
||||
|
||||
func (s *stateObject) SetNonce(nonce uint64) {
|
||||
func (s *StateObject) SetNonce(nonce uint64) {
|
||||
s.db.journal.append(nonceChange{
|
||||
account: &s.address,
|
||||
prev: s.data.Nonce,
|
||||
|
|
@ -521,22 +521,22 @@ func (s *stateObject) SetNonce(nonce uint64) {
|
|||
s.setNonce(nonce)
|
||||
}
|
||||
|
||||
func (s *stateObject) setNonce(nonce uint64) {
|
||||
func (s *StateObject) setNonce(nonce uint64) {
|
||||
s.data.Nonce = nonce
|
||||
}
|
||||
|
||||
func (s *stateObject) CodeHash() []byte {
|
||||
func (s *StateObject) CodeHash() []byte {
|
||||
return s.data.CodeHash
|
||||
}
|
||||
|
||||
func (s *stateObject) Balance() *big.Int {
|
||||
func (s *StateObject) Balance() *big.Int {
|
||||
return s.data.Balance
|
||||
}
|
||||
|
||||
func (s *stateObject) Nonce() uint64 {
|
||||
func (s *StateObject) Nonce() uint64 {
|
||||
return s.data.Nonce
|
||||
}
|
||||
|
||||
func (s *stateObject) Root() common.Hash {
|
||||
func (s *StateObject) Root() common.Hash {
|
||||
return s.data.Root
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ func TestSnapshot2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func compareStateObjects(so0, so1 *stateObject, t *testing.T) {
|
||||
func compareStateObjects(so0, so1 *StateObject, t *testing.T) {
|
||||
if so0.Address() != so1.Address() {
|
||||
t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ type StateDB struct {
|
|||
|
||||
// This map holds 'live' objects, which will get modified while processing
|
||||
// a state transition.
|
||||
stateObjects map[common.Address]*stateObject
|
||||
stateObjects map[common.Address]*StateObject
|
||||
stateObjectsPending map[common.Address]struct{} // State objects finalized but not yet written to the trie
|
||||
stateObjectsDirty map[common.Address]struct{} // State objects modified in the current execution
|
||||
stateObjectsDestruct map[common.Address]*types.StateAccount // State objects destructed in the block along with its previous value
|
||||
|
|
@ -106,7 +106,7 @@ type StateDB struct {
|
|||
preimages map[common.Hash][]byte
|
||||
|
||||
// Per-transaction access list
|
||||
accessList *accessList
|
||||
accessList *AccessList
|
||||
|
||||
// Transient storage
|
||||
transientStorage transientStorage
|
||||
|
|
@ -155,14 +155,14 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
|||
storages: make(map[common.Hash]map[common.Hash][]byte),
|
||||
accountsOrigin: make(map[common.Address][]byte),
|
||||
storagesOrigin: make(map[common.Address]map[common.Hash][]byte),
|
||||
stateObjects: make(map[common.Address]*stateObject),
|
||||
stateObjects: make(map[common.Address]*StateObject),
|
||||
stateObjectsPending: make(map[common.Address]struct{}),
|
||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||
stateObjectsDestruct: make(map[common.Address]*types.StateAccount),
|
||||
logs: make(map[common.Hash][]*types.Log),
|
||||
preimages: make(map[common.Hash][]byte),
|
||||
journal: newJournal(),
|
||||
accessList: newAccessList(),
|
||||
accessList: NewAccessList(),
|
||||
transientStorage: newTransientStorage(),
|
||||
hasher: crypto.NewKeccakState(),
|
||||
}
|
||||
|
|
@ -172,6 +172,10 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
|||
return sdb, nil
|
||||
}
|
||||
|
||||
func (s *StateDB) GetPrecompileManager() any {
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartPrefetcher initializes a new trie prefetcher to pull in nodes from the
|
||||
// state trie concurrently while the state is mutated so that when we reach the
|
||||
// commit phase, most of the needed data is already hot.
|
||||
|
|
@ -374,38 +378,38 @@ func (s *StateDB) HasSelfDestructed(addr common.Address) bool {
|
|||
|
||||
// AddBalance adds amount to the account associated with addr.
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount)
|
||||
StateObject := s.GetOrNewStateObject(addr)
|
||||
if StateObject != nil {
|
||||
StateObject.AddBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
// SubBalance subtracts amount from the account associated with addr.
|
||||
func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SubBalance(amount)
|
||||
StateObject := s.GetOrNewStateObject(addr)
|
||||
if StateObject != nil {
|
||||
StateObject.SubBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetBalance(amount)
|
||||
StateObject := s.GetOrNewStateObject(addr)
|
||||
if StateObject != nil {
|
||||
StateObject.SetBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetNonce(nonce)
|
||||
StateObject := s.GetOrNewStateObject(addr)
|
||||
if StateObject != nil {
|
||||
StateObject.SetNonce(nonce)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||
StateObject := s.GetOrNewStateObject(addr)
|
||||
if StateObject != nil {
|
||||
StateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -499,7 +503,7 @@ func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common
|
|||
//
|
||||
|
||||
// updateStateObject writes the given object to the trie.
|
||||
func (s *StateDB) updateStateObject(obj *stateObject) {
|
||||
func (s *StateDB) updateStateObject(obj *StateObject) {
|
||||
// Track the amount of time wasted on updating the account from the trie
|
||||
if metrics.EnabledExpensive {
|
||||
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
|
||||
|
|
@ -531,7 +535,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
|
|||
}
|
||||
|
||||
// deleteStateObject removes the given object from the state trie.
|
||||
func (s *StateDB) deleteStateObject(obj *stateObject) {
|
||||
func (s *StateDB) deleteStateObject(obj *StateObject) {
|
||||
// Track the amount of time wasted on deleting the account from the trie
|
||||
if metrics.EnabledExpensive {
|
||||
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
|
||||
|
|
@ -546,7 +550,7 @@ func (s *StateDB) deleteStateObject(obj *stateObject) {
|
|||
// getStateObject retrieves a state object given by the address, returning nil if
|
||||
// the object is not found or was deleted in this execution context. If you need
|
||||
// to differentiate between non-existent/just-deleted, use getDeletedStateObject.
|
||||
func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
||||
func (s *StateDB) getStateObject(addr common.Address) *StateObject {
|
||||
if obj := s.getDeletedStateObject(addr); obj != nil && !obj.deleted {
|
||||
return obj
|
||||
}
|
||||
|
|
@ -557,7 +561,7 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
|||
// nil for a deleted state object, it returns the actual object with the deleted
|
||||
// flag set. This is needed by the state journal to revert to the correct s-
|
||||
// destructed object instead of wiping all knowledge about the state object.
|
||||
func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
||||
func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject {
|
||||
// Prefer live objects if any is available
|
||||
if obj := s.stateObjects[addr]; obj != nil {
|
||||
return obj
|
||||
|
|
@ -610,12 +614,12 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||
return obj
|
||||
}
|
||||
|
||||
func (s *StateDB) setStateObject(object *stateObject) {
|
||||
func (s *StateDB) setStateObject(object *StateObject) {
|
||||
s.stateObjects[object.Address()] = object
|
||||
}
|
||||
|
||||
// GetOrNewStateObject retrieves a state object or create a new state object if nil.
|
||||
func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
||||
func (s *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
stateObject, _ = s.createObject(addr)
|
||||
|
|
@ -625,7 +629,7 @@ func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
|||
|
||||
// createObject creates a new state object. If there is an existing account with
|
||||
// the given address, it is overwritten and returned as the second return value.
|
||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *StateObject) {
|
||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
newobj = newObject(s, addr, nil)
|
||||
if prev == nil {
|
||||
|
|
@ -685,9 +689,8 @@ func (s *StateDB) CreateAccount(addr common.Address) {
|
|||
}
|
||||
}
|
||||
|
||||
// Copy creates a deep, independent copy of the state.
|
||||
// Snapshots of the copied state cannot be applied to the copy.
|
||||
func (s *StateDB) Copy() *StateDB {
|
||||
// GetOrNewStateObject retrieves a state object or create a new state object if nil.
|
||||
func (s *StateDB) Copy() StateDBI {
|
||||
// Copy all the basic fields, initialize the memory ones
|
||||
state := &StateDB{
|
||||
db: s.db,
|
||||
|
|
@ -697,7 +700,7 @@ func (s *StateDB) Copy() *StateDB {
|
|||
storages: make(map[common.Hash]map[common.Hash][]byte),
|
||||
accountsOrigin: make(map[common.Address][]byte),
|
||||
storagesOrigin: make(map[common.Address]map[common.Hash][]byte),
|
||||
stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)),
|
||||
stateObjects: make(map[common.Address]*StateObject, len(s.journal.dirties)),
|
||||
stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)),
|
||||
stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)),
|
||||
stateObjectsDestruct: make(map[common.Address]*types.StateAccount, len(s.stateObjectsDestruct)),
|
||||
|
|
@ -1315,7 +1318,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
|||
func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) {
|
||||
if rules.IsBerlin {
|
||||
// Clear out any leftover from previous executions
|
||||
al := newAccessList()
|
||||
al := NewAccessList()
|
||||
s.accessList = al
|
||||
|
||||
al.AddAddress(sender)
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ func TestCopy(t *testing.T) {
|
|||
orig.Finalise(false)
|
||||
|
||||
// Copy the state
|
||||
copy := orig.Copy()
|
||||
copy := orig.Copy().(*StateDB)
|
||||
|
||||
// Copy the copy state
|
||||
ccopy := copy.Copy()
|
||||
ccopy := copy.Copy().(*StateDB)
|
||||
|
||||
// modify all in memory
|
||||
for i := byte(0); i < 255; i++ {
|
||||
|
|
@ -594,7 +594,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
|||
t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
|
||||
}
|
||||
// Copy the non-committed state database and check pre/post commit balance
|
||||
copyOne := state.Copy()
|
||||
copyOne := state.Copy().(*StateDB)
|
||||
if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
|
||||
t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42)
|
||||
}
|
||||
|
|
@ -681,7 +681,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
|
|||
t.Fatalf("first copy committed storage slot mismatch: have %x, want %x", val, common.Hash{})
|
||||
}
|
||||
// Copy the copy and check the balance once more
|
||||
copyTwo := copyOne.Copy()
|
||||
copyTwo := copyOne.Copy().(*StateDB)
|
||||
if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
|
||||
t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42)
|
||||
}
|
||||
|
|
@ -866,8 +866,8 @@ func TestStateDBAccessList(t *testing.T) {
|
|||
|
||||
memDb := rawdb.NewMemoryDatabase()
|
||||
db := NewDatabase(memDb)
|
||||
state, _ := New(types.EmptyRootHash, db, nil)
|
||||
state.accessList = newAccessList()
|
||||
state, _ := New(common.Hash{}, db, nil)
|
||||
state.accessList = NewAccessList()
|
||||
|
||||
verifyAddrs := func(astrings ...string) {
|
||||
t.Helper()
|
||||
|
|
@ -1018,7 +1018,7 @@ func TestStateDBAccessList(t *testing.T) {
|
|||
}
|
||||
// Check the copy
|
||||
// Make a copy
|
||||
state = stateCopy1
|
||||
state = stateCopy1.(*StateDB)
|
||||
verifyAddrs("aa", "bb")
|
||||
verifySlots("bb", "01", "02")
|
||||
if got, exp := len(state.accessList.addresses), 2; got != exp {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func newStatePrefetcher(config *params.ChainConfig, bc *BlockChain, engine conse
|
|||
// Prefetch processes the state changes according to the Ethereum rules by running
|
||||
// the transaction messages using the statedb, but any changes are discarded. The
|
||||
// only goal is to pre-cache transaction signatures and state trie nodes.
|
||||
func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *atomic.Bool) {
|
||||
func (p *statePrefetcher) Prefetch(block *types.Block, statedb state.StateDBI, cfg vm.Config, interrupt *atomic.Bool) {
|
||||
var (
|
||||
header = block.Header()
|
||||
gaspool = new(GasPool).AddGas(block.GasLimit())
|
||||
|
|
@ -85,7 +85,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
|||
// precacheTransaction attempts to apply a transaction to the given state database
|
||||
// and uses the input parameters for its environment. The goal is not to execute
|
||||
// the transaction successfully, rather to warm up touched data slots.
|
||||
func precacheTransaction(msg *Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
|
||||
func precacheTransaction(msg *Message, config *params.ChainConfig, gaspool *GasPool, statedb state.StateDBI, header *types.Header, evm *vm.EVM) error {
|
||||
// Update the evm with the new transaction context.
|
||||
evm.Reset(NewEVMTxContext(msg), statedb)
|
||||
// Add addresses to access list if applicable
|
||||
|
|
|
|||
|
|
@ -32,18 +32,23 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
type SPBlockchain interface {
|
||||
ChainContext
|
||||
consensus.ChainHeaderReader
|
||||
}
|
||||
|
||||
// StateProcessor is a basic Processor, which takes care of transitioning
|
||||
// state from one point to another.
|
||||
//
|
||||
// StateProcessor implements Processor.
|
||||
type StateProcessor struct {
|
||||
config *params.ChainConfig // Chain configuration options
|
||||
bc *BlockChain // Canonical block chain
|
||||
bc SPBlockchain // Canonical block chain
|
||||
engine consensus.Engine // Consensus engine used for block rewards
|
||||
}
|
||||
|
||||
// NewStateProcessor initialises a new StateProcessor.
|
||||
func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor {
|
||||
func NewStateProcessor(config *params.ChainConfig, bc SPBlockchain, engine consensus.Engine) *StateProcessor {
|
||||
return &StateProcessor{
|
||||
config: config,
|
||||
bc: bc,
|
||||
|
|
@ -58,7 +63,7 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
|
|||
// 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
|
||||
// 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 state.StateDBI, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
|
||||
var (
|
||||
receipts types.Receipts
|
||||
usedGas = new(uint64)
|
||||
|
|
@ -105,7 +110,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
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 state.StateDBI, 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.
|
||||
txContext := NewEVMTxContext(msg)
|
||||
evm.Reset(txContext, statedb)
|
||||
|
|
@ -159,7 +164,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
|
|||
// and uses the input parameters for its environment. It returns the receipt
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// 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 state.StateDBI, 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -172,7 +177,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
|
||||
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
|
||||
// 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 state.StateDBI) {
|
||||
// If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with
|
||||
// the new root
|
||||
msg := &Message{
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
// Execute the preparatory steps for state transition which includes:
|
||||
// - prepare accessList(post-berlin)
|
||||
// - reset transient storage(eip 1153)
|
||||
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
|
||||
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(st.evm, rules), msg.AccessList)
|
||||
|
||||
var (
|
||||
ret []byte
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ type BlobPool struct {
|
|||
chain BlockChain // Chain object to access the state through
|
||||
|
||||
head *types.Header // Current head of the chain
|
||||
state *state.StateDB // Current state at the head of the chain
|
||||
state state.StateDBI // Current state at the head of the chain
|
||||
gasTip *uint256.Int // Currently accepted minimum gas tip
|
||||
|
||||
lookup map[common.Hash]uint64 // Lookup table mapping hashes to tx billy entries
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ func (bt *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
|
|||
return nil
|
||||
}
|
||||
|
||||
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
|
||||
func (bc *testBlockChain) StateAt(common.Hash) (state.StateDBI, error) {
|
||||
return bc.statedb, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,5 +40,5 @@ type BlockChain interface {
|
|||
GetBlock(hash common.Hash, number uint64) *types.Block
|
||||
|
||||
// StateAt returns a state database for a given root hash (generally the head).
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
StateAt(root common.Hash) (state.StateDBI, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,10 @@ type BlockChain interface {
|
|||
GetBlock(hash common.Hash, number uint64) *types.Block
|
||||
|
||||
// StateAt returns a state database for a given root hash (generally the head).
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
StateAt(root common.Hash) (state.StateDBI, error)
|
||||
|
||||
// StateAtBlockNumber returns a state database at the given block number.
|
||||
StateAtBlockNumber(number uint64) (state.StateDBI, error)
|
||||
}
|
||||
|
||||
// Config are the configuration parameters of the transaction pool.
|
||||
|
|
@ -213,7 +216,7 @@ type LegacyPool struct {
|
|||
mu sync.RWMutex
|
||||
|
||||
currentHead atomic.Pointer[types.Header] // Current head of the blockchain
|
||||
currentState *state.StateDB // Current state in the blockchain head
|
||||
currentState state.StateDBI // Current state in the blockchain head
|
||||
pendingNonces *noncer // Pending state tracking virtual nonces
|
||||
|
||||
locals *accountSet // Set of local transaction to exempt from eviction rules
|
||||
|
|
@ -1401,17 +1404,30 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
|
|||
}
|
||||
}
|
||||
// Initialize the internal state to the current head
|
||||
// Initialize the internal state to the current head
|
||||
if newHead == nil {
|
||||
newHead = pool.chain.CurrentBlock() // Special case during testing
|
||||
}
|
||||
if newHead == nil {
|
||||
newHead = &types.Header{
|
||||
Number: big.NewInt(0),
|
||||
}
|
||||
}
|
||||
statedb, err := pool.chain.StateAt(newHead.Root)
|
||||
if err != nil {
|
||||
log.Error("Failed to reset txpool state", "err", err)
|
||||
return
|
||||
statedb, err = pool.chain.StateAtBlockNumber(newHead.Number.Uint64())
|
||||
if err != nil {
|
||||
log.Warn("Failed to get new state", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
pool.currentHead.Store(newHead)
|
||||
pool.currentState = statedb
|
||||
pool.pendingNonces = newNoncer(statedb)
|
||||
if pool.currentState != nil {
|
||||
pool.pendingNonces = newNoncer(statedb)
|
||||
} else {
|
||||
pool.pendingNonces = &noncer{}
|
||||
}
|
||||
|
||||
// Inject any transactions discarded due to reorgs
|
||||
log.Debug("Reinjecting stale transactions", "count", len(reinject))
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func init() {
|
|||
type testBlockChain struct {
|
||||
config *params.ChainConfig
|
||||
gasLimit atomic.Uint64
|
||||
statedb *state.StateDB
|
||||
statedb state.StateDBI
|
||||
chainHeadFeed *event.Feed
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +88,11 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
|
|||
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) (state.StateDBI, error) {
|
||||
return bc.statedb, nil
|
||||
}
|
||||
|
||||
func (bc *testBlockChain) StateAtBlockNumber(uint64) (state.StateDBI, error) {
|
||||
return bc.statedb, nil
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +250,7 @@ type testChain struct {
|
|||
// testChain.State() is used multiple times to reset the pending state.
|
||||
// when simulate is true it will create a state that indicates
|
||||
// that tx0 and tx1 are included in the chain.
|
||||
func (c *testChain) State() (*state.StateDB, error) {
|
||||
func (c *testChain) State() (state.StateDBI, error) {
|
||||
// delay "state change" by one. The tx pool fetches the
|
||||
// state multiple times and by delaying it a bit we simulate
|
||||
// a state change between those fetches.
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ import (
|
|||
// accounts in the pool, falling back to reading from a real state database if
|
||||
// an account is unknown.
|
||||
type noncer struct {
|
||||
fallback *state.StateDB
|
||||
fallback state.StateDBI
|
||||
nonces map[common.Address]uint64
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// newNoncer creates a new virtual state database to track the pool nonces.
|
||||
func newNoncer(statedb *state.StateDB) *noncer {
|
||||
func newNoncer(statedb state.StateDBI) *noncer {
|
||||
return &noncer{
|
||||
fallback: statedb.Copy(),
|
||||
nonces: make(map[common.Address]uint64),
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
|
|||
// ValidationOptionsWithState define certain differences between stateful transaction
|
||||
// validation across the different pools without having to duplicate those checks.
|
||||
type ValidationOptionsWithState struct {
|
||||
State *state.StateDB // State database to check nonces and balances against
|
||||
State state.StateDBI // State database to check nonces and balances against
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ type Validator interface {
|
|||
|
||||
// ValidateState validates the given statedb and optionally the receipts and
|
||||
// gas used.
|
||||
ValidateState(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error
|
||||
ValidateState(block *types.Block, state state.StateDBI, receipts types.Receipts, usedGas uint64) error
|
||||
}
|
||||
|
||||
// Prefetcher is an interface for pre-caching transaction signatures and state.
|
||||
|
|
@ -41,7 +41,7 @@ type Prefetcher interface {
|
|||
// Prefetch processes the state changes according to the Ethereum rules by running
|
||||
// the transaction messages using the statedb, but any changes are discarded. The
|
||||
// only goal is to pre-cache transaction signatures and state trie nodes.
|
||||
Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *atomic.Bool)
|
||||
Prefetch(block *types.Block, statedb state.StateDBI, cfg vm.Config, interrupt *atomic.Bool)
|
||||
}
|
||||
|
||||
// Processor is an interface for processing blocks using a given initial state.
|
||||
|
|
@ -49,5 +49,5 @@ type Processor interface {
|
|||
// 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 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 state.StateDBI, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
|
@ -38,8 +39,12 @@ import (
|
|||
// requires a deterministic gas count based on the input size of the Run method of the
|
||||
// contract.
|
||||
type PrecompiledContract interface {
|
||||
RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use
|
||||
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
|
||||
// RegistryKey returns the address at which the contract will be registered.
|
||||
RegistryKey() common.Address
|
||||
// RequiredGas calculates the contract static gas use.
|
||||
RequiredGas(input []byte) uint64
|
||||
// Run runs the precompiled contract with the given context.
|
||||
Run(ctx context.Context, evm PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error)
|
||||
}
|
||||
|
||||
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
|
||||
|
|
@ -148,44 +153,39 @@ func init() {
|
|||
}
|
||||
|
||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||
func ActivePrecompiles(rules params.Rules) []common.Address {
|
||||
func ActivePrecompiles(evm *EVM, rules params.Rules) []common.Address {
|
||||
var precompiles []common.Address
|
||||
switch {
|
||||
case rules.IsCancun:
|
||||
return PrecompiledAddressesCancun
|
||||
precompiles = append(precompiles, PrecompiledAddressesCancun...)
|
||||
case rules.IsBerlin:
|
||||
return PrecompiledAddressesBerlin
|
||||
precompiles = append(precompiles, PrecompiledAddressesBerlin...)
|
||||
case rules.IsIstanbul:
|
||||
return PrecompiledAddressesIstanbul
|
||||
precompiles = append(precompiles, PrecompiledAddressesIstanbul...)
|
||||
case rules.IsByzantium:
|
||||
return PrecompiledAddressesByzantium
|
||||
precompiles = append(precompiles, PrecompiledAddressesByzantium...)
|
||||
default:
|
||||
return PrecompiledAddressesHomestead
|
||||
precompiles = append(precompiles, PrecompiledAddressesHomestead...)
|
||||
}
|
||||
}
|
||||
|
||||
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
|
||||
// It returns
|
||||
// - the returned bytes,
|
||||
// - the _remaining_ gas,
|
||||
// - any error that occurred
|
||||
func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error) {
|
||||
gasCost := p.RequiredGas(input)
|
||||
if suppliedGas < gasCost {
|
||||
return nil, 0, ErrOutOfGas
|
||||
if evm != nil {
|
||||
precompiles = append(precompiles, evm.PrecompileManager.GetActive(rules)...)
|
||||
}
|
||||
suppliedGas -= gasCost
|
||||
output, err := p.Run(input)
|
||||
return output, suppliedGas, err
|
||||
return precompiles
|
||||
}
|
||||
|
||||
// ECRECOVER implemented as a native contract.
|
||||
type ecrecover struct{}
|
||||
|
||||
func (c *ecrecover) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{1})
|
||||
}
|
||||
|
||||
func (c *ecrecover) RequiredGas(input []byte) uint64 {
|
||||
return params.EcrecoverGas
|
||||
}
|
||||
|
||||
func (c *ecrecover) Run(input []byte) ([]byte, error) {
|
||||
func (c *ecrecover) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
const ecRecoverInputLength = 128
|
||||
|
||||
input = common.RightPadBytes(input, ecRecoverInputLength)
|
||||
|
|
@ -219,6 +219,10 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) {
|
|||
// SHA256 implemented as a native contract.
|
||||
type sha256hash struct{}
|
||||
|
||||
func (c *sha256hash) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{2})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
//
|
||||
// This method does not require any overflow checking as the input size gas costs
|
||||
|
|
@ -226,7 +230,7 @@ type sha256hash struct{}
|
|||
func (c *sha256hash) RequiredGas(input []byte) uint64 {
|
||||
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
|
||||
}
|
||||
func (c *sha256hash) Run(input []byte) ([]byte, error) {
|
||||
func (c *sha256hash) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
h := sha256.Sum256(input)
|
||||
return h[:], nil
|
||||
}
|
||||
|
|
@ -234,6 +238,10 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) {
|
|||
// RIPEMD160 implemented as a native contract.
|
||||
type ripemd160hash struct{}
|
||||
|
||||
func (c *ripemd160hash) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{3})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
//
|
||||
// This method does not require any overflow checking as the input size gas costs
|
||||
|
|
@ -241,7 +249,7 @@ type ripemd160hash struct{}
|
|||
func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
|
||||
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
|
||||
}
|
||||
func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
|
||||
func (c *ripemd160hash) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
ripemd := ripemd160.New()
|
||||
ripemd.Write(input)
|
||||
return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
|
||||
|
|
@ -250,6 +258,10 @@ func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
|
|||
// data copy implemented as a native contract.
|
||||
type dataCopy struct{}
|
||||
|
||||
func (c *dataCopy) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{4})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
//
|
||||
// This method does not require any overflow checking as the input size gas costs
|
||||
|
|
@ -257,8 +269,8 @@ type dataCopy struct{}
|
|||
func (c *dataCopy) RequiredGas(input []byte) uint64 {
|
||||
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
|
||||
}
|
||||
func (c *dataCopy) Run(in []byte) ([]byte, error) {
|
||||
return common.CopyBytes(in), nil
|
||||
func (c *dataCopy) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
// bigModExp implements a native big integer exponential modular operation.
|
||||
|
|
@ -266,6 +278,10 @@ type bigModExp struct {
|
|||
eip2565 bool
|
||||
}
|
||||
|
||||
func (c *bigModExp) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{5})
|
||||
}
|
||||
|
||||
var (
|
||||
big0 = big.NewInt(0)
|
||||
big1 = big.NewInt(1)
|
||||
|
|
@ -286,10 +302,11 @@ var (
|
|||
|
||||
// modexpMultComplexity implements bigModexp multComplexity formula, as defined in EIP-198
|
||||
//
|
||||
// def mult_complexity(x):
|
||||
// if x <= 64: return x ** 2
|
||||
// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072
|
||||
// else: return x ** 2 // 16 + 480 * x - 199680
|
||||
// def mult_complexity(x):
|
||||
//
|
||||
// if x <= 64: return x ** 2
|
||||
// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072
|
||||
// else: return x ** 2 // 16 + 480 * x - 199680
|
||||
//
|
||||
// where is x is max(length_of_MODULUS, length_of_BASE)
|
||||
func modexpMultComplexity(x *big.Int) *big.Int {
|
||||
|
|
@ -383,7 +400,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
|||
return gas.Uint64()
|
||||
}
|
||||
|
||||
func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
||||
func (c *bigModExp) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
var (
|
||||
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
|
||||
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
|
||||
|
|
@ -458,12 +475,16 @@ func runBn256Add(input []byte) ([]byte, error) {
|
|||
// Istanbul consensus rules.
|
||||
type bn256AddIstanbul struct{}
|
||||
|
||||
func (c *bn256AddIstanbul) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{6})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256AddGasIstanbul
|
||||
}
|
||||
|
||||
func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256AddIstanbul) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256Add(input)
|
||||
}
|
||||
|
||||
|
|
@ -471,12 +492,16 @@ func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
|
|||
// conforming to Byzantium consensus rules.
|
||||
type bn256AddByzantium struct{}
|
||||
|
||||
func (c *bn256AddByzantium) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{6})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256AddGasByzantium
|
||||
}
|
||||
|
||||
func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256AddByzantium) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256Add(input)
|
||||
}
|
||||
|
||||
|
|
@ -496,12 +521,16 @@ func runBn256ScalarMul(input []byte) ([]byte, error) {
|
|||
// multiplication conforming to Istanbul consensus rules.
|
||||
type bn256ScalarMulIstanbul struct{}
|
||||
|
||||
func (c *bn256ScalarMulIstanbul) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{7})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256ScalarMulGasIstanbul
|
||||
}
|
||||
|
||||
func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256ScalarMulIstanbul) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256ScalarMul(input)
|
||||
}
|
||||
|
||||
|
|
@ -509,12 +538,16 @@ func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
|
|||
// multiplication conforming to Byzantium consensus rules.
|
||||
type bn256ScalarMulByzantium struct{}
|
||||
|
||||
func (c *bn256ScalarMulByzantium) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{7})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256ScalarMulGasByzantium
|
||||
}
|
||||
|
||||
func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256ScalarMulByzantium) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256ScalarMul(input)
|
||||
}
|
||||
|
||||
|
|
@ -564,12 +597,16 @@ func runBn256Pairing(input []byte) ([]byte, error) {
|
|||
// conforming to Istanbul consensus rules.
|
||||
type bn256PairingIstanbul struct{}
|
||||
|
||||
func (c *bn256PairingIstanbul) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{8})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
|
||||
}
|
||||
|
||||
func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256PairingIstanbul) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256Pairing(input)
|
||||
}
|
||||
|
||||
|
|
@ -577,17 +614,25 @@ func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
|
|||
// conforming to Byzantium consensus rules.
|
||||
type bn256PairingByzantium struct{}
|
||||
|
||||
func (c *bn256PairingByzantium) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{8})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
|
||||
return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
|
||||
}
|
||||
|
||||
func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
|
||||
func (c *bn256PairingByzantium) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
return runBn256Pairing(input)
|
||||
}
|
||||
|
||||
type blake2F struct{}
|
||||
|
||||
func (c *blake2F) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{9})
|
||||
}
|
||||
|
||||
func (c *blake2F) RequiredGas(input []byte) uint64 {
|
||||
// If the input is malformed, we can't calculate the gas, return 0 and let the
|
||||
// actual call choke and fault.
|
||||
|
|
@ -608,7 +653,7 @@ var (
|
|||
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
|
||||
)
|
||||
|
||||
func (c *blake2F) Run(input []byte) ([]byte, error) {
|
||||
func (c *blake2F) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Make sure the input is valid (correct length and final flag)
|
||||
if len(input) != blake2FInputLength {
|
||||
return nil, errBlake2FInvalidInputLength
|
||||
|
|
@ -657,12 +702,16 @@ var (
|
|||
// bls12381G1Add implements EIP-2537 G1Add precompile.
|
||||
type bls12381G1Add struct{}
|
||||
|
||||
func (c *bls12381G1Add) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{10})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G1Add) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381G1AddGas
|
||||
}
|
||||
|
||||
func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G1Add) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G1Add precompile.
|
||||
// > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each).
|
||||
// > Output is an encoding of addition operation result - single G1 point (`128` bytes).
|
||||
|
|
@ -695,12 +744,16 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
|
|||
// bls12381G1Mul implements EIP-2537 G1Mul precompile.
|
||||
type bls12381G1Mul struct{}
|
||||
|
||||
func (c *bls12381G1Mul) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{11})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G1Mul) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381G1MulGas
|
||||
}
|
||||
|
||||
func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G1Mul) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G1Mul precompile.
|
||||
// > G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
|
||||
// > Output is an encoding of multiplication operation result - single G1 point (`128` bytes).
|
||||
|
|
@ -731,6 +784,10 @@ func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) {
|
|||
// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile.
|
||||
type bls12381G1MultiExp struct{}
|
||||
|
||||
func (c *bls12381G1MultiExp) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{12})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
|
||||
// Calculate G1 point, scalar value pair length
|
||||
|
|
@ -750,7 +807,7 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
|
|||
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
|
||||
}
|
||||
|
||||
func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G1MultiExp) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G1MultiExp precompile.
|
||||
// G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
|
||||
// Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes).
|
||||
|
|
@ -788,12 +845,16 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
|||
// bls12381G2Add implements EIP-2537 G2Add precompile.
|
||||
type bls12381G2Add struct{}
|
||||
|
||||
func (c *bls12381G2Add) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{13})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G2Add) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381G2AddGas
|
||||
}
|
||||
|
||||
func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G2Add) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G2Add precompile.
|
||||
// > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each).
|
||||
// > Output is an encoding of addition operation result - single G2 point (`256` bytes).
|
||||
|
|
@ -826,12 +887,16 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
|
|||
// bls12381G2Mul implements EIP-2537 G2Mul precompile.
|
||||
type bls12381G2Mul struct{}
|
||||
|
||||
func (c *bls12381G2Mul) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{14})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G2Mul) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381G2MulGas
|
||||
}
|
||||
|
||||
func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G2Mul) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G2MUL precompile logic.
|
||||
// > G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
|
||||
// > Output is an encoding of multiplication operation result - single G2 point (`256` bytes).
|
||||
|
|
@ -862,6 +927,10 @@ func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) {
|
|||
// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile.
|
||||
type bls12381G2MultiExp struct{}
|
||||
|
||||
func (c *bls12381G2MultiExp) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{15})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
|
||||
// Calculate G2 point, scalar value pair length
|
||||
|
|
@ -881,7 +950,7 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
|
|||
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
|
||||
}
|
||||
|
||||
func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381G2MultiExp) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 G2MultiExp precompile logic
|
||||
// > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
|
||||
// > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes).
|
||||
|
|
@ -919,12 +988,16 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
|||
// bls12381Pairing implements EIP-2537 Pairing precompile.
|
||||
type bls12381Pairing struct{}
|
||||
|
||||
func (c *bls12381Pairing) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{16})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381Pairing) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas
|
||||
}
|
||||
|
||||
func (c *bls12381Pairing) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381Pairing) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 Pairing precompile logic.
|
||||
// > Pairing call expects `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure:
|
||||
// > - `128` bytes of G1 point encoding
|
||||
|
|
@ -998,12 +1071,16 @@ func decodeBLS12381FieldElement(in []byte) ([]byte, error) {
|
|||
// bls12381MapG1 implements EIP-2537 MapG1 precompile.
|
||||
type bls12381MapG1 struct{}
|
||||
|
||||
func (c *bls12381MapG1) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{17})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381MapG1) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381MapG1Gas
|
||||
}
|
||||
|
||||
func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381MapG1) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 Map_To_G1 precompile.
|
||||
// > Field-to-curve call expects `64` bytes an an input that is interpreted as a an element of the base field.
|
||||
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
|
||||
|
|
@ -1033,12 +1110,16 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
|
|||
// bls12381MapG2 implements EIP-2537 MapG2 precompile.
|
||||
type bls12381MapG2 struct{}
|
||||
|
||||
func (c *bls12381MapG2) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{18})
|
||||
}
|
||||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bls12381MapG2) RequiredGas(input []byte) uint64 {
|
||||
return params.Bls12381MapG2Gas
|
||||
}
|
||||
|
||||
func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
||||
func (c *bls12381MapG2) Run(ctx context.Context, _ PrecompileEVM, input []byte, caller common.Address, value *big.Int) ([]byte, error) {
|
||||
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
|
||||
// > Field-to-curve call expects `128` bytes an an input that is interpreted as a an element of the quadratic extension field.
|
||||
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.
|
||||
|
|
@ -1072,6 +1153,10 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
|||
return g.EncodePoint(r), nil
|
||||
}
|
||||
|
||||
func (b *kzgPointEvaluation) RegistryKey() common.Address {
|
||||
return common.BytesToAddress([]byte{19})
|
||||
}
|
||||
|
||||
// kzgPointEvaluation implements the EIP-4844 point evaluation precompile.
|
||||
type kzgPointEvaluation struct{}
|
||||
|
||||
|
|
@ -1093,7 +1178,7 @@ var (
|
|||
)
|
||||
|
||||
// Run executes the point evaluation precompile.
|
||||
func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) {
|
||||
func (b *kzgPointEvaluation) Run(_ context.Context, _ PrecompileEVM, input []byte, _ common.Address, _ *big.Int) ([]byte, error) {
|
||||
if len(input) != blobVerifyInputLength {
|
||||
return nil, errBlobVerifyInvalidInputLength
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ package vm
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -93,6 +95,16 @@ var blake2FMalformedInputTests = []precompiledFailureTest{
|
|||
},
|
||||
}
|
||||
|
||||
func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error) {
|
||||
gasCost := p.RequiredGas(input)
|
||||
if suppliedGas < gasCost {
|
||||
return nil, 0, ErrOutOfGas
|
||||
}
|
||||
suppliedGas -= gasCost
|
||||
output, err := p.Run(context.Background(), nil, input, common.Address{}, new(big.Int))
|
||||
return output, suppliedGas, err
|
||||
}
|
||||
|
||||
func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
|
||||
p := allPrecompiles[common.HexToAddress(addr)]
|
||||
in := common.Hex2Bytes(test.Input)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ func ValidEip(eipNum int) bool {
|
|||
_, ok := activators[eipNum]
|
||||
return ok
|
||||
}
|
||||
|
||||
func ActivateableEips() []string {
|
||||
var nums []string
|
||||
for k := range activators {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
|
||||
|
|
@ -52,6 +53,9 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
|||
precompiles = PrecompiledContractsHomestead
|
||||
}
|
||||
p, ok := precompiles[addr]
|
||||
if p == nil || !ok {
|
||||
p, ok = evm.PrecompileManager.Get(addr, &evm.chainRules)
|
||||
}
|
||||
return p, ok
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +105,8 @@ type EVM struct {
|
|||
TxContext
|
||||
// StateDB gives access to the underlying state
|
||||
StateDB StateDB
|
||||
// PrecompileManager finds and runs precompiled contracts
|
||||
PrecompileManager PrecompileManager
|
||||
// Depth is the current call stack
|
||||
depth int
|
||||
|
||||
|
|
@ -134,6 +140,12 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
|
|||
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
|
||||
}
|
||||
evm.interpreter = NewEVMInterpreter(evm)
|
||||
if pm := statedb.GetPrecompileManager(); pm != nil {
|
||||
evm.PrecompileManager = pm.(PrecompileManager)
|
||||
} else {
|
||||
evm.PrecompileManager = NewPrecompileManager()
|
||||
}
|
||||
|
||||
return evm
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +232,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
}
|
||||
|
||||
if isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||
ret, gas, err = evm.PrecompileManager.Run(evm, p, input, caller.Address(), value, gas, false)
|
||||
} else {
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
|
|
@ -242,7 +254,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
// when we're in homestead this also counts for code storage gas errors.
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
if !errors.Is(err, ErrExecutionReverted) {
|
||||
gas = 0
|
||||
}
|
||||
// TODO: consider clearing up unused snapshots:
|
||||
|
|
@ -283,7 +295,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
|
||||
// It is allowed to call precompiles, even via delegatecall
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||
ret, gas, err = evm.PrecompileManager.Run(evm, p, input, caller.Address(), value, gas, false)
|
||||
} else {
|
||||
addrCopy := addr
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
|
|
@ -295,7 +307,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
if !errors.Is(err, ErrExecutionReverted) {
|
||||
gas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -328,7 +340,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
|
||||
// It is allowed to call precompiles, even via delegatecall
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||
ret, gas, err = evm.PrecompileManager.Run(evm, p, input, caller.Address(), new(big.Int), gas, false)
|
||||
} else {
|
||||
addrCopy := addr
|
||||
// Initialise a new contract and make initialise the delegate values
|
||||
|
|
@ -339,7 +351,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
if !errors.Is(err, ErrExecutionReverted) {
|
||||
gas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -377,7 +389,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
|||
}
|
||||
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas)
|
||||
ret, gas, err = evm.PrecompileManager.Run(evm, p, input, caller.Address(), new(big.Int), gas, true)
|
||||
} else {
|
||||
// At this point, we use a copy of address. If we don't, the go compiler will
|
||||
// leak the 'contract' to the outer scope, and make allocation for 'contract'
|
||||
|
|
@ -395,7 +407,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
if !errors.Is(err, ErrExecutionReverted) {
|
||||
gas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -490,7 +502,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
// when we're in homestead this also counts for code storage gas errors.
|
||||
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
if !errors.Is(err, ErrExecutionReverted) {
|
||||
contract.UseGas(contract.Gas)
|
||||
}
|
||||
}
|
||||
|
|
@ -523,3 +535,5 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
|
|||
|
||||
// ChainConfig returns the environment's chain configuration
|
||||
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||
func (evm *EVM) GetContext() *BlockContext { return &evm.Context }
|
||||
func (evm *EVM) GetStateDB() StateDB { return evm.StateDB }
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ func TestOpTstore(t *testing.T) {
|
|||
value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700")
|
||||
)
|
||||
|
||||
// Add a stateObject for the caller and the contract being called
|
||||
// Add a StateObject for the caller and the contract being called
|
||||
statedb.CreateAccount(caller)
|
||||
statedb.CreateAccount(to)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,64 +20,14 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// StateDB is an EVM database for full state querying.
|
||||
type StateDB interface {
|
||||
CreateAccount(common.Address)
|
||||
|
||||
SubBalance(common.Address, *big.Int)
|
||||
AddBalance(common.Address, *big.Int)
|
||||
GetBalance(common.Address) *big.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
SetNonce(common.Address, uint64)
|
||||
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
GetCode(common.Address) []byte
|
||||
SetCode(common.Address, []byte)
|
||||
GetCodeSize(common.Address) int
|
||||
|
||||
AddRefund(uint64)
|
||||
SubRefund(uint64)
|
||||
GetRefund() uint64
|
||||
|
||||
GetCommittedState(common.Address, common.Hash) common.Hash
|
||||
GetState(common.Address, common.Hash) common.Hash
|
||||
SetState(common.Address, common.Hash, common.Hash)
|
||||
|
||||
GetTransientState(addr common.Address, key common.Hash) common.Hash
|
||||
SetTransientState(addr common.Address, key, value common.Hash)
|
||||
|
||||
SelfDestruct(common.Address)
|
||||
HasSelfDestructed(common.Address) bool
|
||||
|
||||
Selfdestruct6780(common.Address)
|
||||
|
||||
// Exist reports whether the given account exists in state.
|
||||
// Notably this should also return true for self-destructed accounts.
|
||||
Exist(common.Address) bool
|
||||
// Empty returns whether the given account is empty. Empty
|
||||
// is defined according to EIP161 (balance = nonce = code = 0).
|
||||
Empty(common.Address) bool
|
||||
|
||||
AddressInAccessList(addr common.Address) bool
|
||||
SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool)
|
||||
// AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddAddressToAccessList(addr common.Address)
|
||||
// AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddSlotToAccessList(addr common.Address, slot common.Hash)
|
||||
Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList)
|
||||
|
||||
RevertToSnapshot(int)
|
||||
Snapshot() int
|
||||
|
||||
AddLog(*types.Log)
|
||||
AddPreimage(common.Hash, []byte)
|
||||
state.StateDBI
|
||||
}
|
||||
|
||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM
|
||||
|
|
@ -92,3 +42,30 @@ type CallContext interface {
|
|||
// Create creates a new contract
|
||||
Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
|
||||
}
|
||||
|
||||
type (
|
||||
// PrecompileManager allows the EVM to execute a precompiled contract.
|
||||
PrecompileManager interface {
|
||||
// `Get` returns the precompiled contract at `addr`. Returns nil if no
|
||||
// contract is found at `addr`.
|
||||
Get(addr common.Address, rules *params.Rules) (PrecompiledContract, bool)
|
||||
|
||||
GetActive(params.Rules) []common.Address
|
||||
|
||||
// `Run` runs a precompiled contract and returns the remaining gas.
|
||||
Run(evm PrecompileEVM, p PrecompiledContract, input []byte, caller common.Address,
|
||||
value *big.Int, suppliedGas uint64, readonly bool,
|
||||
) (ret []byte, remainingGas uint64, err error)
|
||||
}
|
||||
|
||||
// PrecompileEVM is the interface through which stateful precompiles can call back into the EVM.
|
||||
PrecompileEVM interface {
|
||||
GetStateDB() StateDB
|
||||
|
||||
Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error)
|
||||
StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error)
|
||||
Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error)
|
||||
Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error)
|
||||
GetContext() *BlockContext
|
||||
}
|
||||
)
|
||||
|
|
|
|||
61
core/vm/precompile_manager.go
Normal file
61
core/vm/precompile_manager.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2014 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 vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// precompileManager is used as a default PrecompileManager for the EVM.
|
||||
type precompileManager struct {
|
||||
}
|
||||
|
||||
// NewPrecompileManager returns a new PrecompileManager for the current chain rules.
|
||||
func NewPrecompileManager() PrecompileManager {
|
||||
return &precompileManager{}
|
||||
}
|
||||
|
||||
// Get returns the precompiled contract deployed at the given address.
|
||||
func (pm *precompileManager) Get(addr common.Address, rules *params.Rules) (PrecompiledContract, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// GetActive sets the chain rules on the precompile manager and returns the list of active
|
||||
// precompile addresses.
|
||||
func (pm *precompileManager) GetActive(rules params.Rules) []common.Address {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run runs the given precompiled contract with the given input data and returns the remaining gas.
|
||||
func (pm *precompileManager) Run(
|
||||
evm PrecompileEVM, p PrecompiledContract, input []byte,
|
||||
caller common.Address, value *big.Int, suppliedGas uint64, _ bool,
|
||||
) (ret []byte, remainingGas uint64, err error) {
|
||||
gasCost := p.RequiredGas(input)
|
||||
if gasCost > suppliedGas {
|
||||
return nil, 0, ErrOutOfGas
|
||||
}
|
||||
|
||||
suppliedGas -= gasCost
|
||||
output, err := p.Run(context.Background(), evm, input, caller, value)
|
||||
|
||||
return output, suppliedGas, err
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ type Config struct {
|
|||
BlobHashes []common.Hash
|
||||
Random *common.Hash
|
||||
|
||||
State *state.StateDB
|
||||
State state.StateDBI
|
||||
GetHashFn func(n uint64) common.Hash
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ func setDefaults(cfg *Config) {
|
|||
//
|
||||
// Execute sets up an in-memory, temporary, environment for the execution of
|
||||
// the given code. It makes sure that it's restored to its original state afterwards.
|
||||
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||
func Execute(code, input []byte, cfg *Config) ([]byte, state.StateDBI, error) {
|
||||
if cfg == nil {
|
||||
cfg = new(Config)
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
// Execute the preparatory steps for state transition which includes:
|
||||
// - prepare accessList(post-berlin)
|
||||
// - reset transient storage(eip 1153)
|
||||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
|
||||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(vmenv, rules), nil)
|
||||
cfg.State.CreateAccount(address)
|
||||
// set the receiver's (the executing contract) code for execution.
|
||||
cfg.State.SetCode(address, code)
|
||||
|
|
@ -153,7 +153,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
// Execute the preparatory steps for state transition which includes:
|
||||
// - prepare accessList(post-berlin)
|
||||
// - reset transient storage(eip 1153)
|
||||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(rules), nil)
|
||||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(vmenv, rules), nil)
|
||||
// Call the code with the given configuration.
|
||||
code, address, leftOverGas, err := vmenv.Create(
|
||||
sender,
|
||||
|
|
@ -181,7 +181,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
|||
// Execute the preparatory steps for state transition which includes:
|
||||
// - prepare accessList(post-berlin)
|
||||
// - reset transient storage(eip 1153)
|
||||
statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
|
||||
statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(vmenv, rules), nil)
|
||||
|
||||
// Call the code with the given configuration.
|
||||
ret, leftOverGas, err := vmenv.Call(
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
|||
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) (state.StateDBI, *types.Header, error) {
|
||||
// Pending state is only known by the miner
|
||||
if number == rpc.PendingBlockNumber {
|
||||
block, state := b.eth.miner.Pending()
|
||||
|
|
@ -210,7 +210,7 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.B
|
|||
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) (state.StateDBI, *types.Header, error) {
|
||||
if blockNr, ok := blockNrOrHash.Number(); ok {
|
||||
return b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
}
|
||||
|
|
@ -249,7 +249,7 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
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() error) {
|
||||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state state.StateDBI, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
|
||||
if vmConfig == nil {
|
||||
vmConfig = b.eth.blockchain.GetVMConfig()
|
||||
}
|
||||
|
|
@ -263,6 +263,11 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *st
|
|||
return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig), state.Error
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetBlockContext(ctx context.Context, header *types.Header) *vm.BlockContext {
|
||||
blockContext := core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
||||
return &blockContext
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||
return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch)
|
||||
}
|
||||
|
|
@ -408,10 +413,10 @@ func (b *EthAPIBackend) StartMining() error {
|
|||
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 state.StateDBI, readOnly bool, preferDisk bool) (state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
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, state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
|
@ -134,7 +134,7 @@ const AccountRangeMaxResults = 256
|
|||
|
||||
// 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.IteratorDump, error) {
|
||||
var stateDb *state.StateDB
|
||||
var stateDb state.StateDBI
|
||||
var err error
|
||||
|
||||
if number, ok := blockNrOrHash.Number(); ok {
|
||||
|
|
@ -229,7 +229,7 @@ func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockNrOrHash rpc.Block
|
|||
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 state.StateDBI, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) {
|
||||
storageRoot := statedb.GetStorageRoot(address)
|
||||
if storageRoot == types.EmptyRootHash || storageRoot == (common.Hash{}) {
|
||||
return StorageRangeResult{}, nil // empty storage
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import (
|
|||
|
||||
var dumper = spew.ConfigState{Indent: " "}
|
||||
|
||||
func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
|
||||
func accountRangeTest(t *testing.T, trie *state.Trie, statedb state.StateDBI, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
|
||||
result := statedb.IteratorDump(&state.DumpConfig{
|
||||
SkipCode: true,
|
||||
SkipStorage: true,
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/miner"
|
||||
|
|
@ -242,7 +242,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||
}
|
||||
|
||||
eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock)
|
||||
eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))
|
||||
eth.miner.SetExtra(MakeExtraData(config.Miner.ExtraData))
|
||||
|
||||
eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil}
|
||||
if eth.APIBackend.allowUnprotectedTxs {
|
||||
|
|
@ -279,7 +279,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||
return eth, nil
|
||||
}
|
||||
|
||||
func makeExtraData(extra []byte) []byte {
|
||||
func MakeExtraData(extra []byte) []byte {
|
||||
if len(extra) == 0 {
|
||||
// create default extradata
|
||||
extra, _ = rlp.EncodeToBytes([]interface{}{
|
||||
|
|
@ -299,8 +299,7 @@ func makeExtraData(extra []byte) []byte {
|
|||
// APIs return the collection of RPC services the ethereum package offers.
|
||||
// NOTE, some of these services probably need to be moved to somewhere else.
|
||||
func (s *Ethereum) APIs() []rpc.API {
|
||||
apis := ethapi.GetAPIs(s.APIBackend)
|
||||
|
||||
apis := ethapi.GetAPIs(s.APIBackend, s.BlockChain())
|
||||
// Append any APIs exposed explicitly by the consensus engine
|
||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
||||
|
||||
|
|
@ -468,6 +467,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner }
|
|||
|
||||
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
|
||||
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
|
||||
func (s *Ethereum) MinerChain() miner.BlockChain { return s.blockchain }
|
||||
func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool }
|
||||
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
|
||||
func (s *Ethereum) Engine() consensus.Engine { return s.engine }
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.
|
|||
func (es *EventSystem) eventLoop() {
|
||||
// Ensure all subscriptions get cleaned up
|
||||
defer func() {
|
||||
es.txsSub.Unsubscribe()
|
||||
// es.txsSub.Unsubscribe()
|
||||
es.logsSub.Unsubscribe()
|
||||
es.rmLogsSub.Unsubscribe()
|
||||
es.pendingLogsSub.Unsubscribe()
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ const (
|
|||
minTrienodeHealThrottle = 1
|
||||
|
||||
// maxTrienodeHealThrottle is the maximum divisor for throttling trie node
|
||||
// heal requests to avoid overloading the local node and exessively expanding
|
||||
// the state trie bedth wise.
|
||||
// heal requests to avoid overloading the local node and excessively expanding
|
||||
// the state trie breadth wise.
|
||||
maxTrienodeHealThrottle = maxTrieRequestCount
|
||||
|
||||
// trienodeHealThrottleIncrease is the multiplier for the throttle when the
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import (
|
|||
// for releasing state.
|
||||
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 state.StateDBI, readOnly bool, preferDisk bool) (statedb state.StateDBI, release tracers.StateReleaseFunc, err error) {
|
||||
var (
|
||||
current *types.Block
|
||||
database state.Database
|
||||
|
|
@ -174,7 +174,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
|||
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) (state.StateDBI, func(), error) {
|
||||
// Check if the requested state is available in the live chain.
|
||||
statedb, err := eth.blockchain.StateAt(block.Root())
|
||||
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
|
||||
// provided, it would be preferable to start from a fresh state, if we have it
|
||||
// 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 state.StateDBI, readOnly bool, preferDisk bool) (statedb state.StateDBI, release tracers.StateReleaseFunc, err error) {
|
||||
if eth.blockchain.TrieDB().Scheme() == rawdb.HashScheme {
|
||||
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.
|
||||
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, state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
// Short circuit if it's genesis block.
|
||||
if block.NumberU64() == 0 {
|
||||
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
|
||||
|
|
@ -240,13 +240,12 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||
if idx == txIndex {
|
||||
return msg, context, statedb, release, nil
|
||||
}
|
||||
// Not yet the searched for transaction, execute on top of the current state
|
||||
vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
|
||||
vmenv, vmError := eth.APIBackend.GetEVM(ctx, msg, statedb, block.Header(), &vm.Config{}, &context)
|
||||
statedb.SetTxContext(tx.Hash(), idx)
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
|
|
@ -254,6 +253,9 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
// Ensure any modifications are committed to the state
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
||||
if err := vmError(); err != nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("execution error: %v", err)
|
||||
}
|
||||
}
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
|
|
@ -85,8 +85,8 @@ type Backend interface {
|
|||
ChainConfig() *params.ChainConfig
|
||||
Engine() consensus.Engine
|
||||
ChainDb() ethdb.Database
|
||||
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error)
|
||||
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
|
||||
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base state.StateDBI, readOnly bool, preferDisk bool) (state.StateDBI, StateReleaseFunc, error)
|
||||
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, state.StateDBI, StateReleaseFunc, error)
|
||||
}
|
||||
|
||||
// API is the collection of tracing APIs exposed over the private debugging endpoint.
|
||||
|
|
@ -183,7 +183,7 @@ type txTraceResult struct {
|
|||
// blockTraceTask represents a single block trace task when an entire chain is
|
||||
// being traced.
|
||||
type blockTraceTask struct {
|
||||
statedb *state.StateDB // Intermediate state prepped for tracing
|
||||
statedb state.StateDBI // Intermediate state prepped for tracing
|
||||
block *types.Block // Block to trace the transactions from
|
||||
release StateReleaseFunc // The function to release the held resource for this task
|
||||
results []*txTraceResult // Trace results produced by the task
|
||||
|
|
@ -200,7 +200,7 @@ type blockTraceResult struct {
|
|||
// txTraceTask represents a single transaction trace task when an entire block
|
||||
// is being traced.
|
||||
type txTraceTask struct {
|
||||
statedb *state.StateDB // Intermediate state prepped for tracing
|
||||
statedb state.StateDBI // Intermediate state prepped for tracing
|
||||
index int // Transaction offset in the block
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
|||
number uint64
|
||||
traced uint64
|
||||
failed error
|
||||
statedb *state.StateDB
|
||||
statedb state.StateDBI
|
||||
release StateReleaseFunc
|
||||
)
|
||||
// Ensure everything is properly cleaned up on any exit path
|
||||
|
|
@ -626,7 +626,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
|
||||
// runs along and executes txes without tracing enabled to generate their prestate.
|
||||
// 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 state.StateDBI, config *TraceConfig) ([]*txTraceResult, error) {
|
||||
// Execute all the transaction contained within the block concurrently
|
||||
var (
|
||||
txs = block.Transactions()
|
||||
|
|
@ -922,7 +922,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
|||
// traceTx configures a new tracer according to the provided configuration, and
|
||||
// executes the given message in the provided environment. The return value will
|
||||
// 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 state.StateDBI, config *TraceConfig) (interface{}, error) {
|
||||
var (
|
||||
tracer Tracer
|
||||
err error
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/exp/slices"
|
||||
|
|
@ -139,7 +139,7 @@ func (b *testBackend) teardown() {
|
|||
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 state.StateDBI, readOnly bool, preferDisk bool) (state.StateDBI, StateReleaseFunc, error) {
|
||||
statedb, err := b.chain.StateAt(block.Root())
|
||||
if err != nil {
|
||||
return nil, nil, errStateNotFound
|
||||
|
|
@ -155,7 +155,7 @@ func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reex
|
|||
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, state.StateDBI, StateReleaseFunc, error) {
|
||||
parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||
if parent == nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, errBlockNotFound
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
|
|||
t.ctx["block"] = t.vm.ToValue(env.Context.BlockNumber.Uint64())
|
||||
// Update list of precompiles based on current block
|
||||
rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(rules)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(env, rules)
|
||||
}
|
||||
|
||||
// CaptureState implements the Tracer interface to trace a single step of VM execution.
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ type accessList map[common.Address]accessListSlots
|
|||
// contract that an EVM contract execution touches.
|
||||
type accessListSlots map[common.Hash]struct{}
|
||||
|
||||
// newAccessList creates a new accessList.
|
||||
func newAccessList() accessList {
|
||||
// NewAccessList creates a new accessList.
|
||||
func NewAccessList() accessList {
|
||||
return make(map[common.Address]accessListSlots)
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompi
|
|||
for _, addr := range precompiles {
|
||||
excl[addr] = struct{}{}
|
||||
}
|
||||
list := newAccessList()
|
||||
list := NewAccessList()
|
||||
for _, al := range acl {
|
||||
if _, ok := excl[al.Address]; !ok {
|
||||
list.addAddress(al.Address)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ func (t *fourByteTracer) store(id []byte, size int) {
|
|||
func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
// Update list of precompiles based on current block
|
||||
rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(rules)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(env, rules)
|
||||
|
||||
// Save the outer calldata also
|
||||
if len(input) >= 4 {
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ func (t *flatCallTracer) CaptureStart(env *vm.EVM, from common.Address, to commo
|
|||
t.tracer.CaptureStart(env, from, to, create, input, gas, value)
|
||||
// Update list of precompiles based on current block
|
||||
rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(rules)
|
||||
t.activePrecompiles = vm.ActivePrecompiles(env, rules)
|
||||
}
|
||||
|
||||
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||
|
|
|
|||
|
|
@ -732,14 +732,17 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
|
|||
}
|
||||
|
||||
// Create the accountProof.
|
||||
tr, err := trie.NewStateTrie(trie.StateTrieID(header.Root), state.Database().TrieDB())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var accountProof proofList
|
||||
if err := tr.Prove(crypto.Keccak256(address.Bytes()), &accountProof); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// tr, err := trie.NewStateTrie(trie.StateTrieID(header.Root), state.Database().TrieDB())
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// TODO: Support Proofs
|
||||
var accountProof proofList = make(proofList, 0)
|
||||
// if err := tr.Prove(crypto.Keccak256(address.Bytes()), &accountProof); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
return &AccountResult{
|
||||
Address: address,
|
||||
AccountProof: accountProof,
|
||||
|
|
@ -951,7 +954,7 @@ type OverrideAccount struct {
|
|||
type StateOverride map[common.Address]OverrideAccount
|
||||
|
||||
// Apply overrides the fields of specified accounts into the given state.
|
||||
func (diff *StateOverride) Apply(state *state.StateDB) error {
|
||||
func (diff *StateOverride) Apply(state state.StateDBI) error {
|
||||
if diff == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -959,6 +962,9 @@ func (diff *StateOverride) Apply(state *state.StateDB) error {
|
|||
// Override account nonce.
|
||||
if account.Nonce != nil {
|
||||
state.SetNonce(addr, uint64(*account.Nonce))
|
||||
if err := state.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Override account(contract) code.
|
||||
if account.Code != nil {
|
||||
|
|
@ -967,6 +973,9 @@ func (diff *StateOverride) Apply(state *state.StateDB) error {
|
|||
// Override account balance.
|
||||
if account.Balance != nil {
|
||||
state.SetBalance(addr, (*big.Int)(*account.Balance))
|
||||
if err := state.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if account.State != nil && account.StateDiff != nil {
|
||||
return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
|
||||
|
|
@ -1060,7 +1069,7 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H
|
|||
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 state.StateDBI, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||
if err := overrides.Apply(state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1081,11 +1090,11 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
|
||||
blockCtx := b.GetBlockContext(ctx, header)
|
||||
if blockOverrides != nil {
|
||||
blockOverrides.Apply(&blockCtx)
|
||||
blockOverrides.Apply(blockCtx)
|
||||
}
|
||||
evm, vmError := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx)
|
||||
evm, vmError := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, blockCtx)
|
||||
|
||||
// Wait for the context to be done and cancel the evm. Even if the
|
||||
// EVM has finished, cancelling may be done (repeatedly)
|
||||
|
|
@ -1177,7 +1186,7 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO
|
|||
// 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 *state.StateDB, header *types.Header, gasCap uint64, gasLimit uint64) (bool, *core.ExecutionResult, error) {
|
||||
func executeEstimate(ctx context.Context, b Backend, args TransactionArgs, state state.StateDBI, 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 {
|
||||
|
|
@ -1309,6 +1318,11 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
|||
hi = mid
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIGURE OUT WHY THIS HACK IS NEEDED THANKS
|
||||
// bump the estimate gas by 20% for stateful precompiles
|
||||
hi += uint64(float64(hi) * 0.2)
|
||||
|
||||
return hexutil.Uint64(hi), nil
|
||||
}
|
||||
|
||||
|
|
@ -1617,8 +1631,14 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
|||
to = crypto.CreateAddress(args.from(), uint64(*args.Nonce))
|
||||
}
|
||||
isPostMerge := header.Difficulty.Cmp(common.Big0) == 0
|
||||
rules := b.ChainConfig().Rules(header.Number, isPostMerge, header.Time)
|
||||
// Retrieve the precompiles since they don't need to be added to the access list
|
||||
precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, isPostMerge, header.Time))
|
||||
state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
precompiles := vm.ActivePrecompiles(vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, state, b.ChainConfig(), vm.Config{}), rules) // TODO: use evm precompile manager instead
|
||||
|
||||
// Create an initial tracer
|
||||
prevTracer := logger.NewAccessListTracer(nil, args.from(), to, precompiles)
|
||||
|
|
@ -501,7 +501,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) {
|
||||
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) (state.StateDBI, *types.Header, error) {
|
||||
if number == rpc.PendingBlockNumber {
|
||||
panic("pending state not implemented")
|
||||
}
|
||||
|
|
@ -515,7 +515,7 @@ func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.Bloc
|
|||
stateDb, err := b.chain.StateAt(header.Root)
|
||||
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) (state.StateDBI, *types.Header, error) {
|
||||
if blockNr, ok := blockNrOrHash.Number(); ok {
|
||||
return b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
}
|
||||
|
|
@ -536,7 +536,7 @@ func (b testBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
}
|
||||
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() error) {
|
||||
func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state state.StateDBI, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) (*vm.EVM, func() error) {
|
||||
vmError := func() error { return nil }
|
||||
if vmConfig == nil {
|
||||
vmConfig = b.chain.GetVMConfig()
|
||||
|
|
@ -548,6 +548,10 @@ func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state
|
|||
}
|
||||
return vm.NewEVM(context, txContext, state, b.chain.Config(), *vmConfig), vmError
|
||||
}
|
||||
func (b testBackend) GetBlockContext(ctx context.Context, header *types.Header) *vm.BlockContext {
|
||||
blockContext := core.NewEVMBlockContext(header, b.chain, nil)
|
||||
return &blockContext
|
||||
}
|
||||
func (b testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
|
||||
panic("implement me")
|
||||
}
|
||||
|
|
@ -63,12 +63,13 @@ type Backend interface {
|
|||
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
|
||||
BlockByHash(ctx context.Context, hash common.Hash) (*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)
|
||||
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
|
||||
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (state.StateDBI, *types.Header, error)
|
||||
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDBI, *types.Header, error)
|
||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
||||
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, func() error)
|
||||
GetEVM(ctx context.Context, msg *core.Message, state state.StateDBI, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error)
|
||||
GetBlockContext(ctx context.Context, header *types.Header) *vm.BlockContext
|
||||
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
|
||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
|
||||
|
|
@ -99,7 +100,7 @@ type Backend interface {
|
|||
ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
|
||||
}
|
||||
|
||||
func GetAPIs(apiBackend Backend) []rpc.API {
|
||||
func GetAPIs(apiBackend Backend, chain core.ChainContext) []rpc.API {
|
||||
nonceLock := new(AddrLocker)
|
||||
return []rpc.API{
|
||||
{
|
||||
|
|
@ -291,10 +291,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) {
|
||||
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) (state.StateDBI, *types.Header, error) {
|
||||
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) (state.StateDBI, *types.Header, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
func (b *backendMock) PendingBlockAndReceipts() (*types.Block, types.Receipts) { return nil, nil }
|
||||
|
|
@ -305,9 +305,12 @@ func (b *backendMock) GetLogs(ctx context.Context, blockHash common.Hash, number
|
|||
return nil, 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() error) {
|
||||
func (b *backendMock) GetEVM(ctx context.Context, msg *core.Message, state state.StateDBI, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (b *backendMock) GetBlockContext(ctx context.Context, header *types.Header) *vm.BlockContext {
|
||||
return nil
|
||||
}
|
||||
func (b *backendMock) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return nil }
|
||||
func (b *backendMock) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
|
||||
return nil
|
||||
|
|
@ -51,6 +51,16 @@ func (s *senderFromServer) Sender(tx *types.Transaction) (common.Address, error)
|
|||
return s.addr, nil
|
||||
}
|
||||
|
||||
func (s *senderFromServer) PubKey(tx *types.Transaction) ([]byte, error) {
|
||||
// not implemented
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *senderFromServer) Signature(tx *types.Transaction) ([]byte, error) {
|
||||
// not implemented
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *senderFromServer) ChainID() *big.Int {
|
||||
panic("can't sign with senderFromServer")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
|
@ -85,7 +85,7 @@ type Account struct {
|
|||
}
|
||||
|
||||
// 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) (state.StateDBI, error) {
|
||||
state, _, err := a.r.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
|
||||
return state, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/graph-gophers/graphql-go"
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ func (b *LesApiBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
|
||||
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (state.StateDBI, *types.Header, error) {
|
||||
header, err := b.HeaderByNumber(ctx, number)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
@ -148,7 +148,7 @@ func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.B
|
|||
return light.NewState(ctx, header, b.eth.odr), header, nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
|
||||
func (b *LesApiBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDBI, *types.Header, error) {
|
||||
if blockNr, ok := blockNrOrHash.Number(); ok {
|
||||
return b.StateAndHeaderByNumber(ctx, blockNr)
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ func (b *LesApiBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
|
||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state state.StateDBI, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error) {
|
||||
if vmConfig == nil {
|
||||
vmConfig = new(vm.Config)
|
||||
}
|
||||
|
|
@ -195,6 +195,11 @@ func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *st
|
|||
return vm.NewEVM(context, txContext, state, b.eth.chainConfig, *vmConfig), state.Error
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBlockContext(_ context.Context, header *types.Header) *vm.BlockContext {
|
||||
blockContext := core.NewEVMBlockContext(header, b.eth.blockchain, nil)
|
||||
return &blockContext
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||
return b.eth.txPool.Add(ctx, signedTx)
|
||||
}
|
||||
|
|
@ -328,10 +333,10 @@ func (b *LesApiBackend) CurrentHeader() *types.Header {
|
|||
return b.eth.blockchain.CurrentHeader()
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (b *LesApiBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base state.StateDBI, readOnly bool, preferDisk bool) (state.StateDBI, 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, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
|
||||
"github.com/ethereum/go-ethereum/les/vflux"
|
||||
vfc "github.com/ethereum/go-ethereum/les/vflux/client"
|
||||
|
|
@ -288,7 +288,7 @@ func (s *LightDummyAPI) Mining() bool {
|
|||
// APIs returns the collection of RPC services the ethereum package offers.
|
||||
// NOTE, some of these services probably need to be moved to somewhere else.
|
||||
func (s *LightEthereum) APIs() []rpc.API {
|
||||
apis := ethapi.GetAPIs(s.ApiBackend)
|
||||
apis := ethapi.GetAPIs(s.ApiBackend, s.BlockChain())
|
||||
apis = append(apis, s.engine.APIs(s.BlockChain().HeaderChain())...)
|
||||
return append(apis, []rpc.API{
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainCon
|
|||
|
||||
var (
|
||||
res []byte
|
||||
st *state.StateDB
|
||||
st state.StateDBI
|
||||
err error
|
||||
)
|
||||
for _, addr := range acc {
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ import (
|
|||
var noopReleaser = tracers.StateReleaseFunc(func() {})
|
||||
|
||||
// stateAtBlock retrieves the state database associated with a certain block.
|
||||
func (leth *LightEthereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64) (*state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (leth *LightEthereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64) (state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
return light.NewState(ctx, block.Header(), leth.odr), noopReleaser, nil
|
||||
}
|
||||
|
||||
// stateAtTransaction returns the execution environment of a certain transaction.
|
||||
func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, state.StateDBI, tracers.StateReleaseFunc, error) {
|
||||
// Short circuit if it's genesis block.
|
||||
if block.NumberU64() == 0 {
|
||||
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ func odrAccounts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc
|
|||
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
|
||||
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
|
||||
|
||||
var st *state.StateDB
|
||||
var st state.StateDBI
|
||||
if bc == nil {
|
||||
header := lc.GetHeaderByHash(bhash)
|
||||
st = NewState(ctx, header, lc.Odr())
|
||||
|
|
@ -185,7 +185,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
data[35] = byte(i)
|
||||
|
||||
var (
|
||||
st *state.StateDB
|
||||
st state.StateDBI
|
||||
header *types.Header
|
||||
chain core.ChainContext
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ var (
|
|||
sha3Nil = crypto.Keccak256Hash(nil)
|
||||
)
|
||||
|
||||
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB {
|
||||
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) state.StateDBI {
|
||||
state, _ := state.New(head.Root, NewStateDatabase(ctx, head, odr), nil)
|
||||
return state
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func NewTxPool(config *params.ChainConfig, chain *LightChain, relay TxRelayBacke
|
|||
}
|
||||
|
||||
// currentState returns the light state of the current head header
|
||||
func (pool *TxPool) currentState(ctx context.Context) *state.StateDB {
|
||||
func (pool *TxPool) currentState(ctx context.Context) state.StateDBI {
|
||||
return NewState(ctx, pool.chain.CurrentHeader(), pool.odr)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/txpool"
|
||||
"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/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -39,10 +40,23 @@ import (
|
|||
// Backend wraps all methods required for mining. Only full node is capable
|
||||
// to offer all the functions here.
|
||||
type Backend interface {
|
||||
BlockChain() *core.BlockChain
|
||||
MinerChain() BlockChain
|
||||
TxPool() *txpool.TxPool
|
||||
}
|
||||
|
||||
type BlockChain interface {
|
||||
GetVMConfig() *vm.Config
|
||||
Engine() consensus.Engine
|
||||
CurrentBlock() *types.Header
|
||||
StateAt(common.Hash) (state.StateDBI, error)
|
||||
StateAtBlockNumber(uint64) (state.StateDBI, error)
|
||||
GetBlockByHash(common.Hash) *types.Block
|
||||
consensus.ChainHeaderReader
|
||||
HasBlock(common.Hash, uint64) bool
|
||||
SubscribeChainHeadEvent(chan<- core.ChainHeadEvent) event.Subscription
|
||||
WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state state.StateDBI, emitHeadEvent bool) (status core.WriteStatus, err error)
|
||||
}
|
||||
|
||||
// Config is the configuration parameters of mining.
|
||||
type Config struct {
|
||||
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards
|
||||
|
|
@ -204,7 +218,7 @@ func (miner *Miner) SetRecommitInterval(interval time.Duration) {
|
|||
|
||||
// Pending returns the currently pending block and associated state. The returned
|
||||
// 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, state.StateDBI) {
|
||||
return miner.worker.pending()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import (
|
|||
)
|
||||
|
||||
type mockBackend struct {
|
||||
bc *core.BlockChain
|
||||
bc BlockChain
|
||||
txPool *txpool.TxPool
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,11 @@ func NewMockBackend(bc *core.BlockChain, txPool *txpool.TxPool) *mockBackend {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *mockBackend) BlockChain() *core.BlockChain {
|
||||
func (m *mockBackend) BlockChain() BlockChain {
|
||||
return m.bc
|
||||
}
|
||||
|
||||
func (m *mockBackend) MinerChain() BlockChain {
|
||||
return m.bc
|
||||
}
|
||||
|
||||
|
|
@ -59,14 +63,14 @@ func (m *mockBackend) TxPool() *txpool.TxPool {
|
|||
return m.txPool
|
||||
}
|
||||
|
||||
func (m *mockBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) {
|
||||
func (m *mockBackend) StateAtBlock(block *types.Block, reexec uint64, base state.StateDBI, checkLive bool, preferDisk bool) (statedb state.StateDBI, err error) {
|
||||
return nil, errors.New("not supported")
|
||||
}
|
||||
|
||||
type testBlockChain struct {
|
||||
root common.Hash
|
||||
config *params.ChainConfig
|
||||
statedb *state.StateDB
|
||||
statedb state.StateDBI
|
||||
gasLimit uint64
|
||||
chainHeadFeed *event.Feed
|
||||
}
|
||||
|
|
@ -86,7 +90,11 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
|
|||
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) (state.StateDBI, error) {
|
||||
return bc.statedb, nil
|
||||
}
|
||||
|
||||
func (bc *testBlockChain) StateAtBlockNumber(uint64) (state.StateDBI, error) {
|
||||
return bc.statedb, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,22 +80,22 @@ func (s *txByPriceAndTime) Pop() interface{} {
|
|||
return x
|
||||
}
|
||||
|
||||
// transactionsByPriceAndNonce represents a set of transactions that can return
|
||||
// TransactionsByPriceAndNonce represents a set of transactions that can return
|
||||
// transactions in a profit-maximizing sorted order, while supporting removing
|
||||
// entire batches of transactions for non-executable accounts.
|
||||
type transactionsByPriceAndNonce struct {
|
||||
type TransactionsByPriceAndNonce struct {
|
||||
txs map[common.Address][]*txpool.LazyTransaction // Per account nonce-sorted list of transactions
|
||||
heads txByPriceAndTime // Next transaction for each unique account (price heap)
|
||||
signer types.Signer // Signer for the set of transactions
|
||||
baseFee *big.Int // Current base fee
|
||||
}
|
||||
|
||||
// newTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
||||
// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
||||
// price sorted transactions in a nonce-honouring way.
|
||||
//
|
||||
// Note, the input map is reowned so the caller should not interact any more with
|
||||
// if after providing it to the constructor.
|
||||
func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address][]*txpool.LazyTransaction, baseFee *big.Int) *transactionsByPriceAndNonce {
|
||||
func NewTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address][]*txpool.LazyTransaction, baseFee *big.Int) *TransactionsByPriceAndNonce {
|
||||
// Initialize a price and received time based heap with the head transactions
|
||||
heads := make(txByPriceAndTime, 0, len(txs))
|
||||
for from, accTxs := range txs {
|
||||
|
|
@ -110,7 +110,7 @@ func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address]
|
|||
heap.Init(&heads)
|
||||
|
||||
// Assemble and return the transaction set
|
||||
return &transactionsByPriceAndNonce{
|
||||
return &TransactionsByPriceAndNonce{
|
||||
txs: txs,
|
||||
heads: heads,
|
||||
signer: signer,
|
||||
|
|
@ -119,7 +119,7 @@ func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address]
|
|||
}
|
||||
|
||||
// Peek returns the next transaction by price.
|
||||
func (t *transactionsByPriceAndNonce) Peek() *txpool.LazyTransaction {
|
||||
func (t *TransactionsByPriceAndNonce) Peek() *txpool.LazyTransaction {
|
||||
if len(t.heads) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ func (t *transactionsByPriceAndNonce) Peek() *txpool.LazyTransaction {
|
|||
}
|
||||
|
||||
// Shift replaces the current best head with the next one from the same account.
|
||||
func (t *transactionsByPriceAndNonce) Shift() {
|
||||
func (t *TransactionsByPriceAndNonce) Shift() {
|
||||
acc := t.heads[0].from
|
||||
if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
|
||||
if wrapped, err := newTxWithMinerFee(txs[0], acc, t.baseFee); err == nil {
|
||||
|
|
@ -142,6 +142,6 @@ func (t *transactionsByPriceAndNonce) Shift() {
|
|||
// Pop removes the best transaction, *not* replacing it with the next one from
|
||||
// the same account. This should be used when a transaction cannot be executed
|
||||
// and hence all subsequent ones should be discarded from the same account.
|
||||
func (t *transactionsByPriceAndNonce) Pop() {
|
||||
func (t *TransactionsByPriceAndNonce) Pop() {
|
||||
heap.Pop(&t.heads)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||
expectedCount += count
|
||||
}
|
||||
// Sort the transactions and cross check the nonce ordering
|
||||
txset := newTransactionsByPriceAndNonce(signer, groups, baseFee)
|
||||
txset := NewTransactionsByPriceAndNonce(signer, groups, baseFee)
|
||||
|
||||
txs := types.Transactions{}
|
||||
for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
|
||||
|
|
@ -160,7 +160,7 @@ func TestTransactionTimeSort(t *testing.T) {
|
|||
})
|
||||
}
|
||||
// Sort the transactions and cross check the nonce ordering
|
||||
txset := newTransactionsByPriceAndNonce(signer, groups, nil)
|
||||
txset := NewTransactionsByPriceAndNonce(signer, groups, nil)
|
||||
|
||||
txs := types.Transactions{}
|
||||
for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ var (
|
|||
// information of the sealing block generation.
|
||||
type environment struct {
|
||||
signer types.Signer
|
||||
state *state.StateDB // apply state changes here
|
||||
state state.StateDBI // apply state changes here
|
||||
tcount int // tx count in cycle
|
||||
gasPool *core.GasPool // available gas used to pack transactions
|
||||
coinbase common.Address
|
||||
|
|
@ -131,7 +131,7 @@ func (env *environment) discard() {
|
|||
// task contains all information for consensus engine sealing and result submitting.
|
||||
type task struct {
|
||||
receipts []*types.Receipt
|
||||
state *state.StateDB
|
||||
state state.StateDBI
|
||||
block *types.Block
|
||||
createdAt time.Time
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ type worker struct {
|
|||
chainConfig *params.ChainConfig
|
||||
engine consensus.Engine
|
||||
eth Backend
|
||||
chain *core.BlockChain
|
||||
chain BlockChain
|
||||
|
||||
// Feeds
|
||||
pendingLogsFeed event.Feed
|
||||
|
|
@ -212,7 +212,7 @@ type worker struct {
|
|||
snapshotMu sync.RWMutex // The lock used to protect the snapshots below
|
||||
snapshotBlock *types.Block
|
||||
snapshotReceipts types.Receipts
|
||||
snapshotState *state.StateDB
|
||||
snapshotState state.StateDBI
|
||||
|
||||
// atomic status counters
|
||||
running atomic.Bool // The indicator whether the consensus engine is running or not.
|
||||
|
|
@ -246,7 +246,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
chainConfig: chainConfig,
|
||||
engine: engine,
|
||||
eth: eth,
|
||||
chain: eth.BlockChain(),
|
||||
chain: eth.MinerChain(),
|
||||
mux: mux,
|
||||
isLocalBlock: isLocalBlock,
|
||||
coinbase: config.Etherbase,
|
||||
|
|
@ -266,7 +266,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
// Subscribe NewTxsEvent for tx pool
|
||||
worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh)
|
||||
// Subscribe events for blockchain
|
||||
worker.chainHeadSub = eth.BlockChain().SubscribeChainHeadEvent(worker.chainHeadCh)
|
||||
worker.chainHeadSub = eth.MinerChain().SubscribeChainHeadEvent(worker.chainHeadCh)
|
||||
|
||||
// Sanitize recommit interval if the user-specified one is too short.
|
||||
recommit := worker.config.Recommit
|
||||
|
|
@ -337,7 +337,7 @@ func (w *worker) setRecommitInterval(interval time.Duration) {
|
|||
|
||||
// pending returns the pending state and corresponding block. The returned
|
||||
// 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, state.StateDBI) {
|
||||
w.snapshotMu.RLock()
|
||||
defer w.snapshotMu.RUnlock()
|
||||
if w.snapshotState == nil {
|
||||
|
|
@ -549,7 +549,7 @@ func (w *worker) mainLoop() {
|
|||
GasTipCap: tx.GasTipCap(),
|
||||
})
|
||||
}
|
||||
txset := newTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
|
||||
txset := NewTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
|
||||
tcount := w.current.tcount
|
||||
w.commitTransactions(w.current, txset, nil)
|
||||
|
||||
|
|
@ -706,7 +706,10 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co
|
|||
// the miner to speed block sealing up a bit.
|
||||
state, err := w.chain.StateAt(parent.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
state, err = w.chain.StateAtBlockNumber(parent.Number.Uint64())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
state.StartPrefetcher("miner")
|
||||
|
||||
|
|
@ -791,7 +794,7 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction) (*typ
|
|||
return receipt, err
|
||||
}
|
||||
|
||||
func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error {
|
||||
func (w *worker) commitTransactions(env *environment, txs *TransactionsByPriceAndNonce, interrupt *atomic.Int32) error {
|
||||
gasLimit := env.header.GasLimit
|
||||
if env.gasPool == nil {
|
||||
env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
||||
|
|
@ -987,13 +990,13 @@ func (w *worker) fillTransactions(interrupt *atomic.Int32, env *environment) err
|
|||
|
||||
// Fill the block with all available pending transactions.
|
||||
if len(localTxs) > 0 {
|
||||
txs := newTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
txs := NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
if err := w.commitTransactions(env, txs, interrupt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(remoteTxs) > 0 {
|
||||
txs := newTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
txs := NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
if err := w.commitTransactions(env, txs, interrupt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,8 +144,9 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine
|
|||
}
|
||||
}
|
||||
|
||||
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
|
||||
func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool }
|
||||
func (b *testWorkerBackend) BlockChain() BlockChain { return b.chain }
|
||||
func (b *testWorkerBackend) MinerChain() BlockChain { return b.chain }
|
||||
func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool }
|
||||
|
||||
func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
|
||||
var tx *types.Transaction
|
||||
|
|
|
|||
16
node/node.go
16
node/node.go
|
|
@ -65,6 +65,9 @@ type Node struct {
|
|||
inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
|
||||
|
||||
databases map[*closeTrackingDB]struct{} // All open databases
|
||||
|
||||
// for Polaris
|
||||
disableP2P bool
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -200,6 +203,11 @@ func (n *Node) Start() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// SetP2PDisabled sets the P2P disabled flag.
|
||||
func (n *Node) SetP2PDisabled(disableP2P bool) {
|
||||
n.disableP2P = disableP2P
|
||||
}
|
||||
|
||||
// Close stops the Node and releases resources acquired in
|
||||
// Node constructor New.
|
||||
func (n *Node) Close() error {
|
||||
|
|
@ -265,9 +273,11 @@ func (n *Node) doClose(errs []error) error {
|
|||
// openEndpoints starts all network and RPC endpoints.
|
||||
func (n *Node) openEndpoints() error {
|
||||
// start networking endpoints
|
||||
n.log.Info("Starting peer-to-peer node", "instance", n.server.Name)
|
||||
if err := n.server.Start(); err != nil {
|
||||
return convertFileLockError(err)
|
||||
if !n.disableP2P {
|
||||
n.log.Info("Starting peer-to-peer node", "instance", n.server.Name)
|
||||
if err := n.server.Start(); err != nil {
|
||||
return convertFileLockError(err)
|
||||
}
|
||||
}
|
||||
// start RPC endpoints
|
||||
err := n.startRPC()
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ const (
|
|||
DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
|
||||
InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
|
||||
|
||||
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
|
||||
MaxCodeSize = 40000 // Maximum bytecode to permit for a contract
|
||||
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions
|
||||
|
||||
// Precompiled contract gas prices
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/signer/core"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/console/prompt"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package core
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/jsre/deps"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/signer/core"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/ethapi"
|
||||
"github.com/ethereum/go-ethereum/signer/core"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
"github.com/ethereum/go-ethereum/signer/storage"
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *BlockTest) validatePostState(statedb *state.StateDB) error {
|
||||
func (t *BlockTest) validatePostState(statedb state.StateDBI) error {
|
||||
// validate post state accounts in test file against what we have in state db
|
||||
for addr, acct := range t.json.Post {
|
||||
// address is indirectly verified by the other fields, as it's the db key
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package bls
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -92,7 +93,7 @@ func fuzz(id byte, data []byte) int {
|
|||
}
|
||||
cpy := make([]byte, len(data))
|
||||
copy(cpy, data)
|
||||
_, err := precompile.Run(cpy)
|
||||
_, err := precompile.Run(context.Background(), nil, cpy, common.Address{}, nil)
|
||||
if !bytes.Equal(cpy, data) {
|
||||
panic(fmt.Sprintf("input data modified, precompile %d: %x %x", id, data, cpy))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func TestState(t *testing.T) {
|
|||
t.Run(key+"/hash/trie", func(t *testing.T) {
|
||||
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
||||
var result error
|
||||
test.Run(subtest, vmconfig, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) {
|
||||
test.Run(subtest, vmconfig, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state state.StateDBI) {
|
||||
result = st.checkFailure(t, err)
|
||||
})
|
||||
return result
|
||||
|
|
@ -92,7 +92,7 @@ func TestState(t *testing.T) {
|
|||
t.Run(key+"/hash/snap", func(t *testing.T) {
|
||||
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
||||
var result error
|
||||
test.Run(subtest, vmconfig, true, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) {
|
||||
test.Run(subtest, vmconfig, true, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state state.StateDBI) {
|
||||
if snaps != nil && state != nil {
|
||||
if _, err := snaps.Journal(state.IntermediateRoot(false)); err != nil {
|
||||
result = err
|
||||
|
|
@ -107,7 +107,7 @@ func TestState(t *testing.T) {
|
|||
t.Run(key+"/path/trie", func(t *testing.T) {
|
||||
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
||||
var result error
|
||||
test.Run(subtest, vmconfig, false, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) {
|
||||
test.Run(subtest, vmconfig, false, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state state.StateDBI) {
|
||||
result = st.checkFailure(t, err)
|
||||
})
|
||||
return result
|
||||
|
|
@ -116,7 +116,7 @@ func TestState(t *testing.T) {
|
|||
t.Run(key+"/path/snap", func(t *testing.T) {
|
||||
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
||||
var result error
|
||||
test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) {
|
||||
test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state state.StateDBI) {
|
||||
if snaps != nil && state != nil {
|
||||
if _, err := snaps.Journal(state.IntermediateRoot(false)); err != nil {
|
||||
result = err
|
||||
|
|
@ -276,7 +276,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
snapshot := statedb.Snapshot()
|
||||
statedb.Prepare(rules, msg.From, context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
|
||||
statedb.Prepare(rules, msg.From, context.Coinbase, msg.To, evm.PrecompileManager.GetActive(&rules), msg.AccessList)
|
||||
b.StartTimer()
|
||||
start := time.Now()
|
||||
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ func (t *StateTest) checkError(subtest StateSubtest, err error) error {
|
|||
}
|
||||
|
||||
// Run executes a specific subtest and verifies the post-state and logs
|
||||
func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string, postCheck func(err error, snaps *snapshot.Tree, state *state.StateDB)) (result error) {
|
||||
func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string, postCheck func(err error, snaps *snapshot.Tree, state state.StateDBI)) (result error) {
|
||||
triedb, snaps, statedb, root, err := t.RunNoVerify(subtest, vmconfig, snapshotter, scheme)
|
||||
|
||||
// Invoke the callback at the end of function for further analysis.
|
||||
|
|
@ -225,7 +225,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo
|
|||
}
|
||||
|
||||
// RunNoVerify runs a specific subtest and returns the statedb and post-state root
|
||||
func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, *state.StateDB, common.Hash, error) {
|
||||
func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, state.StateDBI, common.Hash, error) {
|
||||
config, eips, err := GetChainConfig(subtest.Fork)
|
||||
if err != nil {
|
||||
return nil, nil, nil, common.Hash{}, UnsupportedForkError{subtest.Fork}
|
||||
|
|
@ -306,7 +306,7 @@ func (t *StateTest) gasLimit(subtest StateSubtest) uint64 {
|
|||
return t.json.Tx.GasLimit[t.json.Post[subtest.Fork][subtest.Index].Indexes.Gas]
|
||||
}
|
||||
|
||||
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, *state.StateDB) {
|
||||
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, state.StateDBI) {
|
||||
tconf := &trie.Config{Preimages: true}
|
||||
if scheme == rawdb.HashScheme {
|
||||
tconf.HashDB = hashdb.Defaults
|
||||
|
|
|
|||
Loading…
Reference in a new issue