Skip to content

Commit

Permalink
op-e2e: Add Batcher AutoDA test
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianst committed Jul 30, 2024
1 parent 032b3d4 commit 9f6fb96
Showing 1 changed file with 101 additions and 0 deletions.
101 changes: 101 additions & 0 deletions op-e2e/eip4844_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"

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/client"
Expand Down Expand Up @@ -228,3 +231,101 @@ func toIndexedBlobHashes(hs ...common.Hash) []eth.IndexedBlobHash {
}
return hashes
}

// TestBatcherAutoDA tests that the batcher with Auto data availability type
// correctly chooses the cheaper Ethereum-DA type (calldata or blobs).
// The L1 chain is set up with a genesis block that has an excess blob gas that leads
// to a slightly higher blob base fee than 16x the regular base fee.
// So in the first few L1 blocks, calldata will be cheaper than blobs.
// We then send a couple of expensive Deposit transactions, which drives up the
// gas price. The L1 blob gas limit is set to a low value to speed up this process.
func TestBatcherAutoDA(t *testing.T) {
InitParallel(t)

cfg := EcotoneSystemConfig(t, &genesisTime)
cfg.DataAvailabilityType = batcherFlags.AutoType
// We set the genesis fee values and block gas limit such that calldata txs are initally 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
cfg.DeployConfig.L1GenesisBlockExcessBlobGas = (*hexutil.Uint64)(u64Ptr(100 * params.BlobTxTargetBlobGasPerBlock)) // TODO
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.BatcherTargetNumFrames = 6

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

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)

l1Client := sys.Clients["l1"]

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

ethPrivKey := cfg.Secrets.Alice
fromAddr := cfg.Secrets.Addresses().Alice

// 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())
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)
}
require.Len(t, txs, numDeps)

requireEventualBatcherTxType := func(txType uint8, timeout time.Duration, strict bool) {
var foundOtherTxType bool
require.Eventually(t, func() bool {
b, err := l1Client.BlockByNumber(ctx, nil)
require.NoError(t, err)
for _, tx := range b.Transactions() {
if tx.To().Cmp(cfg.DeployConfig.BatchInboxAddress) != 0 {
continue
}
if typ := tx.Type(); typ == txType {
return true
} else if strict {
foundOtherTxType = true
}
}
return false
}, timeout, time.Second, "expected batcher tx type didn't arrive")
require.False(t, foundOtherTxType, "unexpected batcher tx type found")
}
// 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)
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)
}

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

func u64Ptr(v uint64) *uint64 {
return &v
}

0 comments on commit 9f6fb96

Please sign in to comment.