Skip to content

Commit

Permalink
feat: adjust second to millisecond in opbnb inner workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
2020xibao committed Feb 28, 2025
1 parent f3ff1bc commit 1d457a3
Show file tree
Hide file tree
Showing 21 changed files with 93 additions and 40 deletions.
2 changes: 2 additions & 0 deletions op-batcher/batcher/channel_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/holiman/uint256"
)

var ErrReorg = errors.New("block does not extend existing chain")
Expand Down Expand Up @@ -367,6 +368,7 @@ func l2BlockRefFromBlockAndL1Info(block *types.Block, l1info *derive.L1BlockInfo
Number: block.NumberU64(),
ParentHash: block.ParentHash(),
Time: block.Time(),
MilliPartTime: uint256.NewInt(0).SetBytes32(block.MixDigest().Bytes()[:]).Uint64(), // adapts millisecond part
L1Origin: eth.BlockID{Hash: l1info.BlockHash, Number: l1info.Number},
SequenceNumber: l1info.SequenceNumber,
}
Expand Down
23 changes: 12 additions & 11 deletions op-node/rollup/derive/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/holiman/uint256"

"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/bsc"
Expand Down Expand Up @@ -107,7 +108,7 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex

// Calculate bsc block base fee
var l1BaseFee *big.Int
if ba.rollupCfg.IsSnow(l2Parent.Time + ba.rollupCfg.BlockTime) {
if ba.rollupCfg.IsSnow((l2Parent.MillisecondTimestamp() + ba.rollupCfg.BlockTime) / 1000) {
l1BaseFee, err = SnowL1GasPrice(ctx, ba, epoch)
if err != nil {
return nil, err
Expand All @@ -124,29 +125,29 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
l1Info = bsc.NewBlockInfoBSCWrapper(l1Info, l1BaseFee)

// Sanity check the L1 origin was correctly selected to maintain the time invariant between L1 and L2
nextL2Time := l2Parent.Time + ba.rollupCfg.BlockTime
if nextL2Time < l1Info.Time() {
nextL2MilliTime := l2Parent.MillisecondTimestamp() + ba.rollupCfg.BlockTime
if nextL2MilliTime < l1Info.MilliTime() {
return nil, NewResetError(fmt.Errorf("cannot build L2 block on top %s for time %d before L1 origin %s at time %d",
l2Parent, nextL2Time, eth.ToBlockID(l1Info), l1Info.Time()))
l2Parent, nextL2MilliTime, eth.ToBlockID(l1Info), l1Info.MilliTime()))
}

var upgradeTxs []hexutil.Bytes
if ba.rollupCfg.IsEcotoneActivationBlock(nextL2Time) {
if ba.rollupCfg.IsEcotoneActivationBlock(nextL2MilliTime / 1000) {
upgradeTxs, err = EcotoneNetworkUpgradeTransactions()
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to build ecotone network upgrade txs: %w", err))
}
}

if ba.rollupCfg.IsFjordActivationBlock(nextL2Time) {
if ba.rollupCfg.IsFjordActivationBlock(nextL2MilliTime / 1000) {
fjord, err := FjordNetworkUpgradeTransactions()
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to build fjord network upgrade txs: %w", err))
}
upgradeTxs = append(upgradeTxs, fjord...)
}

l1InfoTx, err := L1InfoDepositBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2Time)
l1InfoTx, err := L1InfoDepositBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2MilliTime)
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err))
}
Expand All @@ -157,21 +158,21 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
txs = append(txs, upgradeTxs...)

