From 7e6b814717f69f17e89573f438ed3a639ee307cc Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Mon, 22 Apr 2024 10:26:44 +0100 Subject: [PATCH 01/15] Move tx marshalling to own file as much as possible --- core/types/celo_transaction_marshalling.go | 101 +++++++++++++++++++++ core/types/transaction_marshalling.go | 81 ++--------------- 2 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 core/types/celo_transaction_marshalling.go diff --git a/core/types/celo_transaction_marshalling.go b/core/types/celo_transaction_marshalling.go new file mode 100644 index 0000000000..2614e462e4 --- /dev/null +++ b/core/types/celo_transaction_marshalling.go @@ -0,0 +1,101 @@ +package types + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +func celoTransactionMarshal(tx *Transaction) ([]byte, bool, error) { + var enc txJSON + // These are set for all tx types. + enc.Hash = tx.Hash() + enc.Type = hexutil.Uint64(tx.Type()) + switch itx := tx.inner.(type) { + case *CeloDynamicFeeTx: + enc.ChainID = (*hexutil.Big)(itx.ChainID) + enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) + enc.To = tx.To() + enc.Gas = (*hexutil.Uint64)(&itx.Gas) + enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap) + enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap) + enc.FeeCurrency = itx.FeeCurrency + enc.Value = (*hexutil.Big)(itx.Value) + enc.Input = (*hexutil.Bytes)(&itx.Data) + enc.AccessList = &itx.AccessList + enc.V = (*hexutil.Big)(itx.V) + enc.R = (*hexutil.Big)(itx.R) + enc.S = (*hexutil.Big)(itx.S) + default: + return nil, false, nil + } + bytes, err := json.Marshal(&enc) + return bytes, true, err +} + +func celoTransactionUnmarshal(dec txJSON, inner *TxData) (bool, error) { + switch dec.Type { + case CeloDynamicFeeTxType: + var itx CeloDynamicFeeTx + *inner = &itx + if dec.ChainID == nil { + return true, errors.New("missing required field 'chainId' in transaction") + } + itx.ChainID = (*big.Int)(dec.ChainID) + if dec.Nonce == nil { + return true, errors.New("missing required field 'nonce' in transaction") + } + itx.Nonce = uint64(*dec.Nonce) + if dec.To != nil { + itx.To = dec.To + } + if dec.Gas == nil { + return true, errors.New("missing required field 'gas' for txdata") + } + itx.Gas = uint64(*dec.Gas) + if dec.MaxPriorityFeePerGas == nil { + return true, errors.New("missing required field 'maxPriorityFeePerGas' for txdata") + } + itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas) + if dec.MaxFeePerGas == nil { + return true, errors.New("missing required field 'maxFeePerGas' for txdata") + } + itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas) + if dec.Value == nil { + return true, errors.New("missing required field 'value' in transaction") + } + itx.FeeCurrency = dec.FeeCurrency + itx.Value = (*big.Int)(dec.Value) + if dec.Input == nil { + return true, errors.New("missing required field 'input' in transaction") + } + itx.Data = *dec.Input + if dec.V == nil { + return true, errors.New("missing required field 'v' in transaction") + } + if dec.AccessList != nil { + itx.AccessList = *dec.AccessList + } + itx.V = (*big.Int)(dec.V) + if dec.R == nil { + return true, errors.New("missing required field 'r' in transaction") + } + itx.R = (*big.Int)(dec.R) + if dec.S == nil { + return true, errors.New("missing required field 's' in transaction") + } + itx.S = (*big.Int)(dec.S) + withSignature := itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 + if withSignature { + if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil { + return true, err + } + } + default: + return false, nil + } + + return true, nil +} diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index b800f524e9..3b68418d86 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -90,6 +90,9 @@ func (tx *txJSON) yParityValue() (*big.Int, error) { // MarshalJSON marshals as JSON with a hash. func (tx *Transaction) MarshalJSON() ([]byte, error) { + if marshalled, isCelo, err := celoTransactionMarshal(tx); isCelo { + return marshalled, err + } var enc txJSON // These are set for all tx types. enc.Hash = tx.Hash() @@ -142,21 +145,6 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { yparity := itx.V.Uint64() enc.YParity = (*hexutil.Uint64)(&yparity) - case *CeloDynamicFeeTx: - enc.ChainID = (*hexutil.Big)(itx.ChainID) - enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) - enc.To = tx.To() - enc.Gas = (*hexutil.Uint64)(&itx.Gas) - enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap) - enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap) - enc.FeeCurrency = tx.FeeCurrency() - enc.Value = (*hexutil.Big)(itx.Value) - enc.Input = (*hexutil.Bytes)(&itx.Data) - enc.AccessList = &itx.AccessList - enc.V = (*hexutil.Big)(itx.V) - enc.R = (*hexutil.Big)(itx.R) - enc.S = (*hexutil.Big)(itx.S) - case *BlobTx: enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig()) enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) @@ -206,6 +194,12 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { // Decode / verify fields according to transaction type. var inner TxData + + if isCelo, err := celoTransactionUnmarshal(dec, &inner); isCelo { + tx.setDecoded(inner, 0) + return err + } + switch dec.Type { case LegacyTxType: var itx LegacyTx @@ -369,63 +363,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { } } - case CeloDynamicFeeTxType: - var itx CeloDynamicFeeTx - inner = &itx - if dec.ChainID == nil { - return errors.New("missing required field 'chainId' in transaction") - } - itx.ChainID = (*big.Int)(dec.ChainID) - if dec.Nonce == nil { - return errors.New("missing required field 'nonce' in transaction") - } - itx.Nonce = uint64(*dec.Nonce) - if dec.To != nil { - itx.To = dec.To - } - if dec.Gas == nil { - return errors.New("missing required field 'gas' for txdata") - } - itx.Gas = uint64(*dec.Gas) - if dec.MaxPriorityFeePerGas == nil { - return errors.New("missing required field 'maxPriorityFeePerGas' for txdata") - } - itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas) - if dec.MaxFeePerGas == nil { - return errors.New("missing required field 'maxFeePerGas' for txdata") - } - itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas) - if dec.Value == nil { - return errors.New("missing required field 'value' in transaction") - } - itx.FeeCurrency = dec.FeeCurrency - itx.Value = (*big.Int)(dec.Value) - if dec.Input == nil { - return errors.New("missing required field 'input' in transaction") - } - itx.Data = *dec.Input - if dec.V == nil { - return errors.New("missing required field 'v' in transaction") - } - if dec.AccessList != nil { - itx.AccessList = *dec.AccessList - } - itx.V = (*big.Int)(dec.V) - if dec.R == nil { - return errors.New("missing required field 'r' in transaction") - } - itx.R = (*big.Int)(dec.R) - if dec.S == nil { - return errors.New("missing required field 's' in transaction") - } - itx.S = (*big.Int)(dec.S) - withSignature := itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 - if withSignature { - if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil { - return err - } - } - case BlobTxType: var itx BlobTx inner = &itx From 6759fbe44a0d5a953e87b5d6f4ad9dbdca69aa00 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Mon, 22 Apr 2024 13:32:59 +0100 Subject: [PATCH 02/15] Segregate celo transaction types --- core/types/celo_denominated_tx.go | 2 ++ core/types/celo_extensions.go | 6 ++++++ core/types/transaction.go | 3 --- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 core/types/celo_extensions.go diff --git a/core/types/celo_denominated_tx.go b/core/types/celo_denominated_tx.go index 977397d650..6b5bbc6a99 100644 --- a/core/types/celo_denominated_tx.go +++ b/core/types/celo_denominated_tx.go @@ -8,6 +8,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) +const CeloDenominatedTxType = 0x7a + type CeloDenominatedTx struct { ChainID *big.Int Nonce uint64 diff --git a/core/types/celo_extensions.go b/core/types/celo_extensions.go new file mode 100644 index 0000000000..f4e6654c3e --- /dev/null +++ b/core/types/celo_extensions.go @@ -0,0 +1,6 @@ +package types + +const ( + // CeloDynamicFeeTxType = 0x7c old Celo tx type with gateway fee + CeloDynamicFeeTxType = 0x7b +) diff --git a/core/types/transaction.go b/core/types/transaction.go index 6db82c6430..d942378e1a 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -50,9 +50,6 @@ const ( AccessListTxType = 0x01 DynamicFeeTxType = 0x02 BlobTxType = 0x03 - // CeloDynamicFeeTxType = 0x7c old Celo tx type with gateway fee - CeloDynamicFeeTxType = 0x7b - CeloDenominatedTxType = 0x7a ) // Transaction is an Ethereum transaction. From 2cc092d006fd96b82c15179a0e53c6c685aa160f Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Mon, 22 Apr 2024 11:55:08 +0100 Subject: [PATCH 03/15] Remove feeCurrency notion from op code --- core/types/celo_denominated_tx.go | 4 ---- core/types/celo_dynamic_fee_tx.go | 3 --- core/types/celo_extensions.go | 25 +++++++++++++++++++++++++ core/types/celo_transaction.go | 10 +++++----- core/types/deposit_tx.go | 3 --- core/types/transaction.go | 19 ------------------- core/types/tx_access_list.go | 3 --- core/types/tx_blob.go | 3 --- core/types/tx_dynamic_fee.go | 3 --- core/types/tx_legacy.go | 3 --- 10 files changed, 30 insertions(+), 46 deletions(-) diff --git a/core/types/celo_denominated_tx.go b/core/types/celo_denominated_tx.go index 6b5bbc6a99..21ed9da556 100644 --- a/core/types/celo_denominated_tx.go +++ b/core/types/celo_denominated_tx.go @@ -117,7 +117,3 @@ func (tx *CeloDenominatedTx) encode(b *bytes.Buffer) error { func (tx *CeloDenominatedTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } - -func (tx *CeloDenominatedTx) feeCurrency() *common.Address { return tx.FeeCurrency } - -func (tx *CeloDenominatedTx) maxFeeInFeeCurrency() *big.Int { return tx.MaxFeeInFeeCurrency } diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx.go index 800addd11e..bf92a6f1d9 100644 --- a/core/types/celo_dynamic_fee_tx.go +++ b/core/types/celo_dynamic_fee_tx.go @@ -113,6 +113,3 @@ func (tx *CeloDynamicFeeTx) encode(b *bytes.Buffer) error { func (tx *CeloDynamicFeeTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } - -func (tx *CeloDynamicFeeTx) feeCurrency() *common.Address { return tx.FeeCurrency } -func (tx *CeloDynamicFeeTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/celo_extensions.go b/core/types/celo_extensions.go index f4e6654c3e..f1a535da4d 100644 --- a/core/types/celo_extensions.go +++ b/core/types/celo_extensions.go @@ -1,6 +1,31 @@ package types +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + const ( // CeloDynamicFeeTxType = 0x7c old Celo tx type with gateway fee CeloDynamicFeeTxType = 0x7b ) + +// Returns the fee currency of the transaction if there is one. +func (tx *Transaction) FeeCurrency() *common.Address { + var feeCurrency *common.Address + switch t := tx.inner.(type) { + case *CeloDynamicFeeTx: + feeCurrency = t.FeeCurrency + } + return feeCurrency +} + +func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { + var maxFeeInFeeCurrency *big.Int + switch t := tx.inner.(type) { + case *CeloDenominatedTx: + maxFeeInFeeCurrency = t.MaxFeeInFeeCurrency + } + return maxFeeInFeeCurrency +} diff --git a/core/types/celo_transaction.go b/core/types/celo_transaction.go index 9cc79a7c0e..00f8faf987 100644 --- a/core/types/celo_transaction.go +++ b/core/types/celo_transaction.go @@ -17,16 +17,16 @@ func CompareWithRates(a, b *Transaction, ratesAndFees *exchange.RatesAndFees) in } rates := ratesAndFees.Rates if ratesAndFees.HasBaseFee() { - tipA := a.EffectiveGasTipValue(ratesAndFees.GetBaseFeeIn(a.inner.feeCurrency())) - tipB := b.EffectiveGasTipValue(ratesAndFees.GetBaseFeeIn(b.inner.feeCurrency())) - c, _ := exchange.CompareValue(rates, tipA, a.inner.feeCurrency(), tipB, b.inner.feeCurrency()) + tipA := a.EffectiveGasTipValue(ratesAndFees.GetBaseFeeIn(a.FeeCurrency())) + tipB := b.EffectiveGasTipValue(ratesAndFees.GetBaseFeeIn(b.FeeCurrency())) + c, _ := exchange.CompareValue(rates, tipA, a.FeeCurrency(), tipB, b.FeeCurrency()) return c } // Compare fee caps if baseFee is not specified or effective tips are equal feeA := a.inner.gasFeeCap() feeB := b.inner.gasFeeCap() - c, _ := exchange.CompareValue(rates, feeA, a.inner.feeCurrency(), feeB, b.inner.feeCurrency()) + c, _ := exchange.CompareValue(rates, feeA, a.FeeCurrency(), feeB, b.FeeCurrency()) if c != 0 { return c } @@ -34,6 +34,6 @@ func CompareWithRates(a, b *Transaction, ratesAndFees *exchange.RatesAndFees) in // Compare tips if effective tips and fee caps are equal tipCapA := a.inner.gasTipCap() tipCapB := b.inner.gasTipCap() - c, _ = exchange.CompareValue(rates, tipCapA, a.inner.feeCurrency(), tipCapB, b.inner.feeCurrency()) + c, _ = exchange.CompareValue(rates, tipCapA, a.FeeCurrency(), tipCapB, b.FeeCurrency()) return c } diff --git a/core/types/deposit_tx.go b/core/types/deposit_tx.go index bbfec79323..4131ee7af0 100644 --- a/core/types/deposit_tx.go +++ b/core/types/deposit_tx.go @@ -101,6 +101,3 @@ func (tx *DepositTx) encode(b *bytes.Buffer) error { func (tx *DepositTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } - -func (tx *DepositTx) feeCurrency() *common.Address { return nil } -func (tx *DepositTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index d942378e1a..557f663ca0 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -105,10 +105,6 @@ type TxData interface { encode(*bytes.Buffer) error decode([]byte) error - - // Celo specific fields - feeCurrency() *common.Address - maxFeeInFeeCurrency() *big.Int } // EncodeRLP implements rlp.Encoder @@ -624,21 +620,6 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e return &Transaction{inner: cpy, time: tx.time}, nil } -// FeeCurrency returns the fee currency of the transaction. Nil implies paying in CELO. -func (tx *Transaction) FeeCurrency() *common.Address { - return copyAddressPtr(tx.inner.feeCurrency()) -} - -// MaxFeeInFeeCurrency is only used to guard against very quickly changing exchange rates. -// Txs must be discarded if MaxFeeInFeeCurrency is exceeded. -func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { - mfifc := tx.inner.maxFeeInFeeCurrency() - if mfifc == nil { - return nil - } - return new(big.Int).Set(mfifc) -} - // Transactions implements DerivableList for transactions. type Transactions []*Transaction diff --git a/core/types/tx_access_list.go b/core/types/tx_access_list.go index 618b3de863..59880b0eab 100644 --- a/core/types/tx_access_list.go +++ b/core/types/tx_access_list.go @@ -128,6 +128,3 @@ func (tx *AccessListTx) encode(b *bytes.Buffer) error { func (tx *AccessListTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } - -func (tx *AccessListTx) feeCurrency() *common.Address { return nil } -func (tx *AccessListTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index 728cb2b952..ceaeedb20d 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -237,6 +237,3 @@ func (tx *BlobTx) decode(input []byte) error { } return nil } - -func (tx *BlobTx) feeCurrency() *common.Address { return nil } -func (tx *BlobTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go index e23accb299..9c52cde577 100644 --- a/core/types/tx_dynamic_fee.go +++ b/core/types/tx_dynamic_fee.go @@ -124,6 +124,3 @@ func (tx *DynamicFeeTx) encode(b *bytes.Buffer) error { func (tx *DynamicFeeTx) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } - -func (tx *DynamicFeeTx) feeCurrency() *common.Address { return nil } -func (tx *DynamicFeeTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/tx_legacy.go b/core/types/tx_legacy.go index d1489d5292..bcb65c3934 100644 --- a/core/types/tx_legacy.go +++ b/core/types/tx_legacy.go @@ -124,6 +124,3 @@ func (tx *LegacyTx) encode(*bytes.Buffer) error { func (tx *LegacyTx) decode([]byte) error { panic("decode called on LegacyTx)") } - -func (tx *LegacyTx) feeCurrency() *common.Address { return nil } -func (tx *LegacyTx) maxFeeInFeeCurrency() *big.Int { return nil } From efaf9319cd0b87cbd31967897149a66df89ecc04 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Mon, 22 Apr 2024 14:37:37 +0100 Subject: [PATCH 04/15] Seggregate celoDecodeTyped --- core/types/celo_transaction_marshalling.go | 14 ++++++++++++++ core/types/transaction.go | 9 +++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/core/types/celo_transaction_marshalling.go b/core/types/celo_transaction_marshalling.go index 2614e462e4..941b5043ad 100644 --- a/core/types/celo_transaction_marshalling.go +++ b/core/types/celo_transaction_marshalling.go @@ -99,3 +99,17 @@ func celoTransactionUnmarshal(dec txJSON, inner *TxData) (bool, error) { return true, nil } + +func celoDecodeTyped(b []byte) (TxData, bool, error) { + var inner TxData + switch b[0] { + case CeloDynamicFeeTxType: + inner = new(CeloDynamicFeeTx) + case CeloDenominatedTxType: + inner = new(CeloDenominatedTx) + default: + return nil, false, nil + } + err := inner.decode(b[1:]) + return inner, true, err +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 557f663ca0..63f313734f 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -203,16 +203,17 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { if len(b) <= 1 { return nil, errShortTypedTx } + + if inner, isCelo, err := celoDecodeTyped(b); isCelo { + return inner, err + } + var inner TxData switch b[0] { case AccessListTxType: inner = new(AccessListTx) case DynamicFeeTxType: inner = new(DynamicFeeTx) - case CeloDynamicFeeTxType: - inner = new(CeloDynamicFeeTx) - case CeloDenominatedTxType: - inner = new(CeloDenominatedTx) case BlobTxType: inner = new(BlobTx) case DepositTxType: From f37bc674659d1b0ffa3d6b6c6eea31549fd9abb7 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 14:28:30 +0100 Subject: [PATCH 05/15] Rename the celo tx type to match celo blockchain Since we will be supporting decoding and encoding all old celo tx types in op-geth we may as well use the same naming. --- accounts/external/backend.go | 2 +- core/blockchain_celo_test.go | 2 +- core/state_processor.go | 2 +- core/state_transition.go | 2 +- core/txpool/legacypool/celo_list_test.go | 2 +- core/txpool/legacypool/legacypool.go | 4 +-- core/types/celo_dynamic_fee_tx.go | 42 +++++++++++----------- core/types/celo_extensions.go | 6 ++-- core/types/celo_transaction_marshalling.go | 10 +++--- core/types/celo_transaction_signing.go | 6 ++-- core/types/receipt.go | 12 +++---- core/types/receipt_test.go | 4 +-- internal/ethapi/api.go | 2 +- internal/ethapi/api_test.go | 4 +-- internal/ethapi/transaction_args.go | 2 +- 15 files changed, 51 insertions(+), 51 deletions(-) diff --git a/accounts/external/backend.go b/accounts/external/backend.go index 49b5f2e934..28c6dccabb 100644 --- a/accounts/external/backend.go +++ b/accounts/external/backend.go @@ -215,7 +215,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio switch tx.Type() { case types.LegacyTxType, types.AccessListTxType: args.GasPrice = (*hexutil.Big)(tx.GasPrice()) - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDenominatedTxType: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) default: diff --git a/core/blockchain_celo_test.go b/core/blockchain_celo_test.go index 7775b88188..f2185b7111 100644 --- a/core/blockchain_celo_test.go +++ b/core/blockchain_celo_test.go @@ -77,7 +77,7 @@ func testNativeTransferWithFeeCurrency(t *testing.T, scheme string, feeCurrencyA _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) - txdata := &types.CeloDynamicFeeTx{ + txdata := &types.CeloDynamicFeeTxV2{ ChainID: gspec.Config.ChainID, Nonce: 0, To: &aa, diff --git a/core/state_processor.go b/core/state_processor.go index bc50b2f294..e34dbbd556 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -153,7 +153,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta *receipt.DepositReceiptVersion = types.CanyonDepositReceiptVersion } } - if tx.Type() == types.CeloDynamicFeeTxType { + if tx.Type() == types.CeloDynamicFeeTxV2Type { alternativeBaseFee := evm.Context.BaseFee if msg.FeeCurrency != nil { alternativeBaseFee, err = exchange.ConvertGoldToCurrency(evm.Context.ExchangeRates, msg.FeeCurrency, evm.Context.BaseFee) diff --git a/core/state_transition.go b/core/state_transition.go index bf6aa00591..8b3ad766a9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -212,7 +212,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In } // If baseFee provided, set gasPrice to effectiveGasPrice. if baseFee != nil { - if tx.Type() == types.CeloDynamicFeeTxType { + if tx.Type() == types.CeloDynamicFeeTxV2Type { var err error baseFee, err = exchange.ConvertGoldToCurrency(exchangeRates, msg.FeeCurrency, baseFee) if err != nil { diff --git a/core/txpool/legacypool/celo_list_test.go b/core/txpool/legacypool/celo_list_test.go index 5cba5966b0..31b6741c34 100644 --- a/core/txpool/legacypool/celo_list_test.go +++ b/core/txpool/legacypool/celo_list_test.go @@ -11,7 +11,7 @@ import ( ) func txC(nonce int, feeCap int, tipCap int, gas int, currency *common.Address) *types.Transaction { - return types.NewTx(&types.CeloDynamicFeeTx{ + return types.NewTx(&types.CeloDynamicFeeTxV2{ GasFeeCap: big.NewInt(int64(feeCap)), GasTipCap: big.NewInt(int64(tipCap)), FeeCurrency: currency, diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 7abd75203a..0facd29673 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -290,7 +290,7 @@ func New(config Config, chain BlockChain) *LegacyPool { // pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction. func (pool *LegacyPool) Filter(tx *types.Transaction) bool { switch tx.Type() { - case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.CeloDynamicFeeTxType: + case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.CeloDynamicFeeTxV2Type: return true default: return false @@ -642,7 +642,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, - types.CeloDynamicFeeTxType), + types.CeloDynamicFeeTxV2Type), MaxSize: txMaxSize, MinTip: pool.gasTip.Load().ToBig(), EffectiveGasCeil: pool.config.EffectiveGasCeil, diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx.go index bf92a6f1d9..6757ef1efc 100644 --- a/core/types/celo_dynamic_fee_tx.go +++ b/core/types/celo_dynamic_fee_tx.go @@ -10,8 +10,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -// CeloDynamicFeeTx represents a CIP-64 transaction. -type CeloDynamicFeeTx struct { +// CeloDynamicFeeTxV2 represents a CIP-64 transaction. +type CeloDynamicFeeTxV2 struct { ChainID *big.Int Nonce uint64 GasTipCap *big.Int @@ -31,8 +31,8 @@ type CeloDynamicFeeTx struct { } // copy creates a deep copy of the transaction data and initializes all fields. -func (tx *CeloDynamicFeeTx) copy() TxData { - cpy := &CeloDynamicFeeTx{ +func (tx *CeloDynamicFeeTxV2) copy() TxData { + cpy := &CeloDynamicFeeTxV2{ Nonce: tx.Nonce, To: copyAddressPtr(tx.To), Data: common.CopyBytes(tx.Data), @@ -74,20 +74,20 @@ func (tx *CeloDynamicFeeTx) copy() TxData { } // accessors for innerTx. -func (tx *CeloDynamicFeeTx) txType() byte { return CeloDynamicFeeTxType } -func (tx *CeloDynamicFeeTx) chainID() *big.Int { return tx.ChainID } -func (tx *CeloDynamicFeeTx) accessList() AccessList { return tx.AccessList } -func (tx *CeloDynamicFeeTx) data() []byte { return tx.Data } -func (tx *CeloDynamicFeeTx) gas() uint64 { return tx.Gas } -func (tx *CeloDynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } -func (tx *CeloDynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } -func (tx *CeloDynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } -func (tx *CeloDynamicFeeTx) value() *big.Int { return tx.Value } -func (tx *CeloDynamicFeeTx) nonce() uint64 { return tx.Nonce } -func (tx *CeloDynamicFeeTx) to() *common.Address { return tx.To } -func (tx *CeloDynamicFeeTx) isSystemTx() bool { return false } +func (tx *CeloDynamicFeeTxV2) txType() byte { return CeloDynamicFeeTxV2Type } +func (tx *CeloDynamicFeeTxV2) chainID() *big.Int { return tx.ChainID } +func (tx *CeloDynamicFeeTxV2) accessList() AccessList { return tx.AccessList } +func (tx *CeloDynamicFeeTxV2) data() []byte { return tx.Data } +func (tx *CeloDynamicFeeTxV2) gas() uint64 { return tx.Gas } +func (tx *CeloDynamicFeeTxV2) gasFeeCap() *big.Int { return tx.GasFeeCap } +func (tx *CeloDynamicFeeTxV2) gasTipCap() *big.Int { return tx.GasTipCap } +func (tx *CeloDynamicFeeTxV2) gasPrice() *big.Int { return tx.GasFeeCap } +func (tx *CeloDynamicFeeTxV2) value() *big.Int { return tx.Value } +func (tx *CeloDynamicFeeTxV2) nonce() uint64 { return tx.Nonce } +func (tx *CeloDynamicFeeTxV2) to() *common.Address { return tx.To } +func (tx *CeloDynamicFeeTxV2) isSystemTx() bool { return false } -func (tx *CeloDynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { +func (tx *CeloDynamicFeeTxV2) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { if baseFee == nil { return dst.Set(tx.GasFeeCap) } @@ -98,18 +98,18 @@ func (tx *CeloDynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *b return tip.Add(tip, baseFee) } -func (tx *CeloDynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) { +func (tx *CeloDynamicFeeTxV2) rawSignatureValues() (v, r, s *big.Int) { return tx.V, tx.R, tx.S } -func (tx *CeloDynamicFeeTx) setSignatureValues(chainID, v, r, s *big.Int) { +func (tx *CeloDynamicFeeTxV2) setSignatureValues(chainID, v, r, s *big.Int) { tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s } -func (tx *CeloDynamicFeeTx) encode(b *bytes.Buffer) error { +func (tx *CeloDynamicFeeTxV2) encode(b *bytes.Buffer) error { return rlp.Encode(b, tx) } -func (tx *CeloDynamicFeeTx) decode(input []byte) error { +func (tx *CeloDynamicFeeTxV2) decode(input []byte) error { return rlp.DecodeBytes(input, tx) } diff --git a/core/types/celo_extensions.go b/core/types/celo_extensions.go index f1a535da4d..38ba75bcc8 100644 --- a/core/types/celo_extensions.go +++ b/core/types/celo_extensions.go @@ -7,15 +7,15 @@ import ( ) const ( - // CeloDynamicFeeTxType = 0x7c old Celo tx type with gateway fee - CeloDynamicFeeTxType = 0x7b + // CeloDynamicFeeTxV2Type = 0x7c old Celo tx type with gateway fee + CeloDynamicFeeTxV2Type = 0x7b ) // Returns the fee currency of the transaction if there is one. func (tx *Transaction) FeeCurrency() *common.Address { var feeCurrency *common.Address switch t := tx.inner.(type) { - case *CeloDynamicFeeTx: + case *CeloDynamicFeeTxV2: feeCurrency = t.FeeCurrency } return feeCurrency diff --git a/core/types/celo_transaction_marshalling.go b/core/types/celo_transaction_marshalling.go index 941b5043ad..14e4c0e4fc 100644 --- a/core/types/celo_transaction_marshalling.go +++ b/core/types/celo_transaction_marshalling.go @@ -14,7 +14,7 @@ func celoTransactionMarshal(tx *Transaction) ([]byte, bool, error) { enc.Hash = tx.Hash() enc.Type = hexutil.Uint64(tx.Type()) switch itx := tx.inner.(type) { - case *CeloDynamicFeeTx: + case *CeloDynamicFeeTxV2: enc.ChainID = (*hexutil.Big)(itx.ChainID) enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) enc.To = tx.To() @@ -37,8 +37,8 @@ func celoTransactionMarshal(tx *Transaction) ([]byte, bool, error) { func celoTransactionUnmarshal(dec txJSON, inner *TxData) (bool, error) { switch dec.Type { - case CeloDynamicFeeTxType: - var itx CeloDynamicFeeTx + case CeloDynamicFeeTxV2Type: + var itx CeloDynamicFeeTxV2 *inner = &itx if dec.ChainID == nil { return true, errors.New("missing required field 'chainId' in transaction") @@ -103,8 +103,8 @@ func celoTransactionUnmarshal(dec txJSON, inner *TxData) (bool, error) { func celoDecodeTyped(b []byte) (TxData, bool, error) { var inner TxData switch b[0] { - case CeloDynamicFeeTxType: - inner = new(CeloDynamicFeeTx) + case CeloDynamicFeeTxV2Type: + inner = new(CeloDynamicFeeTxV2) case CeloDenominatedTxType: inner = new(CeloDenominatedTx) default: diff --git a/core/types/celo_transaction_signing.go b/core/types/celo_transaction_signing.go index 1dffdbe408..4a25a94450 100644 --- a/core/types/celo_transaction_signing.go +++ b/core/types/celo_transaction_signing.go @@ -36,7 +36,7 @@ func NewCel2Signer(chainId *big.Int) Signer { } func (s cel2Signer) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != CeloDynamicFeeTxType && tx.Type() != CeloDenominatedTxType { + if tx.Type() != CeloDynamicFeeTxV2Type && tx.Type() != CeloDenominatedTxType { return s.londonSigner.Sender(tx) } V, R, S := tx.RawSignatureValues() @@ -55,7 +55,7 @@ func (s cel2Signer) Equal(s2 Signer) bool { } func (s cel2Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - if tx.Type() != CeloDynamicFeeTxType && tx.Type() != CeloDenominatedTxType { + if tx.Type() != CeloDynamicFeeTxV2Type && tx.Type() != CeloDenominatedTxType { return s.londonSigner.SignatureValues(tx, sig) } @@ -73,7 +73,7 @@ func (s cel2Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.I // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (s cel2Signer) Hash(tx *Transaction) common.Hash { - if tx.Type() == CeloDynamicFeeTxType { + if tx.Type() == CeloDynamicFeeTxV2Type { return prefixedRlpHash( tx.Type(), []interface{}{ diff --git a/core/types/receipt.go b/core/types/receipt.go index 69e143ff8b..5ce8302dd3 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -278,7 +278,7 @@ func (r *Receipt) EncodeRLP(w io.Writer) error { func (r *Receipt) encodeTyped(data *receiptRLP, w *bytes.Buffer) error { w.WriteByte(r.Type) switch r.Type { - case CeloDynamicFeeTxType: + case CeloDynamicFeeTxV2Type: withBaseFee := &celoDynamicReceiptRLP{data.PostStateOrStatus, data.CumulativeGasUsed, data.Bloom, data.Logs, r.BaseFee} return rlp.Encode(w, withBaseFee) case DepositTxType: @@ -362,7 +362,7 @@ func (r *Receipt) decodeTyped(b []byte) error { } r.Type = b[0] return r.setFromRLP(data) - case CeloDynamicFeeTxType: + case CeloDynamicFeeTxV2Type: var data celoDynamicReceiptRLP err := rlp.DecodeBytes(b[1:], &data) if err != nil { @@ -435,7 +435,7 @@ type ReceiptForStorage Receipt func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error { w := rlp.NewEncoderBuffer(_w) outerList := w.List() - if r.Type == CeloDynamicFeeTxType { + if r.Type == CeloDynamicFeeTxV2Type { // Mark receipt as CeloDynamicFee receipt by starting with an empty list listIndex := w.List() w.ListEnd(listIndex) @@ -455,7 +455,7 @@ func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error { w.WriteUint64(*r.DepositReceiptVersion) } } - if r.Type == CeloDynamicFeeTxType { + if r.Type == CeloDynamicFeeTxV2Type { w.WriteBigInt(r.BaseFee) } w.ListEnd(outerList) @@ -576,7 +576,7 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { switch r.Type { case AccessListTxType, DynamicFeeTxType, BlobTxType: rlp.Encode(w, data) - case CeloDynamicFeeTxType: + case CeloDynamicFeeTxV2Type: celoDynamicData := &celoDynamicReceiptRLP{data.PostStateOrStatus, data.CumulativeGasUsed, data.Bloom, data.Logs, r.BaseFee} rlp.Encode(w, celoDynamicData) case DepositTxType: @@ -608,7 +608,7 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu rs[i].Type = txs[i].Type() rs[i].TxHash = txs[i].Hash() // The CeloDynamicFeeTxs set the baseFee in the receipt - if txs[i].Type() != CeloDynamicFeeTxType { + if txs[i].Type() != CeloDynamicFeeTxV2Type { rs[i].EffectiveGasPrice = txs[i].inner.effectiveGasPrice(new(big.Int), baseFee) } else { rs[i].EffectiveGasPrice = txs[i].inner.effectiveGasPrice(new(big.Int), rs[i].BaseFee) diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index 25e468ec86..58c67f3790 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -115,7 +115,7 @@ var ( }, }, BaseFee: new(big.Int).SetUint64(1), - Type: CeloDynamicFeeTxType, + Type: CeloDynamicFeeTxV2Type, } depositReceiptNoNonce = &Receipt{ Status: ReceiptStatusFailed, @@ -1094,7 +1094,7 @@ func TestRoundTripReceiptForStorage(t *testing.T) { require.Equal(t, test.rcpt.Logs, d.Logs) require.Equal(t, test.rcpt.DepositNonce, d.DepositNonce) require.Equal(t, test.rcpt.DepositReceiptVersion, d.DepositReceiptVersion) - if test.rcpt.Type == CeloDynamicFeeTxType { + if test.rcpt.Type == CeloDynamicFeeTxV2Type { require.Equal(t, test.rcpt.EffectiveGasPrice, d.EffectiveGasPrice) } }) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index e67fee25f3..3594bccc10 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1544,7 +1544,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber result.ChainID = (*hexutil.Big)(tx.ChainId()) result.YParity = &yparity - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDenominatedTxType: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: al := tx.AccessList() yparity := hexutil.Uint64(v.Sign()) result.Accesses = &al diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index e8a6449e91..3801d7ac45 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -2314,7 +2314,7 @@ func TestCeloTransaction_RoundTripRpcJSON(t *testing.T) { } func celoTransactionTypes(addr common.Address, config *params.ChainConfig) []types.TxData { return []types.TxData{ - &types.CeloDynamicFeeTx{ + &types.CeloDynamicFeeTxV2{ ChainID: config.ChainID, Nonce: 5, GasTipCap: big.NewInt(6), @@ -2334,7 +2334,7 @@ func celoTransactionTypes(addr common.Address, config *params.ChainConfig) []typ R: big.NewInt(10), S: big.NewInt(11), }, - &types.CeloDynamicFeeTx{ + &types.CeloDynamicFeeTxV2{ ChainID: config.ChainID, Nonce: 5, GasTipCap: big.NewInt(6), diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 34148b6959..7758c966bf 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -556,7 +556,7 @@ func (args *TransactionArgs) toTransaction() *types.Transaction { } if args.FeeCurrency != nil { if args.IsFeeCurrencyDenominated() { - data = &types.CeloDynamicFeeTx{ + data = &types.CeloDynamicFeeTxV2{ To: args.To, ChainID: (*big.Int)(args.ChainID), Nonce: uint64(*args.Nonce), From 9e7d00427a61fef70e72ea2634a0131e9b1bc9d2 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 14:30:10 +0100 Subject: [PATCH 06/15] Move file to match the name --- core/types/{celo_dynamic_fee_tx.go => celo_dynamic_fee_tx_v2.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/types/{celo_dynamic_fee_tx.go => celo_dynamic_fee_tx_v2.go} (100%) diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx_v2.go similarity index 100% rename from core/types/celo_dynamic_fee_tx.go rename to core/types/celo_dynamic_fee_tx_v2.go From 590ffa45891da27695b3630a782b374b19487ad6 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 14:31:33 +0100 Subject: [PATCH 07/15] Move tx type to be next to impl --- core/types/celo_dynamic_fee_tx_v2.go | 2 ++ core/types/celo_extensions.go | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/core/types/celo_dynamic_fee_tx_v2.go b/core/types/celo_dynamic_fee_tx_v2.go index 6757ef1efc..a80399441c 100644 --- a/core/types/celo_dynamic_fee_tx_v2.go +++ b/core/types/celo_dynamic_fee_tx_v2.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) +const CeloDynamicFeeTxV2Type = 0x7b + // CeloDynamicFeeTxV2 represents a CIP-64 transaction. type CeloDynamicFeeTxV2 struct { ChainID *big.Int diff --git a/core/types/celo_extensions.go b/core/types/celo_extensions.go index 38ba75bcc8..ae36832783 100644 --- a/core/types/celo_extensions.go +++ b/core/types/celo_extensions.go @@ -6,11 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" ) -const ( - // CeloDynamicFeeTxV2Type = 0x7c old Celo tx type with gateway fee - CeloDynamicFeeTxV2Type = 0x7b -) - // Returns the fee currency of the transaction if there is one. func (tx *Transaction) FeeCurrency() *common.Address { var feeCurrency *common.Address From f561f7cf3f75db155485ba6f2410d6393de925c7 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 14:32:55 +0100 Subject: [PATCH 08/15] Move functionality to appropriate file --- core/types/celo_extensions.go | 26 -------------------------- core/types/celo_transaction.go | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 core/types/celo_extensions.go diff --git a/core/types/celo_extensions.go b/core/types/celo_extensions.go deleted file mode 100644 index ae36832783..0000000000 --- a/core/types/celo_extensions.go +++ /dev/null @@ -1,26 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -// Returns the fee currency of the transaction if there is one. -func (tx *Transaction) FeeCurrency() *common.Address { - var feeCurrency *common.Address - switch t := tx.inner.(type) { - case *CeloDynamicFeeTxV2: - feeCurrency = t.FeeCurrency - } - return feeCurrency -} - -func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { - var maxFeeInFeeCurrency *big.Int - switch t := tx.inner.(type) { - case *CeloDenominatedTx: - maxFeeInFeeCurrency = t.MaxFeeInFeeCurrency - } - return maxFeeInFeeCurrency -} diff --git a/core/types/celo_transaction.go b/core/types/celo_transaction.go index 00f8faf987..4993adeded 100644 --- a/core/types/celo_transaction.go +++ b/core/types/celo_transaction.go @@ -1,9 +1,31 @@ package types import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/exchange" ) +// Returns the fee currency of the transaction if there is one. +func (tx *Transaction) FeeCurrency() *common.Address { + var feeCurrency *common.Address + switch t := tx.inner.(type) { + case *CeloDynamicFeeTxV2: + feeCurrency = t.FeeCurrency + } + return feeCurrency +} + +func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { + var maxFeeInFeeCurrency *big.Int + switch t := tx.inner.(type) { + case *CeloDenominatedTx: + maxFeeInFeeCurrency = t.MaxFeeInFeeCurrency + } + return maxFeeInFeeCurrency +} + // CompareWithRates compares the effective gas price of two transactions according to the exchange rates and // the base fees in the transactions currencies. func CompareWithRates(a, b *Transaction, ratesAndFees *exchange.RatesAndFees) int { From b65e74b0ed7d117f719a17b05cf9809e4e9f66d6 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 21 Mar 2024 19:36:48 +0000 Subject: [PATCH 09/15] Add support for celo legacy transactions --- core/types/legacy_tx_marshalling.go | 162 ++++++++++++++++++++++++++++ core/types/tx_legacy.go | 26 +++-- 2 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 core/types/legacy_tx_marshalling.go diff --git a/core/types/legacy_tx_marshalling.go b/core/types/legacy_tx_marshalling.go new file mode 100644 index 0000000000..e3551b4f5a --- /dev/null +++ b/core/types/legacy_tx_marshalling.go @@ -0,0 +1,162 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "io" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +var ethCompatibleTxNumFields = 9 + +// ethCompatibleTxRlpList is used for RLP encoding/decoding of eth-compatible transactions. +// As such, it: +// (a) excludes the Celo-only fields, +// (b) doesn't need the Hash or EthCompatible fields, and +// (c) doesn't need the `json` or `gencodec` tags +type ethCompatibleTxRlpList struct { + Nonce uint64 // nonce of sender account + GasPrice *big.Int // wei per gas + Gas uint64 // gas limit + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int // wei amount + Data []byte // contract invocation input data + V, R, S *big.Int // signature values +} + +// celoTxRlpList is used for RLP encoding/decoding of celo transactions. +type celoTxRlpList struct { + Nonce uint64 // nonce of sender account + GasPrice *big.Int // wei per gas + Gas uint64 // gas limit + FeeCurrency *common.Address `rlp:"nil"` // nil means native currency + GatewayFeeRecipient *common.Address `rlp:"nil"` // nil means no gateway fee is paid + GatewayFee *big.Int `rlp:"nil"` + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int // wei amount + Data []byte // contract invocation input data + V, R, S *big.Int // signature values +} + +func toEthCompatibleRlpList(tx LegacyTx) ethCompatibleTxRlpList { + return ethCompatibleTxRlpList{ + Nonce: tx.Nonce, + GasPrice: tx.GasPrice, + Gas: tx.Gas, + To: tx.To, + Value: tx.Value, + Data: tx.Data, + V: tx.V, + R: tx.R, + S: tx.S, + } +} + +func toCeloRlpList(tx LegacyTx) celoTxRlpList { + return celoTxRlpList{ + Nonce: tx.Nonce, + GasPrice: tx.GasPrice, + Gas: tx.Gas, + To: tx.To, + Value: tx.Value, + Data: tx.Data, + V: tx.V, + R: tx.R, + S: tx.S, + + // Celo specific fields + FeeCurrency: tx.FeeCurrency, + GatewayFeeRecipient: tx.GatewayFeeRecipient, + GatewayFee: tx.GatewayFee, + } +} + +func setTxFromEthCompatibleRlpList(tx *LegacyTx, rlplist ethCompatibleTxRlpList) { + tx.Nonce = rlplist.Nonce + tx.GasPrice = rlplist.GasPrice + tx.Gas = rlplist.Gas + tx.To = rlplist.To + tx.Value = rlplist.Value + tx.Data = rlplist.Data + tx.V = rlplist.V + tx.R = rlplist.R + tx.S = rlplist.S + tx.Hash = nil // txdata.Hash is calculated and saved inside tx.Hash() + + // Celo specific fields + tx.FeeCurrency = nil + tx.GatewayFeeRecipient = nil + tx.GatewayFee = big.NewInt(0) + tx.EthCompatible = true +} + +func setTxFromCeloRlpList(tx *LegacyTx, rlplist celoTxRlpList) { + tx.Nonce = rlplist.Nonce + tx.GasPrice = rlplist.GasPrice + tx.Gas = rlplist.Gas + tx.To = rlplist.To + tx.Value = rlplist.Value + tx.Data = rlplist.Data + tx.V = rlplist.V + tx.R = rlplist.R + tx.S = rlplist.S + tx.Hash = nil // txdata.Hash is calculated and saved inside tx.Hash() + + // Celo specific fields + tx.FeeCurrency = rlplist.FeeCurrency + tx.GatewayFeeRecipient = rlplist.GatewayFeeRecipient + tx.GatewayFee = rlplist.GatewayFee + tx.EthCompatible = false +} + +// EncodeRLP implements rlp.Encoder +func (tx *LegacyTx) EncodeRLP(w io.Writer) error { + if tx.EthCompatible { + return rlp.Encode(w, toEthCompatibleRlpList(*tx)) + } else { + return rlp.Encode(w, toCeloRlpList(*tx)) + } +} + +// DecodeRLP implements rlp.Decoder +func (tx *LegacyTx) DecodeRLP(s *rlp.Stream) (err error) { + _, size, _ := s.Kind() + var raw rlp.RawValue + err = s.Decode(&raw) + if err != nil { + return err + } + headerSize := len(raw) - int(size) + numElems, err := rlp.CountValues(raw[headerSize:]) + if err != nil { + return err + } + if numElems == ethCompatibleTxNumFields { + rlpList := ethCompatibleTxRlpList{} + err = rlp.DecodeBytes(raw, &rlpList) + setTxFromEthCompatibleRlpList(tx, rlpList) + } else { + var rlpList celoTxRlpList + err = rlp.DecodeBytes(raw, &rlpList) + setTxFromCeloRlpList(tx, rlpList) + } + + return err +} diff --git a/core/types/tx_legacy.go b/core/types/tx_legacy.go index bcb65c3934..6ca3652724 100644 --- a/core/types/tx_legacy.go +++ b/core/types/tx_legacy.go @@ -25,13 +25,25 @@ import ( // LegacyTx is the transaction data of the original Ethereum transactions. type LegacyTx struct { - Nonce uint64 // nonce of sender account - GasPrice *big.Int // wei per gas - Gas uint64 // gas limit - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int // wei amount - Data []byte // contract invocation input data - V, R, S *big.Int // signature values + Nonce uint64 // nonce of sender account + GasPrice *big.Int // wei per gas + Gas uint64 // gas limit + + // Celo-specific fields + FeeCurrency *common.Address // nil means native currency + GatewayFeeRecipient *common.Address // nil means no gateway fee is paid + GatewayFee *big.Int + + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int // wei amount + Data []byte // contract invocation input data + V, R, S *big.Int // signature values + + // This is only used when marshaling to JSON. + Hash *common.Hash `rlp:"-"` + + // Whether this is an ethereum-compatible transaction (i.e. with FeeCurrency, GatewayFeeRecipient and GatewayFee omitted) + EthCompatible bool `rlp:"-"` } // NewTransaction creates an unsigned legacy transaction. From 441333a49c7de56a17e8e286aa5b34a1a45157af Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 14:39:32 +0100 Subject: [PATCH 10/15] Move content to appropriate file --- core/types/{legacy_tx_marshalling.go => celo_legacy_tx.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/types/{legacy_tx_marshalling.go => celo_legacy_tx.go} (100%) diff --git a/core/types/legacy_tx_marshalling.go b/core/types/celo_legacy_tx.go similarity index 100% rename from core/types/legacy_tx_marshalling.go rename to core/types/celo_legacy_tx.go From 2fd2c74bab2736b7d947e1a9fa090c3baff8a891 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 13 Jun 2024 21:23:44 +0100 Subject: [PATCH 11/15] Reverse eth compatible flag This means most of the existing codebase should work now --- core/types/celo_legacy_tx.go | 10 +++++----- core/types/tx_legacy.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/types/celo_legacy_tx.go b/core/types/celo_legacy_tx.go index e3551b4f5a..e8bb2941d2 100644 --- a/core/types/celo_legacy_tx.go +++ b/core/types/celo_legacy_tx.go @@ -104,7 +104,7 @@ func setTxFromEthCompatibleRlpList(tx *LegacyTx, rlplist ethCompatibleTxRlpList) tx.FeeCurrency = nil tx.GatewayFeeRecipient = nil tx.GatewayFee = big.NewInt(0) - tx.EthCompatible = true + tx.CeloLegacy = false } func setTxFromCeloRlpList(tx *LegacyTx, rlplist celoTxRlpList) { @@ -123,15 +123,15 @@ func setTxFromCeloRlpList(tx *LegacyTx, rlplist celoTxRlpList) { tx.FeeCurrency = rlplist.FeeCurrency tx.GatewayFeeRecipient = rlplist.GatewayFeeRecipient tx.GatewayFee = rlplist.GatewayFee - tx.EthCompatible = false + tx.CeloLegacy = true } // EncodeRLP implements rlp.Encoder func (tx *LegacyTx) EncodeRLP(w io.Writer) error { - if tx.EthCompatible { - return rlp.Encode(w, toEthCompatibleRlpList(*tx)) - } else { + if tx.CeloLegacy { return rlp.Encode(w, toCeloRlpList(*tx)) + } else { + return rlp.Encode(w, toEthCompatibleRlpList(*tx)) } } diff --git a/core/types/tx_legacy.go b/core/types/tx_legacy.go index 6ca3652724..a5e30522b8 100644 --- a/core/types/tx_legacy.go +++ b/core/types/tx_legacy.go @@ -42,8 +42,8 @@ type LegacyTx struct { // This is only used when marshaling to JSON. Hash *common.Hash `rlp:"-"` - // Whether this is an ethereum-compatible transaction (i.e. with FeeCurrency, GatewayFeeRecipient and GatewayFee omitted) - EthCompatible bool `rlp:"-"` + // Whether this is a celo legacy transaction (i.e. with FeeCurrency, GatewayFeeRecipient and GatewayFee) + CeloLegacy bool `rlp:"-"` } // NewTransaction creates an unsigned legacy transaction. From 1949380f374bc768d4f97bfc31fafc7db3dddd36 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Tue, 7 May 2024 18:08:31 +0100 Subject: [PATCH 12/15] Add celo dynamic fee tx This adds the structure and rlp encode/decode functionality but no signing or json marshaling logic because for syncing it may not be required. --- core/types/celo_dynamic_fee_tx.go | 136 +++++++++++++++++++++ core/types/celo_transaction_marshalling.go | 6 +- 2 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 core/types/celo_dynamic_fee_tx.go diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx.go new file mode 100644 index 0000000000..2f88c52107 --- /dev/null +++ b/core/types/celo_dynamic_fee_tx.go @@ -0,0 +1,136 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +const CeloDynamicFeeTxType = 0x7c + +type CeloDynamicFeeTx struct { + ChainID *big.Int + Nonce uint64 + GasTipCap *big.Int + GasFeeCap *big.Int + Gas uint64 + FeeCurrency *common.Address `rlp:"nil"` // nil means native currency + GatewayFeeRecipient *common.Address `rlp:"nil"` // nil means no gateway fee is paid + GatewayFee *big.Int `rlp:"nil"` + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int + Data []byte + AccessList AccessList + + // Signature values + V *big.Int `json:"v" gencodec:"required"` + R *big.Int `json:"r" gencodec:"required"` + S *big.Int `json:"s" gencodec:"required"` +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *CeloDynamicFeeTx) copy() TxData { + cpy := &CeloDynamicFeeTx{ + Nonce: tx.Nonce, + To: copyAddressPtr(tx.To), + Data: common.CopyBytes(tx.Data), + Gas: tx.Gas, + FeeCurrency: copyAddressPtr(tx.FeeCurrency), + GatewayFeeRecipient: copyAddressPtr(tx.GatewayFeeRecipient), + // These are copied below. + AccessList: make(AccessList, len(tx.AccessList)), + GatewayFee: new(big.Int), + Value: new(big.Int), + ChainID: new(big.Int), + GasTipCap: new(big.Int), + GasFeeCap: new(big.Int), + V: new(big.Int), + R: new(big.Int), + S: new(big.Int), + } + copy(cpy.AccessList, tx.AccessList) + if tx.Value != nil { + cpy.Value.Set(tx.Value) + } + if tx.ChainID != nil { + cpy.ChainID.Set(tx.ChainID) + } + if tx.GasTipCap != nil { + cpy.GasTipCap.Set(tx.GasTipCap) + } + if tx.GasFeeCap != nil { + cpy.GasFeeCap.Set(tx.GasFeeCap) + } + if tx.GatewayFee != nil { + cpy.GatewayFee.Set(tx.GatewayFee) + } + if tx.V != nil { + cpy.V.Set(tx.V) + } + if tx.R != nil { + cpy.R.Set(tx.R) + } + if tx.S != nil { + cpy.S.Set(tx.S) + } + return cpy +} + +// accessors for innerTx. +func (tx *CeloDynamicFeeTx) txType() byte { return CeloDynamicFeeTxType } +func (tx *CeloDynamicFeeTx) chainID() *big.Int { return tx.ChainID } +func (tx *CeloDynamicFeeTx) accessList() AccessList { return tx.AccessList } +func (tx *CeloDynamicFeeTx) data() []byte { return tx.Data } +func (tx *CeloDynamicFeeTx) gas() uint64 { return tx.Gas } +func (tx *CeloDynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } +func (tx *CeloDynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } +func (tx *CeloDynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } +func (tx *CeloDynamicFeeTx) value() *big.Int { return tx.Value } +func (tx *CeloDynamicFeeTx) nonce() uint64 { return tx.Nonce } +func (tx *CeloDynamicFeeTx) to() *common.Address { return tx.To } +func (tx *CeloDynamicFeeTx) isSystemTx() bool { return false } + +func (tx *CeloDynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { + if baseFee == nil { + return dst.Set(tx.GasFeeCap) + } + tip := dst.Sub(tx.GasFeeCap, baseFee) + if tip.Cmp(tx.GasTipCap) > 0 { + tip.Set(tx.GasTipCap) + } + return tip.Add(tip, baseFee) +} + +func (tx *CeloDynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V, tx.R, tx.S +} + +func (tx *CeloDynamicFeeTx) setSignatureValues(chainID, v, r, s *big.Int) { + tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s +} + +func (tx *CeloDynamicFeeTx) encode(b *bytes.Buffer) error { + return rlp.Encode(b, tx) +} + +func (tx *CeloDynamicFeeTx) decode(input []byte) error { + return rlp.DecodeBytes(input, tx) +} diff --git a/core/types/celo_transaction_marshalling.go b/core/types/celo_transaction_marshalling.go index 14e4c0e4fc..c1aca38baf 100644 --- a/core/types/celo_transaction_marshalling.go +++ b/core/types/celo_transaction_marshalling.go @@ -103,10 +103,12 @@ func celoTransactionUnmarshal(dec txJSON, inner *TxData) (bool, error) { func celoDecodeTyped(b []byte) (TxData, bool, error) { var inner TxData switch b[0] { - case CeloDynamicFeeTxV2Type: - inner = new(CeloDynamicFeeTxV2) case CeloDenominatedTxType: inner = new(CeloDenominatedTx) + case CeloDynamicFeeTxV2Type: + inner = new(CeloDynamicFeeTxV2) + case CeloDynamicFeeTxType: + inner = new(CeloDynamicFeeTx) default: return nil, false, nil } From 0e32e280af618befa045248811ac18866d54ede0 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Fri, 21 Jun 2024 14:20:54 +0100 Subject: [PATCH 13/15] Add godoc strings for new methods on Transaction --- core/types/celo_transaction.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/types/celo_transaction.go b/core/types/celo_transaction.go index 4993adeded..08d9b0ac12 100644 --- a/core/types/celo_transaction.go +++ b/core/types/celo_transaction.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common/exchange" ) -// Returns the fee currency of the transaction if there is one. +// FeeCurrency returns the fee currency of the transaction if there is one. func (tx *Transaction) FeeCurrency() *common.Address { var feeCurrency *common.Address switch t := tx.inner.(type) { @@ -17,6 +17,7 @@ func (tx *Transaction) FeeCurrency() *common.Address { return feeCurrency } +// MaxFeeInFeeCurrency returns the maximum fee in the fee currency of the transaction if there is one. func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { var maxFeeInFeeCurrency *big.Int switch t := tx.inner.(type) { From bebce87bd3a35198e0fab5732d6d5789c4273d7c Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Fri, 21 Jun 2024 14:49:02 +0100 Subject: [PATCH 14/15] Add/Update copyright notices --- core/types/celo_dynamic_fee_tx.go | 10 +++++----- core/types/celo_dynamic_fee_tx_v2.go | 16 +++++++++++++++- core/types/celo_legacy_tx.go | 10 +++++----- core/types/celo_transaction.go | 16 ++++++++++++++++ core/types/celo_transaction_marshalling.go | 16 ++++++++++++++++ core/types/celo_transaction_signing.go | 10 +++++----- 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx.go index 2f88c52107..f1fab1f4d8 100644 --- a/core/types/celo_dynamic_fee_tx.go +++ b/core/types/celo_dynamic_fee_tx.go @@ -1,18 +1,18 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. +// Copyright 2024 The Celo Authors +// This file is part of the celo library. // -// The go-ethereum library is free software: you can redistribute it and/or modify +// The celo library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// The go-ethereum library is distributed in the hope that it will be useful, +// The celo library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// along with the celo library. If not, see . package types diff --git a/core/types/celo_dynamic_fee_tx_v2.go b/core/types/celo_dynamic_fee_tx_v2.go index a80399441c..45f83a5b70 100644 --- a/core/types/celo_dynamic_fee_tx_v2.go +++ b/core/types/celo_dynamic_fee_tx_v2.go @@ -1,4 +1,18 @@ -// TODO: needs copyright header? +// Copyright 2024 The Celo Authors +// This file is part of the celo library. +// +// The celo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The celo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the celo library. If not, see . package types diff --git a/core/types/celo_legacy_tx.go b/core/types/celo_legacy_tx.go index e8bb2941d2..b1ea042095 100644 --- a/core/types/celo_legacy_tx.go +++ b/core/types/celo_legacy_tx.go @@ -1,18 +1,18 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. +// Copyright 2024 The Celo Authors +// This file is part of the celo library. // -// The go-ethereum library is free software: you can redistribute it and/or modify +// The celo library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// The go-ethereum library is distributed in the hope that it will be useful, +// The celo library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// along with the celo library. If not, see . package types diff --git a/core/types/celo_transaction.go b/core/types/celo_transaction.go index 08d9b0ac12..06dbd52ed4 100644 --- a/core/types/celo_transaction.go +++ b/core/types/celo_transaction.go @@ -1,3 +1,19 @@ +// Copyright 2024 The Celo Authors +// This file is part of the celo library. +// +// The celo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The celo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the celo library. If not, see . + package types import ( diff --git a/core/types/celo_transaction_marshalling.go b/core/types/celo_transaction_marshalling.go index c1aca38baf..109342a366 100644 --- a/core/types/celo_transaction_marshalling.go +++ b/core/types/celo_transaction_marshalling.go @@ -1,3 +1,19 @@ +// Copyright 2024 The Celo Authors +// This file is part of the celo library. +// +// The celo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The celo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the celo library. If not, see . + package types import ( diff --git a/core/types/celo_transaction_signing.go b/core/types/celo_transaction_signing.go index 4a25a94450..0fe6ed3eb4 100644 --- a/core/types/celo_transaction_signing.go +++ b/core/types/celo_transaction_signing.go @@ -1,18 +1,18 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. +// Copyright 2024 The Celo Authors +// This file is part of the celo library. // -// The go-ethereum library is free software: you can redistribute it and/or modify +// The celo library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// The go-ethereum library is distributed in the hope that it will be useful, +// The celo library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// along with the celo library. If not, see . package types From 4a3c7aff1dccd8fb1a72cfe1eb9a7c60307b5954 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Fri, 21 Jun 2024 14:50:56 +0100 Subject: [PATCH 15/15] Renamed to follow the naming convention --- core/types/{celo_legacy_tx.go => celo_tx_legacy.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/types/{celo_legacy_tx.go => celo_tx_legacy.go} (100%) diff --git a/core/types/celo_legacy_tx.go b/core/types/celo_tx_legacy.go similarity index 100% rename from core/types/celo_legacy_tx.go rename to core/types/celo_tx_legacy.go