Skip to content

Commit 0ef2d6a

Browse files
committed
fix: Fix parsing of legacy transactions without chain ID
Newer go-ethereum versions reject a zero `chainID` in `LatestSignerForChainID`. For legacy transactions without a chain ID, we now correctly pass `nil`.
1 parent 318aa53 commit 0ef2d6a

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

indexer/utils.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,14 @@ func blockToModels(
149149
for idx, ethTx := range transactions {
150150
ethTxHex := ethTx.Hash().Hex()
151151
v, r, s := ethTx.RawSignatureValues()
152-
signer := ethtypes.LatestSignerForChainID(ethTx.ChainId())
152+
chainID := ethTx.ChainId()
153+
if chainID != nil && chainID.Cmp(big.NewInt(0)) == 0 {
154+
// Legacy transactions don't have a chain ID but `ChainId()` returns 0, which is invalid
155+
// for `LatestSignerForChainId` which expects a null in that case (zero causes a panic).
156+
// https://github.com/ethereum/go-ethereum/issues/31653
157+
chainID = nil
158+
}
159+
signer := ethtypes.LatestSignerForChainID(chainID)
153160
from, _ := signer.Sender(ethTx)
154161
ethAccList := ethTx.AccessList()
155162
accList := make([]model.AccessTuple, 0, len(ethAccList))

tests/rpc/rpc_test.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func call(t *testing.T, method string, params interface{}) *Response {
6363
}
6464

6565
//nolint:unparam
66-
func submitTransaction(ctx context.Context, t *testing.T, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *types.Receipt {
66+
func submitTransaction(ctx context.Context, t *testing.T, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, legacy bool) *types.Receipt {
6767
ec := localClient(t, false)
6868
chainID, err := ec.ChainID(context.Background())
6969
require.NoError(t, err)
@@ -81,9 +81,18 @@ func submitTransaction(ctx context.Context, t *testing.T, to common.Address, amo
8181
data,
8282
)
8383
signer := types.LatestSignerForChainID(chainID)
84+
if legacy {
85+
signer = types.LatestSignerForChainID(nil)
86+
}
8487
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), tests.TestKey1.Private)
8588
require.Nil(t, err, "sign tx")
8689

90+
if legacy {
91+
// Adjust V from {0,1} to {27,28} as required by Ethereum legacy signature format.
92+
// crypto.Sign returns V in {0,1}, but legacy transactions expect V ∈ {27,28}.
93+
signature[64] += 27
94+
}
95+
8796
signedTx, err := tx.WithSignature(signer, signature)
8897
require.Nil(t, err, "pack tx")
8998

@@ -100,7 +109,7 @@ func submitTransaction(ctx context.Context, t *testing.T, to common.Address, amo
100109
func submitTestTransaction(ctx context.Context, t *testing.T) *types.Receipt {
101110
data := common.FromHex("0x7f7465737432000000000000000000000000000000000000000000000000000000600057")
102111
to := common.BytesToAddress(common.FromHex("0x1122334455667788990011223344556677889900"))
103-
return submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data)
112+
return submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data, false)
104113
}
105114

106115
func TestEth_GetBalance(t *testing.T) {
@@ -209,7 +218,15 @@ func TestEth_SendRawTransaction(t *testing.T) {
209218
ctx, cancel := context.WithTimeout(context.Background(), OasisBlockTimeout)
210219
defer cancel()
211220

212-
receipt := submitTransaction(ctx, t, common.Address{1}, big.NewInt(1), GasLimit, GasPrice, nil)
221+
receipt := submitTransaction(ctx, t, common.Address{1}, big.NewInt(1), GasLimit, GasPrice, nil, false)
222+
require.EqualValues(t, 1, receipt.Status)
223+
}
224+
225+
func TestEth_SendRawLegacyTransaction(t *testing.T) {
226+
ctx, cancel := context.WithTimeout(context.Background(), OasisBlockTimeout)
227+
defer cancel()
228+
229+
receipt := submitTransaction(ctx, t, common.Address{1}, big.NewInt(1), GasLimit, GasPrice, nil, true)
213230
require.EqualValues(t, 1, receipt.Status)
214231
}
215232

@@ -328,7 +345,7 @@ func TestEth_GetTransactionByHash(t *testing.T) {
328345
input := "0x7f7465737432000000000000000000000000000000000000000000000000000000600057"
329346
data := common.FromHex(input)
330347
to := common.BytesToAddress(common.FromHex("0x1122334455667788990011223344556677889900"))
331-
receipt := submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data)
348+
receipt := submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data, false)
332349
require.EqualValues(t, 1, receipt.Status)
333350
require.NotNil(t, receipt)
334351

@@ -361,7 +378,7 @@ func TestEth_GetTransactionByBlockAndIndex(t *testing.T) {
361378
input := "0x7f7465737432000000000000000000000000000000000000000000000000000000600057"
362379
data := common.FromHex(input)
363380
to := common.BytesToAddress(common.FromHex("0x1122334455667788990011223344556677889900"))
364-
receipt := submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data)
381+
receipt := submitTransaction(ctx, t, to, big.NewInt(1), GasLimit, GasPrice, data, false)
365382
require.EqualValues(t, 1, receipt.Status)
366383
require.NotNil(t, receipt)
367384

0 commit comments

Comments
 (0)