From cf697fb61c76d265e4343aa2b2ecbb8e6dcd5257 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:42:03 +0900 Subject: [PATCH] fix: add tx protected check at `eth_sendRawTranasaction` api (#144) * add tx protected check at eth_sendRawTranasaction api * update jsonrpc readme * add test case --- jsonrpc/README.md | 2 +- jsonrpc/backend/tx.go | 5 +++++ jsonrpc/backend/tx_test.go | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/jsonrpc/README.md b/jsonrpc/README.md index dcfa2592..3499a7a0 100644 --- a/jsonrpc/README.md +++ b/jsonrpc/README.md @@ -34,7 +34,7 @@ The ETH JSON-RPC (Remote Procedure Call) is a protocol that allows clients to in | eth | eth_fillTransaction | 🚫 | Fills the defaults (nonce, gas, gasPrice or 1559 fields) on a given unsigned transaction, and returns it to the caller for further processing (signing + broadcast). | | eth | eth_sendTransaction | 🚫 | Creates a new message call transaction or a contract creation if the data field contains code. | | eth | eth_resend | 🚫 | Remove the given transaction from the pool and reinsert it with the new gas price and limit. | -| eth | eth_sendRawTransaction | ✅ | Sends a signed transaction to the network. | +| eth | eth_sendRawTransaction | ✅ | Sends a signed transaction to the network. Only replay-protected (EIP-155) transactions are accepted. | | eth | eth_call | ✅ | Executes a new message call immediately without creating a transaction on the block chain. | | eth | eth_estimateGas | ✅ | Generates an estimate of how much gas is necessary to allow the transaction to complete. | | eth | eth_getBlockByHash | ✅ | Returns information about a block by hash. | diff --git a/jsonrpc/backend/tx.go b/jsonrpc/backend/tx.go index 3fb76e0f..c940d43a 100644 --- a/jsonrpc/backend/tx.go +++ b/jsonrpc/backend/tx.go @@ -29,6 +29,11 @@ func (b *JSONRPCBackend) SendRawTransaction(input hexutil.Bytes) (common.Hash, e return common.Hash{}, err } + if !tx.Protected() { + // Ensure only eip155 signed transactions are submitted if EIP155Required is set. + return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") + } + if err := b.SendTx(tx); err != nil { return common.Hash{}, err } diff --git a/jsonrpc/backend/tx_test.go b/jsonrpc/backend/tx_test.go index 2017c588..d46c33ca 100644 --- a/jsonrpc/backend/tx_test.go +++ b/jsonrpc/backend/tx_test.go @@ -13,6 +13,16 @@ import ( "github.com/stretchr/testify/require" ) +func Test_SendRawTransaction_EIP155(t *testing.T) { + input := setupBackend(t) + + txBz, err := hexutil.Decode("0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222") + require.NoError(t, err) + + _, err = input.backend.SendRawTransaction(txBz) + require.ErrorContains(t, err, "EIP-155") +} + func Test_SendRawTransaction(t *testing.T) { input := setupBackend(t) app, _, backend, addrs, privKeys := input.app, input.addrs, input.backend, input.addrs, input.privKeys