From bfdac6e979c36c645147c18ca1f94ee4d655ecc9 Mon Sep 17 00:00:00 2001 From: geoknee Date: Thu, 23 Jan 2025 13:59:30 +0000 Subject: [PATCH] make e2e test handle pectra --- op-e2e/system/da/eip4844_test.go | 97 ++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/op-e2e/system/da/eip4844_test.go b/op-e2e/system/da/eip4844_test.go index 3ef45788809f..69768816d426 100644 --- a/op-e2e/system/da/eip4844_test.go +++ b/op-e2e/system/da/eip4844_test.go @@ -10,6 +10,7 @@ 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" @@ -17,7 +18,6 @@ import ( "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" @@ -25,6 +25,7 @@ import ( "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" @@ -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 { @@ -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) }