fix(txpool): revert duplicated l1 data fee check (#612)

* Revert "fix(tx-pool): consider L1 data fee in validateTx"

This reverts commit 0a5c04b85d0f8b509542306894c03bd3feff65bd.

* simplify veriftfee

* bump version

* address comments

* keep the original behavior

* fix again

* nit

* tweak comments
This commit is contained in:
colin 2024-01-08 20:25:46 +08:00 committed by GitHub
parent 5b7079b3a4
commit 219b84e1af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 59 deletions

View file

@ -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)

View file

@ -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

View file

@ -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
)

View file

@ -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
}