From 9ec83a509ac7f6dd2d0beb054eb14c19f3e67a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Mon, 3 Jun 2024 16:24:03 +0200 Subject: [PATCH] fix: use correct encoding for L1 data fee of EIP2718 transactions (#793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: use correct encoding for L1 data fee of EIP2718 transactions * add tests * lint * Update rollup/fees/rollup_fee.go Co-authored-by: Ömer Faruk Irmak --------- Co-authored-by: Ömer Faruk Irmak --- core/types/transaction.go | 1 - core/types/transaction_test.go | 38 ++++++++++++++++++++++++++++++++-- params/version.go | 2 +- rollup/fees/rollup_fee.go | 22 ++++++++------------ 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index 12b6ecc47f..875ed8e622 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -40,7 +40,6 @@ var ( ErrInvalidTxType = errors.New("transaction type not valid in this context") ErrTxTypeNotSupported = errors.New("transaction type not supported") ErrGasFeeCapTooLow = errors.New("fee cap less than base fee") - errEmptyTypedTx = errors.New("empty typed transaction bytes") errShortTypedTx = errors.New("typed transaction too short") errInvalidYParity = errors.New("'yParity' field must be 0 or 1") errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match") diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 417bc546f7..60ef48aa46 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -78,7 +78,7 @@ func TestDecodeEmptyTypedTx(t *testing.T) { input := []byte{0x80} var tx Transaction err := rlp.DecodeBytes(input, &tx) - if err != errEmptyTypedTx { + if err != errShortTypedTx { t.Fatal("wrong error:", err) } } @@ -94,11 +94,33 @@ func TestTransactionSigHash(t *testing.T) { } func TestTransactionEncode(t *testing.T) { + should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3") + + // EncodeToBytes txb, err := rlp.EncodeToBytes(rightvrsTx) if err != nil { t.Fatalf("encode error: %v", err) } - should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3") + if !bytes.Equal(txb, should) { + t.Errorf("encoded RLP mismatch, got %x", txb) + } + + // tx.EncodeRLP + raw := new(bytes.Buffer) + err = rightvrsTx.EncodeRLP(raw) + if err != nil { + t.Fatalf("encode error: %v", err) + } + txb = raw.Bytes() + if !bytes.Equal(txb, should) { + t.Errorf("encoded RLP mismatch, got %x", txb) + } + + // tx.MarshalBinary + txb, err = rightvrsTx.MarshalBinary() + if err != nil { + t.Fatalf("encode error: %v", err) + } if !bytes.Equal(txb, should) { t.Errorf("encoded RLP mismatch, got %x", txb) } @@ -194,6 +216,7 @@ func TestEIP2930Signer(t *testing.T) { func TestEIP2718TransactionEncode(t *testing.T) { // RLP representation { + // rlp.EncodeToBytes have, err := rlp.EncodeToBytes(signedEip2718Tx) if err != nil { t.Fatalf("encode error: %v", err) @@ -202,6 +225,17 @@ func TestEIP2718TransactionEncode(t *testing.T) { if !bytes.Equal(have, want) { t.Errorf("encoded RLP mismatch, got %x", have) } + + // tx.EncodeRLP + raw := new(bytes.Buffer) + err = signedEip2718Tx.EncodeRLP(raw) + if err != nil { + t.Fatalf("encode error: %v", err) + } + have = raw.Bytes() + if !bytes.Equal(have, want) { + t.Errorf("encoded RLP mismatch, got %x", have) + } } // Binary representation { diff --git a/params/version.go b/params/version.go index 26ff900c37..766652cc48 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 33 // Patch version component of the current release + VersionPatch = 34 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/fees/rollup_fee.go b/rollup/fees/rollup_fee.go index 7eb1109394..9df6c215c5 100644 --- a/rollup/fees/rollup_fee.go +++ b/rollup/fees/rollup_fee.go @@ -2,6 +2,7 @@ package fees import ( "bytes" + "math" "math/big" "github.com/scroll-tech/go-ethereum/common" @@ -40,7 +41,6 @@ type Message interface { // required to compute the L1 fee type StateDB interface { GetState(common.Address, common.Hash) common.Hash - GetBalance(addr common.Address) *big.Int } type gpoState struct { @@ -64,7 +64,7 @@ func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.C return nil, err } - raw, err := rlpEncode(tx) + raw, err := tx.MarshalBinary() if err != nil { return nil, err } @@ -133,16 +133,6 @@ func asUnsignedDynamicTx(msg Message, chainID *big.Int) *types.Transaction { }) } -// rlpEncode RLP encodes the transaction into bytes -func rlpEncode(tx *types.Transaction) ([]byte, error) { - raw := new(bytes.Buffer) - if err := tx.EncodeRLP(raw); err != nil { - return nil, err - } - - return raw.Bytes(), nil -} - func readGPOStorageSlots(addr common.Address, state StateDB) gpoState { var gpoState gpoState gpoState.l1BaseFee = state.GetState(addr, rcfg.L1BaseFeeSlot).Big() @@ -216,7 +206,7 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.Cha return big.NewInt(0), nil } - raw, err := rlpEncode(tx) + raw, err := tx.MarshalBinary() if err != nil { return nil, err } @@ -231,6 +221,12 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.Cha l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar) } + // ensure l1DataFee fits into uint64 for circuit compatibility + // (note: in practice this value should never be this big) + if !l1DataFee.IsUint64() { + l1DataFee.SetUint64(math.MaxUint64) + } + return l1DataFee, nil }