diff --git a/core/tx_pool.go b/core/tx_pool.go index af7f5a991d..b1aac93092 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -658,16 +658,25 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if pool.currentState.GetNonce(from) > tx.Nonce() { return ErrNonceTooLow } - // Get L1 data fee in current state - l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState) - if err != nil { - return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) - } + // 1. Check balance >= transaction cost (V + GP * GL) to maintain compatibility with the logic without considering L1 data fee. // Transactor should have enough funds to cover the costs // cost == V + GP * GL - if pool.currentState.GetBalance(from).Cmp(new(big.Int).Add(tx.Cost(), l1DataFee)) < 0 { + if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { return ErrInsufficientFunds } + // 2. If FeeVault is enabled, perform an additional check for L1 data fees. + if pool.chainconfig.Scroll.FeeVaultEnabled() { + // Get L1 data fee in current state + l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState) + if err != nil { + return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) + } + // Transactor should have enough funds to cover the costs + // cost == L1 data fee + V + GP * GL + if b := pool.currentState.GetBalance(from); b.Cmp(new(big.Int).Add(tx.Cost(), l1DataFee)) < 0 { + return errors.New("invalid transaction: insufficient funds for l1fee + gas * price + value") + } + } // Ensure the transaction has more gas than the basic tx fee. intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, pool.shanghai) if err != nil { @@ -698,14 +707,6 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e // the sender is marked as local previously, treat it as the local transaction. isLocal := local || pool.locals.containsTx(tx) - if pool.chainconfig.Scroll.FeeVaultEnabled() { - if err := fees.VerifyFee(pool.signer, tx, pool.currentState); err != nil { - log.Trace("Discarding insufficient l1DataFee transaction", "hash", hash, "err", err) - invalidTxMeter.Mark(1) - return false, err - } - } - // If the transaction fails basic validation, discard it if err := pool.validateTx(tx, isLocal); err != nil { log.Trace("Discarding invalid transaction", "hash", hash, "err", err) diff --git a/light/txpool.go b/light/txpool.go index 1ecd771f7e..d6b697fcbe 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -18,6 +18,7 @@ package light import ( "context" + "errors" "fmt" "math/big" "sync" @@ -377,12 +378,25 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error if tx.Value().Sign() < 0 { return core.ErrNegativeValue } - + // 1. Check balance >= transaction cost (V + GP * GL) to maintain compatibility with the logic without considering L1 data fee. // Transactor should have enough funds to cover the costs // cost == V + GP * GL if b := currentState.GetBalance(from); b.Cmp(tx.Cost()) < 0 { return core.ErrInsufficientFunds } + // 2. If FeeVault is enabled, perform an additional check for L1 data fees. + if pool.config.Scroll.FeeVaultEnabled() { + // Get L1 data fee in current state + l1DataFee, err := fees.CalculateL1DataFee(tx, currentState) + if err != nil { + return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) + } + // Transactor should have enough funds to cover the costs + // cost == L1 data fee + V + GP * GL + if b := currentState.GetBalance(from); b.Cmp(new(big.Int).Add(tx.Cost(), l1DataFee)) < 0 { + return errors.New("invalid transaction: insufficient funds for l1fee + gas * price + value") + } + } // Should supply enough intrinsic gas gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, pool.shanghai) @@ -404,12 +418,6 @@ func (pool *TxPool) add(ctx context.Context, tx *types.Transaction) error { return fmt.Errorf("Known transaction (%x)", hash[:4]) } - if pool.config.Scroll.FeeVaultEnabled() { - if err := fees.VerifyFee(pool.signer, tx, pool.currentState(ctx)); err != nil { - return err - } - } - err := pool.validateTx(ctx, tx) if err != nil { return err diff --git a/params/version.go b/params/version.go index b0051b97eb..43885f6ec9 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 = 1 // Minor version component of the current release - VersionPatch = 10 // Patch version component of the current release + VersionPatch = 11 // 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 6e21042de6..29110a1e9b 100644 --- a/rollup/fees/rollup_fee.go +++ b/rollup/fees/rollup_fee.go @@ -2,8 +2,6 @@ package fees import ( "bytes" - "errors" - "fmt" "math/big" "github.com/scroll-tech/go-ethereum/common" @@ -189,38 +187,3 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error) l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar) return l1DataFee, nil } - -func calculateL2Fee(tx *types.Transaction) *big.Int { - l2GasLimit := new(big.Int).SetUint64(tx.Gas()) - return new(big.Int).Mul(tx.GasPrice(), l2GasLimit) -} - -func VerifyFee(signer types.Signer, tx *types.Transaction, state StateDB) error { - from, err := types.Sender(signer, tx) - if err != nil { - return errors.New("invalid transaction: invalid sender") - } - - balance := state.GetBalance(from) - cost := tx.Value() - - l2Fee := calculateL2Fee(tx) - cost = cost.Add(cost, l2Fee) - if balance.Cmp(cost) < 0 { - return errors.New("invalid transaction: insufficient funds for gas * price + value") - } - - l1DataFee, err := CalculateL1DataFee(tx, state) - if err != nil { - return fmt.Errorf("invalid transaction: %w", err) - } - - cost = cost.Add(cost, l1DataFee) - if balance.Cmp(cost) < 0 { - return errors.New("invalid transaction: insufficient funds for l1fee + gas * price + value") - } - - // TODO: check GasPrice is in an expected range - - return nil -}