var withdrawals *types.Withdrawals
if ba.rollupCfg.IsCanyon(nextL2Time) {
if ba.rollupCfg.IsCanyon(nextL2MilliTime / 1000) {
withdrawals = &types.Withdrawals{}
}

var parentBeaconRoot *common.Hash
if ba.rollupCfg.IsEcotone(nextL2Time) {
if ba.rollupCfg.IsEcotone(nextL2MilliTime / 1000) {
parentBeaconRoot = l1Info.ParentBeaconRoot()
if parentBeaconRoot == nil { // default to zero hash if there is no beacon-block-root available
parentBeaconRoot = new(common.Hash)
}
}

return &eth.PayloadAttributes{
Timestamp: hexutil.Uint64(nextL2Time),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
Timestamp: hexutil.Uint64(nextL2MilliTime / 1000), // second part
PrevRandao: uint256.NewInt(nextL2MilliTime % 1000).Bytes32(), // millisecond part
SuggestedFeeRecipient: predeploys.SequencerFeeVaultAddr,
Transactions: txs,
NoTxPool: true,
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/attributes_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *Sing
return nil, NewResetError(fmt.Errorf("valid batch has bad parent hash %s, expected %s", batch.ParentHash, l2SafeHead.Hash))
}
// sanity check timestamp
if expected := l2SafeHead.Time + aq.config.BlockTime; expected != batch.Timestamp {
if expected := l2SafeHead.MillisecondTimestamp() + aq.config.BlockTime; expected != batch.Timestamp {
return nil, NewResetError(fmt.Errorf("valid batch has bad timestamp %d, expected %d", batch.Timestamp, expected))
}
fetchCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/batch_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*Si
if len(bq.nextSpan) > 0 {
// There are cached singular batches derived from the span batch.
// Check if the next cached batch matches the given parent block.
if bq.nextSpan[0].Timestamp == parent.Time+bq.config.BlockTime {
if bq.nextSpan[0].Timestamp == parent.MillisecondTimestamp()+bq.config.BlockTime {
// Pop first one and return.
nextBatch := bq.popNextBatch(parent)
// len(bq.nextSpan) == 0 means it's the last batch of the span.
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/batch_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func BatchQueueEager(t *testing.T, batchType int) {
Genesis: rollup.Genesis{
L2Time: 10,
},
BlockTime: 2,
BlockTime: 2000,
MaxSequencerDrift: 600,
SeqWindowSize: 30,
DeltaTime: getDeltaTime(batchType),
Expand Down
13 changes: 11 additions & 2 deletions op-node/rollup/derive/channel_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (
"io"

"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/holiman/uint256"
)

var (
Expand Down Expand Up @@ -234,16 +236,23 @@ func BlockToSingularBatch(rollupCfg *rollup.Config, block *types.Block) (*Singul
if l1InfoTx.Type() != types.DepositTxType {
return nil, nil, ErrNotDepositTx
}
l1Info, err := L1BlockInfoFromBytes(rollupCfg, block.Time(), l1InfoTx.Data())
l1Info, err := L1BlockInfoFromBytes(rollupCfg, block.Time() /*second timestamp for fork*/, l1InfoTx.Data())
if err != nil {
return nil, l1Info, fmt.Errorf("could not parse the L1 Info deposit: %w", err)
}

milliPart := uint64(0)
if block.MixDigest() != (common.Hash{}) {
milliPart = uint256.NewInt(0).SetBytes32(block.MixDigest().Bytes()[:]).Uint64()
}

milliTimestamp := block.Time()*1000 + milliPart

return &SingularBatch{
ParentHash: block.ParentHash(),
EpochNum: rollup.Epoch(l1Info.Number),
EpochHash: l1Info.BlockHash,
Timestamp: block.Time(),
Timestamp: milliTimestamp, // has changed to milli timestamp
Transactions: opaqueTxs,
}, l1Info, nil
}
Expand Down
10 changes: 5 additions & 5 deletions op-node/rollup/derive/l1_block_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []b

// L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block,
// and the L2 block-height difference with the start of the epoch.
func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64) (*types.DepositTx, error) {
func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, nextL2MilliTime uint64) (*types.DepositTx, error) {
l1BlockInfo := L1BlockInfo{
Number: block.NumberU64(),
Time: block.Time(),
Expand All @@ -270,7 +270,7 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber
BatcherAddr: sysCfg.BatcherAddr,
}
var data []byte
if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) {
if isEcotoneButNotFirstBlock(rollupCfg, nextL2MilliTime/1000) {
l1BlockInfo.BlobBaseFee = block.BlobBaseFee()
if l1BlockInfo.BlobBaseFee == nil {
// The L2 spec states to use the MIN_BLOB_GASPRICE from EIP-4844 if not yet active on L1.
Expand Down Expand Up @@ -314,16 +314,16 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber
Data: data,
}
// With the regolith fork we disable the IsSystemTx functionality, and allocate real gas
if rollupCfg.IsRegolith(l2BlockTime) {
if rollupCfg.IsRegolith(nextL2MilliTime / 1000) {
out.IsSystemTransaction = false
out.Gas = RegolithSystemTxGas
}
return out, nil
}

// L1InfoDepositBytes returns a serialized L1-info attributes transaction.
func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64) ([]byte, error) {
dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime)
func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, nextL2MilliTime uint64) ([]byte, error) {
dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, nextL2MilliTime)
if err != nil {
return nil, fmt.Errorf("failed to create L1 info tx: %w", err)
}
Expand Down
3 changes: 3 additions & 0 deletions op-node/rollup/derive/l2block_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/holiman/uint256"

"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth"
Expand All @@ -18,6 +19,7 @@ import (
type L2BlockRefSource interface {
Hash() common.Hash
ParentHash() common.Hash
MixDigest() common.Hash // millisecond part
NumberU64() uint64
Time() uint64
Transactions() types.Transactions
Expand Down Expand Up @@ -59,6 +61,7 @@ func L2BlockToBlockRef(rollupCfg *rollup.Config, block L2BlockRefSource) (eth.L2
Number: number,
ParentHash: block.ParentHash(),
Time: block.Time(),
MilliPartTime: uint256.NewInt(0).SetBytes32(block.MixDigest().Bytes()[:]).Uint64(),
L1Origin: l1Origin,
SequenceNumber: sequenceNumber,
}, nil
Expand Down
7 changes: 4 additions & 3 deletions op-node/rollup/derive/payload_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"encoding/binary"
"fmt"

"github.com/ethereum/go-ethereum/core/types"

"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/core/types"
"github.com/holiman/uint256"
)

// PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload,
Expand All @@ -33,7 +33,7 @@ func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload)
if tx.Type() != types.DepositTxType {
return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type())
}
info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data())
info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp) /* second timestamp for fork*/, tx.Data())
if err != nil {
return eth.L2BlockRef{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err)
}
Expand All @@ -46,6 +46,7 @@ func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload)
Number: uint64(payload.BlockNumber),
ParentHash: payload.ParentHash,
Time: uint64(payload.Timestamp),
MilliPartTime: uint256.NewInt(0).SetBytes32(payload.PrevRandao[:]).Uint64(), // adapts millisecond part
L1Origin: l1Origin,
SequenceNumber: sequenceNumber,
}, nil
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/singular_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type SingularBatch struct {
ParentHash common.Hash // parent L2 block hash
EpochNum rollup.Epoch // aka l1 num
EpochHash common.Hash // l1 block hash
Timestamp uint64
Timestamp uint64 // millisecond
Transactions []hexutil.Bytes
}

Expand Down
8 changes: 4 additions & 4 deletions op-node/rollup/derive/span_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var ErrTooBigSpanBatchSize = errors.New("span batch size limit reached")
var ErrEmptySpanBatch = errors.New("span-batch must not be empty")

type spanBatchPrefix struct {
relTimestamp uint64 // Relative timestamp of the first block
relTimestamp uint64 // Relative timestamp of the first block, millisecond
l1OriginNum uint64 // L1 origin number
parentCheck [20]byte // First 20 bytes of the first block's parent hash
l1OriginCheck [20]byte // First 20 bytes of the last block's L1 origin hash
Expand Down Expand Up @@ -340,7 +340,7 @@ func (b *RawSpanBatch) encode(w io.Writer) error {

// derive converts RawSpanBatch into SpanBatch, which has a list of SpanBatchElement.
// We need chain config constants to derive values for making payload attributes.
func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) {
func (b *RawSpanBatch) derive(milliBlockInterval, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) {
if b.blockCount == 0 {
return nil, ErrEmptySpanBatch
}
Expand Down Expand Up @@ -368,7 +368,7 @@ func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.I
txIdx := 0
for i := 0; i < int(b.blockCount); i++ {
batch := SpanBatchElement{}
batch.Timestamp = genesisTimestamp + b.relTimestamp + blockTime*uint64(i)
batch.Timestamp = genesisTimestamp*1000 + b.relTimestamp + milliBlockInterval*uint64(i)
batch.EpochNum = rollup.Epoch(blockOriginNums[i])
for j := 0; j < int(b.blockTxCounts[i]); j++ {
batch.Transactions = append(batch.Transactions, fullTxs[txIdx])
Expand Down Expand Up @@ -402,7 +402,7 @@ type SpanBatchElement struct {
func singularBatchToElement(singularBatch *SingularBatch) *SpanBatchElement {
return &SpanBatchElement{
EpochNum: singularBatch.EpochNum,
Timestamp: singularBatch.Timestamp,
Timestamp: singularBatch.Timestamp, // ms
Transactions: singularBatch.Transactions,
}
}
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/span_batch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func TestSpanBatchDerive(t *testing.T) {
rng := rand.New(rand.NewSource(0xbab0bab0))

chainID := new(big.Int).SetUint64(rng.Uint64())
l2BlockTime := uint64(2)
l2BlockTime := uint64(2000)

for originChangedBit := 0; originChangedBit < 2; originChangedBit++ {
singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID)
Expand Down
12 changes: 6 additions & 6 deletions op-node/rollup/driver/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (d *Sequencer) PlanNextSequencerAction() time.Duration {
if safe {
d.log.Warn("delaying sequencing to not interrupt safe-head changes", "onto", buildingOnto, "onto_time", buildingOnto.Time)
// approximates the worst-case time it takes to build a block, to reattempt sequencing after.
return time.Second * time.Duration(d.rollupCfg.BlockTime)
return time.Millisecond * time.Duration(d.rollupCfg.BlockTime)
}

head := d.engine.UnsafeL2Head()
Expand All @@ -166,8 +166,8 @@ func (d *Sequencer) PlanNextSequencerAction() time.Duration {
return delay
}

blockTime := time.Duration(d.rollupCfg.BlockTime) * time.Second
payloadTime := time.Unix(int64(head.Time+d.rollupCfg.BlockTime), 0)
blockTime := time.Duration(d.rollupCfg.BlockTime) * time.Millisecond
payloadTime := time.UnixMilli(int64(head.Time + d.rollupCfg.BlockTime))
remainingTime := payloadTime.Sub(now)

// If we started building a block already, and if that work is still consistent,
Expand Down Expand Up @@ -226,7 +226,7 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context, agossip async.As
if safe {
d.log.Warn("avoiding sequencing to not interrupt safe-head changes", "onto", onto, "onto_time", onto.Time)
// approximates the worst-case time it takes to build a block, to reattempt sequencing after.
d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime))
d.nextAction = d.timeNow().Add(time.Millisecond * time.Duration(d.rollupCfg.BlockTime))
return nil, nil
}
envelope, err := d.CompleteBuildingBlock(ctx, agossip, sequencerConductor)
Expand All @@ -236,7 +236,7 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context, agossip async.As
} else if errors.Is(err, derive.ErrReset) {
d.log.Error("sequencer failed to seal new block, requiring derivation reset", "err", err)
d.metrics.RecordSequencerReset()
d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block
d.nextAction = d.timeNow().Add(time.Millisecond * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block
d.CancelBuildingBlock(ctx)
return nil, err
} else if errors.Is(err, derive.ErrTemporary) {
Expand Down Expand Up @@ -265,7 +265,7 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context, agossip async.As
} else if errors.Is(err, derive.ErrReset) {
d.log.Error("sequencer failed to seal new block, requiring derivation reset", "err", err)
d.metrics.RecordSequencerReset()
d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block
d.nextAction = d.timeNow().Add(time.Millisecond * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block
return nil, err
} else if errors.Is(err, derive.ErrTemporary) {
d.log.Error("sequencer temporarily failed to start building new block", "err", err)
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/driver/sequencer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func TestSequencerChaosMonkey(t *testing.T) {
L2Time: l1Time + 300, // L2 may start with a relative old L1 origin and will have to catch it up
SystemConfig: eth.SystemConfig{},
},
BlockTime: 2,
BlockTime: 2000,
MaxSequencerDrift: 30,
}
// keep track of the L1 timestamps we mock because sometimes we only have the L1 hash/num handy
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/driver/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (s *Driver) eventLoop() {

// Create a ticker to check if there is a gap in the engine queue. Whenever
// there is, we send requests to sync source to retrieve the missing payloads.
syncCheckInterval := time.Duration(s.config.BlockTime) * time.Second * 2
syncCheckInterval := time.Duration(s.config.BlockTime) * time.Millisecond * 2
altSyncTicker := time.NewTicker(syncCheckInterval)
defer altSyncTicker.Stop()
lastUnsafeL2 := s.engineController.UnsafeL2Head()
Expand Down
3 changes: 2 additions & 1 deletion op-node/rollup/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ type PlasmaConfig struct {
type Config struct {
// Genesis anchor point of the rollup
Genesis Genesis `json:"genesis"`
// Seconds per L2 block
// BlockTime is the interval configuration of L2 block;
// which supports the new millisecond unit and is compatible with the legacy second unit.
BlockTime uint64 `json:"block_time"`
// Sequencer batches may not be more than MaxSequencerDrift seconds after
// the L1 timestamp of the sequencing window end.
Expand Down
11 changes: 11 additions & 0 deletions op-node/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
rollupConfig.ProtocolVersionsAddress = common.Address{}
}

{
if rollupConfig.BlockTime >= 1 && rollupConfig.BlockTime <= 3 {
// Convert legacy second-level timestamp to millisecond timestamp,
// This is a compatibility behavior.
rollupConfig.BlockTime = rollupConfig.BlockTime * 1000
} else if rollupConfig.BlockTime%50 != 0 && rollupConfig.BlockTime > 750 {
return nil, fmt.Errorf("block time is invalid, block_time: %v", rollupConfig.BlockTime)
}
// rollupConfig.BlockTime is millisecond block interval
}

configPersistence := NewConfigPersistence(ctx)

driverConfig := NewDriverConfig(ctx)
Expand Down
Loading

0 comments on commit 1d457a3

Please sign in to comment.