Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 61 additions & 21 deletions go/batch-submitter/drivers/proposer/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"crypto/ecdsa"
"fmt"
"math/big"
"time"
"strings"

"github.com/ethereum-optimism/optimism/go/batch-submitter/bindings/ctc"
"github.com/ethereum-optimism/optimism/go/batch-submitter/bindings/scc"
Expand All @@ -14,6 +14,8 @@ import (
"github.com/ethereum-optimism/optimism/go/batch-submitter/txmgr"
l2ethclient "github.com/ethereum-optimism/optimism/l2geth/ethclient"
"github.com/ethereum-optimism/optimism/l2geth/log"
"github.com/ethereum-optimism/optimism/l2geth/params"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
Expand All @@ -39,11 +41,12 @@ type Config struct {
}

type Driver struct {
cfg Config
sccContract *scc.StateCommitmentChain
ctcContract *ctc.CanonicalTransactionChain
walletAddr common.Address
metrics *metrics.Metrics
cfg Config
sccContract *scc.StateCommitmentChain
rawSccContract *bind.BoundContract
ctcContract *ctc.CanonicalTransactionChain
walletAddr common.Address
metrics *metrics.Metrics
}

func NewDriver(cfg Config) (*Driver, error) {
Expand All @@ -61,14 +64,26 @@ func NewDriver(cfg Config) (*Driver, error) {
return nil, err
}

parsed, err := abi.JSON(strings.NewReader(
scc.StateCommitmentChainABI,
))
if err != nil {
return nil, err
}

rawSccContract := bind.NewBoundContract(
cfg.SCCAddr, parsed, cfg.L1Client, cfg.L1Client, cfg.L1Client,
)

walletAddr := crypto.PubkeyToAddress(cfg.PrivKey.PublicKey)

return &Driver{
cfg: cfg,
sccContract: sccContract,
ctcContract: ctcContract,
walletAddr: walletAddr,
metrics: metrics.NewMetrics(cfg.Name),
cfg: cfg,
sccContract: sccContract,
rawSccContract: rawSccContract,
ctcContract: ctcContract,
walletAddr: walletAddr,
metrics: metrics.NewMetrics(cfg.Name),
}, nil
}

Expand Down Expand Up @@ -136,16 +151,20 @@ func (d *Driver) GetBatchBlockRange(
return start, end, nil
}

// SubmitBatchTx transforms the L2 blocks between start and end into a batch
// transaction using the given nonce and gasPrice. The final transaction is
// published and returned to the call.
func (d *Driver) SubmitBatchTx(
// CraftBatchTx transforms the L2 blocks between start and end into a batch
// transaction using the given nonce. A dummy gas price is used in the resulting
// transaction to use for size estimation.
//
// NOTE: This method SHOULD NOT publish the resulting transaction.
func (d *Driver) CraftBatchTx(
ctx context.Context,
start, end, nonce, gasPrice *big.Int) (*types.Transaction, error) {
start, end, nonce *big.Int,
) (*types.Transaction, error) {

name := d.cfg.Name

batchTxBuildStart := time.Now()
log.Info(name+" crafting batch tx", "start", start, "end", end,
"nonce", nonce)

var (
stateRoots [][stateRootSize]byte
Expand All @@ -166,8 +185,6 @@ func (d *Driver) SubmitBatchTx(
stateRoots = append(stateRoots, block.Root())
}

batchTxBuildTime := float64(time.Since(batchTxBuildStart) / time.Millisecond)
d.metrics.BatchTxBuildTime.Set(batchTxBuildTime)
d.metrics.NumElementsPerBatch.Observe(float64(len(stateRoots)))

log.Info(name+" batch constructed", "num_state_roots", len(stateRoots))
Expand All @@ -178,12 +195,35 @@ func (d *Driver) SubmitBatchTx(
if err != nil {
return nil, err
}
opts.Nonce = nonce
opts.Context = ctx
opts.GasPrice = gasPrice
opts.Nonce = nonce
opts.GasPrice = big.NewInt(params.GWei) // dummy
opts.NoSend = true

blockOffset := new(big.Int).SetUint64(d.cfg.BlockOffset)
offsetStartsAtIndex := new(big.Int).Sub(start, blockOffset)

return d.sccContract.AppendStateBatch(opts, stateRoots, offsetStartsAtIndex)
}

// SubmitBatchTx using the passed transaction as a template, signs and publishes
// an otherwise identical transaction after setting the provided gas price. The
// final transaction is returned to the caller.
func (d *Driver) SubmitBatchTx(
ctx context.Context,
tx *types.Transaction,
gasPrice *big.Int,
) (*types.Transaction, error) {

opts, err := bind.NewKeyedTransactorWithChainID(
d.cfg.PrivKey, d.cfg.ChainID,
)
if err != nil {
return nil, err
}
opts.Context = ctx
opts.Nonce = new(big.Int).SetUint64(tx.Nonce())
opts.GasPrice = gasPrice

return d.rawSccContract.RawTransact(opts, tx.Data())
}
51 changes: 36 additions & 15 deletions go/batch-submitter/drivers/sequencer/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import (
"fmt"
"math/big"
"strings"
"time"

"github.com/ethereum-optimism/optimism/go/batch-submitter/bindings/ctc"
"github.com/ethereum-optimism/optimism/go/batch-submitter/drivers"
"github.com/ethereum-optimism/optimism/go/batch-submitter/metrics"
"github.com/ethereum-optimism/optimism/go/batch-submitter/txmgr"
l2ethclient "github.com/ethereum-optimism/optimism/l2geth/ethclient"
"github.com/ethereum-optimism/optimism/l2geth/params"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -148,19 +148,20 @@ func (d *Driver) GetBatchBlockRange(
return start, end, nil
}

// SubmitBatchTx transforms the L2 blocks between start and end into a batch
// transaction using the given nonce and gasPrice. The final transaction is
// published and returned to the call.
func (d *Driver) SubmitBatchTx(
// CraftBatchTx transforms the L2 blocks between start and end into a batch
// transaction using the given nonce. A dummy gas price is used in the resulting
// transaction to use for size estimation.
//
// NOTE: This method SHOULD NOT publish the resulting transaction.
func (d *Driver) CraftBatchTx(
ctx context.Context,
start, end, nonce, gasPrice *big.Int) (*types.Transaction, error) {
start, end, nonce *big.Int,
) (*types.Transaction, error) {

name := d.cfg.Name

log.Info(name+" submitting batch tx", "start", start, "end", end,
"gasPrice", gasPrice)

batchTxBuildStart := time.Now()
log.Info(name+" crafting batch tx", "start", start, "end", end,
"nonce", nonce)

var (
batchElements []BatchElement
Expand Down Expand Up @@ -219,9 +220,6 @@ func (d *Driver) SubmitBatchTx(
continue
}

// Record the batch_tx_build_time.
batchTxBuildTime := float64(time.Since(batchTxBuildStart) / time.Millisecond)
d.metrics.BatchTxBuildTime.Set(batchTxBuildTime)
d.metrics.NumElementsPerBatch.Observe(float64(len(batchElements)))
d.metrics.BatchPruneCount.Set(float64(pruneCount))

Expand All @@ -233,10 +231,33 @@ func (d *Driver) SubmitBatchTx(
if err != nil {
return nil, err
}
opts.Nonce = nonce
opts.Context = ctx
opts.GasPrice = gasPrice
opts.Nonce = nonce
opts.GasPrice = big.NewInt(params.GWei) // dummy
opts.NoSend = true

return d.rawCtcContract.RawTransact(opts, batchCallData)
}
}

// SubmitBatchTx using the passed transaction as a template, signs and publishes
// an otherwise identical transaction after setting the provided gas price. The
// final transaction is returned to the caller.
func (d *Driver) SubmitBatchTx(
ctx context.Context,
tx *types.Transaction,
gasPrice *big.Int,
) (*types.Transaction, error) {

opts, err := bind.NewKeyedTransactorWithChainID(
d.cfg.PrivKey, d.cfg.ChainID,
)
if err != nil {
return nil, err
}
opts.Context = ctx
opts.Nonce = new(big.Int).SetUint64(tx.Nonce())
opts.GasPrice = gasPrice

return d.rawCtcContract.RawTransact(opts, tx.Data())
}
46 changes: 37 additions & 9 deletions go/batch-submitter/service.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package batchsubmitter

import (
"bytes"
"context"
"math/big"
"sync"
Expand Down Expand Up @@ -43,12 +44,23 @@ type Driver interface {
// processed.
GetBatchBlockRange(ctx context.Context) (*big.Int, *big.Int, error)

// SubmitBatchTx transforms the L2 blocks between start and end into a
// batch transaction using the given nonce and gasPrice. The final
// transaction is published and returned to the call.
// CraftBatchTx transforms the L2 blocks between start and end into a batch
// transaction using the given nonce. A dummy gas price is used in the
// resulting transaction to use for size estimation.
//
// NOTE: This method SHOULD NOT publish the resulting transaction.
CraftBatchTx(
ctx context.Context,
start, end, nonce *big.Int,
) (*types.Transaction, error)

// SubmitBatchTx using the passed transaction as a template, signs and
// publishes an otherwise identical transaction after setting the provided
// gas price. The final transaction is returned to the caller.
SubmitBatchTx(
ctx context.Context,
start, end, nonce, gasPrice *big.Int,
tx *types.Transaction,
gasPrice *big.Int,
) (*types.Transaction, error)
}

Expand Down Expand Up @@ -160,6 +172,26 @@ func (s *Service) eventLoop() {
}
nonce := new(big.Int).SetUint64(nonce64)

batchTxBuildStart := time.Now()
tx, err := s.cfg.Driver.CraftBatchTx(
s.ctx, start, end, nonce,
)
if err != nil {
log.Error(name+" unable to craft batch tx",
"err", err)
continue
}
batchTxBuildTime := time.Since(batchTxBuildStart) / time.Millisecond
s.metrics.BatchTxBuildTime.Set(float64(batchTxBuildTime))

// Record the size of the batch transaction.
var txBuf bytes.Buffer
if err := tx.EncodeRLP(&txBuf); err != nil {
log.Error(name+" unable to encode batch tx", "err", err)
continue
}
s.metrics.BatchSizeInBytes.Observe(float64(len(txBuf.Bytes())))

// Construct the transaction submission clousure that will attempt
// to send the next transaction at the given nonce and gas price.
sendTx := func(
Expand All @@ -170,9 +202,7 @@ func (s *Service) eventLoop() {
"end", end, "nonce", nonce,
"gasPrice", gasPrice)

tx, err := s.cfg.Driver.SubmitBatchTx(
ctx, start, end, nonce, gasPrice,
)
tx, err := s.cfg.Driver.SubmitBatchTx(ctx, tx, gasPrice)
if err != nil {
return nil, err
}
Expand All @@ -186,8 +216,6 @@ func (s *Service) eventLoop() {
"gasPrice", gasPrice,
)

s.metrics.BatchSizeInBytes.Observe(float64(tx.Size()))

return tx, nil
}

Expand Down