go-blockchain/config/hardfork_test.go

198 lines
5 KiB
Go
Raw Permalink Normal View History

// Copyright (c) 2017-2026 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// SPDX-License-Identifier: EUPL-1.2
package config
import (
"testing"
)
func TestVersionAtHeight_Good(t *testing.T) {
tests := []struct {
name string
height uint64
want uint8
}{
// Genesis block should return HF0 (the initial version).
{"genesis", 0, HF0Initial},
// Just before HF1/HF2 activation on mainnet (height 10080).
// HF1 activates at heights > 10080, so height 10080 is still HF0.
{"before_hf1", 10080, HF0Initial},
// At height 10081, both HF1 and HF2 activate (both have height 10080).
// The highest version wins.
{"at_hf1_hf2", 10081, HF2},
// Well past HF2 but before any future forks.
{"mid_chain", 50000, HF2},
// Far future but still below 999999999 — should still be HF2.
{"high_but_before_future", 999999999, HF2},
// At height 1000000000 (> 999999999), all future forks activate.
{"all_forks_active", 1000000000, HF6},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := VersionAtHeight(MainnetForks, tt.height)
if got != tt.want {
t.Errorf("VersionAtHeight(MainnetForks, %d) = %d, want %d", tt.height, got, tt.want)
}
})
}
}
func TestVersionAtHeightTestnet_Good(t *testing.T) {
tests := []struct {
name string
height uint64
want uint8
}{
// On testnet, HF0, HF1, and HF3 all have Height=0 so they are
// active from genesis. The highest version at genesis is HF3.
{"genesis", 0, HF3},
// At height 10, HF2 is still not active (activates at > 10).
{"before_hf2", 10, HF3},
// At height 11, HF2 activates — but HF3 is already active so
// the version remains 3.
{"after_hf2", 11, HF3},
// At height 101, HF4 Zarcanum activates.
{"after_hf4", 101, HF4Zarcanum},
// At height 201, HF5 activates.
{"after_hf5", 201, HF5},
// Far future activates HF6.
{"far_future", 1000000000, HF6},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := VersionAtHeight(TestnetForks, tt.height)
if got != tt.want {
t.Errorf("VersionAtHeight(TestnetForks, %d) = %d, want %d", tt.height, got, tt.want)
}
})
}
}
func TestIsHardForkActive_Good(t *testing.T) {
tests := []struct {
name string
version uint8
height uint64
want bool
}{
// HF0 is always active (Height=0).
{"hf0_at_genesis", HF0Initial, 0, true},
{"hf0_at_10000", HF0Initial, 10000, true},
// HF1 activates at heights > 10080.
{"hf1_before", HF1, 10080, false},
{"hf1_at", HF1, 10081, true},
// HF4 is far future on mainnet.
{"hf4_now", HF4Zarcanum, 50000, false},
{"hf4_far_future", HF4Zarcanum, 1000000000, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := IsHardForkActive(MainnetForks, tt.version, tt.height)
if got != tt.want {
t.Errorf("IsHardForkActive(MainnetForks, %d, %d) = %v, want %v",
tt.version, tt.height, got, tt.want)
}
})
}
}
func TestIsHardForkActive_Bad(t *testing.T) {
// Querying a version that does not exist should return false.
got := IsHardForkActive(MainnetForks, 99, 1000000000)
if got {
t.Error("IsHardForkActive with unknown version should return false")
}
}
func TestVersionAtHeight_Ugly(t *testing.T) {
// Empty fork list should return version 0.
got := VersionAtHeight(nil, 100)
if got != 0 {
t.Errorf("VersionAtHeight(nil, 100) = %d, want 0", got)
}
// Single-element fork list.
single := []HardFork{{Version: 1, Height: 0, Mandatory: true}}
got = VersionAtHeight(single, 0)
if got != 1 {
t.Errorf("VersionAtHeight(single, 0) = %d, want 1", got)
}
}
func TestMainnetForkSchedule_Good(t *testing.T) {
// Verify the fork schedule matches the C++ ZANO_HARDFORK_* constants.
expectedMainnet := []struct {
version uint8
height uint64
}{
{0, 0},
{1, 10080},
{2, 10080},
{3, 999999999},
{4, 999999999},
{5, 999999999},
{6, 999999999},
}
if len(MainnetForks) != len(expectedMainnet) {
t.Fatalf("MainnetForks length: got %d, want %d", len(MainnetForks), len(expectedMainnet))
}
for i, exp := range expectedMainnet {
hf := MainnetForks[i]
if hf.Version != exp.version {
t.Errorf("MainnetForks[%d].Version = %d, want %d", i, hf.Version, exp.version)
}
if hf.Height != exp.height {
t.Errorf("MainnetForks[%d].Height = %d, want %d", i, hf.Height, exp.height)
}
}
}
func TestTestnetForkSchedule_Good(t *testing.T) {
expectedTestnet := []struct {
version uint8
height uint64
}{
{0, 0},
{1, 0},
{2, 10},
{3, 0},
{4, 100},
{5, 200},
{6, 999999999},
}
if len(TestnetForks) != len(expectedTestnet) {
t.Fatalf("TestnetForks length: got %d, want %d", len(TestnetForks), len(expectedTestnet))
}
for i, exp := range expectedTestnet {
hf := TestnetForks[i]
if hf.Version != exp.version {
t.Errorf("TestnetForks[%d].Version = %d, want %d", i, hf.Version, exp.version)
}
if hf.Height != exp.height {
t.Errorf("TestnetForks[%d].Height = %d, want %d", i, hf.Height, exp.height)
}
}
}