Skip to content

Commit

Permalink
finish rollup gas optimize
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethanncnm committed Aug 30, 2023
1 parent f713e9c commit 605fab1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 112 deletions.
117 changes: 16 additions & 101 deletions batch-submitter/drivers/sequencer/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sequencer
import (
"errors"
"fmt"

l2types "github.com/mantlenetworkio/mantle/l2geth/core/types"
)

Expand Down Expand Up @@ -76,113 +77,27 @@ type groupedBlock struct {
func GenSequencerBatchParams(
shouldStartAtElement uint64,
blockOffset uint64,
batch []BatchElement,
batchNumber uint64,
timestamp uint64,
blockNumber uint64,

numSequencedTxs uint64,
numSubsequentQueueTxs uint64,

) (*AppendSequencerBatchParams, error) {
var (
contexts []BatchContext
groupedBlocks []groupedBlock
txs []*CachedTx
lastBlockIsSequencerTx bool
lastTimestamp uint64
lastBlockNumber uint64
contexts []BatchContext
)
// Iterate over the batch elements, grouping the elements according to
// the following criteria:
// - All txs in the same group must have the same timestamp.
// - All sequencer txs in the same group must have the same block number.
// - If sequencer txs exist in a group, they must come before all
// queued txs.
//
// Assuming the block and timestamp criteria for sequencer txs are
// respected within each group, the following are examples of groupings:
// - [s] // sequencer can exist by itself
// - [q] // ququed tx can exist by itself
// - [s] [s] // differing sequencer tx timestamp/blocknumber
// - [s q] [s] // sequencer tx must precede queued tx in group
// - [q] [q s] // INVALID: consecutive queued txs are split
// - [q q] [s] // correct split for preceding case
// - [s q] [s q] // alternating sequencer tx interleaved with queued
for _, el := range batch {
// To enforce the above groupings, the following condition is
// used to determine when to create a new batch:
// - On the first pass, or
// - The preceding tx has a different timestamp, or
// - Whenever a sequencer tx is observed, and:
// - The preceding tx was a queued tx, or
// - The preceding sequencer tx has a different block number.
// Note that a sequencer tx is usually required to create a new group,
// so a queued tx may ONLY exist as the first element in a group if it
// is the very first element or it has a different timestamp from the
// preceding tx.
needsNewGroupOnSequencerTx := !lastBlockIsSequencerTx ||
el.BlockNumber != lastBlockNumber
if len(groupedBlocks) == 0 ||
el.Timestamp != lastTimestamp ||
(el.IsSequencerTx() && needsNewGroupOnSequencerTx) {

groupedBlocks = append(groupedBlocks, groupedBlock{})
}

// Append the tx to either the sequenced or queued txs,
// depending on its type.
cur := len(groupedBlocks) - 1
if el.IsSequencerTx() {
groupedBlocks[cur].sequenced =
append(groupedBlocks[cur].sequenced, el)

// Gather all sequencer txs, as these will be encoded in
// the calldata of the batch tx submitted to the L1 CTC
// contract.
txs = append(txs, el.Tx)
} else {
groupedBlocks[cur].queued =
append(groupedBlocks[cur].queued, el)
}

lastBlockIsSequencerTx = el.IsSequencerTx()
lastTimestamp = el.Timestamp
lastBlockNumber = el.BlockNumber
}
contexts = append(contexts, BatchContext{
NumSequencedTxs: numSequencedTxs,
NumSubsequentQueueTxs: numSubsequentQueueTxs,
Timestamp: timestamp,
BlockNumber: blockNumber,
})

// For each group, construct the resulting BatchContext.
for _, block := range groupedBlocks {
numSequencedTxs := uint64(len(block.sequenced))
numSubsequentQueueTxs := uint64(len(block.queued))

// Ensure at least one tx was included in this group.
if numSequencedTxs == 0 && numSubsequentQueueTxs == 0 {
return nil, ErrBlockWithInvalidContext
}

// Compute the timestamp and block number from for the batch
// using either the earliest sequenced tx or the earliest queued
// tx. If a batch has a sequencer tx it is given preference,
// since it is guaranteed to be the earliest item in the group.
// Otherwise, we fallback to the earliest queued tx since it was
// the very first item.
var (
timestamp uint64
blockNumber uint64
)
if numSequencedTxs > 0 {
timestamp = block.sequenced[0].Timestamp
blockNumber = block.sequenced[0].BlockNumber
} else {
timestamp = block.queued[0].Timestamp
blockNumber = block.queued[0].BlockNumber
}

contexts = append(contexts, BatchContext{
NumSequencedTxs: numSequencedTxs,
NumSubsequentQueueTxs: numSubsequentQueueTxs,
Timestamp: timestamp,
BlockNumber: blockNumber,
})
}
return &AppendSequencerBatchParams{
ShouldStartAtElement: shouldStartAtElement - blockOffset,
TotalElementsToAppend: uint64(len(batch)),
TotalElementsToAppend: batchNumber,
Contexts: contexts,
Txs: txs,
}, nil
}
27 changes: 19 additions & 8 deletions batch-submitter/drivers/sequencer/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ func (d *Driver) CraftBatchTx(
log.Info(name+" crafting batch tx", "start", start, "end", end,
"nonce", nonce, "type", d.cfg.BatchType.String())

var batchElements []BatchElement
var lastTimestamp uint64
var lastBlockNumber uint64
numSequencedTxs := 0
numSubsequentQueueTxs := 0

for i := new(big.Int).Set(start); i.Cmp(end) < 0; i.Add(i, bigOne) {
block, err := d.cfg.L2Client.BlockByNumber(ctx, i)
Expand All @@ -242,20 +245,28 @@ func (d *Driver) CraftBatchTx(
// For each sequencer transaction, update our running total with the
// size of the transaction.
batchElement := BatchElementFromBlock(block)
batchElements = append(batchElements, batchElement)
if batchElement.IsSequencerTx() {
numSequencedTxs += 1
} else {
numSubsequentQueueTxs += 1
}
if i.Cmp(big.NewInt(0).Sub(end, bigOne)) == 0 {
lastTimestamp = batchElement.Timestamp
lastBlockNumber = batchElement.BlockNumber
}
}

blocksLen := numSequencedTxs + numSubsequentQueueTxs
shouldStartAt := start.Uint64()
for {
batchParams, err := GenSequencerBatchParams(
shouldStartAt, d.cfg.BlockOffset, batchElements,
)
shouldStartAt, d.cfg.BlockOffset, uint64(blocksLen), lastTimestamp,
lastBlockNumber, uint64(numSequencedTxs), uint64(numSubsequentQueueTxs))
if err != nil {
return nil, err
}

// Encode the batch arguments using the configured encoding type.
batchArguments, err := batchParams.Serialize(d.cfg.BatchType, start, big.NewInt(int64(d.cfg.DaUpgradeBlock)))
batchArguments, err := batchParams.Serialize(d.cfg.BatchType)
if err != nil {
return nil, err
}
Expand All @@ -266,10 +277,10 @@ func (d *Driver) CraftBatchTx(
log.Info(name+" testing batch size",
"calldata_size", len(calldata))

d.metrics.NumElementsPerBatch().Observe(float64(len(batchElements)))
d.metrics.NumElementsPerBatch().Observe(float64(blocksLen))

log.Info(name+" batch constructed",
"num_txs", len(batchElements),
"num_txs", blocksLen,
"final_size", len(calldata),
"batch_type", d.cfg.BatchType)

Expand Down
3 changes: 0 additions & 3 deletions batch-submitter/drivers/sequencer/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"fmt"
"io"
"math"
"math/big"

l2types "github.com/mantlenetworkio/mantle/l2geth/core/types"
l2rlp "github.com/mantlenetworkio/mantle/l2geth/rlp"
Expand Down Expand Up @@ -239,8 +238,6 @@ func (p *AppendSequencerBatchParams) WriteNoTxn(
// bytes slice.
func (p *AppendSequencerBatchParams) Serialize(
batchType BatchType,
l2BlockNumber *big.Int,
upgradeBlock *big.Int,
) ([]byte, error) {
var buf bytes.Buffer
if err := p.WriteNoTxn(&buf, batchType); err != nil {
Expand Down

0 comments on commit 605fab1

Please sign in to comment.