diff --git a/cmd/algod/main.go b/cmd/algod/main.go index 47008256ac..306435ad94 100644 --- a/cmd/algod/main.go +++ b/cmd/algod/main.go @@ -194,6 +194,10 @@ func run() int { log.Fatalf("Error validating DNSBootstrap input: %v", err) } + // Apply network-specific consensus overrides, noting the configurable consensus protocols file + // takes precedence over network-specific overrides. + config.ApplyShorterUpgradeRoundsForDevNetworks(genesis.Network) + err = config.LoadConfigurableConsensusProtocols(absolutePath) if err != nil { // log is not setup yet, this will log to stderr diff --git a/config/consensus.go b/config/consensus.go index f86e45e831..c5f3801b8e 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -1560,6 +1560,23 @@ func initConsensusProtocols() { vAlpha4.ApprovedUpgrades[protocol.ConsensusVAlpha5] = 10000 } +// ApplyShorterUpgradeRoundsForDevNetworks applies a shorter upgrade round time for the Devnet and Betanet networks. +// This function should not take precedence over settings loaded via `PreloadConfigurableConsensusProtocols`. +func ApplyShorterUpgradeRoundsForDevNetworks(id protocol.NetworkID) { + if id == Betanet || id == Devnet { + // Go through all approved upgrades and set to the MinUpgradeWaitRounds valid where MinUpgradeWaitRounds is set + for _, p := range Consensus { + if p.ApprovedUpgrades != nil { + for v := range p.ApprovedUpgrades { + if p.MinUpgradeWaitRounds > 0 { + p.ApprovedUpgrades[v] = p.MinUpgradeWaitRounds + } + } + } + } + } +} + // Global defines global Algorand protocol parameters which should not be overridden. type Global struct { SmallLambda time.Duration // min amount of time to wait for leader's credential (i.e., time to propagate one credential) diff --git a/config/consensus_test.go b/config/consensus_test.go index d7fbed4085..c0d079cdf0 100644 --- a/config/consensus_test.go +++ b/config/consensus_test.go @@ -59,6 +59,83 @@ func TestConsensusUpgradeWindow(t *testing.T) { } } +func TestConsensusUpgradeWindow_NetworkOverrides(t *testing.T) { + partitiontest.PartitionTest(t) + + ApplyShorterUpgradeRoundsForDevNetworks(Devnet) + for _, params := range Consensus { + for toVersion, delay := range params.ApprovedUpgrades { + if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 { + require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion) + require.Equalf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + // This check is not really needed, but leaving for sanity + require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + } else { + // If no MinUpgradeWaitRounds is set, leaving everything as zero value is expected + require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion) + } + } + } + + // Should be no-ops for Mainnet + Consensus = make(ConsensusProtocols) + initConsensusProtocols() + + origConsensus := Consensus.DeepCopy() + ApplyShorterUpgradeRoundsForDevNetworks(Mainnet) + require.EqualValues(t, origConsensus, Consensus) + for _, params := range Consensus { + for toVersion, delay := range params.ApprovedUpgrades { + if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 { + require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion) + require.GreaterOrEqualf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + } else { + require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion) + + } + } + } + + // reset consensus settings + Consensus = make(ConsensusProtocols) + initConsensusProtocols() + + ApplyShorterUpgradeRoundsForDevNetworks(Betanet) + for _, params := range Consensus { + for toVersion, delay := range params.ApprovedUpgrades { + if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 { + require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion) + require.Equalf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + // This check is not really needed, but leaving for sanity + require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + } else { + // If no MinUpgradeWaitRounds is set, leaving everything as zero value is expected + require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion) + } + } + } + + // should be no-ops for Testnet + Consensus = make(ConsensusProtocols) + initConsensusProtocols() + + ApplyShorterUpgradeRoundsForDevNetworks(Testnet) + require.EqualValues(t, origConsensus, Consensus) + for _, params := range Consensus { + for toVersion, delay := range params.ApprovedUpgrades { + if params.MinUpgradeWaitRounds != 0 || params.MaxUpgradeWaitRounds != 0 { + require.NotZerof(t, delay, "From :%v\nTo :%v", params, toVersion) + require.GreaterOrEqualf(t, delay, params.MinUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + require.LessOrEqualf(t, delay, params.MaxUpgradeWaitRounds, "From :%v\nTo :%v", params, toVersion) + } else { + require.Zerof(t, delay, "From :%v\nTo :%v", params, toVersion) + + } + } + } +} + func TestConsensusStateProofParams(t *testing.T) { partitiontest.PartitionTest(t)