Skip to content

Commit

Permalink
make e2e test handle pectra
Browse files Browse the repository at this point in the history
  • Loading branch information
geoknee committed Jan 23, 2025
1 parent 0ae7ede commit bfdac6e
Showing 1 changed file with 61 additions and 36 deletions.
97 changes: 61 additions & 36 deletions op-e2e/system/da/eip4844_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ import (

op_e2e "github.com/ethereum-optimism/optimism/op-e2e"

"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
gethutils "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testutils"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -251,56 +252,45 @@ func toIndexedBlobHashes(hs ...common.Hash) []eth.IndexedBlobHash {
// gas price. The L1 blob gas limit is set to a low value to speed up this process.
func TestBatcherAutoDA(t *testing.T) {
op_e2e.InitParallel(t)
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()

// System setup
cfg := e2esys.EcotoneSystemConfig(t, new(hexutil.Uint64))
cfg.DataAvailabilityType = batcherFlags.AutoType
// We set the genesis fee values and block gas limit such that calldata txs are initially cheaper,
// but then drive up the base fee over the coming L1 blocks such that blobs become cheaper again.
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7500))
// 100 blob targets leads to 130_393 starting blob base fee, which is ~ 16 * 8_150
// but then manipulate the fee markets over the coming L1 blocks such that blobs become cheaper again.
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(3100))
// 100 blob targets leads to 130_393 starting blob base fee, which is ~ 42 * 2_000 (equilibrium is ~16x or ~40x under Pectra)
cfg.DeployConfig.L1GenesisBlockExcessBlobGas = (*hexutil.Uint64)(u64Ptr(100 * params.BlobTxTargetBlobGasPerBlock))
cfg.DeployConfig.L1GenesisBlockBlobGasUsed = (*hexutil.Uint64)(u64Ptr(0))
cfg.DeployConfig.L1GenesisBlockGasLimit = 2_500_000 // low block gas limit to drive up gas price more quickly
t.Logf("L1BlockTime: %d, L2BlockTime: %d", cfg.DeployConfig.L1BlockTime, cfg.DeployConfig.L2BlockTime)

cfg.DeployConfig.L1GenesisBlockGasLimit = 2_500_000
cfg.BatcherTargetNumFrames = eth.MaxBlobsPerBlobTx

sys, err := cfg.Start(t)
require.NoError(t, err, "Error starting up system")

log := testlog.Logger(t, log.LevelInfo)
log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time)

// Constants
l1Client := sys.NodeClient("l1")

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

ethPrivKey := cfg.Secrets.Alice
depositContract, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
depAmount := big.NewInt(1_000_000_000_000)
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
require.NoError(t, err)
opts.Value = depAmount
fromAddr := cfg.Secrets.Addresses().Alice
const numTxs = 18

// Send deposit transactions in a loop to drive up L1 base fee
depAmount := big.NewInt(1_000_000_000_000)
const numDeps = 3
txs := make([]*types.Transaction, 0, numDeps)
t.Logf("Sending %d deposits...", numDeps)
for i := int64(0); i < numDeps; i++ {
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
// Helpers
mustGetFees := func() (*big.Int, *big.Int, *big.Int, float64) {
tip, baseFee, blobFee, err := txmgr.DefaultGasPriceEstimatorFn(ctx, l1Client)
require.NoError(t, err)
opts.Value = depAmount
opts.Nonce = big.NewInt(i)
depositContract, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)

tx, err := transactions.PadGasEstimate(opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return depositContract.DepositTransaction(opts, fromAddr, depAmount, 1_000_000, false, nil)
})
require.NoErrorf(t, err, "failed to send deposit tx[%d]", i)
t.Logf("Deposit submitted[%d]: tx hash: %v", i, tx.Hash())
txs = append(txs, tx)
feeRatio := float64(blobFee.Int64()) / float64(baseFee.Int64()+tip.Int64())
t.Logf("L1 fees are: baseFee(%d), tip(%d), blobBaseFee(%d). feeRatio: %f", baseFee, tip, blobFee, feeRatio)
return tip, baseFee, blobFee, feeRatio
}
require.Len(t, txs, numDeps)

requireEventualBatcherTxType := func(txType uint8, timeout time.Duration, strict bool) {
var foundOtherTxType bool
require.Eventually(t, func() bool {
Expand All @@ -320,17 +310,52 @@ func TestBatcherAutoDA(t *testing.T) {
}, timeout, time.Second, "expected batcher tx type didn't arrive")
require.False(t, foundOtherTxType, "unexpected batcher tx type found")
}

// Check markets are set up as expected.
_, _, _, feeRatio := mustGetFees()
require.Greater(t, feeRatio, 41.0, "expected feeRatio to be greater than 41 (calldata should be cheaper, even with Pectra)")

// Market manipulations:
// Send deposit transactions in a loop to shore up L1 base fee
// as blobBaseFee drops (batcher uses calldata initially so the blob market is quiet).
txs := make([]*types.Transaction, 0, numTxs)
t.Logf("Sending %d l1 txs...", numTxs)
for i := int64(0); i < numTxs; i++ {
opts.Nonce = big.NewInt(i)
tx, err := transactions.PadGasEstimate(opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return depositContract.DepositTransaction(opts, fromAddr, depAmount, 800_000, false, nil)
})
require.NoErrorf(t, err, "failed to send deposit tx[%d]", i)
t.Logf("Deposit submitted[%d]: tx hash: %v", i, tx.Hash())
txs = append(txs, tx)
}

// At this point, we didn't wait on any blocks yet, so we can check that
// the first batcher tx used calldata.
requireEventualBatcherTxType(types.DynamicFeeTxType, 8*time.Second, true)

t.Logf("Confirming %d deposits on L1...", numDeps)
// Now wait for txs to confirm on L1:
t.Logf("Confirming %d txs on L1...", numTxs)
blockNum := 0
for i, tx := range txs {
rec, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash())
require.NoErrorf(t, err, "Waiting for deposit[%d] tx on L1", i)
t.Logf("Deposit confirmed[%d]: L1 block num: %v, gas used: %d", i, rec.BlockNumber, rec.GasUsed)
require.NoErrorf(t, err, "Waiting for tx[%d] on L1", i)
t.Logf("Tx confirmed[%d]: L1 block num: %v, gas used: %d", i, rec.BlockNumber, rec.GasUsed)
if rec.BlockNumber.Int64() > int64(blockNum) {
blockNum++
block, err := l1Client.BlockByNumber(ctx, rec.BlockNumber)
require.NoError(t, err)
t.Logf("gas used %d/%d", block.GasUsed(), block.GasLimit())
_, _, _, feeRatio = mustGetFees()
if feeRatio < 16.0 {
break
}
}
}

// Check we managed to manipulate the markets correctly.
require.Less(t, feeRatio, 16.0, "expected fee ratio to be less than 16 (blobspace should be cheaper, even without Pectra)")

// Now wait for batcher to have switched to blob txs.
requireEventualBatcherTxType(types.BlobTxType, 8*time.Second, false)
}
Expand Down

0 comments on commit bfdac6e

Please sign in to comment.