Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions ethrpc/ethrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,31 @@ func TestDoRequest_SeqChainHealth(t *testing.T) {
assert.NotEmpty(t, expiresAt)
}

func TestTransactionByHash_Katana(t *testing.T) {
p, err := ethrpc.NewProvider("https://nodes.sequence.app/katana")
require.NoError(t, err)

ctx := context.Background()
txHash := common.HexToHash("0x7777fecc4e53f840f07ce615a3f9e491d1a45c003f1e11a7a0183426f08cc79e")

// This transaction is an OP Stack deposit transaction (type 0x7e) which is
// not supported by the local go-ethereum types. TransactionByHash should
// return ErrTxTypeNotSupported instead of panicking.
_, _, err = p.TransactionByHash(ctx, txHash)
require.Error(t, err)
assert.ErrorIs(t, err, types.ErrTxTypeNotSupported)

// The transaction receipt should still be fetchable since receipt JSON
// unmarshalling does not validate the transaction type.
receipt, err := p.TransactionReceipt(ctx, txHash)
require.NoError(t, err)
require.NotNil(t, receipt)
assert.Equal(t, txHash, receipt.TxHash)
assert.Equal(t, uint64(1), receipt.Status) // success
assert.Greater(t, receipt.BlockNumber.Uint64(), uint64(0))
assert.Equal(t, uint8(0x7e), receipt.Type)
}

func TestFetchBlockWithInvalidVRS(t *testing.T) {
url := "https://rpc.telos.net"
// url := "https://node.mainnet.etherlink.com"
Expand Down
36 changes: 28 additions & 8 deletions ethrpc/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ type rpcBlock struct {
}

type rpcTransaction struct {
tx *types.Transaction
txVRSInvalid bool
tx *types.Transaction
txVRSInvalid bool
txTypeNotSupported bool
txExtraInfo
}

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

// flag unsupported txn type (e.g. OP Stack deposit txns, type 0x7e)
// and nil out tx.tx which has nil inner after the failed unmarshal.
if err == types.ErrTxTypeNotSupported {
tx.txTypeNotSupported = true
tx.tx = nil
}

// we set internal flag to check if txn has invalid VRS signature
if err == types.ErrInvalidSig {
tx.txVRSInvalid = true
Expand Down Expand Up @@ -110,12 +118,10 @@ func IntoBlock(raw json.RawMessage, ret **types.Block, strictness StrictnessLeve
// Fill the sender cache of transactions in the block.
txs := make([]*types.Transaction, 0, len(body.Transactions))
for _, tx := range body.Transactions {
if tx.From != nil {
setSenderFromServer(tx.tx, *tx.From, body.Hash)
}

if strictness >= StrictnessLevel_Semi && tx.txVRSInvalid {
return types.ErrInvalidSig
// Skip transactions with unsupported types (e.g. OP Stack deposit
// txns, type 0x7e) where tx.tx will be nil after unmarshalling.
if tx.tx == nil {
continue
}

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

if strictness >= StrictnessLevel_Semi && tx.txVRSInvalid {
return types.ErrInvalidSig
}

if tx.From != nil {
setSenderFromServer(tx.tx, *tx.From, body.Hash)
}

txs = append(txs, tx.tx)
}

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

// tx will be nil when the transaction type is not supported by the
// local go-ethereum types (e.g. OP Stack deposit txns, type 0x7e).
if body.tx == nil {
return types.ErrTxTypeNotSupported
}

if strictness >= StrictnessLevel_Semi {
if body.txVRSInvalid {
return types.ErrInvalidSig
Expand Down
Loading