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
2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v4.7.6"
var tag = "v4.7.7"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down
17 changes: 16 additions & 1 deletion rollup/internal/controller/watcher/chunk_proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,13 @@ func (p *ChunkProposer) ProposeChunk() error {
// Ensure all blocks in the same chunk use the same hardfork name
// If a different hardfork name is found, truncate the blocks slice at that point
hardforkName := encoding.GetHardforkName(p.chainCfg, blocks[0].Header.Number.Uint64(), blocks[0].Header.Time)
hardforkBoundary := false
for i := 1; i < len(blocks); i++ {
currentHardfork := encoding.GetHardforkName(p.chainCfg, blocks[i].Header.Number.Uint64(), blocks[i].Header.Time)
if currentHardfork != hardforkName {
blocks = blocks[:i]
// Truncate blocks at hardfork boundary
blocks = blocks[:i]
hardforkBoundary = true
break
}
}
Expand Down Expand Up @@ -321,6 +323,19 @@ func (p *ChunkProposer) ProposeChunk() error {
return fmt.Errorf("failed to calculate chunk metrics: %w", calcErr)
}

// No breaking condition met, but hardfork boundary reached
if hardforkBoundary {
log.Info("hardfork boundary reached, proposing chunk",
"block count", len(chunk.Blocks),
"codec version", codecVersion,
"start block number", chunk.Blocks[0].Header.Number,
"end block number", chunk.Blocks[len(chunk.Blocks)-1].Header.Number)

p.recordAllChunkMetrics(metrics)
return p.updateDBChunkInfo(&chunk, codecVersion, metrics)
}

// No breaking condition met, check for timeout
currentTimeSec := uint64(time.Now().Unix())
if metrics.FirstBlockTimestamp+p.cfg.ChunkTimeoutSec < currentTimeSec {
log.Info("first block timeout reached",
Expand Down
28 changes: 27 additions & 1 deletion rollup/internal/controller/watcher/chunk_proposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ import (
"scroll-tech/rollup/internal/utils"
)

func newUint64(val uint64) *uint64 { return &val }

func testChunkProposerLimitsCodecV7(t *testing.T) {
tests := []struct {
name string
maxL2Gas uint64
chunkTimeoutSec uint64
expectedChunksLen int
expectedBlocksInFirstChunk int // only be checked when expectedChunksLen > 0
GalileoTime *uint64
}{
{
name: "NoLimitReached",
Expand Down Expand Up @@ -62,6 +65,14 @@ func testChunkProposerLimitsCodecV7(t *testing.T) {
expectedChunksLen: 1,
expectedBlocksInFirstChunk: 1,
},
{
name: "SingleBlockByForkBoundary",
maxL2Gas: 20_000_000,
chunkTimeoutSec: 1000000000000,
expectedChunksLen: 1,
expectedBlocksInFirstChunk: 1,
GalileoTime: newUint64(1669364525), // timestamp of `block2`
},
}

for _, tt := range tests {
Expand All @@ -78,11 +89,26 @@ func testChunkProposerLimitsCodecV7(t *testing.T) {
_, err = chunkOrm.InsertChunk(context.Background(), &encoding.Chunk{Blocks: []*encoding.Block{{Header: &gethTypes.Header{Number: big.NewInt(0)}}}}, encoding.CodecV0, utils.ChunkMetrics{})
assert.NoError(t, err)

// Initialize the chunk proposer.
chainConfig := &params.ChainConfig{
LondonBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DarwinTime: new(uint64),
DarwinV2Time: new(uint64),
EuclidTime: new(uint64),
EuclidV2Time: new(uint64),
FeynmanTime: new(uint64),
GalileoTime: tt.GalileoTime,
}

cp := NewChunkProposer(context.Background(), &config.ChunkProposerConfig{
MaxL2GasPerChunk: tt.maxL2Gas,
ChunkTimeoutSec: tt.chunkTimeoutSec,
MaxUncompressedBatchBytesSize: math.MaxUint64,
}, encoding.CodecV7, &params.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64), EuclidTime: new(uint64), EuclidV2Time: new(uint64)}, db, nil)
}, encoding.CodecV7, chainConfig, db, nil)

// Run one round of chunk proposing.
cp.TryProposeChunk()

chunks, err := chunkOrm.GetChunksGEIndex(context.Background(), 1, 0)
Expand Down