Skip to content

Commit ccf84b9

Browse files
authored
ethrpc: detect unsupported txn type (#200)
1 parent 7906066 commit ccf84b9

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

ethrpc/ethrpc_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,31 @@ func TestDoRequest_SeqChainHealth(t *testing.T) {
318318
assert.NotEmpty(t, expiresAt)
319319
}
320320

321+
func TestTransactionByHash_Katana(t *testing.T) {
322+
p, err := ethrpc.NewProvider("https://nodes.sequence.app/katana")
323+
require.NoError(t, err)
324+
325+
ctx := context.Background()
326+
txHash := common.HexToHash("0x7777fecc4e53f840f07ce615a3f9e491d1a45c003f1e11a7a0183426f08cc79e")
327+
328+
// This transaction is an OP Stack deposit transaction (type 0x7e) which is
329+
// not supported by the local go-ethereum types. TransactionByHash should
330+
// return ErrTxTypeNotSupported instead of panicking.
331+
_, _, err = p.TransactionByHash(ctx, txHash)
332+
require.Error(t, err)
333+
assert.ErrorIs(t, err, types.ErrTxTypeNotSupported)
334+
335+
// The transaction receipt should still be fetchable since receipt JSON
336+
// unmarshalling does not validate the transaction type.
337+
receipt, err := p.TransactionReceipt(ctx, txHash)
338+
require.NoError(t, err)
339+
require.NotNil(t, receipt)
340+
assert.Equal(t, txHash, receipt.TxHash)
341+
assert.Equal(t, uint64(1), receipt.Status) // success
342+
assert.Greater(t, receipt.BlockNumber.Uint64(), uint64(0))
343+
assert.Equal(t, uint8(0x7e), receipt.Type)
344+
}
345+
321346
func TestFetchBlockWithInvalidVRS(t *testing.T) {
322347
url := "https://rpc.telos.net"
323348
// url := "https://node.mainnet.etherlink.com"

ethrpc/unmarshal.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ type rpcBlock struct {
2020
}
2121

2222
type rpcTransaction struct {
23-
tx *types.Transaction
24-
txVRSInvalid bool
23+
tx *types.Transaction
24+
txVRSInvalid bool
25+
txTypeNotSupported bool
2526
txExtraInfo
2627
}
2728

@@ -44,6 +45,13 @@ func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error {
4445
return err
4546
}
4647

48+
// flag unsupported txn type (e.g. OP Stack deposit txns, type 0x7e)
49+
// and nil out tx.tx which has nil inner after the failed unmarshal.
50+
if err == types.ErrTxTypeNotSupported {
51+
tx.txTypeNotSupported = true
52+
tx.tx = nil
53+
}
54+
4755
// we set internal flag to check if txn has invalid VRS signature
4856
if err == types.ErrInvalidSig {
4957
tx.txVRSInvalid = true
@@ -110,12 +118,10 @@ func IntoBlock(raw json.RawMessage, ret **types.Block, strictness StrictnessLeve
110118
// Fill the sender cache of transactions in the block.
111119
txs := make([]*types.Transaction, 0, len(body.Transactions))
112120
for _, tx := range body.Transactions {
113-
if tx.From != nil {
114-
setSenderFromServer(tx.tx, *tx.From, body.Hash)
115-
}
116-
117-
if strictness >= StrictnessLevel_Semi && tx.txVRSInvalid {
118-
return types.ErrInvalidSig
121+
// Skip transactions with unsupported types (e.g. OP Stack deposit
122+
// txns, type 0x7e) where tx.tx will be nil after unmarshalling.
123+
if tx.tx == nil {
124+
continue
119125
}
120126

121127
if tx.txExtraInfo.TxType != "" {
@@ -130,6 +136,14 @@ func IntoBlock(raw json.RawMessage, ret **types.Block, strictness StrictnessLeve
130136
}
131137
}
132138

139+
if strictness >= StrictnessLevel_Semi && tx.txVRSInvalid {
140+
return types.ErrInvalidSig
141+
}
142+
143+
if tx.From != nil {
144+
setSenderFromServer(tx.tx, *tx.From, body.Hash)
145+
}
146+
133147
txs = append(txs, tx.tx)
134148
}
135149

@@ -170,6 +184,12 @@ func IntoTransactionWithPending(raw json.RawMessage, tx **types.Transaction, pen
170184
return ethereum.NotFound
171185
}
172186

187+
// tx will be nil when the transaction type is not supported by the
188+
// local go-ethereum types (e.g. OP Stack deposit txns, type 0x7e).
189+
if body.tx == nil {
190+
return types.ErrTxTypeNotSupported
191+
}
192+
173193
if strictness >= StrictnessLevel_Semi {
174194
if body.txVRSInvalid {
175195
return types.ErrInvalidSig

0 commit comments

Comments
 (0)