forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 284
SystemContract: support millisecond block generation #1174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 19 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
2f9555e
support ms block generation
georgehao 2844e18
update
georgehao bad6a6c
bump version
georgehao b8d0863
deadline to common sense
georgehao e282204
remove unused code
georgehao 1e378fa
add logs
georgehao 1748594
update
georgehao d088aff
update
georgehao a7e3c17
update
georgehao 446492a
add more logs
georgehao ab1a331
add tryCommitNewWork log
georgehao d50ff4e
add more logs
georgehao 680221d
rc10
georgehao 13a6df5
address comments
georgehao 646679a
resolve conflict
georgehao 08f9a24
address comments
georgehao 2e9d9f9
Merge remote-tracking branch 'origin/develop' into feat/support_ms_bl…
jonastheis 3abad55
chore: auto version bump [bot]
jonastheis 7c997fb
update logic
georgehao 2b67b81
fix CalcTimestamp
georgehao fdbc4a5
add debug log
georgehao a964e2a
address comments
georgehao 00f37de
update logic
georgehao 586544c
fix lint
georgehao 5cf9b4c
remove debug log
georgehao 71dd65e
fix RelaxedPeriod
georgehao 004f070
chore: auto version bump [bot]
georgehao 0e51603
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
georgehao 9b8650c
update version
georgehao eb9f213
Merge branch 'feat/support_ms_block_generation' of github.com:scroll-…
georgehao 4bd59ee
Merge branch 'develop' into feat/support_ms_block_generation
Thegaram 5bc1c9f
make relaxed_period omitempty
georgehao 0837abe
Merge branch 'feat/support_ms_block_generation' of github.com:scroll-…
georgehao 826c3d9
fix omitempty
georgehao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,282 @@ | ||
| package system_contract | ||
|
|
||
| import ( | ||
| "math/big" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/scroll-tech/go-ethereum/core/types" | ||
| "github.com/scroll-tech/go-ethereum/params" | ||
| ) | ||
|
|
||
| func TestSystemContract_CalcTimestamp(t *testing.T) { | ||
| // Use a future timestamp to avoid the "timestamp < time.Now()" condition | ||
| futureTime := uint64(time.Now().Unix()) + 3600 // 1 hour in the future | ||
|
|
||
| tests := []struct { | ||
| name string | ||
| period uint64 | ||
| blocksPerSecond uint64 | ||
| parentTime uint64 | ||
| parentNumber uint64 | ||
| expectedTime uint64 | ||
| description string | ||
| }{ | ||
| { | ||
| name: "1 second period, 1 block per second - first block", | ||
| period: 1, | ||
| blocksPerSecond: 1, | ||
| parentTime: futureTime, | ||
| parentNumber: 0, | ||
| expectedTime: futureTime + 1, // Should increment by 1 second after 1 block | ||
| description: "First block in period, should increment timestamp", | ||
| }, | ||
| { | ||
| name: "1 second period, 2 blocks per second - first block", | ||
| period: 1, | ||
| blocksPerSecond: 2, | ||
| parentTime: futureTime, | ||
| parentNumber: 0, | ||
| expectedTime: futureTime, // Should not increment yet (block 0, need block 1 to complete period) | ||
| description: "First of two blocks in period, should not increment timestamp yet", | ||
| }, | ||
| { | ||
| name: "1 second period, 2 blocks per second - second block", | ||
| period: 1, | ||
| blocksPerSecond: 2, | ||
| parentTime: futureTime, | ||
| parentNumber: 1, | ||
| expectedTime: futureTime + 1, // Should increment by 1 second after 2 blocks | ||
| description: "Second of two blocks in period, should increment timestamp", | ||
| }, | ||
| { | ||
| name: "2 second period, 1 block per second - first block", | ||
| period: 2, | ||
| blocksPerSecond: 1, | ||
| parentTime: futureTime, | ||
| parentNumber: 0, | ||
| expectedTime: futureTime, // Should not increment yet (need 2 blocks for 2-second period) | ||
| description: "First of two blocks in 2-second period", | ||
| }, | ||
| { | ||
| name: "2 second period, 1 block per second - second block", | ||
| period: 2, | ||
| blocksPerSecond: 1, | ||
| parentTime: futureTime, | ||
| parentNumber: 1, | ||
| expectedTime: futureTime + 2, // Should increment by 2 seconds after 2 blocks | ||
| description: "Second of two blocks in 2-second period, should increment by period", | ||
| }, | ||
| { | ||
| name: "2 second period, 2 blocks per second - fourth block", | ||
| period: 2, | ||
| blocksPerSecond: 2, | ||
| parentTime: futureTime, | ||
| parentNumber: 3, // blocks 0,1,2,3 = 4 blocks total for 2-second period | ||
| expectedTime: futureTime + 2, // Should increment by 2 seconds after 4 blocks | ||
| description: "Last block in 2-second period with 2 blocks/sec", | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| config := ¶ms.SystemContractConfig{ | ||
| Period: tt.period, | ||
| BlocksPerSecond: tt.blocksPerSecond, | ||
| RelaxedPeriod: false, // Ensure we test strict timing | ||
| } | ||
|
|
||
| sc := &SystemContract{ | ||
| config: config, | ||
| } | ||
|
|
||
| parent := &types.Header{ | ||
| Time: tt.parentTime, | ||
| Number: new(big.Int).SetUint64(tt.parentNumber), | ||
| } | ||
|
|
||
| result := sc.CalcTimestamp(parent) | ||
| if result != tt.expectedTime { | ||
| t.Errorf("%s: CalcTimestamp() = %d, want %d\nDescription: %s\nConfig: Period=%d, BlocksPerSecond=%d, ParentNumber=%d", | ||
| tt.name, result, tt.expectedTime, tt.description, tt.period, tt.blocksPerSecond, tt.parentNumber) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestBlockIntervalTiming(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| period uint64 | ||
| blocksPerSecond uint64 | ||
| expectedInterval time.Duration | ||
| description string | ||
| }{ | ||
| { | ||
| name: "1 block per second", | ||
| period: 1, | ||
| blocksPerSecond: 1, | ||
| expectedInterval: 1000 * time.Millisecond, | ||
| description: "Traditional 1 second block time", | ||
| }, | ||
| { | ||
| name: "2 blocks per second", | ||
| period: 1, | ||
| blocksPerSecond: 2, | ||
| expectedInterval: 500 * time.Millisecond, | ||
| description: "Fast blocks every 500ms", | ||
| }, | ||
| { | ||
| name: "4 blocks per second", | ||
| period: 1, | ||
| blocksPerSecond: 4, | ||
| expectedInterval: 250 * time.Millisecond, | ||
| description: "Very fast blocks every 250ms", | ||
| }, | ||
| { | ||
| name: "10 blocks per second", | ||
| period: 1, | ||
| blocksPerSecond: 10, | ||
| expectedInterval: 100 * time.Millisecond, | ||
| description: "Ultra fast blocks every 100ms", | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| periodMs := CalcPeriodMs(tt.blocksPerSecond) | ||
| actualInterval := time.Duration(periodMs) * time.Millisecond | ||
|
|
||
| if actualInterval != tt.expectedInterval { | ||
| t.Errorf("%s: Block interval = %v, want %v\nDescription: %s", | ||
| tt.name, actualInterval, tt.expectedInterval, tt.description) | ||
| } | ||
|
|
||
| // Also verify the math: blocksPerSecond * interval should equal 1 second | ||
| totalTimePerSecond := time.Duration(tt.blocksPerSecond) * actualInterval | ||
| expectedTotalTime := 1 * time.Second | ||
|
|
||
| if totalTimePerSecond != expectedTotalTime { | ||
| t.Errorf("%s: %d blocks * %v interval = %v, want %v", | ||
| tt.name, tt.blocksPerSecond, actualInterval, totalTimePerSecond, expectedTotalTime) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestComplexTimingScenarios(t *testing.T) { | ||
| // Test a more complex scenario: tracking timestamp progression over multiple blocks | ||
| config := ¶ms.SystemContractConfig{ | ||
| Period: 1, | ||
| BlocksPerSecond: 4, // 250ms per block | ||
| RelaxedPeriod: false, | ||
| } | ||
|
|
||
| sc := &SystemContract{ | ||
| config: config, | ||
| } | ||
|
|
||
| baseTime := uint64(time.Now().Unix()) + 3600 // 1 hour in the future | ||
| expectedTimestamps := []uint64{ | ||
| baseTime, // block 0: no increment yet | ||
| baseTime, // block 1: no increment yet | ||
| baseTime, // block 2: no increment yet | ||
| baseTime + 1, // block 3: complete period, increment by 1 second | ||
| baseTime + 1, // block 4: start new period | ||
| baseTime + 1, // block 5: continue period | ||
| baseTime + 1, // block 6: continue period | ||
| baseTime + 2, // block 7: complete second period, increment by 1 second | ||
| } | ||
|
|
||
| for i, expectedTime := range expectedTimestamps { | ||
| parent := &types.Header{ | ||
| Time: baseTime, | ||
| Number: new(big.Int).SetUint64(uint64(i)), | ||
| } | ||
|
|
||
| result := sc.CalcTimestamp(parent) | ||
| if result != expectedTime { | ||
| t.Errorf("Block %d: CalcTimestamp() = %d, want %d", i, result, expectedTime) | ||
| } | ||
|
|
||
| // Update baseTime for next iteration to simulate time progression | ||
| baseTime = result | ||
| } | ||
| } | ||
|
|
||
| func TestDefaultValues(t *testing.T) { | ||
| // Test with default/zero values | ||
| config := ¶ms.SystemContractConfig{ | ||
| Period: 0, // Should default to 1 | ||
| BlocksPerSecond: 0, // Should default to 1 | ||
| RelaxedPeriod: false, | ||
| } | ||
|
|
||
| sc := &SystemContract{ | ||
| config: config, | ||
| } | ||
|
|
||
| futureTime := uint64(time.Now().Unix()) + 3600 // 1 hour in the future | ||
| parent := &types.Header{ | ||
| Time: futureTime, | ||
| Number: new(big.Int).SetUint64(0), | ||
| } | ||
|
|
||
| result := sc.CalcTimestamp(parent) | ||
| // With defaults (period=1, blocksPerSecond=1), first block should increment timestamp | ||
| expected := futureTime + 1 | ||
|
|
||
| if result != expected { | ||
| t.Errorf("With default values: CalcTimestamp() = %d, want %d", result, expected) | ||
| } | ||
|
|
||
| // Verify the period calculation | ||
| periodMs := CalcPeriodMs(0) // Should default to 1000ms | ||
| if periodMs != 1000 { | ||
| t.Errorf("Default period calculation: got %d ms, want 1000 ms", periodMs) | ||
| } | ||
| } | ||
|
|
||
| // TestTimestampIncrementLogic specifically tests the timestamp increment logic | ||
| func TestTimestampIncrementLogic(t *testing.T) { | ||
| config := ¶ms.SystemContractConfig{ | ||
| Period: 1, | ||
| BlocksPerSecond: 2, // 2 blocks per second | ||
| RelaxedPeriod: false, | ||
| } | ||
|
|
||
| sc := &SystemContract{ | ||
| config: config, | ||
| } | ||
|
|
||
| baseTime := uint64(time.Now().Unix()) + 3600 // 1 hour in the future | ||
| currentTime := baseTime | ||
|
|
||
| // Test for several blocks | ||
| for i := 0; i < 6; i++ { | ||
| parent := &types.Header{ | ||
| Time: currentTime, | ||
| Number: new(big.Int).SetUint64(uint64(i)), | ||
| } | ||
|
|
||
| newTimestamp := sc.CalcTimestamp(parent) | ||
| nextBlockNumber := uint64(i + 1) | ||
|
|
||
| // Calculate expected timestamp | ||
| var expectedTimestamp uint64 | ||
| if nextBlockNumber%2 == 0 { | ||
| // This is a period boundary (blocks 2, 4, 6, ...) | ||
| expectedTimestamp = currentTime + 1 | ||
| } else { | ||
| // This is within a period (blocks 1, 3, 5, ...) | ||
| expectedTimestamp = currentTime | ||
| } | ||
|
|
||
| if newTimestamp != expectedTimestamp { | ||
| t.Errorf("Block %d: got timestamp %d, want %d", nextBlockNumber, newTimestamp, expectedTimestamp) | ||
| } | ||
|
|
||
| // Update currentTime for next iteration (simulate blockchain progression) | ||
| currentTime = newTimestamp | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.