diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 83a0c05330a..b544b5b6f97 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -42,7 +42,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/ethdb/olddb" "github.com/ledgerwatch/erigon/event" "github.com/ledgerwatch/erigon/params" @@ -66,9 +65,8 @@ var ( // ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor, // DeployBackend, GasEstimator, GasPricer, LogFilterer, PendingContractCaller, TransactionReader, and TransactionSender type SimulatedBackend struct { - m *stages.MockSentry - getHeader func(hash common.Hash, number uint64) *types.Header - contractHasTEVM func(common.Hash) (bool, error) + m *stages.MockSentry + getHeader func(hash common.Hash, number uint64) *types.Header mu sync.Mutex prependBlock *types.Block @@ -105,7 +103,6 @@ func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *params.Chain return h }, } - backend.contractHasTEVM = ethdb.GetHasTEVM(olddb.NewObjectDatabase(m.DB)) backend.events = filters.NewEventSystem(&filterBackend{m.DB, backend}) backend.emptyPendingBlock() return backend @@ -667,7 +664,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg txContext := core.NewEVMTxContext(msg) header := block.Header() - evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil, b.contractHasTEVM) + evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmEnv := vm.NewEVM(evmContext, txContext, statedb, b.m.ChainConfig, vm.Config{}) @@ -700,7 +697,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx types.Transac &b.pendingHeader.Coinbase, b.gasPool, b.pendingState, state.NewNoopWriter(), b.pendingHeader, tx, - &b.pendingHeader.GasUsed, vm.Config{}, b.contractHasTEVM); err != nil { + &b.pendingHeader.GasUsed, vm.Config{}); err != nil { return err } //fmt.Printf("==== Start producing block %d\n", (b.prependBlock.NumberU64() + 1)) diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index fdc12446369..2f7a183653e 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -282,7 +282,7 @@ func Main(ctx *cli.Context) error { reader, writer := MakePreState(chainConfig.Rules(0), tx, prestate.Pre) engine := ethash.NewFaker() - result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, nil, nil, true, getTracer) + result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, nil, true, getTracer) if hashError != nil { return NewError(ErrorMissingBlockhash, fmt.Errorf("blockhash error: %v", err)) diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index 53aaffc946f..6acee847a04 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -85,7 +85,6 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) { rootCmd.PersistentFlags().IntVar(&cfg.DBReadConcurrency, utils.DBReadConcurrencyFlag.Name, utils.DBReadConcurrencyFlag.Value, utils.DBReadConcurrencyFlag.Usage) rootCmd.PersistentFlags().BoolVar(&cfg.TraceCompatibility, "trace.compat", false, "Bug for bug compatibility with OE for trace_ routines") rootCmd.PersistentFlags().StringVar(&cfg.TxPoolApiAddr, "txpool.api.addr", "", "txpool api network address, for example: 127.0.0.1:9090 (default: use value of --private.api.addr)") - rootCmd.PersistentFlags().BoolVar(&cfg.TevmEnabled, utils.TevmFlag.Name, false, utils.TevmFlag.Usage) rootCmd.PersistentFlags().BoolVar(&cfg.Sync.UseSnapshots, "snapshot", true, utils.SnapshotFlag.Usage) rootCmd.PersistentFlags().IntVar(&cfg.StateCache.KeysLimit, "state.cache", kvcache.DefaultCoherentConfig.KeysLimit, "Amount of keys to store in StateCache (enabled if no --datadir set). Set 0 to disable StateCache. 1_000_000 keys ~ equal to 2Gb RAM (maybe we will add RAM accounting in future versions).") rootCmd.PersistentFlags().BoolVar(&cfg.GRPCServerEnabled, "grpc", false, "Enable GRPC server") diff --git a/cmd/rpcdaemon/cli/httpcfg/http_cfg.go b/cmd/rpcdaemon/cli/httpcfg/http_cfg.go index a81b3460ea1..f05faa05794 100644 --- a/cmd/rpcdaemon/cli/httpcfg/http_cfg.go +++ b/cmd/rpcdaemon/cli/httpcfg/http_cfg.go @@ -35,7 +35,6 @@ type HttpCfg struct { DBReadConcurrency int TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum TxPoolApiAddr string - TevmEnabled bool StateCache kvcache.CoherentConfig Snap ethconfig.Snapshot Sync ethconfig.Sync diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 1fcfe147608..3720042a7fd 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -18,9 +18,6 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool. blockReader services.FullBlockReader, agg *libstate.Aggregator22, txNums *exec22.TxNums, cfg httpcfg.HttpCfg) (list []rpc.API) { base := NewBaseApi(filters, stateCache, blockReader, agg, txNums, cfg.WithDatadir) - if cfg.TevmEnabled { - base.EnableTevmExperiment() - } ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap) erigonImpl := NewErigonAPI(base, db, eth) txpoolImpl := NewTxPoolAPI(base, db, txPool) diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go index f692da238d5..a3c5debbd6c 100644 --- a/cmd/rpcdaemon/commands/debug_api.go +++ b/cmd/rpcdaemon/commands/debug_api.go @@ -15,7 +15,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/eth/tracers" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/transactions" @@ -82,12 +81,7 @@ func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash co return h } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - _, _, _, _, stateReader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + _, _, _, _, stateReader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { return StorageRangeResult{}, err } @@ -249,11 +243,7 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common. getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index d3682c59e4b..c26261df85e 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -110,7 +110,6 @@ type BaseAPI struct { _txnReader services.TxnReader _agg *libstate.Aggregator22 _txNums *exec22.TxNums - TevmEnabled bool // experiment } func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.Aggregator22, txNums *exec22.TxNums, singleNodeMode bool) *BaseAPI { @@ -131,8 +130,6 @@ func (api *BaseAPI) chainConfig(tx kv.Tx) (*params.ChainConfig, error) { return cfg, err } -func (api *BaseAPI) EnableTevmExperiment() { api.TevmEnabled = true } - // nolint:unused func (api *BaseAPI) genesis(tx kv.Tx) (*types.Block, error) { _, genesis, err := api.chainConfigWithGenesis(tx) diff --git a/cmd/rpcdaemon/commands/eth_block.go b/cmd/rpcdaemon/commands/eth_block.go index 380ab7385d5..987e2c2b089 100644 --- a/cmd/rpcdaemon/commands/eth_block.go +++ b/cmd/rpcdaemon/commands/eth_block.go @@ -15,7 +15,6 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" @@ -115,12 +114,7 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat return nil, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - blockCtx, txCtx := transactions.GetEvmContext(firstMsg, header, stateBlockNumberOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(firstMsg, header, stateBlockNumberOrHash.RequireCanonical, tx, api._blockReader) evm := vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) timeoutMilliSeconds := int64(5000) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 5aafbed69d9..03e33a71987 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -21,7 +21,6 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/tracers/logger" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" @@ -46,11 +45,6 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHas args.Gas = (*hexutil.Uint64)(&api.GasCap) } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - blockNumber, hash, _, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return nil, err @@ -63,7 +57,7 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHas return nil, nil } - result, err := transactions.DoCall(ctx, args, tx, blockNrOrHash, block, overrides, api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM, api._blockReader) + result, err := transactions.DoCall(ctx, args, tx, blockNrOrHash, block, overrides, api.GasCap, chainConfig, api.filters, api.stateCache, api._blockReader) if err != nil { return nil, err } @@ -205,11 +199,6 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, return 0, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - // Create a helper to check if a gas allowance results in an executable transaction executable := func(gas uint64) (bool, *core.ExecutionResult, error) { args.Gas = (*hexutil.Uint64)(&gas) @@ -228,7 +217,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, } result, err := transactions.DoCall(ctx, args, dbtx, numOrHash, block, nil, - api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM, api._blockReader) + api.GasCap, chainConfig, api.filters, api.stateCache, api._blockReader) if err != nil { if errors.Is(err, core.ErrIntrinsicGas) { // Special case, raise gas limit @@ -311,10 +300,6 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, if err != nil { return nil, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } blockNumber, hash, latest, err := rpchelper.GetCanonicalBlockNumber(bNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return nil, err @@ -402,7 +387,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, // Apply the transaction with the access list tracer tracer := logger.NewAccessListTracer(accessList, *args.From, to, precompiles) config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} - blockCtx, txCtx := transactions.GetEvmContext(msg, header, bNrOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, bNrOrHash.RequireCanonical, tx, api._blockReader) evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, config) gp := new(core.GasPool).AddGas(msg.Gas()) diff --git a/cmd/rpcdaemon/commands/eth_callMany.go b/cmd/rpcdaemon/commands/eth_callMany.go index 9de19308369..88935b29ea9 100644 --- a/cmd/rpcdaemon/commands/eth_callMany.go +++ b/cmd/rpcdaemon/commands/eth_callMany.go @@ -16,7 +16,6 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" rpcapi "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" @@ -149,12 +148,6 @@ func (api *APIImpl) CallMany(ctx context.Context, bundles []Bundle, simulateCont signer := types.MakeSigner(chainConfig, blockNum) rules := chainConfig.Rules(blockNum) - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - getHash := func(i uint64) common.Hash { if hash, ok := overrideBlockHash[i]; ok { return hash @@ -171,16 +164,15 @@ func (api *APIImpl) CallMany(ctx context.Context, bundles []Bundle, simulateCont } blockCtx = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - ContractHasTEVM: contractHasTEVM, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: getHash, + Coinbase: parent.Coinbase, + BlockNumber: parent.Number.Uint64(), + Time: parent.Time, + Difficulty: new(big.Int).Set(parent.Difficulty), + GasLimit: parent.GasLimit, + BaseFee: &baseFee, } evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index b6dba244546..382cef8120b 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -22,7 +22,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/ethdb/bitmapdb" "github.com/ledgerwatch/erigon/ethdb/cbor" "github.com/ledgerwatch/erigon/params" @@ -43,8 +42,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *para } return h } - contractHasTEVM := ethdb.GetHasTEVM(tx) - _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) + _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, block.Hash(), 0) if err != nil { return nil, err } @@ -60,7 +58,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *para for i, txn := range block.Transactions() { ibs.Prepare(txn.Hash(), block.Hash(), i) header := block.Header() - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), ethashFaker, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}, contractHasTEVM) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), ethashFaker, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index acb42089017..7ea3c337d80 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -21,7 +21,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/shards" @@ -943,11 +942,7 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp return nil, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, api._blockReader) blockCtx.GasLimit = math.MaxUint64 blockCtx.MaxGasLimit = true @@ -1132,11 +1127,6 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type useParent = true } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - for txIndex, msg := range msgs { if err := libcommon.Stopped(ctx.Done()); err != nil { return nil, err @@ -1173,7 +1163,7 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type } // Get a new instance of the EVM. - blockCtx, txCtx := transactions.GetEvmContext(msg, header, parentNrOrHash.RequireCanonical, dbtx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, parentNrOrHash.RequireCanonical, dbtx, api._blockReader) if useParent { blockCtx.GasLimit = math.MaxUint64 blockCtx.MaxGasLimit = true diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index ea68b90aacd..befc80e2fa5 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -18,7 +18,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/tracers" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" @@ -76,11 +75,6 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - getHeader := func(hash common.Hash, number uint64) *types.Header { h, e := api._blockReader.Header(ctx, tx, hash, number) if e != nil { @@ -89,7 +83,7 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return h } - _, blockCtx, _, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) + _, blockCtx, _, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, block.Hash(), 0) if err != nil { stream.WriteNil() return err @@ -186,11 +180,7 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txnIndex) + msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, blockHash, txnIndex) if err != nil { stream.WriteNil() return err @@ -254,11 +244,7 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA return err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, dbtx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, dbtx, api._blockReader) // Trace the transaction and return return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) } @@ -350,12 +336,6 @@ func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bun signer := types.MakeSigner(chainConfig, blockNum) rules := chainConfig.Rules(blockNum) - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - getHash := func(i uint64) common.Hash { if hash, ok := overrideBlockHash[i]; ok { return hash @@ -372,16 +352,15 @@ func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bun } blockCtx = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - ContractHasTEVM: contractHasTEVM, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: getHash, + Coinbase: parent.Coinbase, + BlockNumber: parent.Number.Uint64(), + Time: parent.Time, + Difficulty: new(big.Int).Set(parent.Difficulty), + GasLimit: parent.GasLimit, + BaseFee: &baseFee, } evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) diff --git a/cmd/rpcdaemon22/cli/config.go b/cmd/rpcdaemon22/cli/config.go index 3ec14940e52..a3e814f8109 100644 --- a/cmd/rpcdaemon22/cli/config.go +++ b/cmd/rpcdaemon22/cli/config.go @@ -85,7 +85,6 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) { rootCmd.PersistentFlags().IntVar(&cfg.DBReadConcurrency, utils.DBReadConcurrencyFlag.Name, utils.DBReadConcurrencyFlag.Value, utils.DBReadConcurrencyFlag.Usage) rootCmd.PersistentFlags().BoolVar(&cfg.TraceCompatibility, "trace.compat", false, "Bug for bug compatibility with OE for trace_ routines") rootCmd.PersistentFlags().StringVar(&cfg.TxPoolApiAddr, "txpool.api.addr", "", "txpool api network address, for example: 127.0.0.1:9090 (default: use value of --private.api.addr)") - rootCmd.PersistentFlags().BoolVar(&cfg.TevmEnabled, utils.TevmFlag.Name, false, utils.TevmFlag.Usage) rootCmd.PersistentFlags().BoolVar(&cfg.Sync.UseSnapshots, "snapshot", true, utils.SnapshotFlag.Usage) rootCmd.PersistentFlags().IntVar(&cfg.StateCache.KeysLimit, "state.cache", kvcache.DefaultCoherentConfig.KeysLimit, "Amount of keys to store in StateCache (enabled if no --datadir set). Set 0 to disable StateCache. 1_000_000 keys ~ equal to 2Gb RAM (maybe we will add RAM accounting in future versions).") rootCmd.PersistentFlags().BoolVar(&cfg.GRPCServerEnabled, "grpc", false, "Enable GRPC server") diff --git a/cmd/rpcdaemon22/cli/httpcfg/http_cfg.go b/cmd/rpcdaemon22/cli/httpcfg/http_cfg.go index a81b3460ea1..f05faa05794 100644 --- a/cmd/rpcdaemon22/cli/httpcfg/http_cfg.go +++ b/cmd/rpcdaemon22/cli/httpcfg/http_cfg.go @@ -35,7 +35,6 @@ type HttpCfg struct { DBReadConcurrency int TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum TxPoolApiAddr string - TevmEnabled bool StateCache kvcache.CoherentConfig Snap ethconfig.Snapshot Sync ethconfig.Sync diff --git a/cmd/rpcdaemon22/commands/call_traces_test.go b/cmd/rpcdaemon22/commands/call_traces_test.go deleted file mode 100644 index 5e88fdf8d73..00000000000 --- a/cmd/rpcdaemon22/commands/call_traces_test.go +++ /dev/null @@ -1,269 +0,0 @@ -package commands - -import ( - "bytes" - "context" - "sync" - "testing" - - "github.com/holiman/uint256" - jsoniter "github.com/json-iterator/go" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/cli/httpcfg" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" -) - -func blockNumbersFromTraces(t *testing.T, b []byte) []int { - var err error - var p fastjson.Parser - response := b - var v *fastjson.Value - if v, err = p.ParseBytes(response); err != nil { - t.Fatalf("parsing response: %v", err) - } - var elems []*fastjson.Value - if elems, err = v.Array(); err != nil { - t.Fatalf("expected array in the response: %v", err) - } - numbers := make([]int, 0, len(elems)) - for _, elem := range elems { - bn := elem.GetInt("blockNumber") - numbers = append(numbers, bn) - } - return numbers -} - -func TestCallTraceOneByOne(t *testing.T) { - t.Skip() - m := stages.Mock(t) - defer m.DB.Close() - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 10, func(i int, gen *core.BlockGen) { - gen.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - if err != nil { - t.Fatalf("generate chain: %v", err) - } - api := NewTraceAPI( - NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), nil, nil, false), - m.DB, &httpcfg.HttpCfg{}) - // Insert blocks 1 by 1, to tirgget possible "off by one" errors - for i := 0; i < chain.Length(); i++ { - if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { - t.Fatalf("inserting chain: %v", err) - } - } - stream := jsoniter.ConfigDefault.BorrowStream(nil) - defer jsoniter.ConfigDefault.ReturnStream(stream) - var fromBlock, toBlock uint64 - fromBlock = 1 - toBlock = 10 - toAddress1 := common.Address{1} - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - ToAddress: []*common.Address{&toAddress1}, - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) -} - -func TestCallTraceUnwind(t *testing.T) { - t.Skip() - m := stages.Mock(t) - defer m.DB.Close() - var chainA, chainB *core.ChainPack - var err error - chainA, err = core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 10, func(i int, gen *core.BlockGen) { - gen.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - if err != nil { - t.Fatalf("generate chainA: %v", err) - } - chainB, err = core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 20, func(i int, gen *core.BlockGen) { - if i < 5 || i >= 10 { - gen.SetCoinbase(common.Address{1}) - } else { - gen.SetCoinbase(common.Address{2}) - } - }, false /* intermediateHashes */) - if err != nil { - t.Fatalf("generate chainB: %v", err) - } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), nil, nil, false), m.DB, &httpcfg.HttpCfg{}) - if err = m.InsertChain(chainA); err != nil { - t.Fatalf("inserting chainA: %v", err) - } - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - var fromBlock, toBlock uint64 - fromBlock = 1 - toBlock = 10 - toAddress1 := common.Address{1} - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - ToAddress: []*common.Address{&toAddress1}, - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - - assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, buf.Bytes())) - if err = m.InsertChain(chainB.Slice(0, 12)); err != nil { - t.Fatalf("inserting chainB: %v", err) - } - buf.Reset() - toBlock = 12 - traceReq2 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - ToAddress: []*common.Address{&toAddress1}, - } - if err = api.Filter(context.Background(), traceReq2, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{1, 2, 3, 4, 5, 11, 12}, blockNumbersFromTraces(t, buf.Bytes())) - if err = m.InsertChain(chainB.Slice(12, 20)); err != nil { - t.Fatalf("inserting chainB: %v", err) - } - buf.Reset() - fromBlock = 12 - toBlock = 20 - traceReq3 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - ToAddress: []*common.Address{&toAddress1}, - } - if err = api.Filter(context.Background(), traceReq3, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{12, 13, 14, 15, 16, 17, 18, 19, 20}, blockNumbersFromTraces(t, buf.Bytes())) -} - -func TestFilterNoAddresses(t *testing.T) { - t.Skip() - m := stages.Mock(t) - defer m.DB.Close() - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 10, func(i int, gen *core.BlockGen) { - gen.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - if err != nil { - t.Fatalf("generate chain: %v", err) - } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), nil, nil, false), m.DB, &httpcfg.HttpCfg{}) - // Insert blocks 1 by 1, to tirgget possible "off by one" errors - for i := 0; i < chain.Length(); i++ { - if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { - t.Fatalf("inserting chain: %v", err) - } - } - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - var fromBlock, toBlock uint64 - fromBlock = 1 - toBlock = 10 - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, buf.Bytes())) -} - -func TestFilterAddressIntersection(t *testing.T) { - t.Skip() - m := stages.Mock(t) - defer m.DB.Close() - - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), nil, nil, false), m.DB, &httpcfg.HttpCfg{}) - - toAddress1, toAddress2, other := common.Address{1}, common.Address{2}, common.Address{3} - - once := new(sync.Once) - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 15, func(i int, block *core.BlockGen) { - once.Do(func() { block.SetCoinbase(common.Address{4}) }) - - var rcv common.Address - if i < 5 { - rcv = toAddress1 - } else if i < 10 { - rcv = toAddress2 - } else { - rcv = other - } - - signer := types.LatestSigner(m.ChainConfig) - txn, err := types.SignTx(types.NewTransaction(block.TxNonce(m.Address), rcv, new(uint256.Int), 21000, new(uint256.Int), nil), *signer, m.Key) - if err != nil { - t.Fatal(err) - } - block.AddTx(txn) - }, false /* intermediateHashes */) - require.NoError(t, err, "generate chain") - - err = m.InsertChain(chain) - require.NoError(t, err, "inserting chain") - - fromBlock, toBlock := uint64(1), uint64(15) - t.Run("second", func(t *testing.T) { - stream := jsoniter.ConfigDefault.BorrowStream(nil) - defer jsoniter.ConfigDefault.ReturnStream(stream) - - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - FromAddress: []*common.Address{&m.Address, &other}, - ToAddress: []*common.Address{&m.Address, &toAddress2}, - Mode: TraceFilterModeIntersection, - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) - }) - t.Run("first", func(t *testing.T) { - stream := jsoniter.ConfigDefault.BorrowStream(nil) - defer jsoniter.ConfigDefault.ReturnStream(stream) - - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - FromAddress: []*common.Address{&m.Address, &other}, - ToAddress: []*common.Address{&toAddress1, &m.Address}, - Mode: TraceFilterModeIntersection, - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - assert.Equal(t, []int{1, 2, 3, 4, 5}, blockNumbersFromTraces(t, stream.Buffer())) - }) - t.Run("empty", func(t *testing.T) { - stream := jsoniter.ConfigDefault.BorrowStream(nil) - defer jsoniter.ConfigDefault.ReturnStream(stream) - - traceReq1 := TraceFilterRequest{ - FromBlock: (*hexutil.Uint64)(&fromBlock), - ToBlock: (*hexutil.Uint64)(&toBlock), - ToAddress: []*common.Address{&other}, - FromAddress: []*common.Address{&toAddress2, &toAddress1, &other}, - Mode: TraceFilterModeIntersection, - } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { - t.Fatalf("trace_filter failed: %v", err) - } - require.Empty(t, blockNumbersFromTraces(t, stream.Buffer())) - }) -} diff --git a/cmd/rpcdaemon22/commands/corner_cases_support_test.go b/cmd/rpcdaemon22/commands/corner_cases_support_test.go deleted file mode 100644 index 0b95ba2c657..00000000000 --- a/cmd/rpcdaemon22/commands/corner_cases_support_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package commands - -import ( - "context" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/stretchr/testify/require" -) - -// TestNotFoundMustReturnNil - next methods - when record not found in db - must return nil instead of error -// see https://github.com/ledgerwatch/erigon/issues/1645 -func TestNotFoundMustReturnNil(t *testing.T) { - require := require.New(t) - db := rpcdaemontest.CreateTestKV(t) - defer db.Close() - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI( - NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), - db, nil, nil, nil, 5000000) - ctx := context.Background() - - a, err := api.GetTransactionByBlockNumberAndIndex(ctx, 10_000, 1) - require.Nil(a) - require.Nil(err) - - b, err := api.GetTransactionByBlockHashAndIndex(ctx, common.Hash{}, 1) - require.Nil(b) - require.Nil(err) - - c, err := api.GetTransactionByBlockNumberAndIndex(ctx, 10_000, 1) - require.Nil(c) - require.Nil(err) - - d, err := api.GetTransactionReceipt(ctx, common.Hash{}) - require.Nil(d) - require.Nil(err) - - e, err := api.GetBlockByHash(ctx, rpc.BlockNumberOrHashWithHash(common.Hash{}, true), false) - require.Nil(e) - require.Nil(err) - - f, err := api.GetBlockByNumber(ctx, 10_000, false) - require.Nil(f) - require.Nil(err) - - g, err := api.GetUncleByBlockHashAndIndex(ctx, common.Hash{}, 1) - require.Nil(g) - require.Nil(err) - - h, err := api.GetUncleByBlockNumberAndIndex(ctx, 10_000, 1) - require.Nil(h) - require.Nil(err) - - j, err := api.GetBlockTransactionCountByNumber(ctx, 10_000) - require.Nil(j) - require.Nil(err) -} diff --git a/cmd/rpcdaemon22/commands/daemon.go b/cmd/rpcdaemon22/commands/daemon.go index c648bd309ae..336dceb3596 100644 --- a/cmd/rpcdaemon22/commands/daemon.go +++ b/cmd/rpcdaemon22/commands/daemon.go @@ -18,20 +18,8 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool. blockReader services.FullBlockReader, agg *libstate.Aggregator, txNums *exec22.TxNums, cfg httpcfg.HttpCfg) (list []rpc.API) { base := NewBaseApi(filters, stateCache, blockReader, agg, txNums, cfg.WithDatadir) - if cfg.TevmEnabled { - base.EnableTevmExperiment() - } ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap) - erigonImpl := NewErigonAPI(base, db, eth) - txpoolImpl := NewTxPoolAPI(base, db, txPool) - netImpl := NewNetAPIImpl(eth) - debugImpl := NewPrivateDebugAPI(base, db, cfg.Gascap) traceImpl := NewTraceAPI(base, db, &cfg) - web3Impl := NewWeb3APIImpl(eth) - dbImpl := NewDBAPIImpl() /* deprecated */ - adminImpl := NewAdminAPI(eth) - parityImpl := NewParityAPIImpl(db) - borImpl := NewBorAPI(base, db, borDb) // bor (consensus) specific for _, enabledAPI := range cfg.API { switch enabledAPI { @@ -42,34 +30,6 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool. Service: EthAPI(ethImpl), Version: "1.0", }) - case "debug": - list = append(list, rpc.API{ - Namespace: "debug", - Public: true, - Service: PrivateDebugAPI(debugImpl), - Version: "1.0", - }) - case "net": - list = append(list, rpc.API{ - Namespace: "net", - Public: true, - Service: NetAPI(netImpl), - Version: "1.0", - }) - case "txpool": - list = append(list, rpc.API{ - Namespace: "txpool", - Public: true, - Service: TxPoolAPI(txpoolImpl), - Version: "1.0", - }) - case "web3": - list = append(list, rpc.API{ - Namespace: "web3", - Public: true, - Service: Web3API(web3Impl), - Version: "1.0", - }) case "trace": list = append(list, rpc.API{ Namespace: "trace", @@ -77,66 +37,8 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool. Service: TraceAPI(traceImpl), Version: "1.0", }) - case "db": /* Deprecated */ - list = append(list, rpc.API{ - Namespace: "db", - Public: true, - Service: DBAPI(dbImpl), - Version: "1.0", - }) - case "erigon": - list = append(list, rpc.API{ - Namespace: "erigon", - Public: true, - Service: ErigonAPI(erigonImpl), - Version: "1.0", - }) - case "bor": - list = append(list, rpc.API{ - Namespace: "bor", - Public: true, - Service: BorAPI(borImpl), - Version: "1.0", - }) - case "admin": - list = append(list, rpc.API{ - Namespace: "admin", - Public: false, - Service: AdminAPI(adminImpl), - Version: "1.0", - }) - case "parity": - list = append(list, rpc.API{ - Namespace: "parity", - Public: false, - Service: ParityAPI(parityImpl), - Version: "1.0", - }) } } return list } - -func AuthAPIList(db kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, - filters *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, - cfg httpcfg.HttpCfg) (list []rpc.API) { - base := NewBaseApi(filters, stateCache, blockReader, nil, nil, cfg.WithDatadir) - - ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap) - engineImpl := NewEngineAPI(base, db, eth) - - list = append(list, rpc.API{ - Namespace: "eth", - Public: true, - Service: EthAPI(ethImpl), - Version: "1.0", - }, rpc.API{ - Namespace: "engine", - Public: true, - Service: EngineAPI(engineImpl), - Version: "1.0", - }) - - return list -} diff --git a/cmd/rpcdaemon22/commands/debug_api.go b/cmd/rpcdaemon22/commands/debug_api.go index f692da238d5..45bd7c6a813 100644 --- a/cmd/rpcdaemon22/commands/debug_api.go +++ b/cmd/rpcdaemon22/commands/debug_api.go @@ -15,7 +15,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/eth/tracers" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/transactions" @@ -81,13 +80,7 @@ func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash co } return h } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - _, _, _, _, stateReader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + _, _, _, _, stateReader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { return StorageRangeResult{}, err } @@ -249,11 +242,7 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common. getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon22/commands/debug_api_test.go b/cmd/rpcdaemon22/commands/debug_api_test.go deleted file mode 100644 index 0892a5d37fa..00000000000 --- a/cmd/rpcdaemon22/commands/debug_api_test.go +++ /dev/null @@ -1,185 +0,0 @@ -package commands - -import ( - "bytes" - "context" - "encoding/json" - "testing" - - jsoniter "github.com/json-iterator/go" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/eth/tracers" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" -) - -var debugTraceTransactionTests = []struct { - txHash string - gas uint64 - failed bool - returnValue string -}{ - {"3f3cb8a0e13ed2481f97f53f7095b9cbc78b6ffb779f2d3e565146371a8830ea", 21000, false, ""}, - {"f588c6426861d9ad25d5ccc12324a8d213f35ef1ed4153193f0c13eb81ca7f4a", 49189, false, "0000000000000000000000000000000000000000000000000000000000000001"}, - {"b6449d8e167a8826d050afe4c9f07095236ff769a985f02649b1023c2ded2059", 38899, false, ""}, -} - -var debugTraceTransactionNoRefundTests = []struct { - txHash string - gas uint64 - failed bool - returnValue string -}{ - {"3f3cb8a0e13ed2481f97f53f7095b9cbc78b6ffb779f2d3e565146371a8830ea", 21000, false, ""}, - {"f588c6426861d9ad25d5ccc12324a8d213f35ef1ed4153193f0c13eb81ca7f4a", 49189, false, "0000000000000000000000000000000000000000000000000000000000000001"}, - {"b6449d8e167a8826d050afe4c9f07095236ff769a985f02649b1023c2ded2059", 62899, false, ""}, -} - -func TestTraceBlockByNumber(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - baseApi := NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false) - ethApi := NewEthAPI(baseApi, db, nil, nil, nil, 5000000) - api := NewPrivateDebugAPI(baseApi, db, 0) - for _, tt := range debugTraceTransactionTests { - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - tx, err := ethApi.GetTransactionByHash(context.Background(), common.HexToHash(tt.txHash)) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - txcount, err := ethApi.GetBlockTransactionCountByHash(context.Background(), *tx.BlockHash) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - err = api.TraceBlockByNumber(context.Background(), rpc.BlockNumber(tx.BlockNumber.ToInt().Uint64()), &tracers.TraceConfig{}, stream) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - if err = stream.Flush(); err != nil { - t.Fatalf("error flusing: %v", err) - } - var er []ethapi.ExecutionResult - if err = json.Unmarshal(buf.Bytes(), &er); err != nil { - t.Fatalf("parsing result: %v", err) - } - if len(er) != int(*txcount) { - t.Fatalf("incorrect length: %v", err) - } - } - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - err := api.TraceBlockByNumber(context.Background(), rpc.LatestBlockNumber, &tracers.TraceConfig{}, stream) - if err != nil { - t.Errorf("traceBlock %v: %v", rpc.LatestBlockNumber, err) - } - if err = stream.Flush(); err != nil { - t.Fatalf("error flusing: %v", err) - } - var er []ethapi.ExecutionResult - if err = json.Unmarshal(buf.Bytes(), &er); err != nil { - t.Fatalf("parsing result: %v", err) - } -} - -func TestTraceBlockByHash(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - baseApi := NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false) - ethApi := NewEthAPI(baseApi, db, nil, nil, nil, 5000000) - api := NewPrivateDebugAPI(baseApi, db, 0) - for _, tt := range debugTraceTransactionTests { - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - tx, err := ethApi.GetTransactionByHash(context.Background(), common.HexToHash(tt.txHash)) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - txcount, err := ethApi.GetBlockTransactionCountByHash(context.Background(), *tx.BlockHash) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - err = api.TraceBlockByHash(context.Background(), *tx.BlockHash, &tracers.TraceConfig{}, stream) - if err != nil { - t.Errorf("traceBlock %s: %v", tt.txHash, err) - } - if err = stream.Flush(); err != nil { - t.Fatalf("error flusing: %v", err) - } - var er []ethapi.ExecutionResult - if err = json.Unmarshal(buf.Bytes(), &er); err != nil { - t.Fatalf("parsing result: %v", err) - } - if len(er) != int(*txcount) { - t.Fatalf("incorrect length: %v", err) - } - } -} - -func TestTraceTransaction(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewPrivateDebugAPI( - NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), - db, 0) - for _, tt := range debugTraceTransactionTests { - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - err := api.TraceTransaction(context.Background(), common.HexToHash(tt.txHash), &tracers.TraceConfig{}, stream) - if err != nil { - t.Errorf("traceTransaction %s: %v", tt.txHash, err) - } - if err = stream.Flush(); err != nil { - t.Fatalf("error flusing: %v", err) - } - var er ethapi.ExecutionResult - if err = json.Unmarshal(buf.Bytes(), &er); err != nil { - t.Fatalf("parsing result: %v", err) - } - if er.Gas != tt.gas { - t.Errorf("wrong gas for transaction %s, got %d, expected %d", tt.txHash, er.Gas, tt.gas) - } - if er.Failed != tt.failed { - t.Errorf("wrong failed flag for transaction %s, got %t, expected %t", tt.txHash, er.Failed, tt.failed) - } - if er.ReturnValue != tt.returnValue { - t.Errorf("wrong return value for transaction %s, got %s, expected %s", tt.txHash, er.ReturnValue, tt.returnValue) - } - } -} - -func TestTraceTransactionNoRefund(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewPrivateDebugAPI( - NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), - db, 0) - for _, tt := range debugTraceTransactionNoRefundTests { - var buf bytes.Buffer - stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) - var norefunds = true - err := api.TraceTransaction(context.Background(), common.HexToHash(tt.txHash), &tracers.TraceConfig{NoRefunds: &norefunds}, stream) - if err != nil { - t.Errorf("traceTransaction %s: %v", tt.txHash, err) - } - if err = stream.Flush(); err != nil { - t.Fatalf("error flusing: %v", err) - } - var er ethapi.ExecutionResult - if err = json.Unmarshal(buf.Bytes(), &er); err != nil { - t.Fatalf("parsing result: %v", err) - } - if er.Gas != tt.gas { - t.Errorf("wrong gas for transaction %s, got %d, expected %d", tt.txHash, er.Gas, tt.gas) - } - if er.Failed != tt.failed { - t.Errorf("wrong failed flag for transaction %s, got %t, expected %t", tt.txHash, er.Failed, tt.failed) - } - if er.ReturnValue != tt.returnValue { - t.Errorf("wrong return value for transaction %s, got %s, expected %s", tt.txHash, er.ReturnValue, tt.returnValue) - } - } -} diff --git a/cmd/rpcdaemon22/commands/engine_api_test.go b/cmd/rpcdaemon22/commands/engine_api_test.go deleted file mode 100644 index a209b8469b6..00000000000 --- a/cmd/rpcdaemon22/commands/engine_api_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package commands - -import ( - "testing" - - "github.com/ledgerwatch/erigon-lib/gointerfaces" - "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon/common" - "github.com/stretchr/testify/assert" -) - -// Test case for https://github.com/ethereum/execution-apis/pull/217 responses -func TestZeroLatestValidHash(t *testing.T) { - payloadStatus := remote.EnginePayloadStatus{Status: remote.EngineStatus_INVALID, LatestValidHash: gointerfaces.ConvertHashToH256(common.Hash{})} - json := convertPayloadStatus(&payloadStatus) - assert.Equal(t, "INVALID", json["status"]) - assert.Equal(t, common.Hash{}, json["latestValidHash"]) -} diff --git a/cmd/rpcdaemon22/commands/erigon_api.go b/cmd/rpcdaemon22/commands/erigon_api.go deleted file mode 100644 index d6fd936993e..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_api.go +++ /dev/null @@ -1,57 +0,0 @@ -package commands - -import ( - "context" - - ethFilters "github.com/ledgerwatch/erigon/eth/filters" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/p2p" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/rpchelper" -) - -// ErigonAPI Erigon specific routines -type ErigonAPI interface { - // System related (see ./erigon_system.go) - Forks(ctx context.Context) (Forks, error) - - // Blocks related (see ./erigon_blocks.go) - GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) - GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) - GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Timestamp, fullTx bool) (map[string]interface{}, error) - GetBalanceChangesInBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (map[common.Address]*hexutil.Big, error) - - // Receipt related (see ./erigon_receipts.go) - GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) - //GetLogsByNumber(ctx context.Context, number rpc.BlockNumber) ([][]*types.Log, error) - GetLogs(ctx context.Context, crit ethFilters.FilterCriteria) (types.ErigonLogs, error) - - // WatchTheBurn / reward related (see ./erigon_issuance.go) - WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) - - // CumulativeChainTraffic / related to chain traffic (see ./erigon_cumulative_index.go) - CumulativeChainTraffic(ctx context.Context, blockNr rpc.BlockNumber) (ChainTraffic, error) - - // NodeInfo returns a collection of metadata known about the host. - NodeInfo(ctx context.Context) ([]p2p.NodeInfo, error) -} - -// ErigonImpl is implementation of the ErigonAPI interface -type ErigonImpl struct { - *BaseAPI - db kv.RoDB - ethBackend rpchelper.ApiBackend -} - -// NewErigonAPI returns ErigonImpl instance -func NewErigonAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend) *ErigonImpl { - return &ErigonImpl{ - BaseAPI: base, - db: db, - ethBackend: eth, - } -} diff --git a/cmd/rpcdaemon22/commands/erigon_block.go b/cmd/rpcdaemon22/commands/erigon_block.go deleted file mode 100644 index e56cba2a1d3..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_block.go +++ /dev/null @@ -1,238 +0,0 @@ -package commands - -import ( - "bytes" - "context" - "errors" - "fmt" - "sort" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/changeset" - "github.com/ledgerwatch/erigon/common/dbutils" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/rpchelper" -) - -// GetHeaderByNumber implements erigon_getHeaderByNumber. Returns a block's header given a block number ignoring the block's transaction and uncle list (may be faster). -func (api *ErigonImpl) GetHeaderByNumber(ctx context.Context, blockNumber rpc.BlockNumber) (*types.Header, error) { - // Pending block is only known by the miner - if blockNumber == rpc.PendingBlockNumber { - block := api.pendingBlock() - if block == nil { - return nil, nil - } - return block.Header(), nil - } - - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - blockNum, _, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(blockNumber), tx, api.filters) - if err != nil { - return nil, err - } - - header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) - if err != nil { - return nil, err - } - - if header == nil { - return nil, fmt.Errorf("block header not found: %d", blockNum) - } - - return header, nil -} - -// GetHeaderByHash implements erigon_getHeaderByHash. Returns a block's header given a block's hash. -func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - header, err := api._blockReader.HeaderByHash(ctx, tx, hash) - if err != nil { - return nil, err - } - if header == nil { - return nil, fmt.Errorf("block header not found: %s", hash.String()) - } - - return header, nil -} - -func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Timestamp, fullTx bool) (map[string]interface{}, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - uintTimestamp := timeStamp.TurnIntoUint64() - - currentHeader := rawdb.ReadCurrentHeader(tx) - currenttHeaderTime := currentHeader.Time - highestNumber := currentHeader.Number.Uint64() - - firstHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) - if err != nil { - return nil, err - } - - if firstHeader == nil { - return nil, errors.New("no genesis header found") - } - - firstHeaderTime := firstHeader.Time - - if currenttHeaderTime <= uintTimestamp { - blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) - if err != nil { - return nil, err - } - - return blockResponse, nil - } - - if firstHeaderTime >= uintTimestamp { - blockResponse, err := buildBlockResponse(tx, 0, fullTx) - if err != nil { - return nil, err - } - - return blockResponse, nil - } - - blockNum := sort.Search(int(currentHeader.Number.Uint64()), func(blockNum int) bool { - currentHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) - if err != nil { - return false - } - - if currentHeader == nil { - return false - } - - return currentHeader.Time >= uintTimestamp - }) - - resultingHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) - if err != nil { - return nil, err - } - - if resultingHeader == nil { - return nil, fmt.Errorf("no header found with header number: %d", blockNum) - } - - if resultingHeader.Time > uintTimestamp { - response, err := buildBlockResponse(tx, uint64(blockNum)-1, fullTx) - if err != nil { - return nil, err - } - return response, nil - } - - response, err := buildBlockResponse(tx, uint64(blockNum), fullTx) - if err != nil { - return nil, err - } - - return response, nil -} - -func buildBlockResponse(db kv.Tx, blockNum uint64, fullTx bool) (map[string]interface{}, error) { - block, err := rawdb.ReadBlockByNumber(db, blockNum) - if err != nil { - return nil, err - } - - if block == nil { - return nil, nil - } - - response, err := ethapi.RPCMarshalBlock(block, true, fullTx) - - if err == nil && rpc.BlockNumber(block.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err -} - -func (api *ErigonImpl) GetBalanceChangesInBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (map[common.Address]*hexutil.Big, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - blockNumber, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) - if err != nil { - return nil, err - } - - c, err := tx.Cursor(kv.AccountChangeSet) - if err != nil { - return nil, err - } - defer c.Close() - - startkey := dbutils.EncodeBlockNumber(blockNumber) - - decodeFn := changeset.Mapper[kv.AccountChangeSet].Decode - - balancesMapping := make(map[common.Address]*hexutil.Big) - - newReader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, api.filters, api.stateCache) - if err != nil { - return nil, err - } - - for dbKey, dbValue, _ := c.Seek(startkey); bytes.Equal(dbKey, startkey) && dbKey != nil; dbKey, dbValue, _ = c.Next() { - _, addressBytes, v, err := decodeFn(dbKey, dbValue) - if err != nil { - return nil, err - } - - var oldAcc accounts.Account - if err = oldAcc.DecodeForStorage(v); err != nil { - return nil, err - } - oldBalance := oldAcc.Balance - - address := common.BytesToAddress(addressBytes) - - newAcc, err := newReader.ReadAccountData(address) - if err != nil { - return nil, err - } - - newBalance := uint256.NewInt(0) - if newAcc != nil { - newBalance = &newAcc.Balance - } - - if !oldBalance.Eq(newBalance) { - newBalanceDesc := (*hexutil.Big)(newBalance.ToBig()) - balancesMapping[address] = newBalanceDesc - } - } - - return balancesMapping, nil -} diff --git a/cmd/rpcdaemon22/commands/erigon_cumulative_chain_traffic.go b/cmd/rpcdaemon22/commands/erigon_cumulative_chain_traffic.go deleted file mode 100644 index 640ececce78..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_cumulative_chain_traffic.go +++ /dev/null @@ -1,41 +0,0 @@ -package commands - -import ( - "context" - - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/rpc" -) - -// CumulativeGasIndex implements erigon_cumulativeChainTraffic. Returns how much traffic there has been at the specified block number. -// Aka. amount of gas used so far + total transactions issued to the network -func (api *ErigonImpl) CumulativeChainTraffic(ctx context.Context, blockNr rpc.BlockNumber) (ChainTraffic, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return ChainTraffic{}, err - } - defer tx.Rollback() - - blockNumber := uint64(blockNr) - cumulativeGasUsed, err := rawdb.ReadCumulativeGasUsed(tx, blockNumber) - if err != nil { - return ChainTraffic{}, err - } - - _, baseTxId, txCount, err := rawdb.ReadBodyByNumber(tx, blockNumber) - if err != nil { - return ChainTraffic{}, err - } - - cumulativeTransactionCount := baseTxId + uint64(txCount) - return ChainTraffic{ - CumulativeGasUsed: (*hexutil.Big)(cumulativeGasUsed), - CumulativeTransactionsCount: (*hexutil.Uint64)(&cumulativeTransactionCount), - }, nil -} - -type ChainTraffic struct { - CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed"` - CumulativeTransactionsCount *hexutil.Uint64 `json:"cumulativeTransactionsCount"` -} diff --git a/cmd/rpcdaemon22/commands/erigon_issuance.go b/cmd/rpcdaemon22/commands/erigon_issuance.go deleted file mode 100644 index 7aef3595e2a..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_issuance.go +++ /dev/null @@ -1,133 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "math/big" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/rpc" -) - -// BlockReward returns the block reward for this block -// func (api *ErigonImpl) BlockReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { -// tx, err := api.db.Begin(ctx, ethdb.RO) -// if err != nil { -// return Issuance{}, err -// } -// defer tx.Rollback() -// -// return api.rewardCalc(tx, blockNr, "block") // nolint goconst -//} - -// UncleReward returns the uncle reward for this block -// func (api *ErigonImpl) UncleReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { -// tx, err := api.db.Begin(ctx, ethdb.RO) -// if err != nil { -// return Issuance{}, err -// } -// defer tx.Rollback() -// -// return api.rewardCalc(tx, blockNr, "uncle") // nolint goconst -//} - -// Issuance implements erigon_issuance. Returns the total issuance (block reward plus uncle reward) for the given block. -func (api *ErigonImpl) WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return Issuance{}, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return Issuance{}, err - } - if chainConfig.Ethash == nil { - // Clique for example has no issuance - return Issuance{}, nil - } - hash, err := rawdb.ReadCanonicalHash(tx, uint64(blockNr)) - if err != nil { - return Issuance{}, err - } - header := rawdb.ReadHeader(tx, hash, uint64(blockNr)) - if header == nil { - return Issuance{}, fmt.Errorf("could not find block header") - } - - body := rawdb.ReadCanonicalBodyWithTransactions(tx, hash, uint64(blockNr)) - - if body == nil { - return Issuance{}, fmt.Errorf("could not find block body") - } - - minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, header, body.Uncles) - issuance := minerReward - for _, r := range uncleRewards { - p := r // avoids warning? - issuance.Add(&issuance, &p) - } - - var ret Issuance - ret.BlockReward = (*hexutil.Big)(minerReward.ToBig()) - ret.Issuance = (*hexutil.Big)(issuance.ToBig()) - issuance.Sub(&issuance, &minerReward) - ret.UncleReward = (*hexutil.Big)(issuance.ToBig()) - // Compute how much was burnt - if header.BaseFee != nil { - burnt := header.BaseFee - burnt.Mul(burnt, big.NewInt(int64(header.GasUsed))) - ret.Burnt = (*hexutil.Big)(burnt) - } else { - ret.Burnt = (*hexutil.Big)(big.NewInt(0)) - } - // Compute totalIssued, totalBurnt and the supply of eth - totalIssued, err := rawdb.ReadTotalIssued(tx, uint64(blockNr)) - if err != nil { - return Issuance{}, err - } - totalBurnt, err := rawdb.ReadTotalBurnt(tx, uint64(blockNr)) - if err != nil { - return Issuance{}, err - } - - ret.TotalIssued = (*hexutil.Big)(totalIssued) - ret.TotalBurnt = (*hexutil.Big)(totalBurnt) - - // Compute tips - tips := big.NewInt(0) - - if header.BaseFee != nil { - receipts, err := rawdb.ReadReceiptsByHash(tx, hash) - if err != nil { - return Issuance{}, err - } - - baseFee, overflow := uint256.FromBig(header.BaseFee) - if overflow { - return Issuance{}, fmt.Errorf("baseFee overflow") - } - - for i, transaction := range body.Transactions { - tip := transaction.GetEffectiveGasTip(baseFee).ToBig() - tips.Add(tips, tip.Mul(tip, big.NewInt(int64(receipts[i].GasUsed)))) - } - } - ret.Tips = (*hexutil.Big)(tips) - return ret, nil -} - -// Issuance structure to return information about issuance -type Issuance struct { - BlockReward *hexutil.Big `json:"blockReward"` // Block reward for given block - UncleReward *hexutil.Big `json:"uncleReward"` // Uncle reward for gived block - Issuance *hexutil.Big `json:"issuance"` // Total amount of wei created in the block - Burnt *hexutil.Big `json:"burnt"` // Total amount of wei burned in the block - TotalIssued *hexutil.Big `json:"totalIssued"` // Total amount of wei created in total so far - TotalBurnt *hexutil.Big `json:"totalBurnt"` // Total amount of wei burnt so far - Tips *hexutil.Big `json:"tips"` // Total Tips generated by the block -} diff --git a/cmd/rpcdaemon22/commands/erigon_nodeInfo.go b/cmd/rpcdaemon22/commands/erigon_nodeInfo.go deleted file mode 100644 index 68ef98d9299..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_nodeInfo.go +++ /dev/null @@ -1,16 +0,0 @@ -package commands - -import ( - "context" - - "github.com/ledgerwatch/erigon/p2p" -) - -const ( - // allNodesInfo used in NodeInfo request to receive meta data from all running sentries. - allNodesInfo = 0 -) - -func (api *ErigonImpl) NodeInfo(ctx context.Context) ([]p2p.NodeInfo, error) { - return api.ethBackend.NodeInfo(ctx, allNodesInfo) -} diff --git a/cmd/rpcdaemon22/commands/erigon_receipts.go b/cmd/rpcdaemon22/commands/erigon_receipts.go deleted file mode 100644 index 9534ccee9f8..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_receipts.go +++ /dev/null @@ -1,238 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "time" - - "github.com/RoaringBitmap/roaring/roaring64" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/transactions" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/types" -) - -// GetLogsByHash implements erigon_getLogsByHash. Returns an array of arrays of logs generated by the transactions in the block given by the block's hash. -func (api *ErigonImpl) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - block, err := api.blockByHashWithSenders(tx, hash) - if err != nil { - return nil, err - } - if block == nil { - return nil, nil - } - receipts, err := api.getReceipts(ctx, tx, chainConfig, block, block.Body().SendersFromTxs()) - if err != nil { - return nil, fmt.Errorf("getReceipts error: %w", err) - } - - logs := make([][]*types.Log, len(receipts)) - for i, receipt := range receipts { - logs[i] = receipt.Logs - } - return logs, nil -} - -// GetLogs implements erigon_getLogs. Return an array of logs that matches the filter conditions -func (api *ErigonImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) (types.ErigonLogs, error) { - start := time.Now() - var begin, end uint64 - erigonLogs := types.ErigonLogs{} - - tx, beginErr := api.db.BeginRo(ctx) - if beginErr != nil { - return erigonLogs, beginErr - } - defer tx.Rollback() - - if crit.BlockHash != nil { - number := rawdb.ReadHeaderNumber(tx, *crit.BlockHash) - if number == nil { - return nil, fmt.Errorf("block not found: %x", *crit.BlockHash) - } - begin = *number - end = *number - } else { - // Convert the RPC block numbers into internal representations - latest, err := getLatestBlockNumber(tx) - if err != nil { - return nil, err - } - - begin = latest - if crit.FromBlock != nil { - if crit.FromBlock.Sign() >= 0 { - begin = crit.FromBlock.Uint64() - } else if !crit.FromBlock.IsInt64() || crit.FromBlock.Int64() != int64(rpc.LatestBlockNumber) { - return nil, fmt.Errorf("negative value for FromBlock: %v", crit.FromBlock) - } - } - end = latest - if crit.ToBlock != nil { - if crit.ToBlock.Sign() >= 0 { - end = crit.ToBlock.Uint64() - } else if !crit.ToBlock.IsInt64() || crit.ToBlock.Int64() != int64(rpc.LatestBlockNumber) { - return nil, fmt.Errorf("negative value for ToBlock: %v", crit.ToBlock) - } - } - } - if end < begin { - return nil, fmt.Errorf("end (%d) < begin (%d)", end, begin) - } - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - var fromTxNum, toTxNum uint64 - if begin > 0 { - fromTxNum = api._txNums.MinOf(begin) - } - toTxNum = api._txNums.MaxOf(end) // end is an inclusive bound - - txNumbers := roaring64.New() - txNumbers.AddRange(fromTxNum, toTxNum) // [min,max) - - ac := api._agg.MakeContext() - - topicsBitmap, err := getTopicsBitmap(ac, tx, crit.Topics, fromTxNum, toTxNum) - if err != nil { - return nil, err - } - if topicsBitmap != nil { - txNumbers.And(topicsBitmap) - } - - var addrBitmap *roaring64.Bitmap - for _, addr := range crit.Addresses { - var bitmapForORing roaring64.Bitmap - it := ac.LogAddrIterator(addr.Bytes(), fromTxNum, toTxNum, nil) - for it.HasNext() { - bitmapForORing.Add(it.Next()) - } - if addrBitmap == nil { - addrBitmap = &bitmapForORing - continue - } - addrBitmap = roaring64.Or(addrBitmap, &bitmapForORing) - } - - if addrBitmap != nil { - txNumbers.And(addrBitmap) - } - - if txNumbers.GetCardinality() == 0 { - return erigonLogs, nil - } - var lastBlockNum uint64 - var lastBlockHash common.Hash - var lastHeader *types.Header - var lastSigner *types.Signer - var lastRules *params.Rules - stateReader := state.NewHistoryReader23(ac, nil /* ReadIndices */) - iter := txNumbers.Iterator() - for iter.HasNext() { - txNum := iter.Next() - // Find block number - ok, blockNum := api._txNums.Find(txNum) - if !ok { - return nil, nil - } - if blockNum > lastBlockNum { - if lastHeader, err = api._blockReader.HeaderByNumber(ctx, nil, blockNum); err != nil { - return nil, err - } - lastBlockNum = blockNum - lastBlockHash = lastHeader.Hash() - lastSigner = types.MakeSigner(chainConfig, blockNum) - lastRules = chainConfig.Rules(blockNum) - } - var startTxNum uint64 - if blockNum > 0 { - startTxNum = api._txNums.MinOf(blockNum) - } - txIndex := txNum - startTxNum - 1 - //fmt.Printf("txNum=%d, blockNum=%d, txIndex=%d\n", txNum, blockNum, txIndex) - txn, err := api._txnReader.TxnByIdxInBlock(ctx, nil, blockNum, int(txIndex)) - if err != nil { - return nil, err - } - timestamp := uint64(txn.Time().Unix()) - txHash := txn.Hash() - msg, err := txn.AsMessage(*lastSigner, lastHeader.BaseFee, lastRules) - if err != nil { - return nil, err - } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - blockCtx, txCtx := transactions.GetEvmContext(msg, lastHeader, true /* requireCanonical */, tx, contractHasTEVM, api._blockReader) - stateReader.SetTxNum(txNum) - vmConfig := vm.Config{} - vmConfig.SkipAnalysis = core.SkipAnalysis(chainConfig, blockNum) - ibs := state.New(stateReader) - evm := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vmConfig) - - gp := new(core.GasPool).AddGas(msg.Gas()) - ibs.Prepare(txHash, lastBlockHash, int(txIndex)) - _, err = core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - return nil, err - } - filtered := filterLogs(ibs.GetLogs(txHash), crit.Addresses, crit.Topics) - for i, log := range filtered { - log.BlockNumber = blockNum - log.BlockHash = lastBlockHash - log.TxHash = txHash - log.Index = 0 - - erigonLogs[i].Log = *log - erigonLogs[i].Timestamp = timestamp - } - } - stats := api._agg.GetAndResetStats() - log.Info("Finished", "duration", time.Since(start), "history queries", stats.HistoryQueries, "ef search duration", stats.EfSearchTime) - return erigonLogs, nil -} - -// GetLogsByNumber implements erigon_getLogsByHash. Returns all the logs that appear in a block given the block's hash. -// func (api *ErigonImpl) GetLogsByNumber(ctx context.Context, number rpc.BlockNumber) ([][]*types.Log, error) { -// tx, err := api.db.Begin(ctx, false) -// if err != nil { -// return nil, err -// } -// defer tx.Rollback() - -// number := rawdb.ReadHeaderNumber(tx, hash) -// if number == nil { -// return nil, fmt.Errorf("block not found: %x", hash) -// } - -// receipts, err := getReceipts(ctx, tx, *number, hash) -// if err != nil { -// return nil, fmt.Errorf("getReceipts error: %w", err) -// } - -// logs := make([][]*types.Log, len(receipts)) -// for i, receipt := range receipts { -// logs[i] = receipt.Logs -// } -// return logs, nil -// } diff --git a/cmd/rpcdaemon22/commands/erigon_system.go b/cmd/rpcdaemon22/commands/erigon_system.go deleted file mode 100644 index 67f4190fc3d..00000000000 --- a/cmd/rpcdaemon22/commands/erigon_system.go +++ /dev/null @@ -1,31 +0,0 @@ -package commands - -import ( - "context" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/forkid" -) - -// Forks is a data type to record a list of forks passed by this node -type Forks struct { - GenesisHash common.Hash `json:"genesis"` - Forks []uint64 `json:"forks"` -} - -// Forks implements erigon_forks. Returns the genesis block hash and a sorted list of all forks block numbers -func (api *ErigonImpl) Forks(ctx context.Context) (Forks, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return Forks{}, err - } - defer tx.Rollback() - - chainConfig, genesis, err := api.chainConfigWithGenesis(tx) - if err != nil { - return Forks{}, err - } - forksBlocks := forkid.GatherForks(chainConfig) - - return Forks{genesis.Hash(), forksBlocks}, nil -} diff --git a/cmd/rpcdaemon22/commands/eth_api.go b/cmd/rpcdaemon22/commands/eth_api.go index 1575c48b552..3ed493e777d 100644 --- a/cmd/rpcdaemon22/commands/eth_api.go +++ b/cmd/rpcdaemon22/commands/eth_api.go @@ -20,7 +20,6 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" ethFilters "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" @@ -30,11 +29,6 @@ import ( // EthAPI is a collection of functions that are exposed in the type EthAPI interface { - // Block related (proposed file: ./eth_blocks.go) - GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) - GetBlockByHash(ctx context.Context, hash rpc.BlockNumberOrHash, fullTx bool) (map[string]interface{}, error) - GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) - GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) // Transaction related (see ./eth_txs.go) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) @@ -76,16 +70,6 @@ type EthAPI interface { ProtocolVersion(_ context.Context) (hexutil.Uint, error) GasPrice(_ context.Context) (*hexutil.Big, error) - // Sending related (see ./eth_call.go) - Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) - EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) - SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) - SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) - SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) - CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) - // Mining related (see ./eth_mining.go) Coinbase(ctx context.Context) (common.Address, error) Hashrate(ctx context.Context) (uint64, error) @@ -110,7 +94,6 @@ type BaseAPI struct { _txnReader services.TxnReader _agg *libstate.Aggregator _txNums *exec22.TxNums - TevmEnabled bool // experiment } func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.Aggregator, txNums *exec22.TxNums, singleNodeMode bool) *BaseAPI { @@ -131,8 +114,6 @@ func (api *BaseAPI) chainConfig(tx kv.Tx) (*params.ChainConfig, error) { return cfg, err } -func (api *BaseAPI) EnableTevmExperiment() { api.TevmEnabled = true } - // nolint:unused func (api *BaseAPI) genesis(tx kv.Tx) (*types.Block, error) { _, genesis, err := api.chainConfigWithGenesis(tx) diff --git a/cmd/rpcdaemon22/commands/eth_api_test.go b/cmd/rpcdaemon22/commands/eth_api_test.go deleted file mode 100644 index 41cea108b36..00000000000 --- a/cmd/rpcdaemon22/commands/eth_api_test.go +++ /dev/null @@ -1,244 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "testing" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/stretchr/testify/assert" - - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" -) - -func TestGetBalanceChangesInBlock(t *testing.T) { - assert := assert.New(t) - myBlockNum := rpc.BlockNumberOrHashWithNumber(0) - - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - balances, err := api.GetBalanceChangesInBlock(context.Background(), myBlockNum) - if err != nil { - t.Errorf("calling GetBalanceChangesInBlock resulted in an error: %v", err) - } - expected := map[common.Address]*hexutil.Big{ - common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"): (*hexutil.Big)(uint256.NewInt(200000000000000000).ToBig()), - common.HexToAddress("0x703c4b2bD70c169f5717101CaeE543299Fc946C7"): (*hexutil.Big)(uint256.NewInt(300000000000000000).ToBig()), - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): (*hexutil.Big)(uint256.NewInt(9000000000000000000).ToBig()), - } - assert.Equal(len(expected), len(balances)) - for i := range balances { - assert.Contains(expected, i, "%s is not expected to be present in the output.", i) - assert.Equal(balances[i], expected[i], "the value for %s is expected to be %v, but got %v.", i, expected[i], balances[i]) - } -} - -func TestGetTransactionReceipt(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - // Call GetTransactionReceipt for transaction which is not in the database - if _, err := api.GetTransactionReceipt(context.Background(), common.Hash{}); err != nil { - t.Errorf("calling GetTransactionReceipt with empty hash: %v", err) - } -} - -func TestGetTransactionReceiptUnprotected(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - // Call GetTransactionReceipt for un-protected transaction - if _, err := api.GetTransactionReceipt(context.Background(), common.HexToHash("0x3f3cb8a0e13ed2481f97f53f7095b9cbc78b6ffb779f2d3e565146371a8830ea")); err != nil { - t.Errorf("calling GetTransactionReceipt for unprotected tx: %v", err) - } -} - -// EIP-1898 test cases - -func TestGetStorageAt_ByBlockNumber_WithRequireCanonicalDefault(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithNumber(0)) - if err != nil { - t.Errorf("calling GetStorageAt: %v", err) - } - - assert.Equal(common.HexToHash("0x0").String(), result) -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault(t *testing.T) { - assert := assert.New(t) - m, _, _ := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(m.Genesis.Hash(), false)) - if err != nil { - t.Errorf("calling GetStorageAt: %v", err) - } - - assert.Equal(common.HexToHash("0x0").String(), result) -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue(t *testing.T) { - assert := assert.New(t) - m, _, _ := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(m.Genesis.Hash(), true)) - if err != nil { - t.Errorf("calling GetStorageAt: %v", err) - } - - assert.Equal(common.HexToHash("0x0").String(), result) -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault_BlockNotFoundError(t *testing.T) { - m, _, _ := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - offChain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, block *core.BlockGen) { - }, true) - if err != nil { - t.Fatal(err) - } - offChainBlock := offChain.Blocks[0] - - if _, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(offChainBlock.Hash(), false)); err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("block %s not found", offChainBlock.Hash().String()[2:]) { - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue_BlockNotFoundError(t *testing.T) { - m, _, _ := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - offChain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, block *core.BlockGen) { - }, true) - if err != nil { - t.Fatal(err) - } - offChainBlock := offChain.Blocks[0] - - if _, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(offChainBlock.Hash(), true)); err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("block %s not found", offChainBlock.Hash().String()[2:]) { - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault_NonCanonicalBlock(t *testing.T) { - assert := assert.New(t) - m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - orphanedBlock := orphanedChain[0].Blocks[0] - - result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(orphanedBlock.Hash(), false)) - if err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("hash %s is not currently canonical", orphanedBlock.Hash().String()[2:]) { - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } - - assert.Equal(common.HexToHash("0x0").String(), result) -} - -func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue_NonCanonicalBlock(t *testing.T) { - m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - - orphanedBlock := orphanedChain[0].Blocks[0] - - if _, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(orphanedBlock.Hash(), true)); err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("hash %s is not currently canonical", orphanedBlock.Hash().String()[2:]) { - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } -} - -func TestCall_ByBlockHash_WithRequireCanonicalDefault_NonCanonicalBlock(t *testing.T) { - m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - from := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - to := common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") - - orphanedBlock := orphanedChain[0].Blocks[0] - - if _, err := api.Call(context.Background(), ethapi.CallArgs{ - From: &from, - To: &to, - }, rpc.BlockNumberOrHashWithHash(orphanedBlock.Hash(), false), nil); err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("hash %s is not currently canonical", orphanedBlock.Hash().String()[2:]) { - /* Not sure. Here https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md it is not explicitly said that - eth_call should only work with canonical blocks. - But since there is no point in changing the state of non-canonical block, it ignores RequireCanonical. */ - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } -} - -func TestCall_ByBlockHash_WithRequireCanonicalTrue_NonCanonicalBlock(t *testing.T) { - m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) - db := m.DB - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - from := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - to := common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") - - orphanedBlock := orphanedChain[0].Blocks[0] - - if _, err := api.Call(context.Background(), ethapi.CallArgs{ - From: &from, - To: &to, - }, rpc.BlockNumberOrHashWithHash(orphanedBlock.Hash(), true), nil); err != nil { - if fmt.Sprintf("%v", err) != fmt.Sprintf("hash %s is not currently canonical", orphanedBlock.Hash().String()[2:]) { - t.Errorf("wrong error: %v", err) - } - } else { - t.Error("error expected") - } -} diff --git a/cmd/rpcdaemon22/commands/eth_block.go b/cmd/rpcdaemon22/commands/eth_block.go deleted file mode 100644 index e331226e3e0..00000000000 --- a/cmd/rpcdaemon22/commands/eth_block.go +++ /dev/null @@ -1,358 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "math/big" - "time" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/transactions" - "github.com/ledgerwatch/log/v3" - "golang.org/x/crypto/sha3" -) - -func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stateBlockNumberOrHash rpc.BlockNumberOrHash, timeoutMilliSecondsPtr *int64) (map[string]interface{}, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - if len(txHashes) == 0 { - return nil, nil - } - - var txs types.Transactions - - for _, txHash := range txHashes { - blockNum, ok, err := api.txnLookup(ctx, tx, txHash) - if err != nil { - return nil, err - } - if !ok { - return nil, nil - } - block, err := api.blockByNumberWithSenders(tx, blockNum) - if err != nil { - return nil, err - } - if block == nil { - return nil, nil - } - var txn types.Transaction - for _, transaction := range block.Transactions() { - if transaction.Hash() == txHash { - txn = transaction - break - } - } - if txn == nil { - return nil, nil // not error, see https://github.com/ledgerwatch/turbo-geth/issues/1645 - } - txs = append(txs, txn) - } - defer func(start time.Time) { log.Trace("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) - - stateBlockNumber, hash, latest, err := rpchelper.GetBlockNumber(stateBlockNumberOrHash, tx, api.filters) - if err != nil { - return nil, err - } - - var stateReader state.StateReader - if latest { - cacheView, err := api.stateCache.View(ctx, tx) - if err != nil { - return nil, err - } - stateReader = state.NewCachedReader2(cacheView, tx) - } else { - stateReader = state.NewPlainState(tx, stateBlockNumber) - } - st := state.New(stateReader) - - parent := rawdb.ReadHeader(tx, hash, stateBlockNumber) - if parent == nil { - return nil, fmt.Errorf("block %d(%x) not found", stateBlockNumber, hash) - } - - blockNumber := stateBlockNumber + 1 - - timestamp := parent.Time // Dont care about the timestamp - - coinbase := parent.Coinbase - header := &types.Header{ - ParentHash: parent.Hash(), - Number: big.NewInt(int64(blockNumber)), - GasLimit: parent.GasLimit, - Time: timestamp, - Difficulty: parent.Difficulty, - Coinbase: coinbase, - } - - // Get a new instance of the EVM - signer := types.MakeSigner(chainConfig, blockNumber) - rules := chainConfig.Rules(blockNumber) - firstMsg, err := txs[0].AsMessage(*signer, nil, rules) - if err != nil { - return nil, err - } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - blockCtx, txCtx := transactions.GetEvmContext(firstMsg, header, stateBlockNumberOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) - evm := vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) - - timeoutMilliSeconds := int64(5000) - if timeoutMilliSecondsPtr != nil { - timeoutMilliSeconds = *timeoutMilliSecondsPtr - } - timeout := time.Millisecond * time.Duration(timeoutMilliSeconds) - // Setup context so it may be cancelled the call has completed - // or, in case of unmetered gas, setup a context with a timeout. - var cancel context.CancelFunc - if timeout > 0 { - ctx, cancel = context.WithTimeout(ctx, timeout) - } else { - ctx, cancel = context.WithCancel(ctx) - } - // Make sure the context is cancelled when the call has completed - // this makes sure resources are cleaned up. - defer cancel() - - // Wait for the context to be done and cancel the evm. Even if the - // EVM has finished, cancelling may be done (repeatedly) - go func() { - <-ctx.Done() - evm.Cancel() - }() - - // Setup the gas pool (also for unmetered requests) - // and apply the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) - - results := []map[string]interface{}{} - - bundleHash := sha3.NewLegacyKeccak256() - for _, txn := range txs { - msg, err := txn.AsMessage(*signer, nil, rules) - if err != nil { - return nil, err - } - // Execute the transaction message - result, err := core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - return nil, err - } - // If the timer caused an abort, return an appropriate error message - if evm.Cancelled() { - return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) - } - - txHash := txn.Hash().String() - jsonResult := map[string]interface{}{ - "txHash": txHash, - "gasUsed": result.UsedGas, - } - bundleHash.Write(txn.Hash().Bytes()) - if result.Err != nil { - jsonResult["error"] = result.Err.Error() - } else { - jsonResult["value"] = common.BytesToHash(result.Return()) - } - - results = append(results, jsonResult) - } - - ret := map[string]interface{}{} - ret["results"] = results - ret["bundleHash"] = hexutil.Encode(bundleHash.Sum(nil)) - return ret, nil -} - -// GetBlockByNumber implements eth_getBlockByNumber. Returns information about a block given the block's number. -func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - b, err := api.blockByRPCNumber(number, tx) - if err != nil { - return nil, err - } - if b == nil { - return nil, nil - } - additionalFields := make(map[string]interface{}) - td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) - if err != nil { - return nil, err - } - if td != nil { - additionalFields["totalDifficulty"] = (*hexutil.Big)(td) - } - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - var borTx types.Transaction - var borTxHash common.Hash - if chainConfig.Bor != nil { - borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, b) - if borTx != nil { - borTxHash = types.ComputeBorTxHash(b.NumberU64(), b.Hash()) - } - } - - response, err := ethapi.RPCMarshalBlockEx(b, true, fullTx, borTx, borTxHash, additionalFields) - - if err == nil && number == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err -} - -// GetBlockByHash implements eth_getBlockByHash. Returns information about a block given the block's hash. -func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNumberOrHash, fullTx bool) (map[string]interface{}, error) { - if numberOrHash.BlockHash == nil { - // some web3.js based apps (like ethstats client) for some reason call - // eth_getBlockByHash with a block number as a parameter - // so no matter how weird that is, we would love to support that. - if numberOrHash.BlockNumber == nil { - return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645 - } - return api.GetBlockByNumber(ctx, *numberOrHash.BlockNumber, fullTx) - } - - hash := *numberOrHash.BlockHash - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - additionalFields := make(map[string]interface{}) - - block, err := api.blockByHashWithSenders(tx, hash) - if err != nil { - return nil, err - } - if block == nil { - return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645 - } - number := block.NumberU64() - - td, err := rawdb.ReadTd(tx, hash, number) - if err != nil { - return nil, err - } - additionalFields["totalDifficulty"] = (*hexutil.Big)(td) - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - var borTx types.Transaction - var borTxHash common.Hash - if chainConfig.Bor != nil { - borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, block) - if borTx != nil { - borTxHash = types.ComputeBorTxHash(block.NumberU64(), block.Hash()) - } - } - - response, err := ethapi.RPCMarshalBlockEx(block, true, fullTx, borTx, borTxHash, additionalFields) - - if err == nil && int64(number) == rpc.PendingBlockNumber.Int64() { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err -} - -// GetBlockTransactionCountByNumber implements eth_getBlockTransactionCountByNumber. Returns the number of transactions in a block given the block's block number. -func (api *APIImpl) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - if blockNr == rpc.PendingBlockNumber { - b, err := api.blockByRPCNumber(blockNr, tx) - if err != nil { - return nil, err - } - if b == nil { - return nil, nil - } - n := hexutil.Uint(len(b.Transactions())) - return &n, nil - } - blockNum, blockHash, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(blockNr), tx, api.filters) - if err != nil { - return nil, err - } - _, txAmount, err := api._blockReader.Body(ctx, tx, blockHash, blockNum) - if err != nil { - return nil, err - } - - if txAmount == 0 { - return nil, nil - } - - numOfTx := hexutil.Uint(txAmount) - - return &numOfTx, nil -} - -// GetBlockTransactionCountByHash implements eth_getBlockTransactionCountByHash. Returns the number of transactions in a block given the block's block hash. -func (api *APIImpl) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - blockNum, _, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHash{BlockHash: &blockHash}, tx, nil) - if err != nil { - return nil, err - } - _, txAmount, err := api._blockReader.Body(ctx, tx, blockHash, blockNum) - if err != nil { - return nil, err - } - - if txAmount == 0 { - return nil, nil - } - - numOfTx := hexutil.Uint(txAmount) - - return &numOfTx, nil -} diff --git a/cmd/rpcdaemon22/commands/eth_call.go b/cmd/rpcdaemon22/commands/eth_call.go deleted file mode 100644 index 5aafbed69d9..00000000000 --- a/cmd/rpcdaemon22/commands/eth_call.go +++ /dev/null @@ -1,455 +0,0 @@ -package commands - -import ( - "context" - "errors" - "fmt" - "math/big" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/gointerfaces" - txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - "google.golang.org/grpc" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/eth/tracers/logger" - "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/transactions" -) - -// Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. -func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - if args.Gas == nil || uint64(*args.Gas) == 0 { - args.Gas = (*hexutil.Uint64)(&api.GasCap) - } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - blockNumber, hash, _, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks - if err != nil { - return nil, err - } - block, err := api.BaseAPI.blockWithSenders(tx, hash, blockNumber) - if err != nil { - return nil, err - } - if block == nil { - return nil, nil - } - - result, err := transactions.DoCall(ctx, args, tx, blockNrOrHash, block, overrides, api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM, api._blockReader) - if err != nil { - return nil, err - } - - // If the result contains a revert reason, try to unpack and return it. - if len(result.Revert()) > 0 { - return nil, ethapi.NewRevertError(result) - } - - return result.Return(), result.Err -} - -// headerByNumberOrHash - intent to read recent headers only -func headerByNumberOrHash(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, api *APIImpl) (*types.Header, error) { - blockNum, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) - if err != nil { - return nil, err - } - header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) - if err != nil { - return nil, err - } - // header can be nil - return header, nil -} - -// EstimateGas implements eth_estimateGas. Returns an estimate of how much gas is necessary to allow the transaction to complete. The transaction will not be added to the blockchain. -func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { - var args ethapi.CallArgs - // if we actually get CallArgs here, we use them - if argsOrNil != nil { - args = *argsOrNil - } - - bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - if blockNrOrHash != nil { - bNrOrHash = *blockNrOrHash - } - - dbtx, err := api.db.BeginRo(ctx) - if err != nil { - return 0, err - } - defer dbtx.Rollback() - - // Binary search the gas requirement, as it may be higher than the amount used - var ( - lo = params.TxGas - 1 - hi uint64 - cap uint64 - ) - // Use zero address if sender unspecified. - if args.From == nil { - args.From = new(common.Address) - } - - // Determine the highest gas limit can be used during the estimation. - if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { - hi = uint64(*args.Gas) - } else { - // Retrieve the block to act as the gas ceiling - h, err := headerByNumberOrHash(ctx, dbtx, bNrOrHash, api) - if err != nil { - return 0, err - } - if h == nil { - // if a block number was supplied and there is no header return 0 - if blockNrOrHash != nil { - return 0, nil - } - - // block number not supplied, so we haven't found a pending block, read the latest block instead - bNrOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - h, err = headerByNumberOrHash(ctx, dbtx, bNrOrHash, api) - if err != nil { - return 0, err - } - if h == nil { - return 0, nil - } - } - hi = h.GasLimit - } - - var feeCap *big.Int - if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") - } else if args.GasPrice != nil { - feeCap = args.GasPrice.ToInt() - } else if args.MaxFeePerGas != nil { - feeCap = args.MaxFeePerGas.ToInt() - } else { - feeCap = common.Big0 - } - // Recap the highest gas limit with account's available balance. - if feeCap.Sign() != 0 { - cacheView, err := api.stateCache.View(ctx, dbtx) - if err != nil { - return 0, err - } - stateReader := state.NewCachedReader2(cacheView, dbtx) - state := state.New(stateReader) - if state == nil { - return 0, fmt.Errorf("can't get the current state") - } - - balance := state.GetBalance(*args.From) // from can't be nil - available := balance.ToBig() - if args.Value != nil { - if args.Value.ToInt().Cmp(available) >= 0 { - return 0, errors.New("insufficient funds for transfer") - } - available.Sub(available, args.Value.ToInt()) - } - allowance := new(big.Int).Div(available, feeCap) - - // If the allowance is larger than maximum uint64, skip checking - if allowance.IsUint64() && hi > allowance.Uint64() { - transfer := args.Value - if transfer == nil { - transfer = new(hexutil.Big) - } - log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, - "sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) - hi = allowance.Uint64() - } - } - - // Recap the highest gas allowance with specified gascap. - if hi > api.GasCap { - log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", api.GasCap) - hi = api.GasCap - } - cap = hi - var lastBlockNum = rpc.LatestBlockNumber - - chainConfig, err := api.chainConfig(dbtx) - if err != nil { - return 0, err - } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - - // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) (bool, *core.ExecutionResult, error) { - args.Gas = (*hexutil.Uint64)(&gas) - - numOrHash := rpc.BlockNumberOrHash{BlockNumber: &lastBlockNum} - blockNumber, hash, _, err := rpchelper.GetCanonicalBlockNumber(numOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks - if err != nil { - return false, nil, err - } - block, err := api.BaseAPI.blockWithSenders(dbtx, hash, blockNumber) - if err != nil { - return false, nil, err - } - if block == nil { - return false, nil, nil - } - - result, err := transactions.DoCall(ctx, args, dbtx, numOrHash, block, nil, - api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM, api._blockReader) - if err != nil { - if errors.Is(err, core.ErrIntrinsicGas) { - // Special case, raise gas limit - return true, nil, nil - } - - // Bail out - return true, nil, err - } - return result.Failed(), result, nil - } - // Execute the binary search and hone in on an executable gas limit - for lo+1 < hi { - mid := (hi + lo) / 2 - failed, _, err := executable(mid) - - // If the error is not nil(consensus error), it means the provided message - // call or transaction will never be accepted no matter how much gas it is - // assigened. Return the error directly, don't struggle any more. - if err != nil { - return 0, err - } - if failed { - lo = mid - } else { - hi = mid - } - } - // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { - failed, result, err := executable(hi) - if err != nil { - return 0, err - } - if failed { - if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) { - if len(result.Revert()) > 0 { - return 0, ethapi.NewRevertError(result) - } - return 0, result.Err - } - // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) - } - } - return hexutil.Uint64(hi), nil -} - -// GetProof not implemented -func (api *APIImpl) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) { - var stub interface{} - return &stub, fmt.Errorf(NotImplemented, "eth_getProof") -} - -// accessListResult returns an optional accesslist -// Its the result of the `eth_createAccessList` RPC call. -// It contains an error if the transaction itself failed. -type accessListResult struct { - Accesslist *types.AccessList `json:"accessList"` - Error string `json:"error,omitempty"` - GasUsed hexutil.Uint64 `json:"gasUsed"` -} - -// CreateAccessList implements eth_createAccessList. It creates an access list for the given transaction. -// If the accesslist creation fails an error is returned. -// If the transaction itself fails, an vmErr is returned. -func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) { - bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - if blockNrOrHash != nil { - bNrOrHash = *blockNrOrHash - } - - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - blockNumber, hash, latest, err := rpchelper.GetCanonicalBlockNumber(bNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks - if err != nil { - return nil, err - } - block, err := api.BaseAPI.blockWithSenders(tx, hash, blockNumber) - if err != nil { - return nil, err - } - if block == nil { - return nil, nil - } - var stateReader state.StateReader - if latest { - cacheView, err := api.stateCache.View(ctx, tx) - if err != nil { - return nil, err - } - stateReader = state.NewCachedReader2(cacheView, tx) - } else { - stateReader = state.NewPlainState(tx, blockNumber+1) - } - - header := block.Header() - // If the gas amount is not set, extract this as it will depend on access - // lists and we'll need to reestimate every time - nogas := args.Gas == nil - - var to common.Address - if args.To != nil { - to = *args.To - } else { - // Require nonce to calculate address of created contract - if args.Nonce == nil { - var nonce uint64 - reply, err := api.txPool.Nonce(ctx, &txpool_proto.NonceRequest{ - Address: gointerfaces.ConvertAddressToH160(*args.From), - }, &grpc.EmptyCallOption{}) - if err != nil { - return nil, err - } - if reply.Found { - nonce = reply.Nonce + 1 - } - args.Nonce = (*hexutil.Uint64)(&nonce) - } - to = crypto.CreateAddress(*args.From, uint64(*args.Nonce)) - } - - // Retrieve the precompiles since they don't need to be added to the access list - precompiles := vm.ActivePrecompiles(chainConfig.Rules(blockNumber)) - - // Create an initial tracer - prevTracer := logger.NewAccessListTracer(nil, *args.From, to, precompiles) - if args.AccessList != nil { - prevTracer = logger.NewAccessListTracer(*args.AccessList, *args.From, to, precompiles) - } - for { - state := state.New(stateReader) - // Retrieve the current access list to expand - accessList := prevTracer.AccessList() - log.Trace("Creating access list", "input", accessList) - - // If no gas amount was specified, each unique access list needs it's own - // gas calculation. This is quite expensive, but we need to be accurate - // and it's convered by the sender only anyway. - if nogas { - args.Gas = nil - } - // Set the accesslist to the last al - args.AccessList = &accessList - - var msg types.Message - - var baseFee *uint256.Int = nil - // check if EIP-1559 - if header.BaseFee != nil { - baseFee, _ = uint256.FromBig(header.BaseFee) - } - - msg, err = args.ToMessage(api.GasCap, baseFee) - if err != nil { - return nil, err - } - - // Apply the transaction with the access list tracer - tracer := logger.NewAccessListTracer(accessList, *args.From, to, precompiles) - config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} - blockCtx, txCtx := transactions.GetEvmContext(msg, header, bNrOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) - - evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, config) - gp := new(core.GasPool).AddGas(msg.Gas()) - res, err := core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - return nil, err - } - if tracer.Equal(prevTracer) { - var errString string - if res.Err != nil { - errString = res.Err.Error() - } - accessList := &accessListResult{Accesslist: &accessList, Error: errString, GasUsed: hexutil.Uint64(res.UsedGas)} - if optimizeGas != nil && *optimizeGas { - optimizeToInAccessList(accessList, to) - } - return accessList, nil - } - prevTracer = tracer - } -} - -// to address is warm already, so we can save by adding it to the access list -// only if we are adding a lot of its storage slots as well -func optimizeToInAccessList(accessList *accessListResult, to common.Address) { - indexToRemove := -1 - - for i := 0; i < len(*accessList.Accesslist); i++ { - entry := (*accessList.Accesslist)[i] - if entry.Address != to { - continue - } - - // https://eips.ethereum.org/EIPS/eip-2930#charging-less-for-accesses-in-the-access-list - accessListSavingPerSlot := params.ColdSloadCostEIP2929 - params.WarmStorageReadCostEIP2929 - params.TxAccessListStorageKeyGas - - numSlots := uint64(len(entry.StorageKeys)) - if numSlots*accessListSavingPerSlot <= params.TxAccessListAddressGas { - indexToRemove = i - } - } - - if indexToRemove >= 0 { - *accessList.Accesslist = removeIndex(*accessList.Accesslist, indexToRemove) - } -} - -func removeIndex(s types.AccessList, index int) types.AccessList { - return append(s[:index], s[index+1:]...) -} diff --git a/cmd/rpcdaemon22/commands/eth_callMany.go b/cmd/rpcdaemon22/commands/eth_callMany.go deleted file mode 100644 index 9de19308369..00000000000 --- a/cmd/rpcdaemon22/commands/eth_callMany.go +++ /dev/null @@ -1,310 +0,0 @@ -package commands - -import ( - "context" - "encoding/hex" - "fmt" - "math/big" - "time" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" - rpcapi "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/log/v3" -) - -type BlockOverrides struct { - BlockNumber *hexutil.Uint64 - Coinbase *common.Address - Timestamp *hexutil.Uint64 - GasLimit *hexutil.Uint - Difficulty *hexutil.Uint - BaseFee *uint256.Int - BlockHash *map[uint64]common.Hash -} - -type Bundle struct { - Transactions []rpcapi.CallArgs - BlockOverride BlockOverrides -} - -type StateContext struct { - BlockNumber rpc.BlockNumberOrHash - TransactionIndex *int -} - -func blockHeaderOverride(blockCtx *vm.BlockContext, blockOverride BlockOverrides, overrideBlockHash map[uint64]common.Hash) { - if blockOverride.BlockNumber != nil { - blockCtx.BlockNumber = uint64(*blockOverride.BlockNumber) - } - if blockOverride.BaseFee != nil { - blockCtx.BaseFee = blockOverride.BaseFee - } - if blockOverride.Coinbase != nil { - blockCtx.Coinbase = *blockOverride.Coinbase - } - if blockOverride.Difficulty != nil { - blockCtx.Difficulty = big.NewInt(int64(*blockOverride.Difficulty)) - } - if blockOverride.Timestamp != nil { - blockCtx.Time = uint64(*blockOverride.Timestamp) - } - if blockOverride.GasLimit != nil { - blockCtx.GasLimit = uint64(*blockOverride.GasLimit) - } - if blockOverride.BlockHash != nil { - for blockNum, hash := range *blockOverride.BlockHash { - overrideBlockHash[blockNum] = hash - } - } -} - -func (api *APIImpl) CallMany(ctx context.Context, bundles []Bundle, simulateContext StateContext, stateOverride *rpcapi.StateOverrides, timeoutMilliSecondsPtr *int64) ([][]map[string]interface{}, error) { - var ( - hash common.Hash - replayTransactions types.Transactions - evm *vm.EVM - blockCtx vm.BlockContext - txCtx vm.TxContext - overrideBlockHash map[uint64]common.Hash - baseFee uint256.Int - ) - - overrideBlockHash = make(map[uint64]common.Hash) - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - if len(bundles) == 0 { - return nil, fmt.Errorf("empty bundles") - } - empty := true - for _, bundle := range bundles { - if len(bundle.Transactions) != 0 { - empty = false - } - } - - if empty { - return nil, fmt.Errorf("empty bundles") - } - - defer func(start time.Time) { log.Trace("Executing EVM callMany finished", "runtime", time.Since(start)) }(time.Now()) - - blockNum, hash, _, err := rpchelper.GetBlockNumber(simulateContext.BlockNumber, tx, api.filters) - if err != nil { - return nil, err - } - - block, err := api.blockByNumberWithSenders(tx, blockNum) - if err != nil { - return nil, err - } - - // -1 is a default value for transaction index. - // If it's -1, we will try to replay every single transaction in that block - transactionIndex := -1 - - if simulateContext.TransactionIndex != nil { - transactionIndex = *simulateContext.TransactionIndex - } - - if transactionIndex == -1 { - transactionIndex = len(block.Transactions()) - } - - replayTransactions = block.Transactions()[:transactionIndex] - - stateReader, err := rpchelper.CreateStateReader(ctx, tx, rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(blockNum-1)), api.filters, api.stateCache) - - if err != nil { - return nil, err - } - - st := state.New(stateReader) - - parent := block.Header() - - if parent == nil { - return nil, fmt.Errorf("block %d(%x) not found", blockNum, hash) - } - - // Get a new instance of the EVM - signer := types.MakeSigner(chainConfig, blockNum) - rules := chainConfig.Rules(blockNum) - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - getHash := func(i uint64) common.Hash { - if hash, ok := overrideBlockHash[i]; ok { - return hash - } - hash, err := rawdb.ReadCanonicalHash(tx, i) - if err != nil { - log.Debug("Can't get block hash by number", "number", i, "only-canonical", true) - } - return hash - } - - if parent.BaseFee != nil { - baseFee.SetFromBig(parent.BaseFee) - } - - blockCtx = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - ContractHasTEVM: contractHasTEVM, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, - } - - evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) - - timeoutMilliSeconds := int64(5000) - - if timeoutMilliSecondsPtr != nil { - timeoutMilliSeconds = *timeoutMilliSecondsPtr - } - - timeout := time.Millisecond * time.Duration(timeoutMilliSeconds) - // Setup context so it may be cancelled the call has completed - // or, in case of unmetered gas, setup a context with a timeout. - var cancel context.CancelFunc - if timeout > 0 { - ctx, cancel = context.WithTimeout(ctx, timeout) - } else { - ctx, cancel = context.WithCancel(ctx) - } - // Make sure the context is cancelled when the call has completed - // this makes sure resources are cleaned up. - defer cancel() - - // Wait for the context to be done and cancel the evm. Even if the - // EVM has finished, cancelling may be done (repeatedly) - go func() { - <-ctx.Done() - evm.Cancel() - }() - - // Setup the gas pool (also for unmetered requests) - // and apply the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) - for _, txn := range replayTransactions { - msg, err := txn.AsMessage(*signer, nil, rules) - if err != nil { - return nil, err - } - txCtx = core.NewEVMTxContext(msg) - evm = vm.NewEVM(blockCtx, txCtx, evm.IntraBlockState(), chainConfig, vm.Config{Debug: false}) - // Execute the transaction message - _, err = core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - return nil, err - } - // If the timer caused an abort, return an appropriate error message - if evm.Cancelled() { - return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) - } - } - - // after replaying the txns, we want to overload the state - // overload state - if stateOverride != nil { - err = stateOverride.Override((evm.IntraBlockState()).(*state.IntraBlockState)) - if err != nil { - return nil, err - } - } - - ret := make([][]map[string]interface{}, 0) - - for _, bundle := range bundles { - // first change blockContext - if bundle.BlockOverride.BlockNumber != nil { - blockCtx.BlockNumber = uint64(*bundle.BlockOverride.BlockNumber) - } - if bundle.BlockOverride.BaseFee != nil { - blockCtx.BaseFee = bundle.BlockOverride.BaseFee - } - if bundle.BlockOverride.Coinbase != nil { - blockCtx.Coinbase = *bundle.BlockOverride.Coinbase - } - if bundle.BlockOverride.Difficulty != nil { - blockCtx.Difficulty = big.NewInt(int64(*bundle.BlockOverride.Difficulty)) - } - if bundle.BlockOverride.Timestamp != nil { - blockCtx.Time = uint64(*bundle.BlockOverride.Timestamp) - } - if bundle.BlockOverride.GasLimit != nil { - blockCtx.GasLimit = uint64(*bundle.BlockOverride.GasLimit) - } - if bundle.BlockOverride.BlockHash != nil { - for blockNum, hash := range *bundle.BlockOverride.BlockHash { - overrideBlockHash[blockNum] = hash - } - } - results := []map[string]interface{}{} - for _, txn := range bundle.Transactions { - if txn.Gas == nil || *(txn.Gas) == 0 { - txn.Gas = (*hexutil.Uint64)(&api.GasCap) - } - msg, err := txn.ToMessage(api.GasCap, blockCtx.BaseFee) - if err != nil { - return nil, err - } - txCtx = core.NewEVMTxContext(msg) - evm = vm.NewEVM(blockCtx, txCtx, evm.IntraBlockState(), chainConfig, vm.Config{Debug: false}) - result, err := core.ApplyMessage(evm, msg, gp, true, false) - if err != nil { - return nil, err - } - // If the timer caused an abort, return an appropriate error message - if evm.Cancelled() { - return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) - } - jsonResult := make(map[string]interface{}) - if result.Err != nil { - if len(result.Revert()) > 0 { - jsonResult["error"] = ethapi.NewRevertError(result) - } else { - jsonResult["error"] = result.Err.Error() - } - } else { - jsonResult["value"] = hex.EncodeToString(result.Return()) - } - - results = append(results, jsonResult) - } - - blockCtx.BlockNumber++ - blockCtx.Time++ - ret = append(ret, results) - } - - return ret, err -} diff --git a/cmd/rpcdaemon22/commands/eth_callMany_test.go b/cmd/rpcdaemon22/commands/eth_callMany_test.go deleted file mode 100644 index d96374ba224..00000000000 --- a/cmd/rpcdaemon22/commands/eth_callMany_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package commands - -import ( - "context" - "encoding/hex" - "fmt" - "math/big" - "strconv" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/accounts/abi/bind" - "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands/contracts" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" -) - -// block 1 contains 3 Transactions -// 1. deploy token A -// 2. mint address 2 100 token -// 3. transfer from address 2 to address 1 - -// test 2 bundles -// check balance of addr1 and addr 2 at the end of block and interblock - -func TestCallMany(t *testing.T) { - var ( - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - key1, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") - key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") - address = crypto.PubkeyToAddress(key.PublicKey) - address1 = crypto.PubkeyToAddress(key1.PublicKey) - address2 = crypto.PubkeyToAddress(key2.PublicKey) - gspec = &core.Genesis{ - Config: params.AllEthashProtocolChanges, - Alloc: core.GenesisAlloc{ - address: {Balance: big.NewInt(9000000000000000000)}, - address1: {Balance: big.NewInt(200000000000000000)}, - address2: {Balance: big.NewInt(300000000000000000)}, - }, - GasLimit: 10000000, - } - chainID = big.NewInt(1337) - ctx = context.Background() - - addr1BalanceCheck = "70a08231" + "000000000000000000000000" + address1.Hex()[2:] - addr2BalanceCheck = "70a08231" + "000000000000000000000000" + address2.Hex()[2:] - transferAddr2 = "70a08231" + "000000000000000000000000" + address1.Hex()[2:] + "0000000000000000000000000000000000000000000000000000000000000064" - ) - - hexBytes, _ := hex.DecodeString(addr2BalanceCheck) - balanceCallAddr2 := hexutil.Bytes(hexBytes) - hexBytes, _ = hex.DecodeString(addr1BalanceCheck) - balanceCallAddr1 := hexutil.Bytes(hexBytes) - hexBytes, _ = hex.DecodeString(transferAddr2) - transferCallData := hexutil.Bytes(hexBytes) - - //submit 3 Transactions and commit the results - transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, chainID) - transactOpts1, _ := bind.NewKeyedTransactorWithChainID(key1, chainID) - transactOpts2, _ := bind.NewKeyedTransactorWithChainID(key2, chainID) - contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit) - defer contractBackend.Close() - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - tokenAddr, _, tokenContract, _ := contracts.DeployToken(transactOpts, contractBackend, address1) - tokenContract.Mint(transactOpts1, address2, big.NewInt(100)) - tokenContract.Transfer(transactOpts2, address1, big.NewInt(100)) - contractBackend.Commit() - - // set up the callargs - var nonce hexutil.Uint64 = 1 - var secondNonce hexutil.Uint64 = 2 - - db := contractBackend.DB() - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - - callArgAddr1 := ethapi.CallArgs{From: &address, To: &tokenAddr, Nonce: &nonce, - MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)), - MaxFeePerGas: (*hexutil.Big)(big.NewInt(1e10)), - Data: &balanceCallAddr1, - } - callArgAddr2 := ethapi.CallArgs{From: &address, To: &tokenAddr, Nonce: &secondNonce, - MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)), - MaxFeePerGas: (*hexutil.Big)(big.NewInt(1e10)), - Data: &balanceCallAddr2, - } - - callArgTransferAddr2 := ethapi.CallArgs{From: &address2, To: &tokenAddr, Nonce: &nonce, - MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)), - MaxFeePerGas: (*hexutil.Big)(big.NewInt(1e10)), - Data: &transferCallData, - } - - timeout := int64(50000) - txIndex := -1 - res, err := api.CallMany(ctx, []Bundle{{ - Transactions: []ethapi.CallArgs{callArgAddr1, callArgAddr2}}}, StateContext{BlockNumber: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), TransactionIndex: &txIndex}, nil, &timeout) - if err != nil { - t.Errorf("eth_callMany: %v", err) - } - - // parse the results and do balance checks - addr1CalRet := fmt.Sprintf("%v", res[0][0]["value"])[2:] - addr2CalRet := fmt.Sprintf("%v", res[0][1]["value"])[2:] - addr1Balance, err := strconv.ParseInt(addr1CalRet, 16, 64) - if err != nil { - t.Errorf("eth_callMany: %v", err) - } - addr2Balance, err := strconv.ParseInt(addr2CalRet, 16, 64) - - if err != nil { - t.Errorf("eth_callMany: %v", err) - } - if addr1Balance != 100 || addr2Balance != 0 { - t.Errorf("eth_callMany: %v", "balanceUnmatch") - } - - txIndex = 2 - res, err = api.CallMany(ctx, []Bundle{{ - Transactions: []ethapi.CallArgs{callArgAddr1, callArgAddr2}}}, StateContext{BlockNumber: rpc.BlockNumberOrHashWithNumber(1), TransactionIndex: &txIndex}, nil, &timeout) - if err != nil { - t.Errorf("eth_callMany: %v", err) - } - - addr1CalRet = fmt.Sprintf("%v", res[0][0]["value"])[2:] - addr2CalRet = fmt.Sprintf("%v", res[0][1]["value"])[2:] - addr1Balance, err = strconv.ParseInt(addr1CalRet, 16, 64) - if err != nil { - t.Errorf("%v", err) - } - addr2Balance, err = strconv.ParseInt(addr2CalRet, 16, 64) - if err != nil { - t.Errorf("%v", err) - } - - if addr1Balance != 0 || addr2Balance != 100 { - t.Errorf("eth_callMany: %s", "balanceUnmatch") - } - txIndex = -1 - res, err = api.CallMany(ctx, []Bundle{{Transactions: []ethapi.CallArgs{callArgTransferAddr2, callArgAddr1, callArgAddr2}}}, StateContext{BlockNumber: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), TransactionIndex: &txIndex}, nil, &timeout) - if err != nil { - t.Errorf("%v", err) - } - - addr1CalRet = fmt.Sprintf("%v", res[0][1]["value"])[2:] - addr2CalRet = fmt.Sprintf("%v", res[0][2]["value"])[2:] - - addr1Balance, err = strconv.ParseInt(addr1CalRet, 16, 64) - if err != nil { - t.Errorf("%v", err) - } - addr2Balance, err = strconv.ParseInt(addr2CalRet, 16, 64) - if err != nil { - t.Errorf("%v", err) - } - if addr1Balance != 100 || addr2Balance != 0 { - t.Errorf("eth_callMany: %s", "balanceUnmatch") - } -} diff --git a/cmd/rpcdaemon22/commands/eth_call_test.go b/cmd/rpcdaemon22/commands/eth_call_test.go deleted file mode 100644 index a58c8ba2895..00000000000 --- a/cmd/rpcdaemon22/commands/eth_call_test.go +++ /dev/null @@ -1,380 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "math/big" - "testing" - "time" - - "github.com/holiman/uint256" - "github.com/stretchr/testify/assert" - - "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" -) - -func TestEstimateGas(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) - mining := txpool.NewMiningClient(conn) - ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - api := NewEthAPI(NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - var from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - var to = common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") - if _, err := api.EstimateGas(context.Background(), ðapi.CallArgs{ - From: &from, - To: &to, - }, nil); err != nil { - t.Errorf("calling EstimateGas: %v", err) - } -} - -func TestEthCallNonCanonical(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - var from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") - var to = common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") - if _, err := api.Call(context.Background(), ethapi.CallArgs{ - From: &from, - To: &to, - }, rpc.BlockNumberOrHashWithHash(common.HexToHash("0x3fcb7c0d4569fddc89cbea54b42f163e0c789351d98810a513895ab44b47020b"), true), nil); err != nil { - if fmt.Sprintf("%v", err) != "hash 3fcb7c0d4569fddc89cbea54b42f163e0c789351d98810a513895ab44b47020b is not currently canonical" { - t.Errorf("wrong error: %v", err) - } - } -} - -func TestEthCallToPrunedBlock(t *testing.T) { - pruneTo := uint64(3) - ethCallBlockNumber := rpc.BlockNumber(2) - - db, bankAddress, contractAddress := chainWithDeployedContract(t) - - prune(t, db, pruneTo) - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - - callData := hexutil.MustDecode("0x2e64cec1") - callDataBytes := hexutil.Bytes(callData) - - if _, err := api.Call(context.Background(), ethapi.CallArgs{ - From: &bankAddress, - To: &contractAddress, - Data: &callDataBytes, - }, rpc.BlockNumberOrHashWithNumber(ethCallBlockNumber), nil); err != nil { - t.Errorf("unexpected error: %v", err) - } -} - -func TestGetBlockByTimestampLatestTime(t *testing.T) { - ctx := context.Background() - db := rpcdaemontest.CreateTestKV(t) - - tx, err := db.BeginRo(ctx) - if err != nil { - t.Errorf("fail at beginning tx") - } - defer tx.Rollback() - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - - latestBlock := rawdb.ReadCurrentBlock(tx) - response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) - - if err != nil { - t.Error("couldn't get the rpc marshal block") - } - - if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - - block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(latestBlock.Header().Time), false) - if err != nil { - t.Errorf("couldn't retrieve block %v", err) - } - - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) - } -} - -func TestGetBlockByTimestampOldestTime(t *testing.T) { - ctx := context.Background() - db := rpcdaemontest.CreateTestKV(t) - - tx, err := db.BeginRo(ctx) - if err != nil { - t.Errorf("failed at beginning tx") - } - defer tx.Rollback() - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - - oldestBlock, err := rawdb.ReadBlockByNumber(tx, 0) - if err != nil { - t.Error("couldn't retrieve oldest block") - } - - response, err := ethapi.RPCMarshalBlock(oldestBlock, true, false) - - if err != nil { - t.Error("couldn't get the rpc marshal block") - } - - if err == nil && rpc.BlockNumber(oldestBlock.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - - block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(oldestBlock.Header().Time), false) - if err != nil { - t.Errorf("couldn't retrieve block %v", err) - } - - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) - } -} - -func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { - ctx := context.Background() - db := rpcdaemontest.CreateTestKV(t) - - tx, err := db.BeginRo(ctx) - if err != nil { - t.Errorf("fail at beginning tx") - } - defer tx.Rollback() - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - - latestBlock := rawdb.ReadCurrentBlock(tx) - - response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) - - if err != nil { - t.Error("couldn't get the rpc marshal block") - } - - if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - - block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(latestBlock.Header().Time+999999999999), false) - if err != nil { - t.Errorf("couldn't retrieve block %v", err) - } - - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) - } -} - -func TestGetBlockByTimeMiddle(t *testing.T) { - ctx := context.Background() - db := rpcdaemontest.CreateTestKV(t) - - tx, err := db.BeginRo(ctx) - if err != nil { - t.Errorf("fail at beginning tx") - } - defer tx.Rollback() - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - - currentHeader := rawdb.ReadCurrentHeader(tx) - oldestHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) - if err != nil { - t.Errorf("error getting the oldest header %s", err) - } - if oldestHeader == nil { - t.Error("couldn't find oldest header") - } - - middleNumber := (currentHeader.Number.Uint64() + oldestHeader.Number.Uint64()) / 2 - middleBlock, err := rawdb.ReadBlockByNumber(tx, middleNumber) - if err != nil { - t.Error("couldn't retrieve middle block") - } - - response, err := ethapi.RPCMarshalBlock(middleBlock, true, false) - - if err != nil { - t.Error("couldn't get the rpc marshal block") - } - - if err == nil && rpc.BlockNumber(middleBlock.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - - block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(middleBlock.Header().Time), false) - if err != nil { - t.Errorf("couldn't retrieve block %v", err) - } - - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) - } -} - -func TestGetBlockByTimestamp(t *testing.T) { - ctx := context.Background() - db := rpcdaemontest.CreateTestKV(t) - - tx, err := db.BeginRo(ctx) - if err != nil { - t.Errorf("fail at beginning tx") - } - defer tx.Rollback() - - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) - - highestBlockNumber := rawdb.ReadCurrentHeader(tx).Number - pickedBlock, err := rawdb.ReadBlockByNumber(tx, highestBlockNumber.Uint64()/3) - if err != nil { - t.Errorf("couldn't get block %v", pickedBlock.Number()) - } - - if pickedBlock == nil { - t.Error("couldn't retrieve picked block") - } - response, err := ethapi.RPCMarshalBlock(pickedBlock, true, false) - - if err != nil { - t.Error("couldn't get the rpc marshal block") - } - - if err == nil && rpc.BlockNumber(pickedBlock.NumberU64()) == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - - block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(pickedBlock.Header().Time), false) - if err != nil { - t.Errorf("couldn't retrieve block %v", err) - } - - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { - t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) - } -} - -func chainWithDeployedContract(t *testing.T) (kv.RwDB, common.Address, common.Address) { - var ( - signer = types.LatestSignerForChainID(nil) - bankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - bankAddress = crypto.PubkeyToAddress(bankKey.PublicKey) - bankFunds = big.NewInt(1e9) - contract = hexutil.MustDecode("0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea26469706673582212209a159a4f3847890f10bfb87871a61eba91c5dbf5ee3cf6398207e292eee22a1664736f6c63430008070033") - gspec = &core.Genesis{ - Config: params.AllEthashProtocolChanges, - Alloc: core.GenesisAlloc{bankAddress: {Balance: bankFunds}}, - } - ) - m := stages.MockWithGenesis(t, gspec, bankKey, false) - db := m.DB - - var contractAddr common.Address - - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { - nonce := block.TxNonce(bankAddress) - switch i { - case 0: - tx, err := types.SignTx(types.NewContractCreation(nonce, new(uint256.Int), 1e6, new(uint256.Int), contract), *signer, bankKey) - assert.NoError(t, err) - block.AddTx(tx) - contractAddr = crypto.CreateAddress(bankAddress, nonce) - case 1: - txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 90000, new(uint256.Int), nil), *signer, bankKey) - assert.NoError(t, err) - block.AddTx(txn) - } - }, false /* intermediateHashes */) - if err != nil { - t.Fatalf("generate blocks: %v", err) - } - - err = m.InsertChain(chain) - assert.NoError(t, err) - - tx, err := db.BeginRo(context.Background()) - if err != nil { - t.Fatalf("read only db tx to read state: %v", err) - } - defer tx.Rollback() - - st := state.New(state.NewPlainState(tx, 1)) - assert.NoError(t, err) - assert.False(t, st.Exist(contractAddr), "Contract should not exist at block #1") - - st = state.New(state.NewPlainState(tx, 2)) - assert.NoError(t, err) - assert.True(t, st.Exist(contractAddr), "Contract should exist at block #2") - - return db, bankAddress, contractAddr -} - -func prune(t *testing.T, db kv.RwDB, pruneTo uint64) { - ctx := context.Background() - tx, err := db.BeginRw(ctx) - assert.NoError(t, err) - - logEvery := time.NewTicker(20 * time.Second) - - err = rawdb.PruneTableDupSort(tx, kv.AccountChangeSet, "", pruneTo, logEvery, ctx) - assert.NoError(t, err) - - err = rawdb.PruneTableDupSort(tx, kv.StorageChangeSet, "", pruneTo, logEvery, ctx) - assert.NoError(t, err) - - err = rawdb.PruneTable(tx, kv.Receipts, pruneTo, ctx, math.MaxInt32) - assert.NoError(t, err) - - err = rawdb.PruneTable(tx, kv.Log, pruneTo, ctx, math.MaxInt32) - assert.NoError(t, err) - - err = rawdb.PruneTableDupSort(tx, kv.CallTraceSet, "", pruneTo, logEvery, ctx) - assert.NoError(t, err) - - err = tx.Commit() - assert.NoError(t, err) -} diff --git a/cmd/rpcdaemon22/commands/eth_filters_test.go b/cmd/rpcdaemon22/commands/eth_filters_test.go deleted file mode 100644 index 0cd1dfbca0a..00000000000 --- a/cmd/rpcdaemon22/commands/eth_filters_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package commands - -import ( - "math/rand" - "sync" - "testing" - "time" - - "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/stretchr/testify/assert" - - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" -) - -func TestNewFilters(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) - mining := txpool.NewMiningClient(conn) - ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - api := NewEthAPI(NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000) - - ptf, err := api.NewPendingTransactionFilter(ctx) - assert.Nil(err) - - nf, err := api.NewFilter(ctx, filters.FilterCriteria{}) - assert.Nil(err) - - bf, err := api.NewBlockFilter(ctx) - assert.Nil(err) - - ok, err := api.UninstallFilter(ctx, nf) - assert.Nil(err) - assert.Equal(ok, true) - - ok, err = api.UninstallFilter(ctx, bf) - assert.Nil(err) - assert.Equal(ok, true) - - ok, err = api.UninstallFilter(ctx, ptf) - assert.Nil(err) - assert.Equal(ok, true) -} - -func TestLogsSubscribeAndUnsubscribe_WithoutConcurrentMapIssue(t *testing.T) { - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) - mining := txpool.NewMiningClient(conn) - ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - - // generate some random topics - topics := make([][]common.Hash, 0) - for i := 0; i < 10; i++ { - bytes := make([]byte, common.HashLength) - rand.Read(bytes) - toAdd := []common.Hash{common.BytesToHash(bytes)} - topics = append(topics, toAdd) - } - - // generate some addresses - addresses := make([]common.Address, 0) - for i := 0; i < 10; i++ { - bytes := make([]byte, common.AddressLength) - rand.Read(bytes) - addresses = append(addresses, common.BytesToAddress(bytes)) - } - - crit := filters.FilterCriteria{ - Topics: topics, - Addresses: addresses, - } - - ids := make([]rpchelper.LogsSubID, 1000) - - // make a lot of subscriptions - wg := sync.WaitGroup{} - for i := 0; i < 1000; i++ { - wg.Add(1) - go func(idx int) { - out := make(chan *types.Log, 1) - id := ff.SubscribeLogs(out, crit) - defer func() { - time.Sleep(100 * time.Nanosecond) - ff.UnsubscribeLogs(id) - wg.Done() - }() - ids[idx] = id - }(i) - } - wg.Wait() -} diff --git a/cmd/rpcdaemon22/commands/eth_ming_test.go b/cmd/rpcdaemon22/commands/eth_ming_test.go deleted file mode 100644 index a3d39e9e101..00000000000 --- a/cmd/rpcdaemon22/commands/eth_ming_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package commands - -import ( - "math/big" - "testing" - "time" - - "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/rlp" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/stretchr/testify/require" -) - -func TestPendingBlock(t *testing.T) { - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) - mining := txpool.NewMiningClient(conn) - ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), nil, nil, nil, mining, 5000000) - expect := uint64(12345) - b, err := rlp.EncodeToBytes(types.NewBlockWithHeader(&types.Header{Number: big.NewInt(int64(expect))})) - require.NoError(t, err) - ch := make(chan *types.Block, 1) - id := ff.SubscribePendingBlock(ch) - defer ff.UnsubscribePendingBlock(id) - - ff.HandlePendingBlock(&txpool.OnPendingBlockReply{RplBlock: b}) - block := api.pendingBlock() - - require.Equal(t, block.NumberU64(), expect) - select { - case got := <-ch: - require.Equal(t, expect, got.NumberU64()) - case <-time.After(100 * time.Millisecond): - t.Fatalf("timeout waiting for expected notification") - } -} - -func TestPendingLogs(t *testing.T) { - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) - mining := txpool.NewMiningClient(conn) - ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - expect := []byte{211} - - ch := make(chan types.Logs, 1) - defer close(ch) - id := ff.SubscribePendingLogs(ch) - defer ff.UnsubscribePendingLogs(id) - - b, err := rlp.EncodeToBytes([]*types.Log{{Data: expect}}) - require.NoError(t, err) - ff.HandlePendingLogs(&txpool.OnPendingLogsReply{RplLogs: b}) - select { - case logs := <-ch: - require.Equal(t, expect, logs[0].Data) - case <-time.After(100 * time.Millisecond): - t.Fatalf("timeout waiting for expected notification") - } -} diff --git a/cmd/rpcdaemon22/commands/eth_receipts.go b/cmd/rpcdaemon22/commands/eth_receipts.go index 1da4bf7d5bf..c9b90644245 100644 --- a/cmd/rpcdaemon22/commands/eth_receipts.go +++ b/cmd/rpcdaemon22/commands/eth_receipts.go @@ -23,7 +23,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/filters" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/transactions" @@ -41,8 +40,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *para } return h } - contractHasTEVM := ethdb.GetHasTEVM(tx) - _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) + _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, ethash.NewFaker(), tx, block.Hash(), 0) if err != nil { return nil, err } @@ -58,7 +56,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *para for i, txn := range block.Transactions() { ibs.Prepare(txn.Hash(), block.Hash(), i) header := block.Header() - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), ethashFaker, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}, contractHasTEVM) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), ethashFaker, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}) if err != nil { return nil, err } @@ -210,8 +208,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([ if err != nil { return nil, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - blockCtx, txCtx := transactions.GetEvmContext(msg, lastHeader, true /* requireCanonical */, tx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, lastHeader, true /* requireCanonical */, tx, api._blockReader) stateReader.SetTxNum(txNum) vmConfig := vm.Config{} vmConfig.SkipAnalysis = core.SkipAnalysis(chainConfig, blockNum) diff --git a/cmd/rpcdaemon22/commands/eth_subscribe_test.go b/cmd/rpcdaemon22/commands/eth_subscribe_test.go deleted file mode 100644 index 65e83e4b1af..00000000000 --- a/cmd/rpcdaemon22/commands/eth_subscribe_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "testing" - - "github.com/ledgerwatch/erigon-lib/direct" - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcservices" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/eth/protocols/eth" - "github.com/ledgerwatch/erigon/ethdb/privateapi" - "github.com/ledgerwatch/erigon/rlp" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/stretchr/testify/require" -) - -func TestEthSubscribe(t *testing.T) { - m, require := stages.Mock(t), require.New(t) - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 7, func(i int, b *core.BlockGen) { - b.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - require.NoError(err) - - b, err := rlp.EncodeToBytes(ð.BlockHeadersPacket66{ - RequestId: 1, - BlockHeadersPacket: chain.Headers, - }) - require.NoError(err) - - m.ReceiveWg.Add(1) - for _, err = range m.Send(&sentry.InboundMessage{Id: sentry.MessageId_BLOCK_HEADERS_66, Data: b, PeerId: m.PeerId}) { - require.NoError(err) - } - m.ReceiveWg.Wait() // Wait for all messages to be processed before we proceeed - - ctx := context.Background() - backendServer := privateapi.NewEthBackendServer(ctx, nil, m.DB, m.Notifications.Events, snapshotsync.NewBlockReader(), nil, nil, nil, false) - backendClient := direct.NewEthBackendClientDirect(backendServer) - backend := rpcservices.NewRemoteBackend(backendClient, m.DB, snapshotsync.NewBlockReader()) - ff := rpchelper.New(ctx, backend, nil, nil, func() {}) - - newHeads := make(chan *types.Header) - id := ff.SubscribeNewHeads(newHeads) - defer ff.UnsubscribeHeads(id) - - initialCycle := true - highestSeenHeader := chain.TopBlock.NumberU64() - if _, err := stages.StageLoopStep(m.Ctx, m.DB, m.Sync, highestSeenHeader, m.Notifications, initialCycle, m.UpdateHead, nil); err != nil { - t.Fatal(err) - } - - for i := uint64(1); i <= highestSeenHeader; i++ { - header := <-newHeads - fmt.Printf("Got header %d\n", header.Number.Uint64()) - require.Equal(i, header.Number.Uint64()) - } -} diff --git a/cmd/rpcdaemon22/commands/get_chain_config_test.go b/cmd/rpcdaemon22/commands/get_chain_config_test.go deleted file mode 100644 index a4ed4fdad65..00000000000 --- a/cmd/rpcdaemon22/commands/get_chain_config_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package commands - -import ( - "context" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/core" -) - -func TestGetChainConfig(t *testing.T) { - db := memdb.NewTestDB(t) - config, _, err := core.CommitGenesisBlock(db, core.DefaultGenesisBlock()) - if err != nil { - t.Fatalf("setting up genensis block: %v", err) - } - - tx, txErr := db.BeginRo(context.Background()) - if txErr != nil { - t.Fatalf("error starting tx: %v", txErr) - } - defer tx.Rollback() - - api := &BaseAPI{} - config1, err1 := api.chainConfig(tx) - if err1 != nil { - t.Fatalf("reading chain config: %v", err1) - } - if config.String() != config1.String() { - t.Fatalf("read different config: %s, expected %s", config1.String(), config.String()) - } - config2, err2 := api.chainConfig(tx) - if err2 != nil { - t.Fatalf("reading chain config: %v", err2) - } - if config.String() != config2.String() { - t.Fatalf("read different config: %s, expected %s", config2.String(), config.String()) - } -} diff --git a/cmd/rpcdaemon22/commands/parity_api_test.go b/cmd/rpcdaemon22/commands/parity_api_test.go deleted file mode 100644 index 0117eddfab8..00000000000 --- a/cmd/rpcdaemon22/commands/parity_api_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "testing" - - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/rpc" - "github.com/stretchr/testify/assert" -) - -var latestBlock = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - -func TestParityAPIImpl_ListStorageKeys_NoOffset(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - api := NewParityAPIImpl(db) - answers := []string{ - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000002", - "0a2127994676ca91e4eb3d2a1e46ec9dcee074dc2643bb5ebd4e9ac6541a3148", - "0fe673b4bc06161f39bc26f4e8831c810a72ffe69e5c8cb26f7f54752618e696", - "120e23dcb7e4437386073613853db77b10011a2404eefc716b97c7767e37f8eb", - } - addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") - result, err := api.ListStorageKeys(context.Background(), addr, 5, nil, latestBlock) - if err != nil { - t.Errorf("calling ListStorageKeys: %v", err) - } - assert.Equal(len(answers), len(result)) - for k, v := range result { - assert.Equal(answers[k], common.Bytes2Hex(v)) - } -} - -func TestParityAPIImpl_ListStorageKeys_WithOffset_ExistingPrefix(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - api := NewParityAPIImpl(db) - answers := []string{ - "29d05770ca9ee7088a64e18c8e5160fc62c3c2179dc8ef9b4dbc970c9e51b4d8", - "29edc84535d98b29835079d685b97b41ee8e831e343cc80793057e462353a26d", - "2c05ac60f9aa2df5e64ef977f271e4b9a2d13951f123a2cb5f5d4ad5eb344f1a", - "4644be453c81744b6842ddf615d7fca0e14a23b09734be63d44c23452de95631", - "4974416255391052161ba8184fe652f3bf8c915592c65f7de127af8e637dce5d", - } - addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") - offset := common.Hex2Bytes("29") - b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 5, &b, latestBlock) - if err != nil { - t.Errorf("calling ListStorageKeys: %v", err) - } - assert.Equal(len(answers), len(result)) - for k, v := range result { - assert.Equal(answers[k], common.Bytes2Hex(v)) - } -} - -func TestParityAPIImpl_ListStorageKeys_WithOffset_NonExistingPrefix(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - api := NewParityAPIImpl(db) - answers := []string{ - "4644be453c81744b6842ddf615d7fca0e14a23b09734be63d44c23452de95631", - "4974416255391052161ba8184fe652f3bf8c915592c65f7de127af8e637dce5d", - } - addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") - offset := common.Hex2Bytes("30") - b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) - if err != nil { - t.Errorf("calling ListStorageKeys: %v", err) - } - assert.Equal(len(answers), len(result)) - for k, v := range result { - assert.Equal(answers[k], common.Bytes2Hex(v)) - } -} - -func TestParityAPIImpl_ListStorageKeys_WithOffset_EmptyResponse(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - api := NewParityAPIImpl(db) - addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") - offset := common.Hex2Bytes("ff") - b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) - if err != nil { - t.Errorf("calling ListStorageKeys: %v", err) - } - assert.Equal(0, len(result)) -} - -func TestParityAPIImpl_ListStorageKeys_AccNotFound(t *testing.T) { - assert := assert.New(t) - db := rpcdaemontest.CreateTestKV(t) - api := NewParityAPIImpl(db) - addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcaef") - _, err := api.ListStorageKeys(context.Background(), addr, 2, nil, latestBlock) - assert.Error(err, fmt.Errorf("acc not found")) -} diff --git a/cmd/rpcdaemon22/commands/send_transaction_test.go b/cmd/rpcdaemon22/commands/send_transaction_test.go deleted file mode 100644 index 87c6ef411b3..00000000000 --- a/cmd/rpcdaemon22/commands/send_transaction_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package commands_test - -import ( - "bytes" - "crypto/ecdsa" - "math/big" - "testing" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" - "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/commands" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/u256" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/eth/protocols/eth" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rlp" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/stretchr/testify/require" -) - -func TestSendRawTransaction(t *testing.T) { - t.Skip("Flaky test") - m, require := stages.Mock(t), require.New(t) - - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) { - b.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - require.NoError(err) - { // Do 1 step to start txPool - - // Send NewBlock message - b, err := rlp.EncodeToBytes(ð.NewBlockPacket{ - Block: chain.TopBlock, - TD: big.NewInt(1), // This is ignored anyway - }) - require.NoError(err) - m.ReceiveWg.Add(1) - for _, err = range m.Send(&sentry.InboundMessage{Id: sentry.MessageId_NEW_BLOCK_66, Data: b, PeerId: m.PeerId}) { - require.NoError(err) - } - // Send all the headers - b, err = rlp.EncodeToBytes(ð.BlockHeadersPacket66{ - RequestId: 1, - BlockHeadersPacket: chain.Headers, - }) - require.NoError(err) - m.ReceiveWg.Add(1) - for _, err = range m.Send(&sentry.InboundMessage{Id: sentry.MessageId_BLOCK_HEADERS_66, Data: b, PeerId: m.PeerId}) { - require.NoError(err) - } - m.ReceiveWg.Wait() // Wait for all messages to be processed before we proceeed - - initialCycle := true - highestSeenHeader := chain.TopBlock.NumberU64() - if _, err := stages.StageLoopStep(m.Ctx, m.DB, m.Sync, highestSeenHeader, m.Notifications, initialCycle, m.UpdateHead, nil); err != nil { - t.Fatal(err) - } - } - - expectValue := uint64(1234) - txn, err := types.SignTx(types.NewTransaction(0, common.Address{1}, uint256.NewInt(expectValue), params.TxGas, uint256.NewInt(10*params.GWei), nil), *types.LatestSignerForChainID(m.ChainConfig.ChainID), m.Key) - require.NoError(err) - - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m) - txPool := txpool.NewTxpoolClient(conn) - ff := rpchelper.New(ctx, nil, txPool, txpool.NewMiningClient(conn), func() {}) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := commands.NewEthAPI(commands.NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), m.DB, nil, txPool, nil, 5000000) - - buf := bytes.NewBuffer(nil) - err = txn.MarshalBinary(buf) - require.NoError(err) - - txsCh := make(chan []types.Transaction, 1) - id := ff.SubscribePendingTxs(txsCh) - defer ff.UnsubscribePendingTxs(id) - - _, err = api.SendRawTransaction(ctx, buf.Bytes()) - require.NoError(err) - - got := <-txsCh - require.Equal(expectValue, got[0].GetValue().Uint64()) - - //send same tx second time and expect error - _, err = api.SendRawTransaction(ctx, buf.Bytes()) - require.NotNil(err) - require.Equal("ALREADY_EXISTS: already known", err.Error()) - m.ReceiveWg.Wait() - - //TODO: make propagation easy to test - now race - //time.Sleep(time.Second) - //sent := m.SentMessage(0) - //require.Equal(eth.ToProto[m.MultiClient.Protocol()][eth.NewPooledTransactionHashesMsg], sent.Id) -} - -func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) types.Transaction { - return pricedTransaction(nonce, gaslimit, u256.Num1, key) -} - -func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *uint256.Int, key *ecdsa.PrivateKey) types.Transaction { - tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, uint256.NewInt(100), gaslimit, gasprice, nil), *types.LatestSignerForChainID(big.NewInt(1337)), key) - return tx -} diff --git a/cmd/rpcdaemon22/commands/trace_adhoc.go b/cmd/rpcdaemon22/commands/trace_adhoc.go index acb42089017..7ea3c337d80 100644 --- a/cmd/rpcdaemon22/commands/trace_adhoc.go +++ b/cmd/rpcdaemon22/commands/trace_adhoc.go @@ -21,7 +21,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/shards" @@ -943,11 +942,7 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp return nil, err } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, api._blockReader) blockCtx.GasLimit = math.MaxUint64 blockCtx.MaxGasLimit = true @@ -1132,11 +1127,6 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type useParent = true } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - for txIndex, msg := range msgs { if err := libcommon.Stopped(ctx.Done()); err != nil { return nil, err @@ -1173,7 +1163,7 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type } // Get a new instance of the EVM. - blockCtx, txCtx := transactions.GetEvmContext(msg, header, parentNrOrHash.RequireCanonical, dbtx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, parentNrOrHash.RequireCanonical, dbtx, api._blockReader) if useParent { blockCtx.GasLimit = math.MaxUint64 blockCtx.MaxGasLimit = true diff --git a/cmd/rpcdaemon22/commands/trace_adhoc_test.go b/cmd/rpcdaemon22/commands/trace_adhoc_test.go deleted file mode 100644 index abd446c1a78..00000000000 --- a/cmd/rpcdaemon22/commands/trace_adhoc_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package commands - -import ( - "context" - "encoding/json" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/cli/httpcfg" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/stretchr/testify/require" -) - -func TestEmptyQuery(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, &httpcfg.HttpCfg{}) - // Call GetTransactionReceipt for transaction which is not in the database - var latest = rpc.LatestBlockNumber - results, err := api.CallMany(context.Background(), json.RawMessage("[]"), &rpc.BlockNumberOrHash{BlockNumber: &latest}) - if err != nil { - t.Errorf("calling CallMany: %v", err) - } - if results == nil { - t.Errorf("expected empty array, got nil") - } - if len(results) > 0 { - t.Errorf("expected empty array, got %d elements", len(results)) - } -} -func TestCoinbaseBalance(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, &httpcfg.HttpCfg{}) - // Call GetTransactionReceipt for transaction which is not in the database - var latest = rpc.LatestBlockNumber - results, err := api.CallMany(context.Background(), json.RawMessage(` -[ - [{"from":"0x71562b71999873db5b286df957af199ec94617f7","to":"0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e","gas":"0x15f90","gasPrice":"0x4a817c800","value":"0x1"},["trace", "stateDiff"]], - [{"from":"0x71562b71999873db5b286df957af199ec94617f7","to":"0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e","gas":"0x15f90","gasPrice":"0x4a817c800","value":"0x1"},["trace", "stateDiff"]] -] -`), &rpc.BlockNumberOrHash{BlockNumber: &latest}) - if err != nil { - t.Errorf("calling CallMany: %v", err) - } - if results == nil { - t.Errorf("expected empty array, got nil") - } - if len(results) != 2 { - t.Errorf("expected array with 2 elements, got %d elements", len(results)) - } - // Expect balance increase of the coinbase (zero address) - if _, ok := results[1].StateDiff[common.Address{}]; !ok { - t.Errorf("expected balance increase for coinbase (zero address)") - } -} - -func TestReplayTransaction(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, &httpcfg.HttpCfg{}) - var txnHash common.Hash - if err := db.View(context.Background(), func(tx kv.Tx) error { - b, err := rawdb.ReadBlockByNumber(tx, 6) - if err != nil { - return err - } - txnHash = b.Transactions()[5].Hash() - return nil - }); err != nil { - t.Fatal(err) - } - - // Call GetTransactionReceipt for transaction which is not in the database - results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"}) - if err != nil { - t.Errorf("calling ReplayTransaction: %v", err) - } - require.NotNil(t, results) - require.NotNil(t, results.StateDiff) - addrDiff := results.StateDiff[common.HexToAddress("0x0000000000000006000000000000000000000000")] - v := addrDiff.Balance.(map[string]*hexutil.Big)["+"].ToInt().Uint64() - require.Equal(t, uint64(1_000_000_000_000_000), v) -} - -func TestReplayBlockTransactions(t *testing.T) { - db := rpcdaemontest.CreateTestKV(t) - stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, &httpcfg.HttpCfg{}) - - // Call GetTransactionReceipt for transaction which is not in the database - n := rpc.BlockNumber(6) - results, err := api.ReplayBlockTransactions(context.Background(), rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"}) - if err != nil { - t.Errorf("calling ReplayBlockTransactions: %v", err) - } - require.NotNil(t, results) - require.NotNil(t, results[0].StateDiff) - addrDiff := results[0].StateDiff[common.HexToAddress("0x0000000000000001000000000000000000000000")] - v := addrDiff.Balance.(map[string]*hexutil.Big)["+"].ToInt().Uint64() - require.Equal(t, uint64(1_000_000_000_000_000), v) -} diff --git a/cmd/rpcdaemon22/commands/trace_filtering.go b/cmd/rpcdaemon22/commands/trace_filtering.go index 78294f0b12f..2d933caa5a1 100644 --- a/cmd/rpcdaemon22/commands/trace_filtering.go +++ b/cmd/rpcdaemon22/commands/trace_filtering.go @@ -465,8 +465,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str stream.WriteObjectEnd() continue } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - blockCtx, txCtx := transactions.GetEvmContext(msg, lastHeader, true /* requireCanonical */, dbtx, contractHasTEVM, api._blockReader) + blockCtx, txCtx := transactions.GetEvmContext(msg, lastHeader, true /* requireCanonical */, dbtx, api._blockReader) stateReader.SetTxNum(txNum) stateCache := shards.NewStateCache(32, 0 /* no limit */) // this cache living only during current RPC call, but required to store state writes cachedReader := state.NewCachedReader(stateReader, stateCache) diff --git a/cmd/rpcdaemon22/commands/tracing.go b/cmd/rpcdaemon22/commands/tracing.go deleted file mode 100644 index a69e3791db8..00000000000 --- a/cmd/rpcdaemon22/commands/tracing.go +++ /dev/null @@ -1,443 +0,0 @@ -package commands - -import ( - "context" - "fmt" - "math/big" - "time" - - "github.com/holiman/uint256" - jsoniter "github.com/json-iterator/go" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/eth/tracers" - "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/transactions" - "github.com/ledgerwatch/log/v3" -) - -// TraceBlockByNumber implements debug_traceBlockByNumber. Returns Geth style block traces. -func (api *PrivateDebugAPIImpl) TraceBlockByNumber(ctx context.Context, blockNum rpc.BlockNumber, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - return api.traceBlock(ctx, rpc.BlockNumberOrHashWithNumber(blockNum), config, stream) -} - -// TraceBlockByHash implements debug_traceBlockByHash. Returns Geth style block traces. -func (api *PrivateDebugAPIImpl) TraceBlockByHash(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - return api.traceBlock(ctx, rpc.BlockNumberOrHashWithHash(hash, true), config, stream) -} - -func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - tx, err := api.db.BeginRo(ctx) - if err != nil { - stream.WriteNil() - return err - } - defer tx.Rollback() - var block *types.Block - if number, ok := blockNrOrHash.Number(); ok { - block, err = api.blockByRPCNumber(number, tx) - } else if hash, ok := blockNrOrHash.Hash(); ok { - block, err = api.blockByHashWithSenders(tx, hash) - } else { - return fmt.Errorf("invalid arguments; neither block nor hash specified") - } - - if err != nil { - stream.WriteNil() - return err - } - - chainConfig, err := api.chainConfig(tx) - if err != nil { - stream.WriteNil() - return err - } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - getHeader := func(hash common.Hash, number uint64) *types.Header { - h, e := api._blockReader.Header(ctx, tx, hash, number) - if e != nil { - log.Error("getHeader error", "number", number, "hash", hash, "err", e) - } - return h - } - - _, blockCtx, _, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) - if err != nil { - stream.WriteNil() - return err - } - - signer := types.MakeSigner(chainConfig, block.NumberU64()) - rules := chainConfig.Rules(block.NumberU64()) - stream.WriteArrayStart() - for idx, tx := range block.Transactions() { - select { - default: - case <-ctx.Done(): - stream.WriteNil() - return ctx.Err() - } - ibs.Prepare(tx.Hash(), block.Hash(), idx) - msg, _ := tx.AsMessage(*signer, block.BaseFee(), rules) - txCtx := vm.TxContext{ - TxHash: tx.Hash(), - Origin: msg.From(), - GasPrice: msg.GasPrice().ToBig(), - } - - transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) - _ = ibs.FinalizeTx(rules, reader) - if idx != len(block.Transactions())-1 { - stream.WriteMore() - } - stream.Flush() - } - stream.WriteArrayEnd() - stream.Flush() - return nil -} - -// TraceTransaction implements debug_traceTransaction. Returns Geth style transaction traces. -func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - tx, err := api.db.BeginRo(ctx) - if err != nil { - stream.WriteNil() - return err - } - defer tx.Rollback() - // Retrieve the transaction and assemble its EVM context - blockNum, ok, err := api.txnLookup(ctx, tx, hash) - if err != nil { - stream.WriteNil() - return err - } - if !ok { - stream.WriteNil() - return nil - } - block, err := api.blockByNumberWithSenders(tx, blockNum) - if err != nil { - stream.WriteNil() - return err - } - if block == nil { - stream.WriteNil() - return nil - } - blockHash := block.Hash() - var txnIndex uint64 - var txn types.Transaction - for i, transaction := range block.Transactions() { - if transaction.Hash() == hash { - txnIndex = uint64(i) - txn = transaction - break - } - } - if txn == nil { - var borTx types.Transaction - borTx, _, _, _, err = rawdb.ReadBorTransaction(tx, hash) - if err != nil { - stream.WriteNil() - return err - } - - if borTx != nil { - stream.WriteNil() - return nil - } - stream.WriteNil() - return fmt.Errorf("transaction %#x not found", hash) - } - chainConfig, err := api.chainConfig(tx) - if err != nil { - stream.WriteNil() - return err - } - - getHeader := func(hash common.Hash, number uint64) *types.Header { - return rawdb.ReadHeader(tx, hash, number) - } - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, blockHash, txnIndex) - if err != nil { - stream.WriteNil() - return err - } - // Trace the transaction and return - return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) -} - -func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - dbtx, err := api.db.BeginRo(ctx) - if err != nil { - stream.WriteNil() - return err - } - defer dbtx.Rollback() - - chainConfig, err := api.chainConfig(dbtx) - if err != nil { - stream.WriteNil() - return err - } - - blockNumber, hash, latest, err := rpchelper.GetBlockNumber(blockNrOrHash, dbtx, api.filters) - if err != nil { - stream.WriteNil() - return err - } - var stateReader state.StateReader - if latest { - cacheView, err := api.stateCache.View(ctx, dbtx) - if err != nil { - return err - } - stateReader = state.NewCachedReader2(cacheView, dbtx) - } else { - stateReader = state.NewPlainState(dbtx, blockNumber) - } - header := rawdb.ReadHeader(dbtx, hash, blockNumber) - if header == nil { - stream.WriteNil() - return fmt.Errorf("block %d(%x) not found", blockNumber, hash) - } - ibs := state.New(stateReader) - - if config != nil && config.StateOverrides != nil { - if err := config.StateOverrides.Override(ibs); err != nil { - return err - } - } - - var baseFee *uint256.Int - if header != nil && header.BaseFee != nil { - var overflow bool - baseFee, overflow = uint256.FromBig(header.BaseFee) - if overflow { - return fmt.Errorf("header.BaseFee uint256 overflow") - } - } - msg, err := args.ToMessage(api.GasCap, baseFee) - if err != nil { - return err - } - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(dbtx) - } - blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, dbtx, contractHasTEVM, api._blockReader) - // Trace the transaction and return - return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) -} - -func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bundle, simulateContext StateContext, config *tracers.TraceConfig, stream *jsoniter.Stream) error { - var ( - hash common.Hash - replayTransactions types.Transactions - evm *vm.EVM - blockCtx vm.BlockContext - txCtx vm.TxContext - overrideBlockHash map[uint64]common.Hash - baseFee uint256.Int - ) - - overrideBlockHash = make(map[uint64]common.Hash) - tx, err := api.db.BeginRo(ctx) - if err != nil { - stream.WriteNil() - return err - } - defer tx.Rollback() - chainConfig, err := api.chainConfig(tx) - if err != nil { - stream.WriteNil() - return err - } - if len(bundles) == 0 { - stream.WriteNil() - return fmt.Errorf("empty bundles") - } - empty := true - for _, bundle := range bundles { - if len(bundle.Transactions) != 0 { - empty = false - } - } - - if empty { - stream.WriteNil() - return fmt.Errorf("empty bundles") - } - - defer func(start time.Time) { log.Trace("Tracing CallMany finished", "runtime", time.Since(start)) }(time.Now()) - - blockNum, hash, _, err := rpchelper.GetBlockNumber(simulateContext.BlockNumber, tx, api.filters) - if err != nil { - stream.WriteNil() - return err - } - - block, err := api.blockByNumberWithSenders(tx, blockNum) - if err != nil { - stream.WriteNil() - return err - } - - // -1 is a default value for transaction index. - // If it's -1, we will try to replay every single transaction in that block - transactionIndex := -1 - - if simulateContext.TransactionIndex != nil { - transactionIndex = *simulateContext.TransactionIndex - } - - if transactionIndex == -1 { - transactionIndex = len(block.Transactions()) - } - - replayTransactions = block.Transactions()[:transactionIndex] - - stateReader, err := rpchelper.CreateStateReader(ctx, tx, rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(blockNum-1)), api.filters, api.stateCache) - - if err != nil { - stream.WriteNil() - return err - } - - st := state.New(stateReader) - - parent := block.Header() - - if parent == nil { - stream.WriteNil() - return fmt.Errorf("block %d(%x) not found", blockNum, hash) - } - - // Get a new instance of the EVM - signer := types.MakeSigner(chainConfig, blockNum) - rules := chainConfig.Rules(blockNum) - - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } - - if api.TevmEnabled { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - - getHash := func(i uint64) common.Hash { - if hash, ok := overrideBlockHash[i]; ok { - return hash - } - hash, err := rawdb.ReadCanonicalHash(tx, i) - if err != nil { - log.Debug("Can't get block hash by number", "number", i, "only-canonical", true) - } - return hash - } - - if parent.BaseFee != nil { - baseFee.SetFromBig(parent.BaseFee) - } - - blockCtx = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - ContractHasTEVM: contractHasTEVM, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, - } - - evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) - - // Setup the gas pool (also for unmetered requests) - // and apply the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) - for _, txn := range replayTransactions { - msg, err := txn.AsMessage(*signer, nil, rules) - if err != nil { - stream.WriteNil() - return err - } - txCtx = core.NewEVMTxContext(msg) - evm = vm.NewEVM(blockCtx, txCtx, evm.IntraBlockState(), chainConfig, vm.Config{Debug: false}) - // Execute the transaction message - _, err = core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - stream.WriteNil() - return err - } - - } - - // after replaying the txns, we want to overload the state - if config.StateOverrides != nil { - err = config.StateOverrides.Override(evm.IntraBlockState().(*state.IntraBlockState)) - if err != nil { - stream.WriteNil() - return err - } - } - - stream.WriteArrayStart() - for bundle_index, bundle := range bundles { - stream.WriteArrayStart() - // first change blockContext - blockHeaderOverride(&blockCtx, bundle.BlockOverride, overrideBlockHash) - for txn_index, txn := range bundle.Transactions { - if txn.Gas == nil || *(txn.Gas) == 0 { - txn.Gas = (*hexutil.Uint64)(&api.GasCap) - } - msg, err := txn.ToMessage(api.GasCap, blockCtx.BaseFee) - if err != nil { - stream.WriteNil() - return err - } - txCtx = core.NewEVMTxContext(msg) - ibs := evm.IntraBlockState().(*state.IntraBlockState) - ibs.Prepare(common.Hash{}, parent.Hash(), txn_index) - err = transactions.TraceTx(ctx, msg, blockCtx, txCtx, evm.IntraBlockState(), config, chainConfig, stream) - - if err != nil { - stream.WriteNil() - return err - } - - if txn_index < len(bundle.Transactions)-1 { - stream.WriteMore() - } - } - stream.WriteArrayEnd() - - if bundle_index < len(bundles)-1 { - stream.WriteMore() - } - blockCtx.BlockNumber++ - blockCtx.Time++ - } - stream.WriteArrayEnd() - return nil -} diff --git a/cmd/rpcdaemon22/commands/txpool_api_test.go b/cmd/rpcdaemon22/commands/txpool_api_test.go deleted file mode 100644 index 5cd85335692..00000000000 --- a/cmd/rpcdaemon22/commands/txpool_api_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package commands - -import ( - "bytes" - "fmt" - "testing" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - txPoolProto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" - "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/snapshotsync" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/stretchr/testify/require" -) - -func TestTxPoolContent(t *testing.T) { - m, require := stages.MockWithTxPool(t), require.New(t) - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) { - b.SetCoinbase(common.Address{1}) - }, false /* intermediateHashes */) - require.NoError(err) - err = m.InsertChain(chain) - require.NoError(err) - - ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m) - txPool := txpool.NewTxpoolClient(conn) - ff := rpchelper.New(ctx, nil, txPool, txpool.NewMiningClient(conn), func() {}) - api := NewTxPoolAPI(NewBaseApi(ff, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), nil, nil, false), m.DB, txPool) - - expectValue := uint64(1234) - txn, err := types.SignTx(types.NewTransaction(0, common.Address{1}, uint256.NewInt(expectValue), params.TxGas, uint256.NewInt(10*params.GWei), nil), *types.LatestSignerForChainID(m.ChainConfig.ChainID), m.Key) - require.NoError(err) - - buf := bytes.NewBuffer(nil) - err = txn.MarshalBinary(buf) - require.NoError(err) - - reply, err := txPool.Add(ctx, &txpool.AddRequest{RlpTxs: [][]byte{buf.Bytes()}}) - require.NoError(err) - for _, res := range reply.Imported { - require.Equal(res, txPoolProto.ImportResult_SUCCESS, fmt.Sprintf("%s", reply.Errors)) - } - - content, err := api.Content(ctx) - require.NoError(err) - - sender := m.Address.String() - require.Equal(1, len(content["pending"][sender])) - require.Equal(expectValue, content["pending"][sender]["0"].Value.ToInt().Uint64()) - - status, err := api.Status(ctx) - require.NoError(err) - require.Len(status, 3) - require.Equal(status["pending"], hexutil.Uint(1)) - require.Equal(status["queued"], hexutil.Uint(0)) -} diff --git a/cmd/state/commands/check_change_sets.go b/cmd/state/commands/check_change_sets.go index aeccc662f32..656791edaf4 100644 --- a/cmd/state/commands/check_change_sets.go +++ b/cmd/state/commands/check_change_sets.go @@ -22,7 +22,6 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/log/v3" @@ -165,8 +164,7 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64, } return h } - contractHasTEVM := ethdb.GetHasTEVM(rwtx) - receipts, err1 := runBlock(engine, intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, contractHasTEVM, b, vmConfig, blockNum == block) + receipts, err1 := runBlock(engine, intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, b, vmConfig, blockNum == block) if err1 != nil { return err1 } diff --git a/cmd/state/commands/erigon2.go b/cmd/state/commands/erigon2.go index 1427aba3ca9..6922d04866c 100644 --- a/cmd/state/commands/erigon2.go +++ b/cmd/state/commands/erigon2.go @@ -413,7 +413,7 @@ func processBlock(trace bool, txNumStart uint64, rw *ReaderWrapper, ww *WriterWr daoBlock = false } ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, nil) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/erigon23.go b/cmd/state/commands/erigon23.go index 6ff83f13192..0bd2fb4eb37 100644 --- a/cmd/state/commands/erigon23.go +++ b/cmd/state/commands/erigon23.go @@ -308,7 +308,7 @@ func processBlock23(startTxNum uint64, trace bool, txNumStart uint64, rw *Reader ibs.Prepare(tx.Hash(), block.Hash(), i) ct := exec22.NewCallTracer() vmConfig.Tracer = ct - receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, nil) + receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/history2.go b/cmd/state/commands/history2.go index 0aa8b07ffee..3fe6ba465e4 100644 --- a/cmd/state/commands/history2.go +++ b/cmd/state/commands/history2.go @@ -157,7 +157,7 @@ func runHistory2(trace bool, blockNum, txNumStart uint64, hw *HistoryWrapper, ww daoBlock = false } ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, nil) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/history22.go b/cmd/state/commands/history22.go index 950d8f287fe..157ba4bf720 100644 --- a/cmd/state/commands/history22.go +++ b/cmd/state/commands/history22.go @@ -247,7 +247,7 @@ func runHistory22(trace bool, blockNum, txNumStart uint64, hw *state.HistoryRead hw.SetTxNum(txNum) ibs := state.New(hw) ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, nil) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index 9f8c7e65cbf..a944be4153b 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -29,7 +29,6 @@ import ( "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/params" ) @@ -559,8 +558,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB intraBlockState.SetTracer(ot) getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(historyTx, hash, number) } - contractHasTEVM := ethdb.GetHasTEVM(historyTx) - receipts, err1 := runBlock(ethash.NewFullFaker(), intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, contractHasTEVM, block, vmConfig, false) + receipts, err1 := runBlock(ethash.NewFullFaker(), intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, block, vmConfig, false) if err1 != nil { return err1 } @@ -671,7 +669,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB } func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter, - chainConfig *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, contractHasTEVM func(common.Hash) (bool, error), block *types.Block, vmConfig vm.Config, trace bool) (types.Receipts, error) { + chainConfig *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, block *types.Block, vmConfig vm.Config, trace bool) (types.Receipts, error) { header := block.Header() vmConfig.TraceJumpDest = true gp := new(core.GasPool).AddGas(block.GasLimit()) @@ -684,7 +682,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta rules := chainConfig.Rules(block.NumberU64()) for i, tx := range block.Transactions() { ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, contractHasTEVM) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/replay_tx.go b/cmd/state/commands/replay_tx.go index 057f01724ca..b7e4ac1404c 100644 --- a/cmd/state/commands/replay_tx.go +++ b/cmd/state/commands/replay_tx.go @@ -150,7 +150,6 @@ func replayTxNum(ctx context.Context, allSnapshots *snapshotsync.RoSnapshots, bl gp := new(core.GasPool).AddGas(txn.GetGas()) //fmt.Printf("txNum=%d, blockNum=%d, txIndex=%d, gas=%d, input=[%x]\n", txNum, blockNum, txIndex, txn.GetGas(), txn.GetData()) vmConfig := vm.Config{NoReceipts: true, SkipAnalysis: core.SkipAnalysis(chainConfig, bn)} - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } getHeader := func(hash common.Hash, number uint64) *types.Header { h, err := blockReader.Header(ctx, nil, hash, number) if err != nil { @@ -162,7 +161,7 @@ func replayTxNum(ctx context.Context, allSnapshots *snapshotsync.RoSnapshots, bl logger := log.New() engine := initConsensusEngine(chainConfig, logger, allSnapshots) txnHash := txn.Hash() - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, contractHasTEVM) + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) ibs.Prepare(txnHash, blockHash, txIndex) msg, err := txn.AsMessage(*types.MakeSigner(chainConfig, bn), header.BaseFee, rules) if err != nil { diff --git a/cmd/state/commands/state_recon.go b/cmd/state/commands/state_recon.go index fdce7a0e850..21b729e3a64 100644 --- a/cmd/state/commands/state_recon.go +++ b/cmd/state/commands/state_recon.go @@ -184,9 +184,8 @@ func (rw *ReconWorker) runTxTask(txTask *state.TxTask) { txHash := txTask.Tx.Hash() gp := new(core.GasPool).AddGas(txTask.Tx.GetGas()) vmConfig := vm.Config{NoReceipts: true, SkipAnalysis: core.SkipAnalysis(rw.chainConfig, txTask.BlockNum)} - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } getHashFn := core.GetHashFn(txTask.Header, rw.getHeader) - blockContext := core.NewEVMBlockContext(txTask.Header, getHashFn, rw.engine, nil /* author */, contractHasTEVM) + blockContext := core.NewEVMBlockContext(txTask.Header, getHashFn, rw.engine, nil /* author */) ibs.Prepare(txHash, txTask.BlockHash, txTask.TxIndex) msg, err := txTask.Tx.AsMessage(*types.MakeSigner(rw.chainConfig, txTask.BlockNum), txTask.Header.BaseFee, rules) if err != nil { diff --git a/cmd/state/commands/state_root.go b/cmd/state/commands/state_root.go index 39b5727ad5f..e94e3e841ee 100644 --- a/cmd/state/commands/state_root.go +++ b/cmd/state/commands/state_root.go @@ -132,7 +132,7 @@ func StateRoot(genesis *core.Genesis, logger log.Logger, blockNum uint64, datadi r := state.NewPlainStateReader(tx) intraBlockState := state.New(r) getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(historyTx, hash, number) } - if _, err = runBlock(ethash.NewFullFaker(), intraBlockState, noOpWriter, w, chainConfig, getHeader, nil, b, vmConfig, false); err != nil { + if _, err = runBlock(ethash.NewFullFaker(), intraBlockState, noOpWriter, w, chainConfig, getHeader, b, vmConfig, false); err != nil { return fmt.Errorf("block %d: %w", block, err) } if block+1 == blockNum { diff --git a/cmd/state/exec22/state.go b/cmd/state/exec22/state.go index 479b185c16f..af1d0793b7c 100644 --- a/cmd/state/exec22/state.go +++ b/cmd/state/exec22/state.go @@ -175,10 +175,9 @@ func (rw *Worker22) RunTxTask(txTask *state.TxTask) { gp := new(core.GasPool).AddGas(txTask.Tx.GetGas()) ct := NewCallTracer() vmConfig := vm.Config{Debug: true, Tracer: ct, SkipAnalysis: core.SkipAnalysis(rw.chainConfig, txTask.BlockNum)} - contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } ibs.Prepare(txHash, txTask.BlockHash, txTask.TxIndex) getHashFn := core.GetHashFn(txTask.Header, rw.getHeader) - blockContext := core.NewEVMBlockContext(txTask.Header, getHashFn, rw.engine, nil /* author */, contractHasTEVM) + blockContext := core.NewEVMBlockContext(txTask.Header, getHashFn, rw.engine, nil /* author */) msg, err := txTask.Tx.AsMessage(*types.MakeSigner(rw.chainConfig, txTask.BlockNum), txTask.Header.BaseFee, txTask.Rules) if err != nil { panic(err) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ce3314a14c0..280ead52583 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -401,10 +401,6 @@ var ( Usage: "Bug for bug compatibility with OE for trace_ routines", } - TevmFlag = cli.BoolFlag{ - Name: "experimental.tevm", - Usage: "Enables Transpiled EVM experiment", - } MemoryOverlayFlag = cli.BoolTFlag{ Name: "experimental.overlay", Usage: "Enables In-Memory Overlay for PoS", diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 394d9c7cf4b..c5de86171dd 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "errors" "fmt" - "github.com/ledgerwatch/erigon/core/rawdb" "io" "math/big" "sort" @@ -14,6 +13,8 @@ import ( "sync" "time" + "github.com/ledgerwatch/erigon/core/rawdb" + lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv" @@ -1232,7 +1233,7 @@ func (p *Parlia) systemCall(from, contract common.Address, data []byte, ibs *sta ) vmConfig := vm.Config{NoReceipts: true} // Create a new context to be used in the EVM environment - blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), p, &from, nil) + blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), p, &from) evm := vm.NewEVM(blockContext, core.NewEVMTxContext(msg), ibs, chainConfig, vmConfig) ret, leftOverGas, err := evm.Call( vm.AccountRef(msg.From()), diff --git a/core/blockchain.go b/core/blockchain.go index fbf12b0b7f4..001f2e54ea0 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -79,7 +79,6 @@ func ExecuteBlockEphemerallyForBSC( stateWriter state.WriterWithChangeSets, epochReader consensus.EpochReader, chainReader consensus.ChainHeaderReader, - contractHasTEVM func(codeHash common.Hash) (bool, error), statelessExec bool, // for usage of this API via cli tools wherein some of the validations need to be relaxed. getTracer func(txIndex int, txHash common.Hash) (vm.Tracer, error), ) (*EphemeralExecResult, error) { @@ -129,7 +128,7 @@ func ExecuteBlockEphemerallyForBSC( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, contractHasTEVM) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -230,7 +229,6 @@ func ExecuteBlockEphemerally( stateWriter state.WriterWithChangeSets, epochReader consensus.EpochReader, chainReader consensus.ChainHeaderReader, - contractHasTEVM func(codeHash common.Hash) (bool, error), statelessExec bool, // for usage of this API via cli tools wherein some of the validations need to be relaxed. getTracer func(txIndex int, txHash common.Hash) (vm.Tracer, error), ) (*EphemeralExecResult, error) { @@ -273,7 +271,7 @@ func ExecuteBlockEphemerally( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, contractHasTEVM) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -389,7 +387,7 @@ func SysCallContract(contract common.Address, data []byte, chainConfig params.Ch author = &state.SystemAddress txContext = NewEVMTxContext(msg) } - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, nil) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author) evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) if isBor { ret, _, err := evm.Call( @@ -433,7 +431,7 @@ func CallContract(contract common.Address, data []byte, chainConfig params.Chain return nil, fmt.Errorf("SysCallContract: %w ", err) } vmConfig := vm.Config{NoReceipts: true} - _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig, nil) + _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig) if err != nil { return result, fmt.Errorf("SysCallContract: %w ", err) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 21ad0882e45..bb535da4b7a 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -112,8 +112,7 @@ func (b *BlockGen) AddTxWithChain(getHeader func(hash common.Hash, number uint64 b.SetCoinbase(common.Address{}) } b.ibs.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) - contractHasTEVM := func(_ common.Hash) (bool, error) { return false, nil } - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, contractHasTEVM) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) if err != nil { panic(err) } @@ -126,8 +125,7 @@ func (b *BlockGen) AddFailedTxWithChain(getHeader func(hash common.Hash, number b.SetCoinbase(common.Address{}) } b.ibs.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) - contractHasTEVM := func(common.Hash) (bool, error) { return false, nil } - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, contractHasTEVM) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) _ = err // accept failed transactions b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) diff --git a/core/evm.go b/core/evm.go index 5c169621801..8504e95e7ae 100644 --- a/core/evm.go +++ b/core/evm.go @@ -30,7 +30,7 @@ import ( ) // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) common.Hash, engine consensus.Engine, author *common.Address, contractHasTEVM func(contractHash common.Hash) (bool, error)) vm.BlockContext { +func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) common.Hash, engine consensus.Engine, author *common.Address) vm.BlockContext { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary common.Address if author == nil { @@ -52,12 +52,6 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) commo prevRandDao = &header.MixDigest } - if contractHasTEVM == nil { - contractHasTEVM = func(_ common.Hash) (bool, error) { - return false, nil - } - } - var transferFunc vm.TransferFunc if engine != nil && engine.Type() == params.BorConsensus { transferFunc = BorTransfer @@ -66,17 +60,16 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) commo } return vm.BlockContext{ - CanTransfer: CanTransfer, - Transfer: transferFunc, - GetHash: blockHashFunc, - Coinbase: beneficiary, - BlockNumber: header.Number.Uint64(), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: &baseFee, - GasLimit: header.GasLimit, - ContractHasTEVM: contractHasTEVM, - PrevRanDao: prevRandDao, + CanTransfer: CanTransfer, + Transfer: transferFunc, + GetHash: blockHashFunc, + Coinbase: beneficiary, + BlockNumber: header.Number.Uint64(), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: &baseFee, + GasLimit: header.GasLimit, + PrevRanDao: prevRandDao, } } diff --git a/core/state_processor.go b/core/state_processor.go index c203685bb9e..9700485dc1f 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -86,7 +86,7 @@ func applyTransaction(config *params.ChainConfig, gp *GasPool, statedb *state.In // 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, blockHashFunc func(n uint64) common.Hash, engine consensus.Engine, author *common.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config, contractHasTEVM func(contractHash common.Hash) (bool, error)) (*types.Receipt, []byte, error) { +func ApplyTransaction(config *params.ChainConfig, blockHashFunc func(n uint64) common.Hash, engine consensus.Engine, author *common.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, []byte, error) { // Create a new context to be used in the EVM environment // Add addresses to access list if applicable @@ -98,7 +98,7 @@ func ApplyTransaction(config *params.ChainConfig, blockHashFunc func(n uint64) c if tx.IsStarkNet() { vmenv = &vm.CVMAdapter{Cvm: vm.NewCVM(ibs)} } else { - blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author, contractHasTEVM) + blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, ibs, config, cfg) } diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go index fa2d7cc8c6b..83793b1bcef 100644 --- a/core/vm/analysis_test.go +++ b/core/vm/analysis_test.go @@ -89,7 +89,7 @@ func BenchmarkJumpDest(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - contract := NewContract(contractRef, contractRef, nil, 0, false /* skipAnalysis */, false) + contract := NewContract(contractRef, contractRef, nil, 0, false /* skipAnalysis */) contract.Code = code contract.CodeHash = hash diff --git a/core/vm/contract.go b/core/vm/contract.go index 64bdfc14650..fe9153631a7 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -51,7 +51,6 @@ type Contract struct { jumpdests map[common.Hash][]uint64 // Aggregated result of JUMPDEST analysis. analysis []uint64 // Locally cached result of JUMPDEST analysis skipAnalysis bool - vmType VmType Code []byte CodeHash common.Hash @@ -63,7 +62,7 @@ type Contract struct { } // NewContract returns a new contract environment for the execution of EVM. -func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64, skipAnalysis bool, isTEVM bool) *Contract { +func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64, skipAnalysis bool) *Contract { c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object} if parent, ok := caller.(*Contract); ok { @@ -81,11 +80,6 @@ func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas c.skipAnalysis = skipAnalysis - c.vmType = EVMType - if isTEVM { - c.vmType = TEVMType - } - return c } diff --git a/core/vm/evm.go b/core/vm/evm.go index 1c41aec3963..dcee26142d9 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -17,7 +17,6 @@ package vm import ( - "errors" "math/big" "sync/atomic" "time" @@ -65,34 +64,9 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) { - callback, err := selectInterpreter(evm, contract) - if err != nil { - return nil, err - } - - defer callback() - return evm.interpreter.Run(contract, input, readOnly) } -func selectInterpreter(evm *EVM, contract *Contract) (func(), error) { - interpreter := evm.interpreter - callback := func() { - evm.interpreter = interpreter - } - - switch contract.vmType { - case EVMType: - evm.interpreter = evm.interpreters[EVMType] - case TEVMType: - evm.interpreter = evm.interpreters[TEVMType] - default: - return nil, errors.New("no compatible interpreter") - } - - return callback, nil -} - // BlockContext provides the EVM with auxiliary information. Once provided // it shouldn't be modified. type BlockContext struct { @@ -103,8 +77,6 @@ type BlockContext struct { Transfer TransferFunc // GetHash returns the hash corresponding to n GetHash GetHashFunc - // ContractHasTEVM returns true if the contract has TEVM code - ContractHasTEVM func(codeHash common.Hash) (bool, error) // Block information Coinbase common.Address // Provides information for COINBASE @@ -153,8 +125,7 @@ type EVM struct { config Config // global (to this context) ethereum virtual machine // used throughout the execution of the tx. - interpreters []Interpreter - interpreter Interpreter + interpreter Interpreter // abort is used to abort the EVM calling operations // NOTE: must be set atomically abort int32 @@ -176,12 +147,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, state IntraBlockState, chain chainRules: chainConfig.Rules(blockCtx.BlockNumber), } - evmInterp := NewEVMInterpreter(evm, vmConfig) - evm.interpreters = []Interpreter{ - EVMType: evmInterp, - TEVMType: NewTEVMInterpreterByVM(evmInterp.VM), - } - evm.interpreter = evm.interpreters[EVMType] + evm.interpreter = NewEVMInterpreter(evm, vmConfig) return evm } @@ -265,15 +231,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // The depth-check is already done, and precompiles handled above codehash := evm.intraBlockState.GetCodeHash(addrCopy) - var contractHasTEVM bool - contractHasTEVM, err = evm.context.ContractHasTEVM(codehash) - - if err == nil { - contract := NewContract(caller, AccountRef(addrCopy), value, gas, evm.config.SkipAnalysis, contractHasTEVM) - contract.SetCallCode(&addrCopy, codehash, code) - ret, err = run(evm, contract, input, false) - gas = contract.Gas - } + contract := NewContract(caller, AccountRef(addrCopy), value, gas, evm.config.SkipAnalysis) + contract.SetCallCode(&addrCopy, codehash, code) + ret, err = run(evm, contract, input, false) + gas = contract.Gas } } // When an error was returned by the EVM or when setting the creation code @@ -336,13 +297,11 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, addrCopy := addr // 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. - var isTEVM bool codeHash := evm.intraBlockState.GetCodeHash(addrCopy) - isTEVM, err = evm.context.ContractHasTEVM(codeHash) if err == nil { - contract := NewContract(caller, AccountRef(caller.Address()), value, gas, evm.config.SkipAnalysis, isTEVM) + contract := NewContract(caller, AccountRef(caller.Address()), value, gas, evm.config.SkipAnalysis) contract.SetCallCode(&addrCopy, codeHash, code) ret, err = run(evm, contract, input, false) gas = contract.Gas @@ -390,12 +349,10 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by } else { addrCopy := addr // Initialise a new contract and make initialise the delegate values - var isTEVM bool codeHash := evm.intraBlockState.GetCodeHash(addrCopy) - isTEVM, err = evm.context.ContractHasTEVM(codeHash) if err == nil { - contract := NewContract(caller, AccountRef(caller.Address()), nil, gas, evm.config.SkipAnalysis, isTEVM).AsDelegate() + contract := NewContract(caller, AccountRef(caller.Address()), nil, gas, evm.config.SkipAnalysis).AsDelegate() contract.SetCallCode(&addrCopy, codeHash, code) ret, err = run(evm, contract, input, false) gas = contract.Gas @@ -456,12 +413,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte addrCopy := addr // 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. - var isTEVM bool codeHash := evm.intraBlockState.GetCodeHash(addrCopy) - isTEVM, err = evm.context.ContractHasTEVM(codeHash) if err == nil { - contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas, evm.config.SkipAnalysis, isTEVM) + contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas, evm.config.SkipAnalysis) contract.SetCallCode(&addrCopy, codeHash, code) // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally @@ -503,7 +458,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if !evm.context.CanTransfer(evm.intraBlockState, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - if evm.config.Debug || evm.config.EnableTEMV { + if evm.config.Debug { evm.config.Tracer.CaptureStart(evm, evm.depth, caller.Address(), address, false /* precompile */, true /* create */, calltype, codeAndHash.code, gas, value.ToBig(), nil) defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters evm.config.Tracer.CaptureEnd(evm.depth, ret, startGas, gas, time.Since(startTime), err) @@ -535,7 +490,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // 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. - contract := NewContract(caller, AccountRef(address), value, gas, evm.config.SkipAnalysis, false) + contract := NewContract(caller, AccountRef(address), value, gas, evm.config.SkipAnalysis) contract.SetCodeOptionalHash(&address, codeAndHash) if evm.config.NoRecursion && evm.depth > 0 { diff --git a/core/vm/evm_test.go b/core/vm/evm_test.go index 9e02dd1784d..39aac4b3c17 100644 --- a/core/vm/evm_test.go +++ b/core/vm/evm_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/params" "github.com/holiman/uint256" @@ -13,9 +12,7 @@ import ( func TestInterpreterReadonly(t *testing.T) { rapid.Check(t, func(t *rapid.T) { - env := NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{EnableTEMV: true}) + env := NewEVM(BlockContext{}, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{}) isEVMSliceTest := rapid.SliceOfN(rapid.Bool(), 1, -1).Draw(t, "tevm").([]bool) readOnlySliceTest := rapid.SliceOfN(rapid.Bool(), len(isEVMSliceTest), len(isEVMSliceTest)).Draw(t, "readonly").([]bool) @@ -26,8 +23,7 @@ func TestInterpreterReadonly(t *testing.T) { *currentIdx = -1 evmInterpreter := &testVM{ - readonlyGetSetter: env.interpreters[EVMType].(*EVMInterpreter), - isTEMV: false, + readonlyGetSetter: env.interpreter.(*EVMInterpreter), recordedReadOnlies: &readOnlies, recordedIsEVMCalled: &isEVMCalled, @@ -37,21 +33,8 @@ func TestInterpreterReadonly(t *testing.T) { readOnlySliceTest: readOnlySliceTest, currentIdx: currentIdx, } - tevmInterpreter := &testVM{ - readonlyGetSetter: env.interpreters[TEVMType].(*TEVMInterpreter), - isTEMV: true, - recordedReadOnlies: &readOnlies, - recordedIsEVMCalled: &isEVMCalled, - - env: env, - isEVMSliceTest: isEVMSliceTest, - readOnlySliceTest: readOnlySliceTest, - currentIdx: currentIdx, - } - - env.interpreters[EVMType] = evmInterpreter - env.interpreters[TEVMType] = tevmInterpreter + env.interpreter = evmInterpreter dummyContract := NewContract( &dummyContractRef{}, @@ -59,7 +42,6 @@ func TestInterpreterReadonly(t *testing.T) { new(uint256.Int), 0, false, - false, ) newTestSequential(env, currentIdx, readOnlySliceTest, isEVMSliceTest).Run(dummyContract, nil, false) @@ -82,10 +64,6 @@ func TestInterpreterReadonly(t *testing.T) { } for i, readOnly := range readOnlies { - if isEVMCalled[i] != isEVMSliceTest[i] { - t.Fatalf("wrong VM was called in %d index, got EVM %t, expected EVM %t", - i, isEVMCalled[i], isEVMSliceTest[i]) - } if readOnly.outer != readOnlySliceTest[i] { t.Fatalf("outer readOnly appeared in %d index, got readOnly %t, expected %t", @@ -289,9 +267,7 @@ func TestReadonlyBasicCases(t *testing.T) { t.Run(testcase.testName+evmsTestcase.suffix, func(t *testing.T) { readonlySliceTest := testcase.readonlySliceTest - env := NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{EnableTEMV: true}) + env := NewEVM(BlockContext{}, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{}) readonliesGot := make([]*readOnlyState, len(testcase.readonlySliceTest)) isEVMGot := make([]bool, len(evmsTestcase.emvs)) @@ -300,8 +276,7 @@ func TestReadonlyBasicCases(t *testing.T) { *currentIdx = -1 evmInterpreter := &testVM{ - readonlyGetSetter: env.interpreters[EVMType].(*EVMInterpreter), - isTEMV: false, + readonlyGetSetter: env.interpreter.(*EVMInterpreter), recordedReadOnlies: &readonliesGot, recordedIsEVMCalled: &isEVMGot, @@ -311,21 +286,8 @@ func TestReadonlyBasicCases(t *testing.T) { readOnlySliceTest: testcase.readonlySliceTest, currentIdx: currentIdx, } - tevmInterpreter := &testVM{ - readonlyGetSetter: env.interpreters[TEVMType].(*TEVMInterpreter), - isTEMV: true, - recordedReadOnlies: &readonliesGot, - recordedIsEVMCalled: &isEVMGot, - - env: env, - isEVMSliceTest: evmsTestcase.emvs, - readOnlySliceTest: testcase.readonlySliceTest, - currentIdx: currentIdx, - } - - env.interpreters[EVMType] = evmInterpreter - env.interpreters[TEVMType] = tevmInterpreter + env.interpreter = evmInterpreter dummyContract := NewContract( &dummyContractRef{}, @@ -333,7 +295,6 @@ func TestReadonlyBasicCases(t *testing.T) { new(uint256.Int), 0, false, - false, ) newTestSequential(env, currentIdx, readonlySliceTest, evmsTestcase.emvs).Run(dummyContract, nil, false) @@ -354,11 +315,6 @@ func TestReadonlyBasicCases(t *testing.T) { var firstReadOnly int for callIndex, readOnly := range readonliesGot { - if isEVMGot[callIndex] != evmsTestcase.emvs[callIndex] { - t.Fatalf("wrong VM was called in %d index, got EVM %t, expected EVM %t. Test EVMs %v; test readonly %v", - callIndex, isEVMGot[callIndex], evmsTestcase.emvs[callIndex], evmsTestcase.emvs, readonlySliceTest) - } - if readOnly.outer != readonlySliceTest[callIndex] { t.Fatalf("outer readOnly appeared in %d index, got readOnly %t, expected %t. Test EVMs %v; test readonly %v", callIndex, readOnly.outer, readonlySliceTest[callIndex], evmsTestcase.emvs, readonlySliceTest) @@ -431,7 +387,6 @@ func (st *testSequential) Run(_ *Contract, _ []byte, _ bool) ([]byte, error) { new(uint256.Int), 0, false, - !st.isEVMCalled[*st.currentIdx], ) return run(st.env, nextContract, nil, st.readOnlys[*st.currentIdx]) diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index 8d6eb2bc955..266746334a5 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -96,9 +96,8 @@ func TestEIP2200(t *testing.T) { _ = s.CommitBlock(params.AllEthashProtocolChanges.Rules(0), state.NewPlainStateWriter(tx, tx, 0)) vmctx := BlockContext{ - CanTransfer: func(IntraBlockState, common.Address, *uint256.Int) bool { return true }, - Transfer: func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) {}, - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, + CanTransfer: func(IntraBlockState, common.Address, *uint256.Int) bool { return true }, + Transfer: func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) {}, } vmenv := NewEVM(vmctx, TxContext{}, s, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index f8d42aa41af..d794cee40d9 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -95,9 +95,7 @@ func init() { func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() pc = uint64(0) evmInterpreter = env.interpreter.(*EVMInterpreter) @@ -196,9 +194,7 @@ func TestSAR(t *testing.T) { func TestAddMod(t *testing.T) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() evmInterpreter = NewEVMInterpreter(env, env.Config()) pc = uint64(0) @@ -285,9 +281,7 @@ func TestJsonTestcases(t *testing.T) { func opBenchmark(bench *testing.B, op executionFunc, args ...string) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() evmInterpreter = NewEVMInterpreter(env, env.Config()) ) @@ -521,9 +515,7 @@ func BenchmarkOpIsZero(b *testing.B) { func TestOpMstore(t *testing.T) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.Config()) @@ -547,9 +539,7 @@ func TestOpMstore(t *testing.T) { func BenchmarkOpMstore(bench *testing.B) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.Config()) @@ -570,9 +560,7 @@ func BenchmarkOpMstore(bench *testing.B) { func BenchmarkOpSHA3(bench *testing.B) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) stack = stack.New() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.Config()) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index c379578ef15..9db3dad3655 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -36,7 +36,6 @@ type Config struct { TraceJumpDest bool // Print transaction hashes where jumpdest analysis was useful NoReceipts bool // Do not calculate receipts ReadOnly bool // Do no perform any block finalisation - EnableTEMV bool // true if execution with TEVM enable flag ExtraEips []int // Additional EIPS that are to be enabled } diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go index c5a3d554034..5364cf0eb58 100644 --- a/core/vm/logger_test.go +++ b/core/vm/logger_test.go @@ -29,13 +29,11 @@ import ( func TestStoreCapture(t *testing.T) { var ( - env = NewEVM(BlockContext{ - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - }, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{}) + env = NewEVM(BlockContext{}, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{}) logger = NewStructLogger(nil) mem = NewMemory() stack = stack.New() - contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 0, false /* skipAnalysis */, false) + contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 0, false /* skipAnalysis */) ) stack.Push(uint256.NewInt(1)) stack.Push(uint256.NewInt(0)) diff --git a/core/vm/mock_vm.go b/core/vm/mock_vm.go index 6228a307ec4..cda6c6d8442 100644 --- a/core/vm/mock_vm.go +++ b/core/vm/mock_vm.go @@ -17,7 +17,6 @@ type readonlyGetSetter interface { type testVM struct { readonlyGetSetter - isTEMV bool recordedReadOnlies *[]*readOnlyState recordedIsEVMCalled *[]bool @@ -45,7 +44,7 @@ func (evm *testVM) Run(_ *Contract, _ []byte, readOnly bool) (ret []byte, err er currentReadOnly.in = evm.getReadonly() (*evm.recordedReadOnlies)[currentIndex] = currentReadOnly - (*evm.recordedIsEVMCalled)[currentIndex] = !evm.isTEMV + (*evm.recordedIsEVMCalled)[currentIndex] = true *evm.currentIdx++ @@ -56,7 +55,6 @@ func (evm *testVM) Run(_ *Contract, _ []byte, readOnly bool) (ret []byte, err er new(uint256.Int), 0, false, - !evm.isEVMSliceTest[*evm.currentIdx], ), nil, evm.readOnlySliceTest[*evm.currentIdx]) return res, err } diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index bf514f74e03..a13e8f08007 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -19,7 +19,6 @@ package runtime import ( "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" ) func NewEnv(cfg *Config) *vm.EVM { @@ -29,16 +28,15 @@ func NewEnv(cfg *Config) *vm.EVM { } blockContext := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: cfg.GetHashFn, - ContractHasTEVM: ethdb.GetHasTEVM(cfg.kv), - Coinbase: cfg.Coinbase, - BlockNumber: cfg.BlockNumber.Uint64(), - Time: cfg.Time.Uint64(), - Difficulty: cfg.Difficulty, - GasLimit: cfg.GasLimit, - BaseFee: cfg.BaseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: cfg.GetHashFn, + Coinbase: cfg.Coinbase, + BlockNumber: cfg.BlockNumber.Uint64(), + Time: cfg.Time.Uint64(), + Difficulty: cfg.Difficulty, + GasLimit: cfg.GasLimit, + BaseFee: cfg.BaseFee, } return vm.NewEVM(blockContext, txContext, cfg.State, cfg.ChainConfig, cfg.EVMConfig) diff --git a/core/vm/tevm_interpreter.go b/core/vm/tevm_interpreter.go deleted file mode 100644 index 4053ce944b1..00000000000 --- a/core/vm/tevm_interpreter.go +++ /dev/null @@ -1,24 +0,0 @@ -package vm - -// todo: TBD actual TEVM interpreter - -// TEVMInterpreter represents an TEVM interpreter -type TEVMInterpreter struct { - *EVMInterpreter -} - -type VmType int8 - -const ( - EVMType VmType = 0 - TEVMType VmType = 1 -) - -// NewTEVMInterpreter returns a new instance of the Interpreter. -func NewTEVMInterpreter(evm *EVM, cfg Config) *TEVMInterpreter { - return &TEVMInterpreter{NewEVMInterpreter(evm, cfg)} -} - -func NewTEVMInterpreterByVM(vm *VM) *TEVMInterpreter { - return &TEVMInterpreter{NewEVMInterpreterByVM(vm)} -} diff --git a/eth/calltracer/calltracer.go b/eth/calltracer/calltracer.go index 2c697a3f2ab..35fac03f0eb 100644 --- a/eth/calltracer/calltracer.go +++ b/eth/calltracer/calltracer.go @@ -11,21 +11,17 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/log/v3" ) type CallTracer struct { - froms map[common.Address]struct{} - tos map[common.Address]bool // address -> isCreated - hasTEVM func(contractHash common.Hash) (bool, error) + froms map[common.Address]struct{} + tos map[common.Address]bool // address -> isCreated } -func NewCallTracer(hasTEVM func(contractHash common.Hash) (bool, error)) *CallTracer { +func NewCallTracer() *CallTracer { return &CallTracer{ - froms: make(map[common.Address]struct{}), - tos: make(map[common.Address]bool), - hasTEVM: hasTEVM, + froms: make(map[common.Address]struct{}), + tos: make(map[common.Address]bool), } } @@ -38,15 +34,8 @@ func (ct *CallTracer) CaptureStart(evm *vm.EVM, depth int, from common.Address, } if !created && create { - if len(code) > 0 && ct.hasTEVM != nil { - has, err := ct.hasTEVM(common.BytesToHash(crypto.Keccak256(code))) - if !has { - ct.tos[to] = true - } - - if err != nil { - log.Warn("while CaptureStart", "err", err) - } + if len(code) > 0 { + ct.tos[to] = true } } } @@ -87,7 +76,6 @@ func (ct *CallTracer) WriteToDb(tx kv.StatelessWriteTx, block *types.Block, vmCo var blockNumEnc [8]byte binary.BigEndian.PutUint64(blockNumEnc[:], block.Number().Uint64()) var prev common.Address - var created bool for j, addr := range list { if j > 0 && prev == addr { continue @@ -100,12 +88,6 @@ func (ct *CallTracer) WriteToDb(tx kv.StatelessWriteTx, block *types.Block, vmCo if _, ok := ct.tos[addr]; ok { v[length.Addr] |= 2 } - // TEVM marking still untranslated contracts - if vmConfig.EnableTEMV { - if created = ct.tos[addr]; created { - v[length.Addr] |= 4 - } - } if j == 0 { if err := tx.Append(kv.CallTraceSet, blockNumEnc[:], v[:]); err != nil { return err diff --git a/eth/stagedsync/default_stages.go b/eth/stagedsync/default_stages.go index 14ffa721812..3d58c8a7bc3 100644 --- a/eth/stagedsync/default_stages.go +++ b/eth/stagedsync/default_stages.go @@ -8,7 +8,7 @@ import ( "github.com/ledgerwatch/erigon/ethdb/prune" ) -func DefaultStages(ctx context.Context, sm prune.Mode, headers HeadersCfg, cumulativeIndex CumulativeIndexCfg, blockHashCfg BlockHashesCfg, bodies BodiesCfg, issuance IssuanceCfg, senders SendersCfg, exec ExecuteBlockCfg, trans TranspileCfg, hashState HashStateCfg, trieCfg TrieCfg, history HistoryCfg, logIndex LogIndexCfg, callTraces CallTracesCfg, txLookup TxLookupCfg, finish FinishCfg, test bool) []*Stage { +func DefaultStages(ctx context.Context, sm prune.Mode, headers HeadersCfg, cumulativeIndex CumulativeIndexCfg, blockHashCfg BlockHashesCfg, bodies BodiesCfg, issuance IssuanceCfg, senders SendersCfg, exec ExecuteBlockCfg, hashState HashStateCfg, trieCfg TrieCfg, history HistoryCfg, logIndex LogIndexCfg, callTraces CallTracesCfg, txLookup TxLookupCfg, finish FinishCfg, test bool) []*Stage { return []*Stage{ { ID: stages.Headers, @@ -91,21 +91,6 @@ func DefaultStages(ctx context.Context, sm prune.Mode, headers HeadersCfg, cumul return PruneExecutionStage(p, tx, exec, ctx, firstCycle) }, }, - { - ID: stages.Translation, - Description: "Transpile marked EVM contracts to TEVM", - Disabled: !sm.Experiments.TEVM, - DisabledDescription: "Enable by adding `tevm` to --experiments", - Forward: func(firstCycle bool, badBlockUnwind bool, s *StageState, u Unwinder, tx kv.RwTx) error { - return SpawnTranspileStage(s, tx, 0, trans, ctx) - }, - Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx) error { - return UnwindTranspileStage(u, s, tx, trans, ctx) - }, - Prune: func(firstCycle bool, p *PruneState, tx kv.RwTx) error { - return PruneTranspileStage(p, tx, trans, firstCycle, ctx) - }, - }, { ID: stages.HashState, Description: "Hash the key in the state", diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index 8ce3e39723c..e8808e5e763 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -134,7 +134,6 @@ func executeBlock( writeChangesets bool, writeReceipts bool, writeCallTraces bool, - contractHasTEVM func(contractHash commonold.Hash) (bool, error), initialCycle bool, effectiveEngine consensus.Engine, ) error { @@ -154,7 +153,7 @@ func executeBlock( return vm.NewStructLogger(&vm.LogConfig{}), nil } - callTracer := calltracer.NewCallTracer(contractHasTEVM) + callTracer := calltracer.NewCallTracer() vmConfig.Debug = true vmConfig.Tracer = callTracer @@ -165,9 +164,9 @@ func executeBlock( getHashFn := core.GetHashFn(block.Header(), getHeader) if isPoSa { - execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, epochReader{tx: tx}, chainReader{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, contractHasTEVM, false, getTracer) + execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, epochReader{tx: tx}, chainReader{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, false, getTracer) } else { - execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, epochReader{tx: tx}, chainReader{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, contractHasTEVM, false, getTracer) + execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, epochReader{tx: tx}, chainReader{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, false, getTracer) } if err != nil { return err @@ -430,17 +429,11 @@ Loop: lastLogTx += uint64(block.Transactions().Len()) - var contractHasTEVM func(contractHash commonold.Hash) (bool, error) - - if cfg.vmConfig.EnableTEMV { - contractHasTEVM = ethdb.GetHasTEVM(tx) - } - // Incremental move of next stages depend on fully written ChangeSets, Receipts, CallTraceSet writeChangeSets := nextStagesExpectData || blockNum > cfg.prune.History.PruneTo(to) writeReceipts := nextStagesExpectData || blockNum > cfg.prune.Receipts.PruneTo(to) writeCallTraces := nextStagesExpectData || blockNum > cfg.prune.CallTraces.PruneTo(to) - if err = executeBlock(block, tx, batch, cfg, *cfg.vmConfig, writeChangeSets, writeReceipts, writeCallTraces, contractHasTEVM, initialCycle, effectiveEngine); err != nil { + if err = executeBlock(block, tx, batch, cfg, *cfg.vmConfig, writeChangeSets, writeReceipts, writeCallTraces, initialCycle, effectiveEngine); err != nil { if !errors.Is(err, context.Canceled) { log.Warn(fmt.Sprintf("[%s] Execution failed", logPrefix), "block", blockNum, "hash", block.Hash().String(), "err", err) if cfg.hd != nil { diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go index f5d805f9edd..1e896906e8e 100644 --- a/eth/stagedsync/stage_mining_exec.go +++ b/eth/stagedsync/stage_mining_exec.go @@ -20,7 +20,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" - "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/snapshotsync" ) @@ -87,14 +86,13 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := ethdb.GetHasTEVM(tx) // Short circuit if there is no available pending transactions. // But if we disable empty precommit already, ignore it. Since // empty block is necessary to keep the liveness of the network. if noempty { if !localTxs.Empty() { - logs, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, contractHasTEVM, cfg.engine, localTxs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt) + logs, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, localTxs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt) if err != nil { return err } @@ -106,7 +104,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c //} } if !remoteTxs.Empty() { - logs, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, contractHasTEVM, cfg.engine, remoteTxs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt) + logs, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, remoteTxs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt) if err != nil { return err } @@ -173,7 +171,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c return nil } -func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainConfig params.ChainConfig, vmConfig *vm.Config, getHeader func(hash common.Hash, number uint64) *types.Header, contractHasTEVM func(common.Hash) (bool, error), engine consensus.Engine, txs types.TransactionsStream, coinbase common.Address, ibs *state.IntraBlockState, quit <-chan struct{}, interrupt *int32) (types.Logs, error) { +func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainConfig params.ChainConfig, vmConfig *vm.Config, getHeader func(hash common.Hash, number uint64) *types.Header, engine consensus.Engine, txs types.TransactionsStream, coinbase common.Address, ibs *state.IntraBlockState, quit <-chan struct{}, interrupt *int32) (types.Logs, error) { header := current.Header tcount := 0 gasPool := new(core.GasPool).AddGas(current.Header.GasLimit) @@ -187,7 +185,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC gasSnap := gasPool.Gas() snap := ibs.Snapshot() log.Info("addTransactionsToMiningBlock", "txn hash", txn.Hash()) - receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig, contractHasTEVM) + receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap) // restore gasPool as well as ibs diff --git a/eth/stagedsync/stage_tevm.go b/eth/stagedsync/stage_tevm.go deleted file mode 100644 index 845eb6ccd87..00000000000 --- a/eth/stagedsync/stage_tevm.go +++ /dev/null @@ -1,375 +0,0 @@ -package stagedsync - -import ( - "context" - "errors" - "fmt" - "runtime" - "time" - - "github.com/c2h5oh/datasize" - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/cmp" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/dbutils" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/eth/stagedsync/stages" - "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/ethdb/olddb" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/log/v3" -) - -type TranspileCfg struct { - db kv.RwDB - batchSize datasize.ByteSize - chainConfig *params.ChainConfig -} - -func StageTranspileCfg( - kv kv.RwDB, - batchSize datasize.ByteSize, - chainConfig *params.ChainConfig, -) TranspileCfg { - return TranspileCfg{ - db: kv, - batchSize: batchSize, - chainConfig: chainConfig, - } -} - -func SpawnTranspileStage(s *StageState, tx kv.RwTx, toBlock uint64, cfg TranspileCfg, ctx context.Context) error { - var prevStageProgress uint64 - var errStart error - - if tx == nil { - errStart = cfg.db.View(ctx, func(tx kv.Tx) error { - prevStageProgress, errStart = stages.GetStageProgress(tx, stages.Execution) - return errStart - }) - } else { - prevStageProgress, errStart = stages.GetStageProgress(tx, stages.Execution) - } - - if errStart != nil { - return errStart - } - - var to = prevStageProgress - if toBlock > 0 { - to = cmp.Min(prevStageProgress, toBlock) - } - - if to <= s.BlockNumber { - return nil - } - - stageProgress := uint64(0) - logPrefix := s.LogPrefix() - if to > s.BlockNumber+16 { - log.Info(fmt.Sprintf("[%s] Contract translation", logPrefix), "from", s.BlockNumber, "to", to) - } - - empty := common.Address{} - - observedAddresses := map[common.Address]struct{}{ - empty: {}, - } - observedCodeHashes := map[common.Hash]struct{}{} - - var err error - for stageProgress <= toBlock { - stageProgress, err = transpileBatch(logPrefix, stageProgress, to, cfg, tx, observedAddresses, observedCodeHashes, ctx.Done()) - if err != nil { - return err - } - } - - if to > s.BlockNumber+16 { - log.Info(fmt.Sprintf("[%s] Completed on", logPrefix), "block", toBlock) - } - - return nil -} - -func transpileBatch(logPrefix string, stageProgress, toBlock uint64, cfg TranspileCfg, tx kv.RwTx, observedAddresses map[common.Address]struct{}, observedCodeHashes map[common.Hash]struct{}, quitCh <-chan struct{}) (uint64, error) { - useExternalTx := tx != nil - var err error - if !useExternalTx { - tx, err = cfg.db.BeginRw(context.Background()) - if err != nil { - return 0, err - } - defer tx.Rollback() - } - - batch := olddb.NewBatch(tx, quitCh) - defer batch.Rollback() - - // read contracts pending for translation - c, err := tx.CursorDupSort(kv.CallTraceSet) - if err != nil { - return 0, err - } - defer c.Close() - - logTime := time.Now() - logEvery := time.NewTicker(logInterval) - defer logEvery.Stop() - - stateReader := state.NewPlainStateReader(batch) - - var ( - codeHash common.Hash - codeHashBytes []byte - addr common.Address - addrBytes []byte - acc *accounts.Account - evmContract []byte - transpiledCode []byte - ok bool - ) - - prevContract := stageProgress - blockKey := dbutils.EncodeBlockNumber(stageProgress) - - var addressStatus []byte - for blockKey, addressStatus, err = c.SeekExact(blockKey); blockKey != nil; blockKey, addressStatus, err = c.Next() { - if err != nil { - return 0, fmt.Errorf("can't read pending code translations: %w", err) - } - - select { - case <-quitCh: - return 0, libcommon.ErrStopped - case <-logEvery.C: - prevContract, logTime = logTEVMProgress(logPrefix, prevContract, logTime, stageProgress) - tx.CollectMetrics() - default: - } - - stageProgress, err = dbutils.DecodeBlockNumber(blockKey) - if err != nil { - return 0, fmt.Errorf("can't read pending code translations. incorrect block key: %w", err) - } - - if stageProgress > toBlock { - break - } - - if addressStatus[len(addressStatus)-1]&4 == 0 { - continue - } - - addrBytes = addressStatus[:len(addressStatus)-1] - addr = common.BytesToAddress(addrBytes) - - _, ok = observedAddresses[addr] - if ok { - continue - } - observedAddresses[addr] = struct{}{} - - acc, err = stateReader.ReadAccountData(addr) - if err != nil { - if errors.Is(err, ethdb.ErrKeyNotFound) { - continue - } - return 0, fmt.Errorf("can't read account by address %q: %w", addr, err) - } - if acc == nil { - continue - } - - codeHash = acc.CodeHash - if ok = accounts.IsEmptyCodeHash(codeHash); ok { - continue - } - codeHashBytes = codeHash.Bytes() - - _, ok = observedCodeHashes[codeHash] - if ok { - continue - } - observedCodeHashes[codeHash] = struct{}{} - - // check if we already have TEVM code - ok, err = batch.Has(kv.ContractTEVMCode, codeHashBytes) - if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) { - return 0, fmt.Errorf("can't read code TEVM bucket by contract hash %q: %w", codeHash, err) - } - if ok && err == nil { - // already has TEVM code - continue - } - - // load the contract code - evmContract, err = batch.GetOne(kv.Code, codeHashBytes) - if err != nil { - if errors.Is(err, ethdb.ErrKeyNotFound) { - continue - } - return 0, fmt.Errorf("can't read pending code translations. incorrect code hash in the bucket: %w", err) - } - if len(evmContract) == 0 { - continue - } - - // call a transpiler - transpiledCode, err = transpileCode(evmContract) - if err != nil { - if errors.Is(err, ethdb.ErrKeyNotFound) { - log.Warn("cannot find EVM contract", "address", addr, "hash", codeHash) - continue - } - return 0, fmt.Errorf("contract %q cannot be translated: %w", codeHash, err) - } - - // store TEVM contract code - err = batch.Put(kv.ContractTEVMCode, codeHashBytes, transpiledCode) - if err != nil { - return 0, fmt.Errorf("cannot store TEVM code %q: %w", codeHash, err) - } - - if batch.BatchSize() >= int(cfg.batchSize) { - break // limit RAM usage. Break to commit batch - } - } - - if err = batch.Commit(); err != nil { - return 0, fmt.Errorf("cannot commit the batch of translations on %q: %w", codeHash, err) - } - - if !useExternalTx { - if err = tx.Commit(); err != nil { - return 0, fmt.Errorf("cannot commit the external transation on %q: %w", codeHash, err) - } - } - - return stageProgress, nil -} - -func logTEVMProgress(logPrefix string, prevContract uint64, prevTime time.Time, currentContract uint64) (uint64, time.Time) { - currentTime := time.Now() - interval := currentTime.Sub(prevTime) - speed := float64(currentContract-prevContract) / float64(interval/time.Second) - var m runtime.MemStats - libcommon.ReadMemStats(&m) - var logpairs = []interface{}{ - "number", currentContract, - "contracts/s", speed, - } - logpairs = append(logpairs, "alloc", libcommon.ByteCount(m.Alloc), "sys", libcommon.ByteCount(m.Sys)) - log.Info(fmt.Sprintf("[%s] Translated contracts", logPrefix), logpairs...) - - return currentContract, currentTime -} - -func UnwindTranspileStage(u *UnwindState, s *StageState, tx kv.RwTx, cfg TranspileCfg, ctx context.Context) (err error) { - useExternalTx := tx != nil - if !useExternalTx { - tx, err = cfg.db.BeginRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() - } - - keyStart := dbutils.EncodeBlockNumber(u.UnwindPoint + 1) - c, err := tx.CursorDupSort(kv.CallTraceSet) - if err != nil { - return err - } - defer c.Close() - - var ( - codeHash common.Hash - codeHashBytes []byte - addr common.Address - addrBytes []byte - acc *accounts.Account - ok bool - ) - - stateReader := state.NewPlainStateReader(tx) - - for k, addrStatus, err := c.Seek(keyStart); k != nil; k, addrStatus, err = c.Next() { - if err != nil { - return err - } - - if addrStatus[len(addrStatus)-1]&4 == 0 { - continue - } - - addrBytes = addrStatus[:len(addrStatus)-1] - addr = common.BytesToAddress(addrBytes) - - acc, err = stateReader.ReadAccountData(addr) - if err != nil { - if errors.Is(err, ethdb.ErrKeyNotFound) { - continue - } - return fmt.Errorf("can't read account by address %q: %w", addr, err) - } - if acc == nil { - continue - } - - codeHash = acc.CodeHash - if ok = accounts.IsEmptyCodeHash(codeHash); ok { - continue - } - codeHashBytes = codeHash.Bytes() - - // check if we already have TEVM code - ok, err = tx.Has(kv.ContractTEVMCode, codeHashBytes) - if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) { - return fmt.Errorf("can't read code TEVM bucket by contract hash %q: %w", codeHash, err) - } - if err != nil || !ok { - // doesn't have TEVM code - continue - } - - err = tx.Delete(kv.ContractTEVMCode, codeHashBytes) - if err != nil { - return fmt.Errorf("can't delete TEVM code by hash %q: %w", codeHash, err) - } - } - - if err = u.Done(tx); err != nil { - return err - } - if !useExternalTx { - if err = tx.Commit(); err != nil { - return err - } - } - return nil -} - -// todo: TBD actual TEVM translator -func transpileCode(code []byte) ([]byte, error) { - return append(make([]byte, 0, len(code)), code...), nil -} - -func PruneTranspileStage(p *PruneState, tx kv.RwTx, cfg TranspileCfg, initialCycle bool, ctx context.Context) (err error) { - useExternalTx := tx != nil - if !useExternalTx { - tx, err = cfg.db.BeginRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() - } - - if !useExternalTx { - if err = tx.Commit(); err != nil { - return err - } - } - return nil -} diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 1365b257a8a..fb22ed097ea 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -58,8 +58,7 @@ type vmContext struct { func testCtx() *vmContext { return &vmContext{blockCtx: vm.BlockContext{ - BlockNumber: 1, - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, + BlockNumber: 1, }, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}} } @@ -69,7 +68,7 @@ func runTrace(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) { startGas uint64 = 10000 value = uint256.NewInt(0) ) - contract := vm.NewContract(account{}, account{}, value, startGas, false, false) + contract := vm.NewContract(account{}, account{}, value, startGas, false) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} tracer.CaptureStart(env, 0, contract.Caller(), contract.Address(), false, false, vm.CallType(0), []byte{}, startGas, big.NewInt(int64(value.Uint64())), contract.Code) @@ -85,8 +84,7 @@ func TestTracer(t *testing.T) { execTracer := func(code string) ([]byte, string) { t.Helper() ctx := &vmContext{blockCtx: vm.BlockContext{ - BlockNumber: 1, - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, + BlockNumber: 1, }, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}} tracer, err := New(code, new(Context)) if err != nil { @@ -158,10 +156,9 @@ func TestHaltBetweenSteps(t *testing.T) { t.Fatal(err) } env := vm.NewEVM(vm.BlockContext{ - BlockNumber: 1, - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, + BlockNumber: 1, }, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) - contract := vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0, false, false) + contract := vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0, false) tracer.CaptureState(env, 0, 0, 0, 0, &vm.ScopeContext{Contract: contract}, nil, 0, nil) //nolint:errcheck timeout := errors.New("stahp") @@ -179,7 +176,7 @@ func TestNoStepExec(t *testing.T) { runEmptyTrace := func(tracer *Tracer, vmctx *vmContext) (json.RawMessage, error) { env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) startGas := uint64(10000) - contract := vm.NewContract(account{}, account{}, uint256.NewInt(1), startGas, true, false) + contract := vm.NewContract(account{}, account{}, uint256.NewInt(1), startGas, true) tracer.CaptureStart(env, 0, contract.Caller(), contract.Address(), false, false, vm.CALLT, nil, 0, big.NewInt(0), nil) tracer.CaptureEnd(0, nil, startGas-contract.Gas, 1, 0, nil) return tracer.GetResult() diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 36b31c447c3..f0e751518d0 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -152,14 +152,13 @@ func TestPrestateTracerCreate2(t *testing.T) { GasPrice: big.NewInt(1), } context := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: common.Address{}, - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, - BlockNumber: 8000000, - Time: 5, - Difficulty: big.NewInt(0x30000), - GasLimit: uint64(6000000), + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: common.Address{}, + BlockNumber: 8000000, + Time: 5, + Difficulty: big.NewInt(0x30000), + GasLimit: uint64(6000000), } alloc := core.GenesisAlloc{} @@ -245,14 +244,13 @@ func TestCallTracer(t *testing.T) { GasPrice: big.NewInt(int64(txn.GetPrice().Uint64())), } context := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: uint64(test.Context.Number), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - ContractHasTEVM: func(common.Hash) (bool, error) { return false, nil }, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: test.Context.Miner, + BlockNumber: uint64(test.Context.Number), + Time: uint64(test.Context.Time), + Difficulty: (*big.Int)(test.Context.Difficulty), + GasLimit: uint64(test.Context.GasLimit), } _, tx := memdb.NewTestTx(t) diff --git a/ethdb/kv_util.go b/ethdb/kv_util.go index c64656521ce..430d9d73860 100644 --- a/ethdb/kv_util.go +++ b/ethdb/kv_util.go @@ -2,11 +2,8 @@ package ethdb import ( "bytes" - "errors" - "fmt" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" ) func Walk(c kv.Cursor, startkey []byte, fixedbits int, walker func(k, v []byte) (bool, error)) error { @@ -31,38 +28,6 @@ func Walk(c kv.Cursor, startkey []byte, fixedbits int, walker func(k, v []byte) return nil } -// todo: return TEVM code and use it -func GetHasTEVM(db kv.Has) func(contractHash common.Hash) (bool, error) { - contractsWithTEVM := map[common.Hash]struct{}{} - var ok bool - - return func(contractHash common.Hash) (bool, error) { - if contractHash == (common.Hash{}) { - return false, nil - } - - if _, ok = contractsWithTEVM[contractHash]; ok { - return true, nil - } - - ok, err := db.Has(kv.ContractTEVMCode, contractHash.Bytes()) - if err != nil && !errors.Is(err, ErrKeyNotFound) { - return false, fmt.Errorf("can't check TEVM bucket by contract %q hash: %w", - contractHash.String(), err) - } - - if errors.Is(err, ErrKeyNotFound) { - return false, nil - } - - if ok { - contractsWithTEVM[contractHash] = struct{}{} - } - - return true, nil - } -} - func Bytesmask(fixedbits int) (fixedbytes int, mask byte) { fixedbytes = (fixedbits + 7) / 8 shiftbits := fixedbits & 7 diff --git a/ethdb/prune/storage_mode.go b/ethdb/prune/storage_mode.go index ace4de2bbab..ac44bdafec3 100644 --- a/ethdb/prune/storage_mode.go +++ b/ethdb/prune/storage_mode.go @@ -30,7 +30,6 @@ var ( ) type Experiments struct { - TEVM bool } func FromCli(chainId uint64, flags string, exactHistory, exactReceipts, exactTxIndex, exactCallTraces, @@ -93,8 +92,6 @@ func FromCli(chainId uint64, flags string, exactHistory, exactReceipts, exactTxI for _, ex := range experiments { switch ex { - case "tevm": - mode.Experiments.TEVM = true case "": // skip default: @@ -153,12 +150,6 @@ func Get(db kv.Getter) (Mode, error) { prune.CallTraces = blockAmount } - v, err := db.GetOne(kv.DatabaseInfo, kv.StorageModeTEVM) - if err != nil { - return prune, err - } - prune.Experiments.TEVM = len(v) == 1 && v[0] == 1 - return prune, nil } @@ -254,9 +245,6 @@ func (m Mode) String() string { long += fmt.Sprintf(" --prune.c.%s=%d", m.CallTraces.dbType(), m.CallTraces.toValue()) } } - if m.Experiments.TEVM { - long += " --experiments.tevm=enabled" - } return strings.TrimLeft(short+long, " ") } @@ -286,11 +274,6 @@ func Override(db kv.RwTx, sm Mode) error { return err } - err = setMode(db, kv.StorageModeTEVM, sm.Experiments.TEVM) - if err != nil { - return err - } - return nil } @@ -341,11 +324,6 @@ func setIfNotExist(db kv.GetPut, pm Mode) error { } } - err = setModeOnEmpty(db, kv.StorageModeTEVM, pm.Experiments.TEVM) - if err != nil { - return err - } - return nil } diff --git a/ethdb/prune/storage_mode_test.go b/ethdb/prune/storage_mode_test.go index 7afc5c81c5c..a5aeca248ac 100644 --- a/ethdb/prune/storage_mode_test.go +++ b/ethdb/prune/storage_mode_test.go @@ -15,16 +15,16 @@ func TestSetStorageModeIfNotExist(t *testing.T) { prune, err := Get(tx) assert.NoError(t, err) assert.Equal(t, Mode{true, Distance(math.MaxUint64), Distance(math.MaxUint64), - Distance(math.MaxUint64), Distance(math.MaxUint64), Experiments{TEVM: false}}, prune) + Distance(math.MaxUint64), Distance(math.MaxUint64), Experiments{}}, prune) err = setIfNotExist(tx, Mode{true, Distance(1), Distance(2), - Before(3), Before(4), Experiments{TEVM: false}}) + Before(3), Before(4), Experiments{}}) assert.NoError(t, err) prune, err = Get(tx) assert.NoError(t, err) assert.Equal(t, Mode{true, Distance(1), Distance(2), - Before(3), Before(4), Experiments{TEVM: false}}, prune) + Before(3), Before(4), Experiments{}}, prune) } var distanceTests = []struct { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 4092a511538..94a47f156c8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -230,9 +230,8 @@ func (t *StateTest) RunNoVerify(rules *params.Rules, tx kv.RwTx, subtest StateSu // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - contractHasTEVM := func(common.Hash) (bool, error) { return false, nil } header := block.Header() - context := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), nil, &t.json.Env.Coinbase, contractHasTEVM) + context := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), nil, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash if baseFee != nil { context.BaseFee = new(uint256.Int) diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index ca7de39585a..e67710f741d 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -67,7 +67,6 @@ var DefaultFlags = []cli.Flag{ utils.RpcAccessListFlag, utils.RpcTraceCompatFlag, utils.RpcGasCapFlag, - utils.TevmFlag, utils.MemoryOverlayFlag, utils.TxpoolApiAddrFlag, utils.TraceMaxtracesFlag, diff --git a/turbo/cli/flags.go b/turbo/cli/flags.go index b055d99ed4a..60d8801e48f 100644 --- a/turbo/cli/flags.go +++ b/turbo/cli/flags.go @@ -359,7 +359,6 @@ func setEmbeddedRpcDaemon(ctx *cli.Context, cfg *nodecfg.Config) { Gascap: ctx.GlobalUint64(utils.RpcGasCapFlag.Name), MaxTraces: ctx.GlobalUint64(utils.TraceMaxtracesFlag.Name), TraceCompatibility: ctx.GlobalBool(utils.RpcTraceCompatFlag.Name), - TevmEnabled: ctx.GlobalBool(utils.TevmFlag.Name), TxPoolApiAddr: ctx.GlobalString(utils.TxpoolApiAddrFlag.Name), diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index e7366ba508a..baafff9afce 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -386,7 +386,6 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey mock.txNums, mock.agg, ), - stagedsync.StageTranspileCfg(mock.DB, cfg.BatchSize, mock.ChainConfig), stagedsync.StageHashStateCfg(mock.DB, mock.Dirs, cfg.HistoryV2, mock.txNums, mock.agg), stagedsync.StageTrieCfg(mock.DB, true, true, false, dirs.Tmp, blockReader, nil, cfg.HistoryV2, mock.txNums, mock.agg), stagedsync.StageHistoryCfg(mock.DB, prune, dirs.Tmp), diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index da1d71ef0ac..e982c5c8378 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -414,7 +414,7 @@ func NewStagedSync(ctx context.Context, nil, controlServer.ChainConfig, controlServer.Engine, - &vm.Config{EnableTEMV: cfg.Prune.Experiments.TEVM}, + &vm.Config{}, notifications.Accumulator, cfg.StateStream, /*stateStream=*/ false, @@ -427,7 +427,6 @@ func NewStagedSync(ctx context.Context, txNums, agg, ), - stagedsync.StageTranspileCfg(db, cfg.BatchSize, controlServer.ChainConfig), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV2, txNums, agg), stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV2, txNums, agg), stagedsync.StageHistoryCfg(db, cfg.Prune, dirs.Tmp), @@ -488,7 +487,7 @@ func NewInMemoryExecution(ctx context.Context, db kv.RwDB, cfg *ethconfig.Config nil, controlServer.ChainConfig, controlServer.Engine, - &vm.Config{EnableTEMV: cfg.Prune.Experiments.TEVM}, + &vm.Config{}, notifications.Accumulator, cfg.StateStream, true, diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index c034ccb6d12..38db2ba7e52 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -33,7 +33,6 @@ func DoCall( chainConfig *params.ChainConfig, filters *rpchelper.Filters, stateCache kvcache.Cache, - contractHasTEVM func(hash common.Hash) (bool, error), headerReader services.HeaderReader, ) (*core.ExecutionResult, error) { // todo: Pending state is only known by the miner @@ -85,7 +84,7 @@ func DoCall( if err != nil { return nil, err } - blockCtx, txCtx := GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, contractHasTEVM, headerReader) + blockCtx, txCtx := GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, headerReader) evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, vm.Config{NoBaseFee: true}) @@ -109,7 +108,7 @@ func DoCall( return result, nil } -func GetEvmContext(msg core.Message, header *types.Header, requireCanonical bool, tx kv.Tx, contractHasTEVM func(address common.Hash) (bool, error), headerReader services.HeaderReader) (vm.BlockContext, vm.TxContext) { +func GetEvmContext(msg core.Message, header *types.Header, requireCanonical bool, tx kv.Tx, headerReader services.HeaderReader) (vm.BlockContext, vm.TxContext) { var baseFee uint256.Int if header.Eip1559 { overflow := baseFee.SetFromBig(header.BaseFee) @@ -118,16 +117,15 @@ func GetEvmContext(msg core.Message, header *types.Header, requireCanonical bool } } return vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHashGetter(requireCanonical, tx, headerReader), - ContractHasTEVM: contractHasTEVM, - Coinbase: header.Coinbase, - BlockNumber: header.Number.Uint64(), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - GasLimit: header.GasLimit, - BaseFee: &baseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: getHashGetter(requireCanonical, tx, headerReader), + Coinbase: header.Coinbase, + BlockNumber: header.Number.Uint64(), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + GasLimit: header.GasLimit, + BaseFee: &baseFee, }, vm.TxContext{ Origin: msg.From(), diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 538219d592d..26933d837ee 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -31,7 +31,7 @@ type BlockGetter interface { } // ComputeTxEnv returns the execution environment of a certain transaction. -func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, contractHasTEVM func(common.Hash) (bool, error), engine consensus.Engine, dbtx kv.Tx, blockHash common.Hash, txIndex uint64) (core.Message, vm.BlockContext, vm.TxContext, *state.IntraBlockState, *state.PlainState, error) { +func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, engine consensus.Engine, dbtx kv.Tx, blockHash common.Hash, txIndex uint64) (core.Message, vm.BlockContext, vm.TxContext, *state.IntraBlockState, *state.PlainState, error) { // Create the parent state database reader := state.NewPlainState(dbtx, block.NumberU64()) statedb := state.New(reader) @@ -43,7 +43,7 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf signer := types.MakeSigner(cfg, block.NumberU64()) header := block.Header() - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, contractHasTEVM) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) vmenv := vm.NewEVM(BlockContext, vm.TxContext{}, statedb, cfg, vm.Config{}) rules := vmenv.ChainRules() for idx, tx := range block.Transactions() {