From aef5219a27ffd12b49a2edcc08a47250f429fe6e Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 26 Feb 2024 12:39:31 -0500 Subject: [PATCH 1/5] Align rollup CLI flags --- cmd/rpcdaemon/cli/config.go | 8 +-- cmd/rpcdaemon/main.go | 5 +- cmd/utils/flags.go | 68 ++++++++++++++---------- erigon-lib/txpool/txpoolcfg/txpoolcfg.go | 23 ++++---- 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index 297f7e8f8d7..aa9ec6d0e51 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -140,15 +140,15 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) { rootCmd.PersistentFlags().DurationVar(&cfg.EvmCallTimeout, "rpc.evmtimeout", rpccfg.DefaultEvmCallTimeout, "Maximum amount of time to wait for the answer from EVM call.") rootCmd.PersistentFlags().IntVar(&cfg.BatchLimit, utils.RpcBatchLimit.Name, utils.RpcBatchLimit.Value, utils.RpcBatchLimit.Usage) rootCmd.PersistentFlags().IntVar(&cfg.ReturnDataLimit, utils.RpcReturnDataLimit.Name, utils.RpcReturnDataLimit.Value, utils.RpcReturnDataLimit.Usage) - rootCmd.PersistentFlags().BoolVar(&cfg.AllowUnprotectedTxs, utils.AllowUnprotectedTxs.Name, utils.AllowUnprotectedTxs.Value, utils.AllowUnprotectedTxs.Usage) - rootCmd.PersistentFlags().IntVar(&cfg.MaxGetProofRewindBlockCount, utils.RpcMaxGetProofRewindBlockCount.Name, utils.RpcMaxGetProofRewindBlockCount.Value, utils.RpcMaxGetProofRewindBlockCount.Usage) - rootCmd.PersistentFlags().Uint64Var(&cfg.OtsMaxPageSize, utils.OtsSearchMaxCapFlag.Name, utils.OtsSearchMaxCapFlag.Value, utils.OtsSearchMaxCapFlag.Usage) - rootCmd.PersistentFlags().DurationVar(&cfg.RPCSlowLogThreshold, utils.RPCSlowFlag.Name, utils.RPCSlowFlag.Value, utils.RPCSlowFlag.Usage) rootCmd.PersistentFlags().StringVar(&cfg.RollupSequencerHTTP, utils.RollupSequencerHTTPFlag.Name, "", "HTTP endpoint for the sequencer mempool") rootCmd.PersistentFlags().StringVar(&cfg.RollupHistoricalRPC, utils.RollupHistoricalRPCFlag.Name, "", "RPC endpoint for historical data") rootCmd.PersistentFlags().DurationVar(&cfg.RollupHistoricalRPCTimeout, utils.RollupHistoricalRPCTimeoutFlag.Name, rpccfg.DefaultHistoricalRPCTimeout, "Timeout for historical RPC requests") + rootCmd.PersistentFlags().BoolVar(&cfg.AllowUnprotectedTxs, utils.AllowUnprotectedTxs.Name, utils.AllowUnprotectedTxs.Value, utils.AllowUnprotectedTxs.Usage) + rootCmd.PersistentFlags().IntVar(&cfg.MaxGetProofRewindBlockCount, utils.RpcMaxGetProofRewindBlockCount.Name, utils.RpcMaxGetProofRewindBlockCount.Value, utils.RpcMaxGetProofRewindBlockCount.Usage) + rootCmd.PersistentFlags().Uint64Var(&cfg.OtsMaxPageSize, utils.OtsSearchMaxCapFlag.Name, utils.OtsSearchMaxCapFlag.Value, utils.OtsSearchMaxCapFlag.Usage) + rootCmd.PersistentFlags().DurationVar(&cfg.RPCSlowLogThreshold, utils.RPCSlowFlag.Name, utils.RPCSlowFlag.Value, utils.RPCSlowFlag.Usage) if err := rootCmd.MarkPersistentFlagFilename("rpc.accessList", "json"); err != nil { panic(err) } diff --git a/cmd/rpcdaemon/main.go b/cmd/rpcdaemon/main.go index 1195b546d90..7a26fe2076e 100644 --- a/cmd/rpcdaemon/main.go +++ b/cmd/rpcdaemon/main.go @@ -12,7 +12,6 @@ import ( "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/debug" "github.com/ledgerwatch/erigon/turbo/jsonrpc" - "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" ) @@ -41,7 +40,7 @@ func main() { client, err := rpc.DialContext(ctx, cfg.RollupSequencerHTTP, logger) cancel() if err != nil { - log.Error(err.Error()) + logger.Error(err.Error()) return nil } seqRPCService = client @@ -51,7 +50,7 @@ func main() { client, err := rpc.DialContext(ctx, cfg.RollupHistoricalRPC, logger) cancel() if err != nil { - log.Error(err.Error()) + logger.Error(err.Error()) return nil } historicalRPCService = client diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 3babb1199cc..51a06e71fc4 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -638,6 +638,23 @@ var ( Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), } + // Rollup Flags + RollupSequencerHTTPFlag = cli.StringFlag{ + Name: "rollup.sequencerhttp", + Usage: "HTTP endpoint for the sequencer mempool", + EnvVars: []string{"ROLLUP_SEQUENCER_HTTP_ENDPOINT"}, + } + RollupHistoricalRPCFlag = cli.StringFlag{ + Name: "rollup.historicalrpc", + Usage: "RPC endpoint for historical data.", + EnvVars: []string{"ROLLUP_HISTORICAL_RPC_ENDPOINT"}, + } + RollupHistoricalRPCTimeoutFlag = cli.StringFlag{ + Name: "rollup.historicalrpctimeout", + Usage: "Timeout for historical RPC requests.", + Value: "5s", + } + // Metrics flags MetricsEnabledFlag = cli.BoolFlag{ Name: "metrics", @@ -871,22 +888,6 @@ var ( Name: "silkworm.sentry", Usage: "Enable embedded Silkworm Sentry service", } - // Rollup Flags - RollupSequencerHTTPFlag = cli.StringFlag{ - Name: "rollup.sequencerhttp", - Usage: "HTTP endpoint for the sequencer mempool", - EnvVars: []string{"ROLLUP_SEQUENCER_HTTP_ENDPOINT"}, - } - RollupHistoricalRPCFlag = cli.StringFlag{ - Name: "rollup.historicalrpc", - Usage: "RPC endpoint for historical data.", - EnvVars: []string{"ROLLUP_HISTORICAL_RPC_ENDPOINT"}, - } - RollupHistoricalRPCTimeoutFlag = cli.StringFlag{ - Name: "rollup.historicalrpctimeout", - Usage: "Timeout for historical RPC requests.", - Value: "5s", - } BeaconAPIFlag = cli.BoolFlag{ Name: "beacon.api", @@ -1733,6 +1734,14 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C cfg.EthDiscoveryURLs = libcommon.CliString2Array(urls) } } + // Only configure sequencer http flag if we're running in verifier mode i.e. --mine is disabled. + if ctx.IsSet(RollupSequencerHTTPFlag.Name) && !ctx.IsSet(MiningEnabledFlag.Name) { + cfg.RollupSequencerHTTP = ctx.String(RollupSequencerHTTPFlag.Name) + } + if ctx.IsSet(RollupHistoricalRPCFlag.Name) { + cfg.RollupHistoricalRPC = ctx.String(RollupHistoricalRPCFlag.Name) + } + cfg.RollupHistoricalRPCTimeout = ctx.Duration(RollupHistoricalRPCTimeoutFlag.Name) // Override any default configs for hard coded networks. chain := ctx.String(ChainFlag.Name) @@ -1771,25 +1780,39 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C if !ctx.IsSet(MinerGasPriceFlag.Name) { cfg.Miner.GasPrice = big.NewInt(1) } + // TODO(jky) Review whether to add OpDevnetChainName } if ctx.IsSet(OverrideCancunFlag.Name) { cfg.OverrideCancunTime = flags.GlobalBig(ctx, OverrideCancunFlag.Name) cfg.TxPool.OverrideCancunTime = cfg.OverrideCancunTime } + if ctx.IsSet(OverrideShanghaiTime.Name) { + cfg.OverrideShanghaiTime = flags.GlobalBig(ctx, OverrideShanghaiTime.Name) + cfg.TxPool.OverrideShanghaiTime = cfg.OverrideShanghaiTime + } if ctx.IsSet(OverrideOptimismCanyonFlag.Name) { cfg.OverrideOptimismCanyonTime = flags.GlobalBig(ctx, OverrideOptimismCanyonFlag.Name) cfg.TxPool.OverrideOptimismCanyonTime = cfg.OverrideOptimismCanyonTime + // Shanghai hardfork is included in canyon hardfork + cfg.OverrideShanghaiTime = flags.GlobalBig(ctx, OverrideOptimismCanyonFlag.Name) + cfg.TxPool.OverrideShanghaiTime = cfg.OverrideOptimismCanyonTime + } + if ctx.IsSet(OverrideShanghaiTime.Name) && ctx.IsSet(OverrideOptimismCanyonFlag.Name) { + overrideShanghaiTime := flags.GlobalBig(ctx, OverrideShanghaiTime.Name) + overrideOptimismCanyonTime := flags.GlobalBig(ctx, OverrideOptimismCanyonFlag.Name) + if overrideShanghaiTime.Cmp(overrideOptimismCanyonTime) != 0 { + logger.Warn("Shanghai hardfork time is overridden by optimism canyon hardfork time", + "shanghai", overrideShanghaiTime.String(), "canyon", overrideOptimismCanyonTime.String()) + } } - if ctx.IsSet(OverrideOptimismEcotoneFlag.Name) { cfg.OverrideOptimismEcotoneTime = flags.GlobalBig(ctx, OverrideOptimismEcotoneFlag.Name) // Cancun hardfork is included in Ecotone hardfork cfg.OverrideCancunTime = flags.GlobalBig(ctx, OverrideOptimismEcotoneFlag.Name) cfg.TxPool.OverrideCancunTime = flags.GlobalBig(ctx, OverrideOptimismEcotoneFlag.Name) } - if ctx.IsSet(OverrideCancunFlag.Name) && ctx.IsSet(OverrideOptimismEcotoneFlag.Name) { overrideCancunTime := flags.GlobalBig(ctx, OverrideCancunFlag.Name) overrideOptimismEcotoneTime := flags.GlobalBig(ctx, OverrideOptimismEcotoneFlag.Name) @@ -1798,7 +1821,6 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C "cancun", overrideCancunTime.String(), "ecotone", overrideOptimismEcotoneTime.String()) } } - if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedSupported(cfg.NetworkID) { cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name) } @@ -1807,14 +1829,6 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C libkzg.SetTrustedSetupFilePath(ctx.String(TrustedSetupFile.Name)) } - // Rollup params - if ctx.IsSet(RollupSequencerHTTPFlag.Name) && !ctx.IsSet(MiningEnabledFlag.Name) { - cfg.RollupSequencerHTTP = ctx.String(RollupSequencerHTTPFlag.Name) - } - if ctx.IsSet(RollupHistoricalRPCFlag.Name) { - cfg.RollupHistoricalRPC = ctx.String(RollupHistoricalRPCFlag.Name) - } - cfg.RollupHistoricalRPCTimeout = ctx.Duration(RollupHistoricalRPCTimeoutFlag.Name) if ctx.IsSet(TxPoolGossipDisableFlag.Name) { cfg.DisableTxPoolGossip = ctx.Bool(TxPoolGossipDisableFlag.Name) } diff --git a/erigon-lib/txpool/txpoolcfg/txpoolcfg.go b/erigon-lib/txpool/txpoolcfg/txpoolcfg.go index 6f9b930ff20..6db72506c17 100644 --- a/erigon-lib/txpool/txpoolcfg/txpoolcfg.go +++ b/erigon-lib/txpool/txpoolcfg/txpoolcfg.go @@ -29,17 +29,18 @@ import ( ) type Config struct { - DBDir string - TracedSenders []string // List of senders for which tx pool should print out debugging info - PendingSubPoolLimit int - BaseFeeSubPoolLimit int - QueuedSubPoolLimit int - MinFeeCap uint64 - AccountSlots uint64 // Number of executable transaction slots guaranteed per account - BlobSlots uint64 // Total number of blobs (not txs) allowed per account - PriceBump uint64 // Price bump percentage to replace an already existing transaction - BlobPriceBump uint64 //Price bump percentage to replace an existing 4844 blob tx (type-3) - OverrideCancunTime *big.Int + DBDir string + TracedSenders []string // List of senders for which tx pool should print out debugging info + PendingSubPoolLimit int + BaseFeeSubPoolLimit int + QueuedSubPoolLimit int + MinFeeCap uint64 + AccountSlots uint64 // Number of executable transaction slots guaranteed per account + BlobSlots uint64 // Total number of blobs (not txs) allowed per account + PriceBump uint64 // Price bump percentage to replace an already existing transaction + BlobPriceBump uint64 //Price bump percentage to replace an existing 4844 blob tx (type-3) + OverrideShanghaiTime *big.Int + OverrideCancunTime *big.Int OverrideOptimismCanyonTime *big.Int From 332bdc6a6bf9c3775eb547712083f81bf793cd31 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 26 Feb 2024 13:01:56 -0500 Subject: [PATCH 2/5] Align engine changes --- turbo/engineapi/engine_server.go | 33 +++++++++++++----------------- turbo/execution/eth1/forkchoice.go | 12 +++++++++++ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/turbo/engineapi/engine_server.go b/turbo/engineapi/engine_server.go index d5da6b86e87..97db165c853 100644 --- a/turbo/engineapi/engine_server.go +++ b/turbo/engineapi/engine_server.go @@ -468,20 +468,18 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e } if payloadAttributes != nil { - if version < clparams.DenebVersion && payloadAttributes.ParentBeaconBlockRoot != nil { - return nil, &engine_helpers.InvalidPayloadAttributesErr // Unexpected Beacon Root - } - if version >= clparams.DenebVersion && payloadAttributes.ParentBeaconBlockRoot == nil { - return nil, &engine_helpers.InvalidPayloadAttributesErr // Beacon Root missing - } - timestamp := uint64(payloadAttributes.Timestamp) - if !s.config.IsCancun(timestamp) && version >= clparams.DenebVersion { // V3 before cancun - return nil, &rpc.UnsupportedForkError{Message: "Unsupported fork"} - } if s.config.IsCancun(timestamp) && version < clparams.DenebVersion { // Not V3 after cancun + if payloadAttributes.ParentBeaconBlockRoot != nil { + return nil, &rpc.InvalidParamsError{Message: "Unexpected Beacon Root"} + } return nil, &rpc.UnsupportedForkError{Message: "Unsupported fork"} } + if s.config.IsCancun(timestamp) && version >= clparams.DenebVersion { + if payloadAttributes.ParentBeaconBlockRoot == nil { + return nil, &rpc.InvalidParamsError{Message: "Beacon Root missing"} + } + } } // No need for payload building @@ -516,7 +514,10 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e if headHeader.Time >= timestamp { return nil, &engine_helpers.InvalidPayloadAttributesErr } - + txs := make([][]byte, len(payloadAttributes.Transactions)) + for i, tx := range payloadAttributes.Transactions { + txs[i] = tx + } if s.config.Optimism != nil && payloadAttributes.GasLimit == nil { return nil, &engine_helpers.InvalidPayloadAttributesErr } @@ -527,14 +528,8 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e PrevRandao: gointerfaces.ConvertHashToH256(payloadAttributes.PrevRandao), SuggestedFeeRecipient: gointerfaces.ConvertAddressToH160(payloadAttributes.SuggestedFeeRecipient), GasLimit: (*uint64)(payloadAttributes.GasLimit), - Transactions: func() [][]byte { - res := make([][]byte, len(payloadAttributes.Transactions)) - for i, tx := range payloadAttributes.Transactions { - res[i] = []byte(tx) - } - return res - }(), - NoTxPool: payloadAttributes.NoTxPool, + Transactions: txs, + NoTxPool: payloadAttributes.NoTxPool, } if version >= clparams.CapellaVersion { diff --git a/turbo/execution/eth1/forkchoice.go b/turbo/execution/eth1/forkchoice.go index 36a431c29f4..ffc928de586 100644 --- a/turbo/execution/eth1/forkchoice.go +++ b/turbo/execution/eth1/forkchoice.go @@ -2,6 +2,7 @@ package eth1 import ( "context" + "errors" "fmt" "time" @@ -79,6 +80,11 @@ func (e *EthereumExecutionModule) UpdateForkChoice(ctx context.Context, req *exe select { case <-fcuTimer.C: + if e.config.IsOptimism() { + // op-node does not handle SYNCING as asynchronous forkChoiceUpdated. + // return an error and make op-node retry + return nil, errors.New("forkChoiceUpdated timeout") + } e.logger.Debug("treating forkChoiceUpdated as asynchronous as it is taking too long") return &execution.ForkChoiceReceipt{ LatestValidHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}), @@ -103,6 +109,12 @@ func writeForkChoiceHashes(tx kv.RwTx, blockHash, safeHash, finalizedHash libcom func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, blockHash, safeHash, finalizedHash libcommon.Hash, outcomeCh chan forkchoiceOutcome) { if !e.semaphore.TryAcquire(1) { + if e.config.IsOptimism() { + // op-node does not handle SYNCING as asynchronous forkChoiceUpdated. + // return an error and make op-node retry + sendForkchoiceErrorWithoutWaiting(outcomeCh, errors.New("cannot update forkchoice. execution service is busy")) + return + } sendForkchoiceReceiptWithoutWaiting(outcomeCh, &execution.ForkChoiceReceipt{ LatestValidHash: gointerfaces.ConvertHashToH256(libcommon.Hash{}), Status: execution.ExecutionStatus_Busy, From 90a2e59b069d345cb52ad321aa532fe1f9a42bae Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 26 Feb 2024 14:15:13 -0500 Subject: [PATCH 3/5] Align turbo/jsonrpc with testinprod/op-erigon --- turbo/jsonrpc/debug_api.go | 4 + turbo/jsonrpc/eth_accounts.go | 79 +++++++++--------- turbo/jsonrpc/eth_accounts_test.go | 10 +-- turbo/jsonrpc/eth_api.go | 104 ++++++++++++++---------- turbo/jsonrpc/eth_api_test.go | 6 +- turbo/jsonrpc/eth_call.go | 76 +++++++++-------- turbo/jsonrpc/eth_call_test.go | 4 +- turbo/jsonrpc/eth_receipts.go | 33 ++++---- turbo/jsonrpc/otterscan_api.go | 1 + turbo/jsonrpc/otterscan_search_trace.go | 8 +- turbo/jsonrpc/trace_adhoc.go | 2 +- turbo/jsonrpc/tracing.go | 58 +++++++++---- 12 files changed, 222 insertions(+), 163 deletions(-) diff --git a/turbo/jsonrpc/debug_api.go b/turbo/jsonrpc/debug_api.go index 81aab4fc903..5be670aca03 100644 --- a/turbo/jsonrpc/debug_api.go +++ b/turbo/jsonrpc/debug_api.go @@ -60,6 +60,10 @@ func NewPrivateDebugAPI(base *BaseAPI, db kv.RoDB, gascap uint64) *PrivateDebugA } } +func (api *PrivateDebugAPIImpl) relayToHistoricalBackend(ctx context.Context, result interface{}, method string, args ...interface{}) error { + return api.historicalRPCService.CallContext(ctx, result, method, args...) +} + // storageRangeAt implements debug_storageRangeAt. Returns information about a range of storage locations (if any) for the given address. func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutility.Bytes, maxResult int) (StorageRangeResult, error) { tx, err := api.db.BeginRo(ctx) diff --git a/turbo/jsonrpc/eth_accounts.go b/turbo/jsonrpc/eth_accounts.go index 254adb8df9b..325982015ce 100644 --- a/turbo/jsonrpc/eth_accounts.go +++ b/turbo/jsonrpc/eth_accounts.go @@ -3,9 +3,10 @@ package jsonrpc import ( "context" "fmt" - "github.com/ledgerwatch/erigon-lib/common/hexutil" "math/big" + "github.com/ledgerwatch/erigon-lib/common/hexutil" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" @@ -27,7 +28,8 @@ func (api *APIImpl) GetBalance(ctx context.Context, address libcommon.Address, b } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return nil, err } @@ -35,15 +37,15 @@ func (api *APIImpl) GetBalance(ctx context.Context, address libcommon.Address, b if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutil.Big - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_getBalance", address, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return &result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback + } + var result hexutil.Big + if err := api.relayToHistoricalBackend(ctx, &result, "eth_getBalance", address, hexutil.EncodeUint64(blockNum)); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) } - return nil, rpc.ErrNoHistoricalFallback + return &result, nil } reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "") @@ -83,7 +85,8 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address libcommon.A } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return nil, err } @@ -91,15 +94,15 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address libcommon.A if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutil.Uint64 - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_getTransactionCount", address, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return &result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback } - return nil, rpc.ErrNoHistoricalFallback + var result hexutil.Uint64 + if err := api.relayToHistoricalBackend(ctx, &result, "eth_getTransactionCount", address, hexutil.EncodeUint64(blockNum)); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) + } + return &result, nil } reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "") @@ -122,7 +125,8 @@ func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, bloc } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return nil, err } @@ -130,15 +134,15 @@ func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, bloc if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutility.Bytes - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_getCode", address, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback + } + var result hexutility.Bytes + if err := api.relayToHistoricalBackend(ctx, &result, "eth_getCode", address, hexutil.EncodeUint64(blockNum)); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) } - return nil, rpc.ErrNoHistoricalFallback + return result, nil } reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), chainConfig.ChainName) @@ -167,7 +171,8 @@ func (api *APIImpl) GetStorageAt(ctx context.Context, address libcommon.Address, } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return hexutility.Encode(common.LeftPadBytes(empty, 32)), err } @@ -175,15 +180,15 @@ func (api *APIImpl) GetStorageAt(ctx context.Context, address libcommon.Address, if err != nil { return hexutility.Encode(common.LeftPadBytes(empty, 32)), fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutility.Bytes - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_getStorageAt", address, index, hexutil.EncodeUint64(bn)); err != nil { - return hexutility.Encode(common.LeftPadBytes(empty, 32)), fmt.Errorf("historical backend failed: %w", err) - } - return hexutility.Encode(common.LeftPadBytes(result, 32)), nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return hexutility.Encode(common.LeftPadBytes(empty, 32)), rpc.ErrNoHistoricalFallback + } + var result hexutility.Bytes + if err := api.relayToHistoricalBackend(ctx, &result, "eth_getStorageAt", address, index, hexutil.EncodeUint64(blockNum)); err != nil { + return hexutility.Encode(common.LeftPadBytes(empty, 32)), fmt.Errorf("historical backend error: %w", err) } - return hexutility.Encode(common.LeftPadBytes(empty, 32)), rpc.ErrNoHistoricalFallback + return hexutility.Encode(common.LeftPadBytes(result, 32)), nil } reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "") diff --git a/turbo/jsonrpc/eth_accounts_test.go b/turbo/jsonrpc/eth_accounts_test.go index d2890ad4843..7368f02bdbc 100644 --- a/turbo/jsonrpc/eth_accounts_test.go +++ b/turbo/jsonrpc/eth_accounts_test.go @@ -75,11 +75,11 @@ func TestGetBalanceHistoricalRPC(t *testing.T) { expected: "0x1", }, { - caseName: "failuer", + caseName: "failure", payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } @@ -140,7 +140,7 @@ func TestGetTransactionCountHistoricalRPC(t *testing.T) { payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } @@ -201,7 +201,7 @@ func TestGetCodeHistoricalRPC(t *testing.T) { payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } @@ -262,7 +262,7 @@ func TestGetStorageAtHistoricalRPC(t *testing.T) { payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } diff --git a/turbo/jsonrpc/eth_api.go b/turbo/jsonrpc/eth_api.go index 0d6b39d76e0..e7d6334beb3 100644 --- a/turbo/jsonrpc/eth_api.go +++ b/turbo/jsonrpc/eth_api.go @@ -17,7 +17,6 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" @@ -131,7 +130,11 @@ type BaseAPI struct { historicalRPCService *rpc.Client } -func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader, dirs datadir.Dirs, seqRPCService, historicalRPCService *rpc.Client) *BaseAPI { +func NewBaseApi( + f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, + singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader, dirs datadir.Dirs, + seqRPCService *rpc.Client, historicalRPCService *rpc.Client, +) *BaseAPI { blocksLRUSize := 128 // ~32Mb if !singleNodeMode { blocksLRUSize = 512 @@ -141,7 +144,11 @@ func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader serv panic(err) } - return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine, dirs: dirs, seqRPCService: seqRPCService, historicalRPCService: historicalRPCService} + return &BaseAPI{ + filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, + _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine, dirs: dirs, + seqRPCService: seqRPCService, historicalRPCService: historicalRPCService, + } } func (api *BaseAPI) chainConfig(tx kv.Tx) (*chain.Config, error) { @@ -185,6 +192,20 @@ func (api *BaseAPI) blockByHashWithSenders(tx kv.Tx, hash common.Hash) (*types.B return api.blockWithSenders(tx, hash, *number) } +func (api *BaseAPI) blockNumberFromBlockNumberOrHash(tx kv.Tx, bnh *rpc.BlockNumberOrHash) (uint64, error) { + if number, ok := bnh.Number(); ok { + return uint64(number.Int64()), nil + } + if hash, ok := bnh.Hash(); ok { + number := rawdb.ReadHeaderNumber(tx, hash) + if number == nil { + return 0, fmt.Errorf("block %x not found", hash) + } + return *number, nil + } + return 0, fmt.Errorf("invalid block number of hash") +} + func (api *BaseAPI) blockWithSenders(tx kv.Tx, hash common.Hash, number uint64) (*types.Block, error) { if api.blocksLRU != nil { if it, ok := api.blocksLRU.Get(hash); ok && it != nil { @@ -321,20 +342,6 @@ func (api *BaseAPI) pruneMode(tx kv.Tx) (*prune.Mode, error) { return p, nil } -func (api *BaseAPI) blockNumberFromBlockNumberOrHash(tx kv.Tx, bnh *rpc.BlockNumberOrHash) (uint64, error) { - if number, ok := bnh.Number(); ok { - return uint64(number.Int64()), nil - } - if hash, ok := bnh.Hash(); ok { - number := rawdb.ReadHeaderNumber(tx, hash) - if number == nil { - return 0, fmt.Errorf("block %x not found", hash) - } - return *number, nil - } - return 0, fmt.Errorf("invalid block number of hash") -} - // APIImpl is implementation of the EthAPI interface based on remote Db access type APIImpl struct { *BaseAPI @@ -371,6 +378,10 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo } } +func (api *APIImpl) relayToHistoricalBackend(ctx context.Context, result interface{}, method string, args ...interface{}) error { + return api.historicalRPCService.CallContext(ctx, result, method, args...) +} + // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction type RPCTransaction struct { BlockHash *common.Hash `json:"blockHash"` @@ -383,7 +394,7 @@ type RPCTransaction struct { Hash common.Hash `json:"hash"` Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` + To *common.Address `json:"to,omitempty"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` Value *hexutil.Big `json:"value"` Type hexutil.Uint64 `json:"type"` @@ -391,19 +402,22 @@ type RPCTransaction struct { ChainID *hexutil.Big `json:"chainId,omitempty"` MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - SourceHash *common.Hash `json:"sourceHash,omitempty"` - Mint *hexutil.Big `json:"mint,omitempty"` - IsSystemTx bool `json:"isSystemTx,omitempty"` + V *hexutil.Big `json:"v,omitempty"` + R *hexutil.Big `json:"r,omitempty"` + S *hexutil.Big `json:"s,omitempty"` + + // deposit-tx only + SourceHash *common.Hash `json:"sourceHash,omitempty"` + Mint *hexutil.Big `json:"mint,omitempty"` + IsSystemTx *bool `json:"isSystemTx,omitempty"` // deposit-tx post-Canyon only DepositReceiptVersion *hexutil.Uint64 `json:"depositReceiptVersion,omitempty"` } // NewRPCTransaction returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). -func NewRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int, receipt *types.Receipt) *RPCTransaction { +func NewRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int, + receipt *types.Receipt) *RPCTransaction { // Determine the signer. For replay-protected transactions, use the most permissive // signer, because we assume that signers are backwards-compatible with old // transactions. For non-protected transactions, the homestead signer signer is used @@ -420,7 +434,6 @@ func NewRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber } switch t := tx.(type) { case *types.LegacyTx: - chainId = types.DeriveChainId(&t.V) // avoid overflow by not calling DeriveChainId. chain id not included when v = 0 if !t.V.IsZero() { chainId = types.DeriveChainId(&t.V) @@ -451,22 +464,14 @@ func NewRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber result.S = (*hexutil.Big)(t.S.ToBig()) result.Accesses = &t.AccessList result.GasPrice = computeGasPrice(tx, blockHash, baseFee) - case *types.BlobTx: - chainId.Set(t.ChainID) - result.ChainID = (*hexutil.Big)(chainId.ToBig()) - result.Tip = (*hexutil.Big)(t.Tip.ToBig()) - result.FeeCap = (*hexutil.Big)(t.FeeCap.ToBig()) - result.V = (*hexutil.Big)(t.V.ToBig()) - result.R = (*hexutil.Big)(t.R.ToBig()) - result.S = (*hexutil.Big)(t.S.ToBig()) - result.Accesses = &t.AccessList - result.GasPrice = computeGasPrice(tx, blockHash, baseFee) - result.MaxFeePerBlobGas = (*hexutil.Big)(t.MaxFeePerBlobGas.ToBig()) - result.BlobVersionedHashes = t.BlobVersionedHashes case *types.DepositTx: + if t.Mint != nil { + result.Mint = (*hexutil.Big)(t.Mint.ToBig()) + } + result.ChainID = nil result.SourceHash = &t.SourceHash if t.IsSystemTransaction { - result.IsSystemTx = t.IsSystemTransaction + result.IsSystemTx = &t.IsSystemTransaction } if receipt != nil && receipt.DepositNonce != nil { result.Nonce = hexutil.Uint64(*receipt.DepositNonce) @@ -475,12 +480,23 @@ func NewRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber *result.DepositReceiptVersion = hexutil.Uint64(*receipt.DepositReceiptVersion) } } - result.Mint = (*hexutil.Big)(t.Mint.ToBig()) - result.GasPrice = (*hexutil.Big)(libcommon.Big0) + result.GasPrice = (*hexutil.Big)(common.Big0) // must contain v, r, s values for backwards compatibility. - result.V = (*hexutil.Big)(libcommon.Big0) - result.R = (*hexutil.Big)(libcommon.Big0) - result.S = (*hexutil.Big)(libcommon.Big0) + result.V = (*hexutil.Big)(common.Big0) + result.R = (*hexutil.Big)(common.Big0) + result.S = (*hexutil.Big)(common.Big0) + case *types.BlobTx: + chainId.Set(t.ChainID) + result.ChainID = (*hexutil.Big)(chainId.ToBig()) + result.Tip = (*hexutil.Big)(t.Tip.ToBig()) + result.FeeCap = (*hexutil.Big)(t.FeeCap.ToBig()) + result.V = (*hexutil.Big)(t.V.ToBig()) + result.R = (*hexutil.Big)(t.R.ToBig()) + result.S = (*hexutil.Big)(t.S.ToBig()) + result.Accesses = &t.AccessList + result.GasPrice = computeGasPrice(tx, blockHash, baseFee) + result.MaxFeePerBlobGas = (*hexutil.Big)(t.MaxFeePerBlobGas.ToBig()) + result.BlobVersionedHashes = t.BlobVersionedHashes } signer := types.LatestSignerForChainID(chainId.ToBig()) result.From, _ = tx.Sender(*signer) diff --git a/turbo/jsonrpc/eth_api_test.go b/turbo/jsonrpc/eth_api_test.go index 38f1f637002..79014212945 100644 --- a/turbo/jsonrpc/eth_api_test.go +++ b/turbo/jsonrpc/eth_api_test.go @@ -261,7 +261,7 @@ func TestNewRPCTransactionDepositTx(t *testing.T) { // Should include deposit tx specific fields require.Equal(t, got.SourceHash, &tx.SourceHash, "NewRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) - require.Equal(t, got.IsSystemTx, tx.IsSystemTransaction, "NewRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) + require.Equal(t, got.IsSystemTx, &tx.IsSystemTransaction, "NewRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint.ToBig()), "NewRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint.ToBig()) require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "NewRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) } @@ -289,7 +289,7 @@ func TestNewRPCTransactionDepositTxWithVersion(t *testing.T) { // Should include versioned deposit tx specific fields require.Equal(t, got.SourceHash, &tx.SourceHash, "NewRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) - require.Equal(t, got.IsSystemTx, tx.IsSystemTransaction, "NewRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) + require.Equal(t, got.IsSystemTx, &tx.IsSystemTransaction, "NewRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint.ToBig()), "NewRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint.ToBig()) require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "NewRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) require.Equal(t, *got.DepositReceiptVersion, (hexutil.Uint64(version)), "NewRPCTransaction().DepositReceiptVersion = %v, want %v", *got.DepositReceiptVersion, version) @@ -311,7 +311,7 @@ func TestNewRPCTransactionOmitIsSystemTxFalse(t *testing.T) { } got := NewRPCTransaction(tx, common.Hash{}, uint64(12), uint64(1), big.NewInt(0), nil) - require.False(t, got.IsSystemTx, "should omit IsSystemTx when false") + require.Nil(t, got.IsSystemTx, "should omit IsSystemTx when false") } func TestUnmarshalRpcDepositTx(t *testing.T) { diff --git a/turbo/jsonrpc/eth_call.go b/turbo/jsonrpc/eth_call.go index 35a865ed444..984a00150cc 100644 --- a/turbo/jsonrpc/eth_call.go +++ b/turbo/jsonrpc/eth_call.go @@ -46,7 +46,8 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHa } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return nil, err } @@ -54,15 +55,15 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHa if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutility.Bytes - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_call", args, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback + } + var result hexutility.Bytes + if err := api.relayToHistoricalBackend(ctx, &result, "eth_call", args, hexutil.EncodeUint64(blockNum), overrides); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) } - return nil, rpc.ErrNoHistoricalFallback + return result, nil } engine := api.engine() @@ -158,7 +159,8 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs bNrOrHash = *blockNrOrHash } - bn, err := api.blockNumberFromBlockNumberOrHash(dbtx, &bNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(dbtx, &bNrOrHash) if err != nil { return 0, err } @@ -166,15 +168,15 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs if err != nil { return 0, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result hexutil.Uint64 - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_estimateGas", args, hexutil.EncodeUint64(bn)); err != nil { - return 0, fmt.Errorf("historical backend failed: %w", err) - } - return result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return 0, rpc.ErrNoHistoricalFallback + } + var result hexutil.Uint64 + if err := api.relayToHistoricalBackend(ctx, &result, "eth_estimateGas", args, hexutil.EncodeUint64(blockNum)); err != nil { + return 0, fmt.Errorf("historical backend error: %w", err) } - return 0, rpc.ErrNoHistoricalFallback + return result, nil } // Determine the highest gas limit can be used during the estimation. @@ -359,7 +361,8 @@ func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, sto return nil, fmt.Errorf("not supported by Erigon3") } - bn, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, &blockNrOrHash) if err != nil { return nil, err } @@ -367,15 +370,15 @@ func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, sto if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result accounts.AccProofResult - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_getProof", address, storageKeys, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return &result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback + } + var result accounts.AccProofResult + if err := api.relayToHistoricalBackend(ctx, &result, "eth_getProof", address, storageKeys, hexutil.EncodeUint64(blockNum)); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) } - return nil, rpc.ErrNoHistoricalFallback + return &result, nil } blockNr, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) @@ -487,7 +490,8 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi2.CallArgs, } defer tx.Rollback() - bn, err := api.blockNumberFromBlockNumberOrHash(tx, blockNrOrHash) + // Handle pre-bedrock blocks + blockNum, err := api.blockNumberFromBlockNumberOrHash(tx, blockNrOrHash) if err != nil { return nil, err } @@ -495,15 +499,15 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi2.CallArgs, if err != nil { return nil, fmt.Errorf("read chain config: %v", err) } - if chainConfig.IsOptimismPreBedrock(bn) { - if api.historicalRPCService != nil { - var result accessListResult - if err := api.historicalRPCService.CallContext(ctx, &result, "eth_createAccessList", args, hexutil.EncodeUint64(bn)); err != nil { - return nil, fmt.Errorf("historical backend failed: %w", err) - } - return &result, nil + if chainConfig.IsOptimismPreBedrock(blockNum) { + if api.historicalRPCService == nil { + return nil, rpc.ErrNoHistoricalFallback + } + var result accessListResult + if err := api.relayToHistoricalBackend(ctx, &result, "eth_createAccessList", args, hexutil.EncodeUint64(blockNum)); err != nil { + return nil, fmt.Errorf("historical backend error: %w", err) } - return nil, rpc.ErrNoHistoricalFallback + return &result, nil } engine := api.engine() diff --git a/turbo/jsonrpc/eth_call_test.go b/turbo/jsonrpc/eth_call_test.go index 91e4ed54545..11e574200b7 100644 --- a/turbo/jsonrpc/eth_call_test.go +++ b/turbo/jsonrpc/eth_call_test.go @@ -86,7 +86,7 @@ func TestEstimateGasHistoricalRPC(t *testing.T) { payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } @@ -311,7 +311,7 @@ func TestGetProofHistoricalRPC(t *testing.T) { payload: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}", appendAPI: true, isError: true, - expected: "historical backend failed: error", + expected: "historical backend error: error", }, } diff --git a/turbo/jsonrpc/eth_receipts.go b/turbo/jsonrpc/eth_receipts.go index 03c20c701fb..2835ac78224 100644 --- a/turbo/jsonrpc/eth_receipts.go +++ b/turbo/jsonrpc/eth_receipts.go @@ -748,6 +748,7 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig * chainId = types.DeriveChainId(&t.V).ToBig() } case *types.DepositTx: + // Deposit TX does not have chain ID chainId = chainConfig.ChainID default: chainId = txn.GetChainID().ToBig() @@ -773,20 +774,6 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig * "logs": receipt.Logs, "logsBloom": types.CreateBloom(types.Receipts{receipt}), } - if chainConfig.Optimism != nil && txn.Type() != types.DepositTxType { - fields["l1GasPrice"] = (*hexutil.Big)(receipt.L1GasPrice) - fields["l1GasUsed"] = (*hexutil.Big)(receipt.L1GasUsed) - fields["l1Fee"] = (*hexutil.Big)(receipt.L1Fee) - if receipt.FeeScalar != nil { // removed in Ecotone - fields["l1FeeScalar"] = receipt.FeeScalar - } - } - if chainConfig.Optimism != nil && txn.Type() == types.DepositTxType && receipt.DepositNonce != nil { - fields["depositNonce"] = hexutil.Uint64(*receipt.DepositNonce) - } - if chainConfig.Optimism != nil && txn.Type() == types.DepositTxType && receipt.DepositReceiptVersion != nil { - fields["depositReceiptVersion"] = hexutil.Uint64(*receipt.DepositReceiptVersion) - } if !chainConfig.IsLondon(header.Number.Uint64()) { fields["effectiveGasPrice"] = hexutil.Uint64(txn.GetPrice().Uint64()) } else { @@ -804,6 +791,24 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig * fields["contractAddress"] = receipt.ContractAddress } + if chainConfig.IsOptimism() { + if txn.Type() != types.DepositTxType { + fields["l1GasPrice"] = hexutil.Big(*receipt.L1GasPrice) + fields["l1GasUsed"] = hexutil.Big(*receipt.L1GasUsed) + fields["l1Fee"] = hexutil.Big(*receipt.L1Fee) + if receipt.FeeScalar != nil { // removed in Ecotone + fields["l1FeeScalar"] = receipt.FeeScalar + } + } else { + if receipt.DepositNonce != nil { + fields["depositNonce"] = hexutil.Uint64(*receipt.DepositNonce) + } + if receipt.DepositReceiptVersion != nil { + fields["depositReceiptVersion"] = hexutil.Uint64(*receipt.DepositReceiptVersion) + } + } + } + // Set derived blob related fields numBlobs := len(txn.GetBlobHashes()) if numBlobs > 0 { diff --git a/turbo/jsonrpc/otterscan_api.go b/turbo/jsonrpc/otterscan_api.go index 710cb970c46..b893d6a8b74 100644 --- a/turbo/jsonrpc/otterscan_api.go +++ b/turbo/jsonrpc/otterscan_api.go @@ -129,6 +129,7 @@ func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash commo if err != nil { return nil, err } + engine := api.engine() msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, tx, int(txIndex), api.historyV3(tx)) diff --git a/turbo/jsonrpc/otterscan_search_trace.go b/turbo/jsonrpc/otterscan_search_trace.go index 9f40b2aef90..7c501d627a9 100644 --- a/turbo/jsonrpc/otterscan_search_trace.go +++ b/turbo/jsonrpc/otterscan_search_trace.go @@ -101,6 +101,10 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu _ = ibs.FinalizeTx(rules, cachedWriter) if tracer.Found { + var receipt *types.Receipt + if chainConfig.IsOptimism() && idx < len(block.Transactions()) { + receipt = blockReceipts[idx] + } if idx > len(blockReceipts) { select { // it may happen because request canceled, then return canelation error case <-ctx.Done(): @@ -109,10 +113,6 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu } return false, nil, fmt.Errorf("requested receipt idx %d, but have only %d", idx, len(blockReceipts)) // otherwise return some error for debugging } - var receipt *types.Receipt - if chainConfig.IsOptimism() && idx < len(block.Transactions()) { - receipt = blockReceipts[idx] - } rpcTx := NewRPCTransaction(tx, block.Hash(), blockNum, uint64(idx), block.BaseFee(), receipt) mReceipt := marshalReceipt(blockReceipts[idx], tx, chainConfig, block.HeaderNoCopy(), tx.Hash(), true) mReceipt["timestamp"] = block.Time() diff --git a/turbo/jsonrpc/trace_adhoc.go b/turbo/jsonrpc/trace_adhoc.go index e1aece9dd62..256cac7892a 100644 --- a/turbo/jsonrpc/trace_adhoc.go +++ b/turbo/jsonrpc/trace_adhoc.go @@ -1187,7 +1187,6 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type // Get a new instance of the EVM. blockCtx := transactions.NewEVMBlockContext(engine, header, parentNrOrHash.RequireCanonical, dbtx, api._blockReader) - blockCtx.L1CostFunc = l1CostFunc txCtx := core.NewEVMTxContext(msg) if useParent { @@ -1195,6 +1194,7 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type blockCtx.MaxGasLimit = true } ibs.Reset() + blockCtx.L1CostFunc = l1CostFunc // Create initial IntraBlockState, we will compare it with ibs (IntraBlockState after the transaction) evm := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vmConfig) diff --git a/turbo/jsonrpc/tracing.go b/turbo/jsonrpc/tracing.go index d1c3b661d78..860ce9d5e0a 100644 --- a/turbo/jsonrpc/tracing.go +++ b/turbo/jsonrpc/tracing.go @@ -3,6 +3,7 @@ package jsonrpc import ( "context" "encoding/json" + "errors" "fmt" "math/big" "time" @@ -72,6 +73,30 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return fmt.Errorf("invalid arguments; block with hash %x not found", hash) } + chainConfig, err := api.chainConfig(tx) + if err != nil { + stream.WriteNil() + return err + } + + if chainConfig.IsOptimismPreBedrock(block.NumberU64()) { + if api.historicalRPCService == nil { + return rpc.ErrNoHistoricalFallback + } + var traceResult interface{} + // relay using block hash + if err := api.relayToHistoricalBackend(ctx, &traceResult, "debug_traceBlockByHash", block.Hash(), config); err != nil { + return fmt.Errorf("historical backend error: %w", err) + } + // stream out relayed response + result, err := json.Marshal(&traceResult) + if err != nil { + return err + } + stream.WriteRaw(string(result)) + return nil + } + // if we've pruned this history away for this block then just return early // to save any red herring errors err = api.BaseAPI.checkPruneHistory(tx, block.NumberU64()) @@ -88,11 +113,6 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp config.BorTraceEnabled = newBoolPtr(false) } - chainConfig, err := api.chainConfig(tx) - if err != nil { - stream.WriteNil() - return err - } engine := api.engine() _, blockCtx, _, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, tx, 0, api.historyV3(tx)) @@ -196,19 +216,19 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo } if chainConfig.IsOptimismPreBedrock(blockNum) { - if api.historicalRPCService != nil { - treeResult := &GethTrace{} - if err := api.historicalRPCService.CallContext(ctx, treeResult, "debug_traceTransaction", hash, config); err != nil { - return fmt.Errorf("historical backend failed: %w", err) - } - result, err := json.Marshal(treeResult) - if err != nil { - return err - } - stream.WriteRaw(string(result)) - return nil + if api.historicalRPCService == nil { + return rpc.ErrNoHistoricalFallback } - return rpc.ErrNoHistoricalFallback + var traceResult interface{} + if err := api.relayToHistoricalBackend(ctx, &traceResult, "debug_traceTransaction", hash, config); err != nil { + return fmt.Errorf("historical backend error: %w", err) + } + result, err := json.Marshal(traceResult) + if err != nil { + return err + } + stream.WriteRaw(string(result)) + return nil } // check pruning to ensure we have history at this block level @@ -292,6 +312,10 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA return fmt.Errorf("get block number: %v", err) } + if chainConfig.IsOptimismPreBedrock(blockNumber) { + return errors.New("l2geth does not have a debug_traceCall method") + } + err = api.BaseAPI.checkPruneHistory(dbtx, blockNumber) if err != nil { return err From 12eac481c08d2ca0b314b1dd7db7260561019a28 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 26 Feb 2024 16:58:34 -0500 Subject: [PATCH 4/5] More testinprod/op-erigon alignment --- core/genesis_write.go | 24 ++- core/types/gen_genesis.go | 6 + core/types/receipt.go | 39 ++-- core/types/receipt_codecgen_gen.go | 304 +++++++++++------------------ core/types/transaction.go | 8 +- core/types/transaction_signing.go | 10 +- erigon-lib/chain/chain_config.go | 38 ++-- go.mod | 4 +- go.sum | 18 +- 9 files changed, 196 insertions(+), 255 deletions(-) diff --git a/core/genesis_write.go b/core/genesis_write.go index 29ec143f0f7..07a73f339be 100644 --- a/core/genesis_write.go +++ b/core/genesis_write.go @@ -107,25 +107,31 @@ func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrideCancunTime, o if overrideCancunTime != nil { config.CancunTime = overrideCancunTime } - if config.IsOptimism() && overrideOptimismEcotoneTime != nil { - config.EcotoneTime = overrideOptimismEcotoneTime - // Cancun hardfork is included in Ecotone hardfork - config.CancunTime = overrideOptimismEcotoneTime - config.ShanghaiTime = overrideOptimismEcotoneTime + if config.IsOptimism() && overrideOptimismCanyonTime != nil { + config.CanyonTime = overrideOptimismCanyonTime + // Shanghai hardfork is included in canyon hardfork + config.ShanghaiTime = overrideOptimismCanyonTime if config.Optimism.EIP1559DenominatorCanyon == 0 { logger.Warn("EIP1559DenominatorCanyon set to 0. Overriding to 250 to avoid divide by zero.") config.Optimism.EIP1559DenominatorCanyon = 250 } } + if overrideShanghaiTime != nil && config.IsOptimism() && overrideOptimismCanyonTime != nil { + if overrideShanghaiTime.Cmp(overrideOptimismCanyonTime) != 0 { + logger.Warn("Shanghai hardfork time is overridden by optimism canyon time", + "shanghai", overrideShanghaiTime.String(), "canyon", overrideOptimismCanyonTime.String()) + } + } + if config.IsOptimism() && overrideOptimismEcotoneTime != nil { + config.EcotoneTime = overrideOptimismEcotoneTime + // Cancun hardfork is included in Ecotone hardfork + config.CancunTime = overrideOptimismEcotoneTime + } if overrideCancunTime != nil && config.IsOptimism() && overrideOptimismEcotoneTime != nil { if overrideCancunTime.Cmp(overrideOptimismEcotoneTime) != 0 { logger.Warn("Cancun hardfork time is overridden by optimism Ecotone time", "cancun", overrideCancunTime.String(), "ecotone", overrideOptimismEcotoneTime.String()) } - if config.ShanghaiTime.Cmp(overrideOptimismCanyonTime) != 0 { - logger.Warn("Shanghai hardfork time is overridden by optimism Ecotone time", - "shanghai", config.ShanghaiTime.String(), "canyon", overrideOptimismCanyonTime.String()) - } } } diff --git a/core/types/gen_genesis.go b/core/types/gen_genesis.go index ed3e92d9614..4ee6ea9efca 100644 --- a/core/types/gen_genesis.go +++ b/core/types/gen_genesis.go @@ -37,6 +37,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var enc Genesis enc.Config = g.Config @@ -62,6 +63,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.BlobGasUsed = (*math.HexOrDecimal64)(g.BlobGasUsed) enc.ExcessBlobGas = (*math.HexOrDecimal64)(g.ExcessBlobGas) enc.ParentBeaconBlockRoot = g.ParentBeaconBlockRoot + enc.StateHash = g.StateHash return json.Marshal(&enc) } @@ -86,6 +88,7 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -151,5 +154,8 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.ParentBeaconBlockRoot != nil { g.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot } + if dec.StateHash != nil { + g.StateHash = dec.StateHash + } return nil } diff --git a/core/types/receipt.go b/core/types/receipt.go index 06198cd27e4..f4764f1ad65 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -72,6 +72,10 @@ type Receipt struct { // DepositNonce was introduced in Regolith to store the actual nonce used by deposit transactions // The state transition process ensures this is only set for Regolith deposit transactions. DepositNonce *uint64 `json:"depositNonce,omitempty"` + // The position of DepositNonce variable must NOT be changed. If changed, cbor decoding will fail + // for the data following previous struct and leading to decoding error(triggering backward imcompatibility). + + // Further fields when added must be appended after the last variable. Watch out for cbor. // Inclusion information: These fields provide information about the inclusion of the // transaction corresponding to this receipt. @@ -92,16 +96,19 @@ type Receipt struct { } type receiptMarshaling struct { - Type hexutil.Uint64 - PostState hexutility.Bytes - Status hexutil.Uint64 - CumulativeGasUsed hexutil.Uint64 - GasUsed hexutil.Uint64 - BlockNumber *hexutil.Big - TransactionIndex hexutil.Uint - L1Fee *hexutil.Big - L1GasUsed *hexutil.Big + Type hexutil.Uint64 + PostState hexutility.Bytes + Status hexutil.Uint64 + CumulativeGasUsed hexutil.Uint64 + GasUsed hexutil.Uint64 + BlockNumber *hexutil.Big + TransactionIndex hexutil.Uint + + // Optimism L1GasPrice *hexutil.Big + L1GasUsed *hexutil.Big + L1Fee *hexutil.Big + FeeScalar *big.Float DepositNonce *hexutil.Uint64 DepositReceiptVersion *hexutil.Uint64 } @@ -543,11 +550,6 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { if err := rlp.Encode(w, data); err != nil { panic(err) } - case BlobTxType: - w.WriteByte(BlobTxType) - if err := rlp.Encode(w, data); err != nil { - panic(err) - } case DepositTxType: w.WriteByte(DepositTxType) if r.DepositReceiptVersion != nil { @@ -561,6 +563,11 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { panic(err) } } + case BlobTxType: + w.WriteByte(BlobTxType) + if err := rlp.Encode(w, data); err != nil { + panic(err) + } default: // For unsupported types, write nothing. Since this is for // DeriveSha, the error will be caught matching the derived hash @@ -630,7 +637,9 @@ func (r Receipts) DeriveFields(config *chain.Config, hash libcommon.Hash, number l1Fee, l1GasUsed := costFunc(txs[i].RollupCostData()) r[i].L1Fee = l1Fee.ToBig() r[i].L1GasUsed = l1GasUsed.ToBig() - r[i].FeeScalar = feeScalar + if feeScalar != nil { + r[i].FeeScalar = feeScalar + } } } return nil diff --git a/core/types/receipt_codecgen_gen.go b/core/types/receipt_codecgen_gen.go index a4ed0451f69..95f37b09066 100644 --- a/core/types/receipt_codecgen_gen.go +++ b/core/types/receipt_codecgen_gen.go @@ -11,6 +11,7 @@ import ( codec1978 "github.com/ugorji/go/codec" pkg2_big "math/big" "runtime" + "sort" "strconv" ) @@ -31,7 +32,8 @@ const ( ) var ( - errCodecSelferOnlyMapOrArrayEncodeToStruct2 = errors.New(`only encoded map or array can be decoded into a struct`) + errCodecSelferOnlyMapOrArrayEncodeToStruct2 = errors.New(`only encoded map or array can be decoded into a struct`) + _ sort.Interface = nil ) type codecSelfer2 struct{} @@ -39,11 +41,35 @@ type codecSelfer2 struct{} func codecSelfer2False() bool { return false } func codecSelfer2True() bool { return true } +type codecSelfer2stringSlice []string + +func (p codecSelfer2stringSlice) Len() int { return len(p) } +func (p codecSelfer2stringSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] } +func (p codecSelfer2stringSlice) Less(i, j int) bool { return p[uint(i)] < p[uint(j)] } + +type codecSelfer2uint64Slice []uint64 + +func (p codecSelfer2uint64Slice) Len() int { return len(p) } +func (p codecSelfer2uint64Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] } +func (p codecSelfer2uint64Slice) Less(i, j int) bool { return p[uint(i)] < p[uint(j)] } + +type codecSelfer2int64Slice []int64 + +func (p codecSelfer2int64Slice) Len() int { return len(p) } +func (p codecSelfer2int64Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] } +func (p codecSelfer2int64Slice) Less(i, j int) bool { return p[uint(i)] < p[uint(j)] } + +type codecSelfer2float64Slice []float64 + +func (p codecSelfer2float64Slice) Len() int { return len(p) } +func (p codecSelfer2float64Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] } +func (p codecSelfer2float64Slice) Less(i, j int) bool { return p[uint(i)] < p[uint(j)] } + func init() { - if codec1978.GenVersion != 19 { + if codec1978.GenVersion != 28 { _, file, _, _ := runtime.Caller(0) ver := strconv.FormatInt(int64(codec1978.GenVersion), 10) - panic(errors.New("codecgen version mismatch: current: 19, need " + ver + ". Re-generate file: " + file)) + panic(errors.New("codecgen version mismatch: current: 28, need " + ver + ". Re-generate file: " + file)) } if false { // reference the types, but skip this branch at build/run time var _ pkg1_common.Address @@ -51,10 +77,15 @@ func init() { } } +func (Receipt) codecSelferViaCodecgen() {} func (x *Receipt) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r + if z.EncBasicHandle().CheckCircularRef { + z.EncEncode(x) + return + } if x == nil { r.EncodeNil() } else { @@ -150,7 +181,7 @@ func (x *Receipt) CodecEncodeSelf(e *codec1978.Encoder) { func (x *Receipt) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(x) @@ -179,27 +210,18 @@ func (x *Receipt) CodecDecodeSelf(d *codec1978.Decoder) { func (x *Receipt) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r var yyhl3 bool = l >= 0 - for yyj3 := 0; ; yyj3++ { - if yyhl3 { - if yyj3 >= l { - break - } - } else { - if z.DecCheckBreak() { - break - } - } + for yyj3 := 0; z.DecContainerNext(yyj3, l, yyhl3); yyj3++ { z.DecReadMapElemKey() - yys3 := z.StringView(r.DecodeStringAsBytes()) + yys3 := r.DecodeStringAsBytes() z.DecReadMapElemValue() - switch yys3 { + switch string(yys3) { case "Type": x.Type = (uint8)(z.C.UintV(r.DecodeUint64(), 8)) case "1": - x.PostState = r.DecodeBytes(([]byte)(x.PostState), false) + x.PostState = z.DecodeBytesInto(([]byte)(x.PostState)) case "2": x.Status = (uint64)(r.DecodeUint64()) case "3": @@ -287,24 +309,19 @@ func (x *Receipt) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { *x.DepositReceiptVersion = (uint64)(r.DecodeUint64()) } default: - z.DecStructFieldNotFound(-1, yys3) + z.DecStructFieldNotFound(-1, string(yys3)) } // end switch yys3 } // end for yyj3 } func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r var yyj21 int var yyb21 bool var yyhl21 bool = l >= 0 - yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -312,23 +329,15 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { z.DecReadArrayElem() x.Type = (uint8)(z.C.UintV(r.DecodeUint64(), 8)) yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return } z.DecReadArrayElem() - x.PostState = r.DecodeBytes(([]byte)(x.PostState), false) + x.PostState = z.DecodeBytesInto(([]byte)(x.PostState)) yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -336,11 +345,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { z.DecReadArrayElem() x.Status = (uint64)(r.DecodeUint64()) yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -348,11 +353,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { z.DecReadArrayElem() x.CumulativeGasUsed = (uint64)(r.DecodeUint64()) yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -369,11 +370,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { *x.DepositNonce = (uint64)(r.DecodeUint64()) } yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -394,11 +391,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } } yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -419,11 +412,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } } yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -444,11 +433,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } } yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -469,11 +454,7 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } } yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } + yyb21 = !z.DecContainerNext(yyj21, l, yyhl21) if yyb21 { z.DecReadArrayEnd() return @@ -489,28 +470,21 @@ func (x *Receipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } *x.DepositReceiptVersion = (uint64)(r.DecodeUint64()) } - for { - yyj21++ - if yyhl21 { - yyb21 = yyj21 > l - } else { - yyb21 = z.DecCheckBreak() - } - if yyb21 { - break - } + yyj21++ + for ; z.DecContainerNext(yyj21, l, yyhl21); yyj21++ { z.DecReadArrayElem() z.DecStructFieldNotFound(yyj21-1, "") } } func (x *Receipt) IsCodecEmpty() bool { - return !(x.Type != 0 && len(x.PostState) != 0 && x.Status != 0 && x.CumulativeGasUsed != 0 && true) + return !(x.Type != 0 || len(x.PostState) != 0 || x.Status != 0 || x.CumulativeGasUsed != 0 || false) } +func (Receipts) codecSelferViaCodecgen() {} func (x Receipts) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() @@ -521,15 +495,20 @@ func (x Receipts) CodecEncodeSelf(e *codec1978.Encoder) { func (x *Receipts) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r h.decReceipts((*Receipts)(x), d) } +func (Log) codecSelferViaCodecgen() {} func (x *Log) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r + if z.EncBasicHandle().CheckCircularRef { + z.EncEncode(x) + return + } if x == nil { r.EncodeNil() } else { @@ -545,7 +524,7 @@ func (x *Log) CodecEncodeSelf(e *codec1978.Encoder) { if !z.EncBinary() { z.EncTextMarshal(*yy6) } else { - h.enccommon_Address((*pkg1_common.Address)(yy6), e) + z.F.EncSliceUint8V(([]uint8)(yy6[:]), e) } z.EncWriteArrayElem() if x.Topics == nil { @@ -566,7 +545,7 @@ func (x *Log) CodecEncodeSelf(e *codec1978.Encoder) { func (x *Log) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(x) @@ -595,52 +574,38 @@ func (x *Log) CodecDecodeSelf(d *codec1978.Decoder) { func (x *Log) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r var yyhl3 bool = l >= 0 - for yyj3 := 0; ; yyj3++ { - if yyhl3 { - if yyj3 >= l { - break - } - } else { - if z.DecCheckBreak() { - break - } - } + for yyj3 := 0; z.DecContainerNext(yyj3, l, yyhl3); yyj3++ { z.DecReadMapElemKey() - yys3 := z.StringView(r.DecodeStringAsBytes()) + yys3 := r.DecodeStringAsBytes() z.DecReadMapElemValue() - switch yys3 { + switch string(yys3) { case "1": if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(&x.Address) } else { - h.deccommon_Address((*pkg1_common.Address)(&x.Address), d) + z.F.DecSliceUint8N(([]uint8)(x.Address[:]), d) } case "2": h.decSlicecommon_Hash((*[]pkg1_common.Hash)(&x.Topics), d) case "3": - x.Data = r.DecodeBytes(([]byte)(x.Data), false) + x.Data = z.DecodeBytesInto(([]byte)(x.Data)) default: - z.DecStructFieldNotFound(-1, yys3) + z.DecStructFieldNotFound(-1, string(yys3)) } // end switch yys3 } // end for yyj3 } func (x *Log) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r var yyj10 int var yyb10 bool var yyhl10 bool = l >= 0 - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l - } else { - yyb10 = z.DecCheckBreak() - } + yyb10 = !z.DecContainerNext(yyj10, l, yyhl10) if yyb10 { z.DecReadArrayEnd() return @@ -649,14 +614,10 @@ func (x *Log) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(&x.Address) } else { - h.deccommon_Address((*pkg1_common.Address)(&x.Address), d) + z.F.DecSliceUint8N(([]uint8)(x.Address[:]), d) } yyj10++ - if yyhl10 { - yyb10 = yyj10 > l - } else { - yyb10 = z.DecCheckBreak() - } + yyb10 = !z.DecContainerNext(yyj10, l, yyhl10) if yyb10 { z.DecReadArrayEnd() return @@ -664,39 +625,28 @@ func (x *Log) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { z.DecReadArrayElem() h.decSlicecommon_Hash((*[]pkg1_common.Hash)(&x.Topics), d) yyj10++ - if yyhl10 { - yyb10 = yyj10 > l - } else { - yyb10 = z.DecCheckBreak() - } + yyb10 = !z.DecContainerNext(yyj10, l, yyhl10) if yyb10 { z.DecReadArrayEnd() return } z.DecReadArrayElem() - x.Data = r.DecodeBytes(([]byte)(x.Data), false) - for { - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l - } else { - yyb10 = z.DecCheckBreak() - } - if yyb10 { - break - } + x.Data = z.DecodeBytesInto(([]byte)(x.Data)) + yyj10++ + for ; z.DecContainerNext(yyj10, l, yyhl10); yyj10++ { z.DecReadArrayElem() z.DecStructFieldNotFound(yyj10-1, "") } } func (x *Log) IsCodecEmpty() bool { - return !(len(x.Address) != 0 && len(x.Topics) != 0 && len(x.Data) != 0 && true) + return !(x.Address != pkg1_common.Address{} || len(x.Topics) != 0 || len(x.Data) != 0 || false) } +func (Logs) codecSelferViaCodecgen() {} func (x Logs) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() @@ -707,26 +657,26 @@ func (x Logs) CodecEncodeSelf(e *codec1978.Encoder) { func (x *Logs) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r h.decLogs((*Logs)(x), d) } func (x codecSelfer2) encReceipts(v Receipts, e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r if v == nil { r.EncodeNil() return } z.EncWriteArrayStart(len(v)) - for _, yyv1 := range v { + for yyv1 := range v { z.EncWriteArrayElem() - if yyv1 == nil { + if v[yyv1] == nil { r.EncodeNil() } else { - yyv1.CodecEncodeSelf(e) + v[yyv1].CodecEncodeSelf(e) } } z.EncWriteArrayEnd() @@ -734,7 +684,7 @@ func (x codecSelfer2) encReceipts(v Receipts, e *codec1978.Encoder) { func (x codecSelfer2) decReceipts(v *Receipts, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r yyv1 := *v @@ -773,7 +723,7 @@ func (x codecSelfer2) decReceipts(v *Receipts, d *codec1978.Decoder) { } } var yyj1 int - for yyj1 = 0; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || z.DecCheckBreak()); yyj1++ { // bounds-check-elimination + for yyj1 = 0; z.DecContainerNext(yyj1, yyl1, yyhl1); yyj1++ { if yyj1 == 0 && yyv1 == nil { if yyhl1 { yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) @@ -806,7 +756,7 @@ func (x codecSelfer2) decReceipts(v *Receipts, d *codec1978.Decoder) { yyv1 = yyv1[:yyj1] yyc1 = true } else if yyj1 == 0 && yyv1 == nil { - yyv1 = make([]*Receipt, 0) + yyv1 = []*Receipt{} yyc1 = true } } @@ -816,40 +766,22 @@ func (x codecSelfer2) decReceipts(v *Receipts, d *codec1978.Decoder) { } } -func (x codecSelfer2) enccommon_Address(v *pkg1_common.Address, e *codec1978.Encoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - if v == nil { - r.EncodeNil() - return - } - r.EncodeStringBytesRaw(((*[20]byte)(v))[:]) -} - -func (x codecSelfer2) deccommon_Address(v *pkg1_common.Address, d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - r.DecodeBytes(((*[20]byte)(v))[:], true) -} - func (x codecSelfer2) encSlicecommon_Hash(v []pkg1_common.Hash, e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r if v == nil { r.EncodeNil() return } z.EncWriteArrayStart(len(v)) - for _, yyv1 := range v { + for yyv1 := range v { z.EncWriteArrayElem() - yy2 := &yyv1 + yy2 := &v[yyv1] if !z.EncBinary() { z.EncTextMarshal(*yy2) } else { - h.enccommon_Hash((*pkg1_common.Hash)(yy2), e) + z.F.EncSliceUint8V(([]uint8)(yy2[:]), e) } } z.EncWriteArrayEnd() @@ -857,7 +789,7 @@ func (x codecSelfer2) encSlicecommon_Hash(v []pkg1_common.Hash, e *codec1978.Enc func (x codecSelfer2) decSlicecommon_Hash(v *[]pkg1_common.Hash, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r yyv1 := *v @@ -896,7 +828,7 @@ func (x codecSelfer2) decSlicecommon_Hash(v *[]pkg1_common.Hash, d *codec1978.De } } var yyj1 int - for yyj1 = 0; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || z.DecCheckBreak()); yyj1++ { // bounds-check-elimination + for yyj1 = 0; z.DecContainerNext(yyj1, yyl1, yyhl1); yyj1++ { if yyj1 == 0 && yyv1 == nil { if yyhl1 { yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 32) @@ -918,7 +850,7 @@ func (x codecSelfer2) decSlicecommon_Hash(v *[]pkg1_common.Hash, d *codec1978.De if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(&yyv1[yyj1]) } else { - h.deccommon_Hash((*pkg1_common.Hash)(&yyv1[yyj1]), d) + z.F.DecSliceUint8N(([]uint8)(yyv1[yyj1][:]), d) } } } @@ -926,7 +858,7 @@ func (x codecSelfer2) decSlicecommon_Hash(v *[]pkg1_common.Hash, d *codec1978.De yyv1 = yyv1[:yyj1] yyc1 = true } else if yyj1 == 0 && yyv1 == nil { - yyv1 = make([]pkg1_common.Hash, 0) + yyv1 = []pkg1_common.Hash{} yyc1 = true } } @@ -936,39 +868,21 @@ func (x codecSelfer2) decSlicecommon_Hash(v *[]pkg1_common.Hash, d *codec1978.De } } -func (x codecSelfer2) enccommon_Hash(v *pkg1_common.Hash, e *codec1978.Encoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - if v == nil { - r.EncodeNil() - return - } - r.EncodeStringBytesRaw(((*[32]byte)(v))[:]) -} - -func (x codecSelfer2) deccommon_Hash(v *pkg1_common.Hash, d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - r.DecodeBytes(((*[32]byte)(v))[:], true) -} - func (x codecSelfer2) encLogs(v Logs, e *codec1978.Encoder) { var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) + z, r := codec1978.GenHelper().Encoder(e) _, _, _ = h, z, r if v == nil { r.EncodeNil() return } z.EncWriteArrayStart(len(v)) - for _, yyv1 := range v { + for yyv1 := range v { z.EncWriteArrayElem() - if yyv1 == nil { + if v[yyv1] == nil { r.EncodeNil() } else { - yyv1.CodecEncodeSelf(e) + v[yyv1].CodecEncodeSelf(e) } } z.EncWriteArrayEnd() @@ -976,7 +890,7 @@ func (x codecSelfer2) encLogs(v Logs, e *codec1978.Encoder) { func (x codecSelfer2) decLogs(v *Logs, d *codec1978.Decoder) { var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) + z, r := codec1978.GenHelper().Decoder(d) _, _, _ = h, z, r yyv1 := *v @@ -1015,7 +929,7 @@ func (x codecSelfer2) decLogs(v *Logs, d *codec1978.Decoder) { } } var yyj1 int - for yyj1 = 0; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || z.DecCheckBreak()); yyj1++ { // bounds-check-elimination + for yyj1 = 0; z.DecContainerNext(yyj1, yyl1, yyhl1); yyj1++ { if yyj1 == 0 && yyv1 == nil { if yyhl1 { yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) @@ -1048,7 +962,7 @@ func (x codecSelfer2) decLogs(v *Logs, d *codec1978.Decoder) { yyv1 = yyv1[:yyj1] yyc1 = true } else if yyj1 == 0 && yyv1 == nil { - yyv1 = make([]*Log, 0) + yyv1 = []*Log{} yyc1 = true } } diff --git a/core/types/transaction.go b/core/types/transaction.go index 87cf5be86c0..f8648a8d44e 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -241,16 +241,16 @@ func UnmarshalTransactionFromBinary(data []byte) (Transaction, error) { return nil, err } return t, nil - case BlobTxType: + case DepositTxType: s := rlp.NewStream(bytes.NewReader(data[1:]), uint64(len(data)-1)) - t := &BlobTx{} + t := &DepositTx{} if err := t.DecodeRLP(s); err != nil { return nil, err } return t, nil - case DepositTxType: + case BlobTxType: s := rlp.NewStream(bytes.NewReader(data[1:]), uint64(len(data)-1)) - t := &DepositTx{} + t := &BlobTx{} if err := t.DecodeRLP(s); err != nil { return nil, err } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 6006b3b641c..6e82843adab 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -205,6 +205,8 @@ func (sg Signer) SenderWithContext(context *secp256k1.Context, tx Transaction) ( signChainID := sg.chainID.ToBig() // This is reset to nil if tx is unprotected // recoverPlain below will subract 27 from V switch t := tx.(type) { + case *DepositTx: + return t.From, nil case *LegacyTx: if !t.Protected() { if !sg.unprotected { @@ -268,10 +270,6 @@ func (sg Signer) SenderWithContext(context *secp256k1.Context, tx Transaction) ( // id, add 27 to become equivalent to unprotected Homestead signatures. V.Add(&t.V, u256.Num27) R, S = &t.R, &t.S - case *DepositTx: - // This type contains an explicit From: field - sender, _ := tx.GetSender() - return sender, nil default: return libcommon.Address{}, ErrTxTypeNotSupported } @@ -304,6 +302,8 @@ func (sg Signer) SignatureValues(tx Transaction, sig []byte) (R, S, V *uint256.I return nil, nil, nil, ErrInvalidChainId } R, S, V = decodeSignature(sig) + case *DepositTx: + return nil, nil, nil, fmt.Errorf("deposits do not have a signature") case *BlobTx: // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. @@ -311,8 +311,6 @@ func (sg Signer) SignatureValues(tx Transaction, sig []byte) (R, S, V *uint256.I return nil, nil, nil, ErrInvalidChainId } R, S, V = decodeSignature(sig) - case *DepositTx: - return nil, nil, nil, fmt.Errorf("deposits do not have a signature") default: return nil, nil, nil, ErrTxTypeNotSupported } diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 121d65f62f5..dbbcc45e6bf 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -68,8 +68,7 @@ type Config struct { CancunTime *big.Int `json:"cancunTime,omitempty"` PragueTime *big.Int `json:"pragueTime,omitempty"` - // Optimism Forks - BedrockBlock *big.Int `json:"bedrockBlock,omitempty"` // bedrockSwitch block (nil = no fork, 0 = already actived) + BedrockBlock *big.Int `json:"bedrockBlock,omitempty"` // Bedrock switch block (nil = no fork, 0 = already on optimism bedrock) RegolithTime *big.Int `json:"regolithTime,omitempty"` // Regolith switch time (nil = no fork, 0 = already on optimism regolith) CanyonTime *big.Int `json:"canyonTime,omitempty"` // Canyon switch time (nil = no fork, 0 = already on optimism canyon) // Delta: the Delta upgrade does not affect the execution-layer, and is thus not configurable in the chain config. @@ -89,12 +88,25 @@ type Config struct { Clique *CliqueConfig `json:"clique,omitempty"` Aura *AuRaConfig `json:"aura,omitempty"` + // Optimism config Optimism *OptimismConfig `json:"optimism,omitempty"` Bor BorConfig `json:"-"` BorJSON json.RawMessage `json:"bor,omitempty"` } +// OptimismConfig is the optimism config. +type OptimismConfig struct { + EIP1559Elasticity uint64 `json:"eip1559Elasticity"` + EIP1559Denominator uint64 `json:"eip1559Denominator"` + EIP1559DenominatorCanyon uint64 `json:"eip1559DenominatorCanyon"` +} + +// String implements the stringer interface, returning the optimism fee config details. +func (o *OptimismConfig) String() string { + return "optimism" +} + type BorConfig interface { fmt.Stringer IsAgra(num uint64) bool @@ -267,13 +279,13 @@ func (c *Config) IsOptimism() bool { return c.Optimism != nil } +// IsOptimismBedrock returns true iff this is an optimism node & bedrock is active func (c *Config) IsOptimismBedrock(num uint64) bool { return c.IsOptimism() && c.IsBedrock(num) } func (c *Config) IsOptimismRegolith(time uint64) bool { - // Optimism op-geth has additional complexity which is not yet ported here. - return /* c.IsOptimism() && */ c.IsRegolith(time) + return c.IsOptimism() && c.IsRegolith(time) } func (c *Config) IsOptimismCanyon(time uint64) bool { @@ -541,18 +553,6 @@ func (c *CliqueConfig) String() string { return "clique" } -// OptimismConfig is the optimism config. -type OptimismConfig struct { - EIP1559Elasticity uint64 `json:"eip1559Elasticity"` - EIP1559Denominator uint64 `json:"eip1559Denominator"` - EIP1559DenominatorCanyon uint64 `json:"eip1559DenominatorCanyon"` -} - -// String implements the stringer interface, returning the optimism fee config details. -func (o *OptimismConfig) String() string { - return "optimism" -} - func borKeyValueConfigHelper[T uint64 | common.Address](field map[string]T, number uint64) T { fieldUint := make(map[uint64]T) for k, v := range field { @@ -587,7 +587,7 @@ type Rules struct { IsCancun, IsNapoli bool IsPrague bool IsAura bool - IsBedrock, IsOptimismRegolith bool + IsOptimismBedrock, IsOptimismRegolith bool } // Rules ensures c's ChainID is not nil and returns a new Rules instance @@ -612,9 +612,9 @@ func (c *Config) Rules(num uint64, time uint64) *Rules { IsCancun: c.IsCancun(time), IsNapoli: c.IsNapoli(num), IsPrague: c.IsPrague(time), - IsBedrock: c.IsBedrock(num), - IsOptimismRegolith: c.IsOptimismRegolith(time), IsAura: c.Aura != nil, + IsOptimismBedrock: c.IsOptimismBedrock(num), + IsOptimismRegolith: c.IsOptimismRegolith(time), } } diff --git a/go.mod b/go.mod index dd7b43214ad..5de87b5ebc8 100644 --- a/go.mod +++ b/go.mod @@ -81,8 +81,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e github.com/tidwall/btree v1.6.0 - github.com/ugorji/go/codec v1.1.13 - github.com/ugorji/go/codec/codecgen v1.1.13 + github.com/ugorji/go/codec v1.2.12 + github.com/ugorji/go/codec/codecgen v1.2.12 github.com/urfave/cli/v2 v2.27.1 github.com/valyala/fastjson v1.6.4 github.com/vektah/gqlparser/v2 v2.5.10 diff --git a/go.sum b/go.sum index 362f0ac3b58..fd4392a2637 100644 --- a/go.sum +++ b/go.sum @@ -916,11 +916,10 @@ github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EU github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= -github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= -github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= -github.com/ugorji/go/codec/codecgen v1.1.13 h1:rGpZ4Q63VcWA3DMBbIHvg+SQweUkfXBBa/f9X0W+tFg= -github.com/ugorji/go/codec/codecgen v1.1.13/go.mod h1:EhCxlc7Crov+HLygD4+hBCitXNrrGKRrRWj+pRsyJGg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec/codecgen v1.2.12 h1:BWbVmWOPwNT9RcRR+WTPYzJeA4WXBSb1O6XJgl4Te0U= +github.com/ugorji/go/codec/codecgen v1.2.12/go.mod h1:JgbiBomDZo5t1eXffkNLgSu+qeuKWCNWxJBvTG4riRI= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= @@ -996,6 +995,7 @@ golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= @@ -1039,6 +1039,7 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1096,6 +1097,7 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1123,6 +1125,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1198,6 +1202,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= @@ -1208,6 +1213,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1220,6 +1226,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1286,6 +1293,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 09fc443feeba0e4cf6a753bae71284a8d13e6c53 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Tue, 27 Feb 2024 22:02:42 -0500 Subject: [PATCH 5/5] More straggling testinprod/op-erigon alignment --- core/state_transition.go | 2 +- eth/backend.go | 2 +- params/config.go | 14 -------- params/superchain.go | 14 ++++++++ turbo/adapter/ethapi/api.go | 47 +++++++++++++------------ turbo/adapter/ethapi/api_test.go | 21 +++++------ turbo/engineapi/engine_server.go | 27 +++++++------- turbo/engineapi/engine_types/jsonrpc.go | 12 ++++--- 8 files changed, 71 insertions(+), 68 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index bf87aef234b..12f1528a3c4 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -572,7 +572,7 @@ func (st *StateTransition) innerTransitionDb(refunds bool, gasBailout bool) (*Ex } // Check that we are post bedrock to be able to create pseudo pre-bedrock blocks (these are pre-bedrock, but don't follow l2 geth rules) - if rules.IsBedrock { + if rules.IsOptimismBedrock { st.state.AddBalance(params.OptimismBaseFeeRecipient, new(uint256.Int).Mul(uint256.NewInt(st.gasUsed()), st.evm.Context.BaseFee)) if st.evm.Context.L1CostFunc == nil { // Erigon EVM context is used in many unexpected/hacky ways, let's panic if it's misconfigured panic("missing L1 cost func in block context, please configure l1 cost when using optimism config to run EVM") diff --git a/eth/backend.go b/eth/backend.go index 16833c8b274..67c1c5a0b46 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -619,7 +619,6 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger } backend.historicalRPCService = client } - config.TxPool.Optimism = config.Genesis.Config.IsOptimism() config.TxPool.NoGossip = config.DisableTxPoolGossip var miningRPC txpool_proto.MiningServer stateDiffClient := direct.NewStateDiffClientDirect(kvRPC) @@ -631,6 +630,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger backend.newTxs = make(chan types2.Announcements, 1024) //defer close(newTxs) + config.TxPool.Optimism = chainConfig.Optimism != nil backend.txPoolDB, backend.txPool, backend.txPoolFetch, backend.txPoolSend, backend.txPoolGrpcServer, err = txpooluitl.AllComponents( ctx, config.TxPool, kvcache.NewDummy(), backend.newTxs, backend.chainDB, backend.sentriesClient.Sentries(), stateDiffClient, misc.Eip1559FeeCalculator, logger, ) diff --git a/params/config.go b/params/config.go index da5cec36b19..5699aada5d7 100644 --- a/params/config.go +++ b/params/config.go @@ -85,20 +85,6 @@ var ( ChiadoGenesisStateRoot = libcommon.HexToHash("0x9ec3eaf4e6188dfbdd6ade76eaa88289b57c63c9a2cde8d35291d5a29e143d31") ) -const ( - OPMainnetChainID = 10 - OPGoerliChainID = 420 - OPSepoliaChainID = 11155420 - BaseMainnetChainID = 8453 - BaseGoerliChainID = 84531 - baseSepoliaChainID = 84532 - baseGoerliDevnetChainID = 11763071 - pgnSepoliaChainID = 58008 - devnetChainID = 997 - chaosnetChainID = 888 - BobaSepoliaChainID = 28882 -) - var ( // MainnetChainConfig is the chain parameters to run a node on the main network. MainnetChainConfig = readChainSpec("chainspecs/mainnet.json") diff --git a/params/superchain.go b/params/superchain.go index ffd09acae10..39b192fe0ff 100644 --- a/params/superchain.go +++ b/params/superchain.go @@ -11,6 +11,20 @@ import ( "github.com/ledgerwatch/erigon-lib/common" ) +const ( + OPMainnetChainID = 10 + OPGoerliChainID = 420 + OPSepoliaChainID = 11155420 + BaseMainnetChainID = 8453 + BaseGoerliChainID = 84531 + baseSepoliaChainID = 84532 + baseGoerliDevnetChainID = 11763071 + pgnSepoliaChainID = 58008 + devnetChainID = 997 + chaosnetChainID = 888 + BobaSepoliaChainID = 28882 +) + // OP Stack chain config var ( // March 17, 2023 @ 7:00:00 pm UTC diff --git a/turbo/adapter/ethapi/api.go b/turbo/adapter/ethapi/api.go index 0935e80c547..d40b0c2e795 100644 --- a/turbo/adapter/ethapi/api.go +++ b/turbo/adapter/ethapi/api.go @@ -408,20 +408,21 @@ type RPCTransaction struct { Hash libcommon.Hash `json:"hash"` Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` - To *libcommon.Address `json:"to"` + To *libcommon.Address `json:"to,omitempty"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` Value *hexutil.Big `json:"value"` Type hexutil.Uint64 `json:"type"` Accesses *types2.AccessList `json:"accessList,omitempty"` ChainID *hexutil.Big `json:"chainId,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - SourceHash *libcommon.Hash `json:"sourceHash,omitempty"` - Mint *hexutil.Big `json:"mint,omitempty"` - IsSystemTx bool `json:"isSystemTx,omitempty"` + V *hexutil.Big `json:"v,omitempty"` + R *hexutil.Big `json:"r,omitempty"` + S *hexutil.Big `json:"s,omitempty"` BlobVersionedHashes []libcommon.Hash `json:"blobVersionedHashes,omitempty"` + // deposit-tx only + SourceHash *libcommon.Hash `json:"sourceHash,omitempty"` + Mint *hexutil.Big `json:"mint,omitempty"` + IsSystemTx *bool `json:"isSystemTx,omitempty"` // deposit-tx post-Canyon only DepositReceiptVersion *hexutil.Uint64 `json:"depositReceiptVersion,omitempty"` } @@ -476,23 +477,13 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb result.Accesses = &t.AccessList // if the transaction has been mined, compute the effective gas price result.GasPrice = computeGasPrice(tx, blockHash, baseFee) - case *types.BlobTx: - chainId.Set(t.ChainID) - result.ChainID = (*hexutil.Big)(chainId.ToBig()) - result.Tip = (*hexutil.Big)(t.Tip.ToBig()) - result.FeeCap = (*hexutil.Big)(t.FeeCap.ToBig()) - result.V = (*hexutil.Big)(t.V.ToBig()) - result.R = (*hexutil.Big)(t.R.ToBig()) - result.S = (*hexutil.Big)(t.S.ToBig()) - result.Accesses = &t.AccessList - // if the transaction has been mined, compute the effective gas price - result.GasPrice = computeGasPrice(tx, blockHash, baseFee) - result.MaxFeePerBlobGas = (*hexutil.Big)(t.MaxFeePerBlobGas.ToBig()) - result.BlobVersionedHashes = t.GetBlobHashes() case *types.DepositTx: + if t.Mint != nil { + result.Mint = (*hexutil.Big)(t.Mint.ToBig()) + } result.SourceHash = &t.SourceHash if t.IsSystemTransaction { - result.IsSystemTx = t.IsSystemTransaction + result.IsSystemTx = &t.IsSystemTransaction } if receipt != nil && receipt.DepositNonce != nil { result.Nonce = hexutil.Uint64(*receipt.DepositNonce) @@ -501,12 +492,24 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb *result.DepositReceiptVersion = hexutil.Uint64(*receipt.DepositReceiptVersion) } } - result.Mint = (*hexutil.Big)(t.Mint.ToBig()) result.GasPrice = (*hexutil.Big)(libcommon.Big0) // must contain v, r, s values for backwards compatibility. result.V = (*hexutil.Big)(libcommon.Big0) result.R = (*hexutil.Big)(libcommon.Big0) result.S = (*hexutil.Big)(libcommon.Big0) + case *types.BlobTx: + chainId.Set(t.ChainID) + result.ChainID = (*hexutil.Big)(chainId.ToBig()) + result.Tip = (*hexutil.Big)(t.Tip.ToBig()) + result.FeeCap = (*hexutil.Big)(t.FeeCap.ToBig()) + result.V = (*hexutil.Big)(t.V.ToBig()) + result.R = (*hexutil.Big)(t.R.ToBig()) + result.S = (*hexutil.Big)(t.S.ToBig()) + result.Accesses = &t.AccessList + // if the transaction has been mined, compute the effective gas price + result.GasPrice = computeGasPrice(tx, blockHash, baseFee) + result.MaxFeePerBlobGas = (*hexutil.Big)(t.MaxFeePerBlobGas.ToBig()) + result.BlobVersionedHashes = t.GetBlobHashes() } signer := types.LatestSignerForChainID(chainId.ToBig()) var err error diff --git a/turbo/adapter/ethapi/api_test.go b/turbo/adapter/ethapi/api_test.go index 7a5685c2b85..918cbe4acb5 100644 --- a/turbo/adapter/ethapi/api_test.go +++ b/turbo/adapter/ethapi/api_test.go @@ -20,7 +20,7 @@ func TestNewRPCTransactionDepositTx(t *testing.T) { Mint: uint256.NewInt(34), Value: uint256.NewInt(1337), } - nonce := uint64(12) + nonce := uint64(7) depositNonce := &nonce receipt := &types.Receipt{DepositNonce: depositNonce} got := newRPCTransaction(tx, libcommon.Hash{}, uint64(12), uint64(1), big.NewInt(0), receipt) @@ -31,16 +31,15 @@ func TestNewRPCTransactionDepositTx(t *testing.T) { require.Equal(t, got.S, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().S = %v, want 0x0", got.S) // Should include deposit tx specific fields - require.Equal(t, got.SourceHash, &tx.SourceHash, "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) - require.Equal(t, got.IsSystemTx, tx.IsSystemTransaction, "newRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) + require.Equal(t, *got.SourceHash, tx.SourceHash, "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) + require.Equal(t, *got.IsSystemTx, tx.IsSystemTransaction, "newRPCTransaction().IsSystemTransaction = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint.ToBig()), "newRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint.ToBig()) - require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "newRPCTransaction().Mint = %v, want %v", got.Nonce, nonce) + require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "newRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) } func TestNewRPCTransactionDepositTxWithVersion(t *testing.T) { tx := &types.DepositTx{ - SourceHash: libcommon.Hash{1}, - From: libcommon.Address{1}, + SourceHash: libcommon.HexToHash("0x1234"), IsSystemTransaction: true, Mint: uint256.NewInt(34), Value: uint256.NewInt(1337), @@ -59,8 +58,8 @@ func TestNewRPCTransactionDepositTxWithVersion(t *testing.T) { require.Equal(t, got.S, (*hexutil.Big)(big.NewInt(0)), "newRPCTransaction().S = %v, want 0x0", got.S) // Should include versioned deposit tx specific fields - require.Equal(t, got.SourceHash, &tx.SourceHash, "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) - require.Equal(t, got.IsSystemTx, tx.IsSystemTransaction, "newRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) + require.Equal(t, *got.SourceHash, tx.SourceHash, "newRPCTransaction().SourceHash = %v, want %v", got.SourceHash, tx.SourceHash) + require.Equal(t, *got.IsSystemTx, tx.IsSystemTransaction, "newRPCTransaction().IsSystemTx = %v, want %v", got.IsSystemTx, tx.IsSystemTransaction) require.Equal(t, got.Mint, (*hexutil.Big)(tx.Mint.ToBig()), "newRPCTransaction().Mint = %v, want %v", got.Mint, tx.Mint.ToBig()) require.Equal(t, got.Nonce, (hexutil.Uint64)(nonce), "newRPCTransaction().Nonce = %v, want %v", got.Nonce, nonce) require.Equal(t, *got.DepositReceiptVersion, (hexutil.Uint64(version)), "newRPCTransaction().DepositReceiptVersion = %v, want %v", *got.DepositReceiptVersion, version) @@ -77,12 +76,11 @@ func TestNewRPCTransactionDepositTxWithVersion(t *testing.T) { func TestNewRPCTransactionOmitIsSystemTxFalse(t *testing.T) { tx := &types.DepositTx{ IsSystemTransaction: false, - From: libcommon.Address{1}, Value: uint256.NewInt(1337), } got := newRPCTransaction(tx, libcommon.Hash{}, uint64(12), uint64(1), big.NewInt(0), nil) - require.False(t, got.IsSystemTx, "should omit IsSystemTx when false") + require.Nil(t, got.IsSystemTx, "should omit IsSystemTx when false") } func TestUnmarshalRpcDepositTx(t *testing.T) { @@ -156,8 +154,7 @@ func TestUnmarshalRpcDepositTx(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { tx := &types.DepositTx{ - SourceHash: libcommon.Hash{1}, - From: libcommon.Address{1}, + SourceHash: libcommon.HexToHash("0x1234"), IsSystemTransaction: true, Mint: uint256.NewInt(34), Value: uint256.NewInt(1337), diff --git a/turbo/engineapi/engine_server.go b/turbo/engineapi/engine_server.go index 97db165c853..8fde4da74d9 100644 --- a/turbo/engineapi/engine_server.go +++ b/turbo/engineapi/engine_server.go @@ -493,20 +493,19 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e headHeader := s.chainRW.GetHeaderByHash(forkchoiceState.HeadHash) - if headHeader.Hash() != forkchoiceState.HeadHash { - // Optimism deviates slightly and allows arbitrary depth re-orgs. - if s.config.Optimism == nil { - // Per Item 2 of https://github.com/ethereum/execution-apis/blob/v1.0.0-alpha.9/src/engine/specification.md#specification-1: - // Client software MAY skip an update of the forkchoice state and - // MUST NOT begin a payload build process if forkchoiceState.headBlockHash doesn't reference a leaf of the block tree. - // That is, the block referenced by forkchoiceState.headBlockHash is neither the head of the canonical chain nor a block at the tip of any other chain. - // In the case of such an event, client software MUST return - // {payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}. - - s.logger.Warn("Skipping payload building because forkchoiceState.headBlockHash is not the head of the canonical chain", - "forkChoice.HeadBlockHash", forkchoiceState.HeadHash, "headHeader.Hash", headHeader.Hash()) - return &engine_types.ForkChoiceUpdatedResponse{PayloadStatus: status}, nil - } + if headHeader.Hash() != forkchoiceState.HeadHash && s.config.Optimism == nil { + // Per Item 2 of https://github.com/ethereum/execution-apis/blob/v1.0.0-alpha.9/src/engine/specification.md#specification-1: + // Client software MAY skip an update of the forkchoice state and + // MUST NOT begin a payload build process if forkchoiceState.headBlockHash doesn't reference a leaf of the block tree. + // That is, the block referenced by forkchoiceState.headBlockHash is neither the head of the canonical chain nor a block at the tip of any other chain. + // In the case of such an event, client software MUST return + // {payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}. + // We skip this check in the Optimism case as Optimism allows arbitrary + // depth re-orgs + + s.logger.Warn("Skipping payload building because forkchoiceState.headBlockHash is not the head of the canonical chain", + "forkChoice.HeadBlockHash", forkchoiceState.HeadHash, "headHeader.Hash", headHeader.Hash()) + return &engine_types.ForkChoiceUpdatedResponse{PayloadStatus: status}, nil } log.Debug("Continuing EngineForkChoiceUpdated", "headNumber", headHeader.Number, "headHash", headHeader.Hash(), "numDeposits", len(payloadAttributes.Transactions)) diff --git a/turbo/engineapi/engine_types/jsonrpc.go b/turbo/engineapi/engine_types/jsonrpc.go index e8248ef0f7f..3032eaeb104 100644 --- a/turbo/engineapi/engine_types/jsonrpc.go +++ b/turbo/engineapi/engine_types/jsonrpc.go @@ -50,9 +50,11 @@ type PayloadAttributes struct { SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` - GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty"` - Transactions []hexutility.Bytes `json:"transactions,omitempty"` - NoTxPool bool `json:"noTxPool,omitempty"` + + // optimism + Transactions []hexutility.Bytes `json:"transactions,omitempty"` + NoTxPool bool `json:"noTxPool,omitempty"` + GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty"` } // TransitionConfiguration represents the correct configurations of the CL and the EL @@ -90,8 +92,10 @@ type GetPayloadResponse struct { ExecutionPayload *ExecutionPayload `json:"executionPayload" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` - ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` ShouldOverrideBuilder bool `json:"shouldOverrideBuilder"` + + // OP-Stack: Ecotone specific fields + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` } type StringifiedError struct{ err error }