diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 4a08e7e8b4d61f43299bb66ae554919771e13b11..3efd15990c535dc308922f6a63bc20c1febc42f6 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -23,12 +23,20 @@ import ( // 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 *map[common.Address]ethapi.Account) (hexutil.Bytes, error) { - tx, err1 := api.db.Begin(ctx, nil, ethdb.RO) - if err1 != nil { - return nil, fmt.Errorf("call cannot open tx: %v", err1) + dbtx, err := api.dbReader.Begin(ctx, ethdb.RO) + if err != nil { + return nil, err + } + defer dbtx.Rollback() + + tx := dbtx.(ethdb.HasTx).Tx() + + chainConfig, err := getChainConfig(dbtx) + if err != nil { + return nil, err } - defer tx.Rollback() - result, err := transactions.DoCall(ctx, args, tx, api.dbReader, blockNrOrHash, overrides, api.GasCap) + + result, err := transactions.DoCall(ctx, args, tx, api.dbReader, blockNrOrHash, overrides, api.GasCap, chainConfig) if err != nil { return nil, err } @@ -50,11 +58,14 @@ func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs) (hexu } func (api *APIImpl) DoEstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) { - tx, err1 := api.db.Begin(ctx, nil, ethdb.RO) - if err1 != nil { - return 0, fmt.Errorf("estimateGas cannot open tx: %v", err1) + dbtx, err := api.dbReader.Begin(ctx, ethdb.RO) + if err != nil { + return 0, err } - defer tx.Rollback() + defer dbtx.Rollback() + + tx := dbtx.(ethdb.HasTx).Tx() + // Binary search the gas requirement, as it may be higher than the amount used var ( lo uint64 = params.TxGas - 1 @@ -71,6 +82,11 @@ func (api *APIImpl) DoEstimateGas(ctx context.Context, args ethapi.CallArgs, blo return 0, err } + chainConfig, err := getChainConfig(dbtx) + if err != nil { + return 0, err + } + // Determine the highest gas limit can be used during the estimation. if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { hi = uint64(*args.Gas) @@ -117,7 +133,7 @@ func (api *APIImpl) DoEstimateGas(ctx context.Context, args ethapi.CallArgs, blo executable := func(gas uint64) (bool, *core.ExecutionResult, error) { args.Gas = (*hexutil.Uint64)(&gas) - result, err := transactions.DoCall(ctx, args, tx, api.dbReader, blockNrOrHash, nil, api.GasCap) + result, err := transactions.DoCall(ctx, args, tx, api.dbReader, blockNrOrHash, nil, api.GasCap, chainConfig) if err != nil { if errors.Is(err, core.ErrIntrinsicGas) { // Special case, raise gas limit diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index 8f323507a11b58d74590b0dc0c19686f9e955e4d..a4753122ed0af7502f28d387ed491287a7bdf031 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -11,6 +11,7 @@ import ( "github.com/ledgerwatch/turbo-geth/eth/gasprice" "github.com/ledgerwatch/turbo-geth/eth/stagedsync/stages" "github.com/ledgerwatch/turbo-geth/ethdb" + "github.com/ledgerwatch/turbo-geth/log" "github.com/ledgerwatch/turbo-geth/params" "github.com/ledgerwatch/turbo-geth/rpc" ) @@ -119,6 +120,17 @@ func (api *APIImpl) BlockByNumber(ctx context.Context, number rpc.BlockNumber) ( // ChainConfig is necessary for gasprice.OracleBackend implementation func (api *APIImpl) ChainConfig() *params.ChainConfig { - // we just harcode mainnet there for now - return params.MainnetChainConfig + tx, err := api.dbReader.Begin(context.TODO(), ethdb.RO) + if err != nil { + log.Warn("Could not read chain config from the db, defaulting to MainnetChainConfig", "err", err) + return params.MainnetChainConfig + } + defer tx.Rollback() + + chainConfig, err := getChainConfig(tx) + if err != nil { + log.Warn("Could not read chain config from the db, defaulting to MainnetChainConfig", "err", err) + return params.MainnetChainConfig + } + return chainConfig } diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index a007120fd3cb9224299ab33395d16ea94c109245..d10f2dbd5dadc6b0190abee6028a33da9ef3f5cc 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -260,7 +260,9 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest) (Pa if err1 != nil { return nil, fmt.Errorf("traceFilter cannot open tx: %v", err1) } + defer dbtx.Rollback() + for i, txOrBlockHash := range filteredHashes { if traceTypes[i] { // In this case, we're processing a block (or uncle) reward trace. The hash is a block hash @@ -297,7 +299,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest) (Pa if err != nil { return nil, err } - trace, err := transactions.TraceTx(ctx, msg, vmctx, ibs, ð.TraceConfig{Tracer: &traceType}) + trace, err := transactions.TraceTx(ctx, msg, vmctx, ibs, ð.TraceConfig{Tracer: &traceType}, chainConfig) if err != nil { return nil, err } @@ -397,7 +399,7 @@ func (api *TraceAPIImpl) getTransactionTraces(dbtx rawdb.DatabaseReader, ctx con } // Time spent 176 out of 205 - trace, err := transactions.TraceTx(ctx, msg, vmctx, ibs, ð.TraceConfig{Tracer: &traceType}) + trace, err := transactions.TraceTx(ctx, msg, vmctx, ibs, ð.TraceConfig{Tracer: &traceType}, chainConfig) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index 253f1578ee40439708e0724077e901e56ae2f374..38a6d8d6dafa1b5e4777456d18cd8d5ca4f6e188 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -8,7 +8,6 @@ import ( "github.com/ledgerwatch/turbo-geth/core/rawdb" "github.com/ledgerwatch/turbo-geth/eth" "github.com/ledgerwatch/turbo-geth/ethdb" - "github.com/ledgerwatch/turbo-geth/params" "github.com/ledgerwatch/turbo-geth/turbo/adapter" "github.com/ledgerwatch/turbo-geth/turbo/transactions" ) @@ -28,10 +27,16 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo } getter := adapter.NewBlockGetter(tx) chainContext := adapter.NewChainContext(tx) - msg, vmctx, ibs, _, err := transactions.ComputeTxEnv(ctx, getter, params.MainnetChainConfig, chainContext, tx.(ethdb.HasTx).Tx(), blockHash, txIndex) + + chainConfig, err := getChainConfig(tx) + if err != nil { + return nil, err + } + + msg, vmctx, ibs, _, err := transactions.ComputeTxEnv(ctx, getter, chainConfig, chainContext, tx.(ethdb.HasTx).Tx(), blockHash, txIndex) if err != nil { return nil, err } // Trace the transaction and return - return transactions.TraceTx(ctx, msg, vmctx, ibs, config) + return transactions.TraceTx(ctx, msg, vmctx, ibs, config, chainConfig) } diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index bf4d0414e997fe08c9531567ee356d62fcd84f0e..1098b4b7707023850ad80fe1f36508104a0f2a33 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -23,7 +23,7 @@ import ( const callTimeout = 5 * time.Minute -func DoCall(ctx context.Context, args ethapi.CallArgs, tx ethdb.Tx, dbReader ethdb.Getter, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account, GasCap uint64) (*core.ExecutionResult, error) { +func DoCall(ctx context.Context, args ethapi.CallArgs, tx ethdb.Tx, dbReader ethdb.Getter, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account, GasCap uint64, chainConfig *params.ChainConfig) (*core.ExecutionResult, error) { // todo: Pending state is only known by the miner /* if blockNrOrHash.BlockNumber != nil && *blockNrOrHash.BlockNumber == rpc.PendingBlockNumber { @@ -99,7 +99,7 @@ func DoCall(ctx context.Context, args ethapi.CallArgs, tx ethdb.Tx, dbReader eth evmCtx := GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, dbReader) - evm := vm.NewEVM(evmCtx, state, params.MainnetChainConfig, vm.Config{}) + evm := vm.NewEVM(evmCtx, state, chainConfig, vm.Config{}) // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 71423e7b7c9391d4d94f480b21a62195056870d8..8b13c6f6b94d3207db96ec10faf13e8c487bdc11 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -85,7 +85,7 @@ func ComputeTxEnv(ctx context.Context, blockGetter BlockGetter, cfg *params.Chai // TraceTx configures a new tracer according to the provided configuration, and // executes the given message in the provided environment. The return value will // be tracer dependent. -func TraceTx(ctx context.Context, message core.Message, vmctx vm.Context, ibs vm.IntraBlockState, config *eth.TraceConfig) (interface{}, error) { +func TraceTx(ctx context.Context, message core.Message, vmctx vm.Context, ibs vm.IntraBlockState, config *eth.TraceConfig, chainConfig *params.ChainConfig) (interface{}, error) { // Assemble the structured logger or the JavaScript tracer var ( tracer vm.Tracer @@ -119,7 +119,7 @@ func TraceTx(ctx context.Context, message core.Message, vmctx vm.Context, ibs vm tracer = vm.NewStructLogger(config.LogConfig) } // Run the transaction with tracing enabled. - vmenv := vm.NewEVM(vmctx, ibs, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer}) + vmenv := vm.NewEVM(vmctx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas())) if err != nil {