diff --git a/rpc/jsonrpc/send_transaction.go b/rpc/jsonrpc/send_transaction.go index fa8c6b74257..c50ce3ba06a 100644 --- a/rpc/jsonrpc/send_transaction.go +++ b/rpc/jsonrpc/send_transaction.go @@ -21,7 +21,7 @@ import ( func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { txn, err := types.DecodeWrappedTransaction(encodedTx) if err != nil { - return common.Hash{}, err + return common.Hash{}, &rpc.InvalidParamsError{Message: err.Error()} } // If the transaction fee cap is already specified, ensure the @@ -52,7 +52,7 @@ func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutil.By txnChainId := txn.GetChainID() chainId := cc.ChainID if chainId.Cmp(txnChainId) != 0 { - return common.Hash{}, fmt.Errorf("invalid chain id, expected: %d got: %d", chainId, txnChainId) + return common.Hash{}, &rpc.InvalidParamsError{Message: fmt.Sprintf("invalid chain id, expected: %d got: %d", chainId, txnChainId)} } } diff --git a/rpc/jsonrpc/send_transaction_test.go b/rpc/jsonrpc/send_transaction_test.go index 140798b3a1b..09f7e206943 100644 --- a/rpc/jsonrpc/send_transaction_test.go +++ b/rpc/jsonrpc/send_transaction_test.go @@ -18,6 +18,7 @@ package jsonrpc import ( "bytes" + "errors" "testing" "time" @@ -26,11 +27,13 @@ import ( "github.com/erigontech/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/erigontech/erigon/common" + "github.com/erigontech/erigon/common/hexutil" "github.com/erigontech/erigon/execution/execmodule/execmoduletester" "github.com/erigontech/erigon/execution/protocol/params" "github.com/erigontech/erigon/execution/tests/blockgen" "github.com/erigontech/erigon/execution/types" "github.com/erigontech/erigon/node/gointerfaces/txpoolproto" + "github.com/erigontech/erigon/rpc" "github.com/erigontech/erigon/rpc/rpchelper" "github.com/erigontech/erigon/txnprovider/txpool/txpoolcfg" ) @@ -116,3 +119,32 @@ func TestSendRawTransactionUnprotected(t *testing.T) { require.Equal(expectedTxValue, jsonTx.Value.Uint64()) } } + +func TestSendRawTransaction_InvalidParams_OnMalformedRLP(t *testing.T) { + m := execmoduletester.New(t, execmoduletester.WithTxPool()) + ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m) + txPool := txpoolproto.NewTxpoolClient(conn) + api := newEthApiForTest(newBaseApiForTest(m), m.DB, txPool, nil) + + cases := []struct { + name string + raw string + }{ + {"empty-list", "0xc0"}, + {"truncated-short-list", "0xd4"}, + {"unknown-tx-type", "0x09c0"}, + {"eip4844-truncated-list", "0x03c0"}, + {"eip7702-truncated-list", "0x04c0"}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + require := require.New(t) + _, err := api.SendRawTransaction(ctx, hexutil.MustDecode(tc.raw)) + require.Error(err) + var invalid *rpc.InvalidParamsError + require.True(errors.As(err, &invalid), "expected *rpc.InvalidParamsError, got %T: %v", err, err) + require.Equal(-32602, invalid.ErrorCode(), "want InvalidParams (-32602), got %d (%v)", invalid.ErrorCode(), err) + }) + } +}