diff --git a/evmrpc/AGENTS.md b/evmrpc/AGENTS.md index f2d2ca8064..7682cceebb 100644 --- a/evmrpc/AGENTS.md +++ b/evmrpc/AGENTS.md @@ -7,6 +7,7 @@ EVM RPCs prefixed by `eth_` and `debug_` on Sei generally follows [Ethereum's sp - **No Uncle** - Sei does not have the concept of uncle blocks, so any endpoint relevant to uncle is not supported. - **No Trie** - Sei does not store states in a trie, so any endpoint relevant to the trie data structure is not supported. - **No PoW** - Sei has never used proof-of-work, so endpoints like `eth_mining` and `eth_hashrate` are not supported. +- **No Blobs** - Sei does not support EIP-4844 blob transactions. `eth_blobBaseFee` is exposed but returns a JSON-RPC error (code -32000, "blobs not supported on this chain") instead of a fee value. ## `sei_` prefixed endpoints Several `eth_` prefixed endpoints have a `sei_` prefixed counterpart. `eth_` endpoints only have visibility into EVM transactions, whereas `sei_` endpoints have visibility into EVM transactions plus Cosmos transactions that have synthetic EVM receipts. diff --git a/evmrpc/info.go b/evmrpc/info.go index ca46f86925..07db5ad9c6 100644 --- a/evmrpc/info.go +++ b/evmrpc/info.go @@ -264,6 +264,26 @@ func (i *InfoAPI) MaxPriorityFeePerGas(ctx context.Context) (fee *hexutil.Big, r return (*hexutil.Big)(feeHist.Reward[0][0].ToInt()), nil } +// ErrCodeBlobsNotSupported is the JSON-RPC error code (-32000) for blob-not-supported errors. +// Matches go-ethereum rpc errcodeDefault (unexported). +const ErrCodeBlobsNotSupported = -32000 + +type ErrBlobsNotSupported struct{} + +func (e *ErrBlobsNotSupported) Error() string { + return "blobs not supported on this chain" +} + +func (e *ErrBlobsNotSupported) ErrorCode() int { + return ErrCodeBlobsNotSupported +} + +func (i *InfoAPI) BlobBaseFee(ctx context.Context) (result *hexutil.Big, returnErr error) { + startTime := time.Now() + defer recordMetricsWithError("eth_BlobBaseFee", i.connectionType, startTime, returnErr) + return nil, &ErrBlobsNotSupported{} +} + func (i *InfoAPI) safeGetBaseFee(targetHeight int64) (res *big.Int) { defer func() { if err := recover(); err != nil { diff --git a/evmrpc/info_test.go b/evmrpc/info_test.go index 9007ac4fdf..8c5656f124 100644 --- a/evmrpc/info_test.go +++ b/evmrpc/info_test.go @@ -180,6 +180,32 @@ func TestMaxPriorityFeePerGas(t *testing.T) { assert.Equal(t, "0x3b9aca00", resObj["result"]) } +func TestBlobBaseFee(t *testing.T) { + Ctx = Ctx.WithBlockHeight(1) + resObj := sendRequestGood(t, "blobBaseFee") + require.Contains(t, resObj, "error", "blobBaseFee should return error (blobs not supported)") + errObj := resObj["error"].(map[string]interface{}) + require.Equal(t, float64(evmrpc.ErrCodeBlobsNotSupported), errObj["code"], "error code should be ErrCodeServerError") + require.Equal(t, "blobs not supported on this chain", errObj["message"]) +} + +func TestBlobBaseFee_Direct(t *testing.T) { + ctxProvider := func(height int64) sdk.Context { + if height == evmrpc.LatestCtxHeight { + return Ctx.WithBlockHeight(MockHeight8) + } + return Ctx.WithBlockHeight(height) + } + api := newInfoAPIWithWatermarks(ctxProvider) + fee, err := api.BlobBaseFee(context.Background()) + require.Error(t, err) + require.Nil(t, fee) + var errWithCode *evmrpc.ErrBlobsNotSupported + require.True(t, errors.As(err, &errWithCode)) + require.Equal(t, evmrpc.ErrCodeBlobsNotSupported, errWithCode.ErrorCode()) + require.Contains(t, err.Error(), "blobs not supported") +} + func TestGasPriceLogic(t *testing.T) { oneGwei := big.NewInt(1000000000) onePointOneGwei := big.NewInt(1100000000) diff --git a/integration_test/evm_module/rpc_io_test/FAILED_TEST_ANALYSIS.md b/integration_test/evm_module/rpc_io_test/FAILED_TEST_ANALYSIS.md index 0fbf76fe5e..b0473750ed 100644 --- a/integration_test/evm_module/rpc_io_test/FAILED_TEST_ANALYSIS.md +++ b/integration_test/evm_module/rpc_io_test/FAILED_TEST_ANALYSIS.md @@ -20,7 +20,7 @@ | debug_getRawHeader | 2 | get-block-n.iox, get-genesis.iox | | debug_getRawReceipts | 2 | get-block-n.iox, get-genesis.iox | | debug_getRawTransaction | 1 | get-tx.iox | -| eth_blobBaseFee | 1 | get-current-blobfee.iox | +| eth_blobBaseFee | 1 | blobs-not-supported-error.iox | | eth_call | 1 | call-callenv-options-eip1559.iox (EIP1559 params; Sei returns error) | | eth_createAccessList | 3 | create-al-abi-revert, create-al-contract-eip1559, create-al-contract (insufficient funds / gas fee) | | eth_estimateGas | 2 | estimate-with-eip4844.iox, estimate-with-eip7702.iox (parse error) | @@ -44,7 +44,7 @@ | debug_getRawHeader | get-block-n, get-genesis | No GetRawHeader | | debug_getRawReceipts | get-block-n, get-genesis | No GetRawReceipts | | debug_getRawTransaction | get-tx.iox | No GetRawTransaction | -| eth_blobBaseFee | get-current-blobfee.iox | Not exposed on eth API | +| eth_blobBaseFee | blobs-not-supported-error.iox | Not exposed on eth API | | eth_newPendingTransactionFilter | newPendingTransactionFilter.iox | No NewPendingTransactionFilter in FilterAPI | | eth_syncing | check-syncing.iox | No Syncing on InfoAPI | diff --git a/integration_test/evm_module/rpc_io_test/RPC_IO_README.md b/integration_test/evm_module/rpc_io_test/RPC_IO_README.md index 512df5fd97..0eae0a99ca 100644 --- a/integration_test/evm_module/rpc_io_test/RPC_IO_README.md +++ b/integration_test/evm_module/rpc_io_test/RPC_IO_README.md @@ -261,7 +261,7 @@ So "seed" = a known-good block (and deploy tx) that the script creates and the r | debug_getRawReceipts | get-block-n.iox | FAIL | Sei | Not implemented | error code=-32601 message="the method debug_getRawReceipts does not exist/is not available" | | debug_getRawReceipts | get-genesis.iox | FAIL | Sei | Not implemented | error code=-32601 message="the method debug_getRawReceipts does not exist/is not available" | | debug_getRawTransaction | get-tx.iox | FAIL | Sei | Not implemented | error code=-32601 message="the method debug_getRawTransaction does not exist/is not available" | -| eth_blobBaseFee | get-current-blobfee.iox | FAIL | Sei | Not implemented | error code=-32601 message="the method eth_blobBaseFee does not exist/is not available" | +| eth_blobBaseFee | blobs-not-supported-error.iox | FAIL | Sei | Not implemented | error code=-32601 message="the method eth_blobBaseFee does not exist/is not available" | | eth_call | call-callenv-options-eip1559.iox | FAIL | Sei | Gas fee issue | error code=-32000 message="max fee per gas less than block base fee" | | eth_createAccessList | create-al-abi-revert.iox | FAIL | Sei | Insufficient funds | error code=-32000 message="insufficient funds for gas * price + value" | | eth_createAccessList | create-al-contract-eip1559.iox | FAIL | Sei | Gas fee issue | error code=-32000 message="max fee per gas less than block base fee" | diff --git a/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/blobs-not-supported-error.iox b/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/blobs-not-supported-error.iox new file mode 100644 index 0000000000..28470a4e0f --- /dev/null +++ b/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/blobs-not-supported-error.iox @@ -0,0 +1,3 @@ +// Sei does not support blobs; eth_blobBaseFee returns -32000 with clear message. +>> {"jsonrpc":"2.0","id":1,"method":"eth_blobBaseFee"} +<< {"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"blobs not supported on this chain"}} diff --git a/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/get-current-blobfee.iox b/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/get-current-blobfee.iox deleted file mode 100644 index 4b9e8cc7b0..0000000000 --- a/integration_test/evm_module/rpc_io_test/testdata/eth_blobBaseFee/get-current-blobfee.iox +++ /dev/null @@ -1,3 +0,0 @@ -// May return result or error depending on blob support. Spec-only: valid response. ->> {"jsonrpc":"2.0","id":1,"method":"eth_blobBaseFee"} -<< {"jsonrpc":"2.0","id":1,"result":"0x"}