core/types: improve error for too short transaction / receipt encoding (#24256)

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
Justus 2022-03-09 03:44:53 -06:00 committed by GitHub
parent 19c2c60bbe
commit d1f6a9f544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 32 deletions

View File

@ -21,19 +21,19 @@
"error": "transaction type not supported" "error": "transaction type not supported"
}, },
{ {
"error": "rlp: expected List" "error": "typed transaction too short"
}, },
{ {
"error": "rlp: expected List" "error": "typed transaction too short"
}, },
{ {
"error": "rlp: expected List" "error": "typed transaction too short"
}, },
{ {
"error": "rlp: expected List" "error": "typed transaction too short"
}, },
{ {
"error": "rlp: expected List" "error": "typed transaction too short"
}, },
{ {
"error": "rlp: expected input list for types.AccessListTx" "error": "rlp: expected input list for types.AccessListTx"

View File

@ -38,8 +38,7 @@ var (
receiptStatusSuccessfulRLP = []byte{0x01} receiptStatusSuccessfulRLP = []byte{0x01}
) )
// This error is returned when a typed receipt is decoded, but the string is empty. var errShortTypedReceipt = errors.New("typed receipt too short")
var errEmptyTypedReceipt = errors.New("empty typed receipt bytes")
const ( const (
// ReceiptStatusFailed is the status code of a transaction if execution failed. // ReceiptStatusFailed is the status code of a transaction if execution failed.
@ -182,26 +181,13 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
} }
r.Type = LegacyTxType r.Type = LegacyTxType
return r.setFromRLP(dec) return r.setFromRLP(dec)
case kind == rlp.String: default:
// It's an EIP-2718 typed tx receipt. // It's an EIP-2718 typed tx receipt.
b, err := s.Bytes() b, err := s.Bytes()
if err != nil { if err != nil {
return err return err
} }
if len(b) == 0 { return r.decodeTyped(b)
return errEmptyTypedReceipt
}
r.Type = b[0]
if r.Type == AccessListTxType || r.Type == DynamicFeeTxType {
var dec receiptRLP
if err := rlp.DecodeBytes(b[1:], &dec); err != nil {
return err
}
return r.setFromRLP(dec)
}
return ErrTxTypeNotSupported
default:
return rlp.ErrExpectedList
} }
} }
@ -224,8 +210,8 @@ func (r *Receipt) UnmarshalBinary(b []byte) error {
// decodeTyped decodes a typed receipt from the canonical format. // decodeTyped decodes a typed receipt from the canonical format.
func (r *Receipt) decodeTyped(b []byte) error { func (r *Receipt) decodeTyped(b []byte) error {
if len(b) == 0 { if len(b) <= 1 {
return errEmptyTypedReceipt return errShortTypedReceipt
} }
switch b[0] { switch b[0] {
case DynamicFeeTxType, AccessListTxType: case DynamicFeeTxType, AccessListTxType:

View File

@ -86,7 +86,7 @@ func TestDecodeEmptyTypedReceipt(t *testing.T) {
input := []byte{0x80} input := []byte{0x80}
var r Receipt var r Receipt
err := rlp.DecodeBytes(input, &r) err := rlp.DecodeBytes(input, &r)
if err != errEmptyTypedReceipt { if err != errShortTypedReceipt {
t.Fatal("wrong error:", err) t.Fatal("wrong error:", err)
} }
} }

View File

@ -37,7 +37,7 @@ var (
ErrInvalidTxType = errors.New("transaction type not valid in this context") ErrInvalidTxType = errors.New("transaction type not valid in this context")
ErrTxTypeNotSupported = errors.New("transaction type not supported") ErrTxTypeNotSupported = errors.New("transaction type not supported")
ErrGasFeeCapTooLow = errors.New("fee cap less than base fee") ErrGasFeeCapTooLow = errors.New("fee cap less than base fee")
errEmptyTypedTx = errors.New("empty typed transaction bytes") errShortTypedTx = errors.New("typed transaction too short")
) )
// Transaction types. // Transaction types.
@ -134,7 +134,7 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
tx.setDecoded(&inner, int(rlp.ListSize(size))) tx.setDecoded(&inner, int(rlp.ListSize(size)))
} }
return err return err
case kind == rlp.String: default:
// It's an EIP-2718 typed TX envelope. // It's an EIP-2718 typed TX envelope.
var b []byte var b []byte
if b, err = s.Bytes(); err != nil { if b, err = s.Bytes(); err != nil {
@ -145,8 +145,6 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
tx.setDecoded(inner, len(b)) tx.setDecoded(inner, len(b))
} }
return err return err
default:
return rlp.ErrExpectedList
} }
} }
@ -174,8 +172,8 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error {
// decodeTyped decodes a typed transaction from the canonical format. // decodeTyped decodes a typed transaction from the canonical format.
func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
if len(b) == 0 { if len(b) <= 1 {
return nil, errEmptyTypedTx return nil, errShortTypedTx
} }
switch b[0] { switch b[0] {
case AccessListTxType: case AccessListTxType:

View File

@ -76,7 +76,7 @@ func TestDecodeEmptyTypedTx(t *testing.T) {
input := []byte{0x80} input := []byte{0x80}
var tx Transaction var tx Transaction
err := rlp.DecodeBytes(input, &tx) err := rlp.DecodeBytes(input, &tx)
if err != errEmptyTypedTx { if err != errShortTypedTx {
t.Fatal("wrong error:", err) t.Fatal("wrong error:", err)
} }
} }