mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 18:37:26 +08:00
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete * 2.1.0 main node rollup
218 lines
7.7 KiB
Go
218 lines
7.7 KiB
Go
package difficulty
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestAsertDifficultyAdjuster_GetNextDifficulty(t *testing.T) {
|
|
// Initialize with the specified anchor values
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
currentFrameNumber uint64
|
|
currentTime int64
|
|
expectedRange [2]uint64 // min and max expected values
|
|
}{
|
|
{
|
|
name: "Same frame, same time - should return anchor difficulty",
|
|
currentFrameNumber: anchorFrameNumber,
|
|
currentTime: anchorParentTime,
|
|
expectedRange: [2]uint64{159800, 160200}, // Allow small variance due to algorithm
|
|
},
|
|
{
|
|
name: "Next frame, ideal time elapsed",
|
|
currentFrameNumber: anchorFrameNumber + 1,
|
|
currentTime: anchorParentTime + IDEAL_FRAME_TIME,
|
|
expectedRange: [2]uint64{159800, 160200}, // Should stay close to anchor
|
|
},
|
|
{
|
|
name: "10 frames later, ideal time elapsed",
|
|
currentFrameNumber: anchorFrameNumber + 10,
|
|
currentTime: anchorParentTime + 10*IDEAL_FRAME_TIME,
|
|
expectedRange: [2]uint64{159800, 160200}, // Should stay close to anchor
|
|
},
|
|
{
|
|
name: "Next frame, double time elapsed (too slow)",
|
|
currentFrameNumber: anchorFrameNumber + 1,
|
|
currentTime: anchorParentTime + 2*IDEAL_FRAME_TIME,
|
|
expectedRange: [2]uint64{159500, 160000}, // Difficulty should barely be impacted
|
|
},
|
|
{
|
|
name: "Next frame, half time elapsed (too fast)",
|
|
currentFrameNumber: anchorFrameNumber + 1,
|
|
currentTime: anchorParentTime + IDEAL_FRAME_TIME/2,
|
|
expectedRange: [2]uint64{160000, 160500}, // Difficulty should barely be impacted
|
|
},
|
|
{
|
|
name: "100 frames later, significantly slower",
|
|
currentFrameNumber: anchorFrameNumber + 100,
|
|
currentTime: anchorParentTime + 500*IDEAL_FRAME_TIME, // 500% slower
|
|
expectedRange: [2]uint64{100000, 110000}, // Difficulty should decrease significantly
|
|
},
|
|
{
|
|
name: "100 frames later, significantly faster",
|
|
currentFrameNumber: anchorFrameNumber + 1000,
|
|
currentTime: anchorParentTime + 50*IDEAL_FRAME_TIME, // 500% faster
|
|
expectedRange: [2]uint64{380000, 400000}, // Difficulty should increase significantly
|
|
},
|
|
{
|
|
name: "Extreme case - very slow progress",
|
|
currentFrameNumber: anchorFrameNumber + 100,
|
|
currentTime: anchorParentTime + 100000*IDEAL_FRAME_TIME,
|
|
expectedRange: [2]uint64{50000, 100000}, // Should decrease towards minimum
|
|
},
|
|
{
|
|
name: "Edge case - minimum difficulty clamp",
|
|
currentFrameNumber: anchorFrameNumber + 1,
|
|
currentTime: anchorParentTime + 100000*IDEAL_FRAME_TIME, // Extremely slow
|
|
expectedRange: [2]uint64{50000, 50001}, // Should clamp to minimum
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := adjuster.GetNextDifficulty(tt.currentFrameNumber, tt.currentTime)
|
|
if result < tt.expectedRange[0] || result > tt.expectedRange[1] {
|
|
t.Errorf("GetNextDifficulty() = %d, expected between %d and %d",
|
|
result, tt.expectedRange[0], tt.expectedRange[1])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAsertDifficultyAdjuster_ExponentCalculation(t *testing.T) {
|
|
// Test the exponent calculation specifically
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
// Test case where exponent should be positive (time elapsed > expected)
|
|
slowFrame := anchorFrameNumber + 100
|
|
slowTime := anchorParentTime + 200*IDEAL_FRAME_TIME // Double the expected time
|
|
slowDifficulty := adjuster.GetNextDifficulty(slowFrame, slowTime)
|
|
|
|
// Test case where exponent should be negative (time elapsed < expected)
|
|
fastFrame := anchorFrameNumber + 100
|
|
fastTime := anchorParentTime + 50*IDEAL_FRAME_TIME // Half the expected time
|
|
fastDifficulty := adjuster.GetNextDifficulty(fastFrame, fastTime)
|
|
|
|
// Fast mining should result in higher difficulty
|
|
if fastDifficulty <= slowDifficulty {
|
|
t.Errorf("Fast mining difficulty (%d) should be higher than slow mining difficulty (%d)",
|
|
fastDifficulty, slowDifficulty)
|
|
}
|
|
}
|
|
|
|
func TestAsertDifficultyAdjuster_ConsistentBehavior(t *testing.T) {
|
|
// Test that the algorithm produces consistent results
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
// Run the same calculation multiple times to ensure deterministic behavior
|
|
testFrame := anchorFrameNumber + 50
|
|
testTime := anchorParentTime + 50*IDEAL_FRAME_TIME + 5000 // Slightly off ideal
|
|
|
|
results := make([]uint64, 5)
|
|
for i := 0; i < 5; i++ {
|
|
results[i] = adjuster.GetNextDifficulty(testFrame, testTime)
|
|
}
|
|
|
|
// All results should be identical
|
|
for i := 1; i < len(results); i++ {
|
|
if results[i] != results[0] {
|
|
t.Errorf("Inconsistent results: run %d returned %d, expected %d",
|
|
i, results[i], results[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAsertDifficultyAdjuster_LargeFrameJumps(t *testing.T) {
|
|
// Test behavior with large frame number jumps
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
// Test with a very large frame jump but proportional time
|
|
largeJump := uint64(10000)
|
|
largeJumpFrame := anchorFrameNumber + largeJump
|
|
largeJumpTime := anchorParentTime + int64(largeJump)*IDEAL_FRAME_TIME
|
|
|
|
result := adjuster.GetNextDifficulty(largeJumpFrame, largeJumpTime)
|
|
|
|
// Should stay close to anchor difficulty since time is proportional
|
|
if result < 159000 || result > 161000 {
|
|
t.Errorf("Large proportional jump resulted in unexpected difficulty: %d", result)
|
|
}
|
|
}
|
|
|
|
func TestAsertDifficultyAdjuster_NegativeTimeDelta(t *testing.T) {
|
|
// Test edge case where current time might be before anchor time
|
|
// (shouldn't happen in practice but good to test)
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
// Current time is before anchor time
|
|
result := adjuster.GetNextDifficulty(anchorFrameNumber+1, anchorParentTime-IDEAL_FRAME_TIME)
|
|
|
|
// Should result in very high difficulty (frames coming too fast)
|
|
if result <= uint64(anchorDifficulty) {
|
|
t.Errorf("Negative time delta should increase difficulty, got %d", result)
|
|
}
|
|
}
|
|
|
|
func BenchmarkAsertDifficultyAdjuster_GetNextDifficulty(b *testing.B) {
|
|
anchorDifficulty := uint32(160000)
|
|
anchorFrameNumber := uint64(244200)
|
|
anchorParentTime := time.Now().Add(-15 * time.Second).UnixMilli()
|
|
|
|
adjuster := &AsertDifficultyAdjuster{
|
|
anchorFrameNumber: anchorFrameNumber,
|
|
anchorParentTime: anchorParentTime,
|
|
anchorDifficulty: anchorDifficulty,
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = adjuster.GetNextDifficulty(
|
|
anchorFrameNumber+uint64(i%1000),
|
|
anchorParentTime+int64(i%1000)*IDEAL_FRAME_TIME,
|
|
)
|
|
}
|
|
}
|