Commit 9678b357 authored by Conner Fromknecht's avatar Conner Fromknecht

feat: add Min/MaxStateRootElements configurations

This commit adds configuration hooks to bound the number of state roots
that are permitted in state root batches. Specifically, the minimum
allows us to amortized the cost of adding state roots to the CTC
contract. Additionally, the maximum is used in place of the old limit
based on tx size, since this is more natural and mirrors the minimum
bound.
parent 4bfddfbb
---
'@eth-optimism/batch-submitter-service': patch
---
Add Min/MaxStateRootElements configuration
...@@ -148,15 +148,16 @@ func Main(gitVersion string) func(ctx *cli.Context) error { ...@@ -148,15 +148,16 @@ func Main(gitVersion string) func(ctx *cli.Context) error {
if cfg.RunStateBatchSubmitter { if cfg.RunStateBatchSubmitter {
batchStateDriver, err := proposer.NewDriver(proposer.Config{ batchStateDriver, err := proposer.NewDriver(proposer.Config{
Name: "Proposer", Name: "Proposer",
L1Client: l1Client, L1Client: l1Client,
L2Client: l2Client, L2Client: l2Client,
BlockOffset: cfg.BlockOffset, BlockOffset: cfg.BlockOffset,
MaxTxSize: cfg.MaxL1TxSize, MinStateRootElements: cfg.MinStateRootElements,
SCCAddr: sccAddress, MaxStateRootElements: cfg.MaxStateRootElements,
CTCAddr: ctcAddress, SCCAddr: sccAddress,
ChainID: chainID, CTCAddr: ctcAddress,
PrivKey: proposerPrivKey, ChainID: chainID,
PrivKey: proposerPrivKey,
}) })
if err != nil { if err != nil {
return err return err
......
...@@ -74,14 +74,18 @@ type Config struct { ...@@ -74,14 +74,18 @@ type Config struct {
// by the batch submitter. // by the batch submitter.
MaxL1TxSize uint64 MaxL1TxSize uint64
// MinStateRootElements is the minimum number of state root elements that
// can be submitted in single proposer batch.
MinStateRootElements uint64
// MaxStateRootElements is the maximum number of state root elements that
// can be submitted in single proposer batch.
MaxStateRootElements uint64
// MaxTxBatchCount is the maximum number of L2 transactions that can ever be // MaxTxBatchCount is the maximum number of L2 transactions that can ever be
// in a batch. // in a batch.
MaxTxBatchCount uint64 MaxTxBatchCount uint64
// MaxStateBatchCount is the maximum number of L2 state roots that can ever
// be in a batch.
MaxStateBatchCount uint64
// MaxBatchSubmissionTime is the maximum amount of time that we will // MaxBatchSubmissionTime is the maximum amount of time that we will
// wait before submitting an under-sized batch. // wait before submitting an under-sized batch.
MaxBatchSubmissionTime time.Duration MaxBatchSubmissionTime time.Duration
...@@ -199,6 +203,8 @@ func NewConfig(ctx *cli.Context) (Config, error) { ...@@ -199,6 +203,8 @@ func NewConfig(ctx *cli.Context) (Config, error) {
SCCAddress: ctx.GlobalString(flags.SCCAddressFlag.Name), SCCAddress: ctx.GlobalString(flags.SCCAddressFlag.Name),
MinL1TxSize: ctx.GlobalUint64(flags.MinL1TxSizeFlag.Name), MinL1TxSize: ctx.GlobalUint64(flags.MinL1TxSizeFlag.Name),
MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeFlag.Name), MaxL1TxSize: ctx.GlobalUint64(flags.MaxL1TxSizeFlag.Name),
MinStateRootElements: ctx.GlobalUint64(flags.MinStateRootElementsFlag.Name),
MaxStateRootElements: ctx.GlobalUint64(flags.MinStateRootElementsFlag.Name),
MaxBatchSubmissionTime: ctx.GlobalDuration(flags.MaxBatchSubmissionTimeFlag.Name), MaxBatchSubmissionTime: ctx.GlobalDuration(flags.MaxBatchSubmissionTimeFlag.Name),
PollInterval: ctx.GlobalDuration(flags.PollIntervalFlag.Name), PollInterval: ctx.GlobalDuration(flags.PollIntervalFlag.Name),
NumConfirmations: ctx.GlobalUint64(flags.NumConfirmationsFlag.Name), NumConfirmations: ctx.GlobalUint64(flags.NumConfirmationsFlag.Name),
......
...@@ -28,15 +28,16 @@ const stateRootSize = 32 ...@@ -28,15 +28,16 @@ const stateRootSize = 32
var bigOne = new(big.Int).SetUint64(1) //nolint:unused var bigOne = new(big.Int).SetUint64(1) //nolint:unused
type Config struct { type Config struct {
Name string Name string
L1Client *ethclient.Client L1Client *ethclient.Client
L2Client *l2ethclient.Client L2Client *l2ethclient.Client
BlockOffset uint64 BlockOffset uint64
MaxTxSize uint64 MaxStateRootElements uint64
SCCAddr common.Address MinStateRootElements uint64
CTCAddr common.Address SCCAddr common.Address
ChainID *big.Int CTCAddr common.Address
PrivKey *ecdsa.PrivateKey ChainID *big.Int
PrivKey *ecdsa.PrivateKey
} }
type Driver struct { type Driver struct {
...@@ -165,13 +166,10 @@ func (d *Driver) CraftBatchTx( ...@@ -165,13 +166,10 @@ func (d *Driver) CraftBatchTx(
log.Info(name+" crafting batch tx", "start", start, "end", end, log.Info(name+" crafting batch tx", "start", start, "end", end,
"nonce", nonce) "nonce", nonce)
var ( var stateRoots [][stateRootSize]byte
stateRoots [][stateRootSize]byte
totalStateRootSize uint64
)
for i := new(big.Int).Set(start); i.Cmp(end) < 0; i.Add(i, bigOne) { for i := new(big.Int).Set(start); i.Cmp(end) < 0; i.Add(i, bigOne) {
// Consume state roots until reach our maximum tx size. // Consume state roots until reach our maximum tx size.
if totalStateRootSize+stateRootSize > d.cfg.MaxTxSize { if uint64(len(stateRoots)) > d.cfg.MaxStateRootElements {
break break
} }
...@@ -180,10 +178,18 @@ func (d *Driver) CraftBatchTx( ...@@ -180,10 +178,18 @@ func (d *Driver) CraftBatchTx(
return nil, err return nil, err
} }
totalStateRootSize += stateRootSize
stateRoots = append(stateRoots, block.Root()) stateRoots = append(stateRoots, block.Root())
} }
// Abort if we don't have enough state roots to meet our minimum
// requirement.
if uint64(len(stateRoots)) < d.cfg.MinStateRootElements {
log.Info(name+" number of state roots below minimum",
"num_state_roots", len(stateRoots),
"min_state_roots", d.cfg.MinStateRootElements)
return nil, nil
}
d.metrics.NumElementsPerBatch().Observe(float64(len(stateRoots))) d.metrics.NumElementsPerBatch().Observe(float64(len(stateRoots)))
log.Info(name+" batch constructed", "num_state_roots", len(stateRoots)) log.Info(name+" batch constructed", "num_state_roots", len(stateRoots))
......
...@@ -66,6 +66,20 @@ var ( ...@@ -66,6 +66,20 @@ var (
Required: true, Required: true,
EnvVar: prefixEnvVar("MAX_L1_TX_SIZE"), EnvVar: prefixEnvVar("MAX_L1_TX_SIZE"),
} }
MinStateRootElementsFlag = cli.Uint64Flag{
Name: "min-state-root-elements",
Usage: "Minimum number of elements required to submit a state " +
"root batch",
Required: true,
EnvVar: prefixEnvVar("MIN_STATE_ROOT_ELEMENTS"),
}
MaxStateRootElementsFlag = cli.Uint64Flag{
Name: "max-state-root-elements",
Usage: "Maximum number of elements required to submit a state " +
"root batch",
Required: true,
EnvVar: prefixEnvVar("MAX_STATE_ROOT_ELEMENTS"),
}
MaxBatchSubmissionTimeFlag = cli.DurationFlag{ MaxBatchSubmissionTimeFlag = cli.DurationFlag{
Name: "max-batch-submission-time", Name: "max-batch-submission-time",
Usage: "Maximum amount of time that we will wait before " + Usage: "Maximum amount of time that we will wait before " +
...@@ -240,6 +254,8 @@ var requiredFlags = []cli.Flag{ ...@@ -240,6 +254,8 @@ var requiredFlags = []cli.Flag{
SCCAddressFlag, SCCAddressFlag,
MinL1TxSizeFlag, MinL1TxSizeFlag,
MaxL1TxSizeFlag, MaxL1TxSizeFlag,
MinStateRootElementsFlag,
MaxStateRootElementsFlag,
MaxBatchSubmissionTimeFlag, MaxBatchSubmissionTimeFlag,
PollIntervalFlag, PollIntervalFlag,
NumConfirmationsFlag, NumConfirmationsFlag,
......
...@@ -6,6 +6,8 @@ BATCH_SUBMITTER_LOG_LEVEL=debug ...@@ -6,6 +6,8 @@ BATCH_SUBMITTER_LOG_LEVEL=debug
BATCH_SUBMITTER_LOG_TERMINAL=true BATCH_SUBMITTER_LOG_TERMINAL=true
BATCH_SUBMITTER_MIN_L1_TX_SIZE=32 BATCH_SUBMITTER_MIN_L1_TX_SIZE=32
BATCH_SUBMITTER_MAX_L1_TX_SIZE=90000 BATCH_SUBMITTER_MAX_L1_TX_SIZE=90000
BATCH_SUBMITTER_MIN_STATE_ROOT_ELEMENTS=1
BATCH_SUBMITTER_MAX_STATE_ROOT_ELEMENTS=3000
BATCH_SUBMITTER_MAX_BATCH_SUBMISSION_TIME=0 BATCH_SUBMITTER_MAX_BATCH_SUBMISSION_TIME=0
BATCH_SUBMITTER_POLL_INTERVAL=500ms BATCH_SUBMITTER_POLL_INTERVAL=500ms
BATCH_SUBMITTER_NUM_CONFIRMATIONS=1 BATCH_SUBMITTER_NUM_CONFIRMATIONS=1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment