mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge #6225: feat: bury v20 fork - fire up test chains by first block - 4/n
23812555b1
fix: possible deadlock during calculation of signals for historical blocks during re-index (Konstantin Akimov)1087489fd4
feat: bury v20 deployment (Konstantin Akimov)64cedb30bd
feat: actually test something EHF unit tests (Konstantin Akimov)762a808b8c
chore: drop irrelevant bip9 code from feature_llmq_rotation.py (Konstantin Akimov)7735631aad
fix: remove v20 from test feature_llmq_evo as far as mn_rr used (Konstantin Akimov)ca83b26815
fix: crash in CreditPool: it meant to check that DIP0003 is activated (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented V20 is activated on mainnet: time to bury it! https://github.com/dashpay/dash/issues/6186 ## What was done? Hard-fork v20 is buried and it requires to implement multiple fixes, simplifications, refactoring: - some tests for EHF moved from functional tests to unit tests - fixed crash in Credit Pool if DIP3 is not activated yet - added a requirement for v20 activation for `CMNHFManager::GetSignalsStage` - removed useless code from functional test feature_llmq_rotation - renamed variables "v20" to "mn_rr" in feature_llmq_evo.py so far as actually used fork is mn_rr ## How Has This Been Tested? Some unit and functional tests to succeed. Done reindex (just in case): src/qt/dash-qt -reindex -assumevalid=0 src/qt/dash-qt -reindex -assumevalid=0 -testnet ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: ACK23812555b1
PastaPastaPasta: utACK23812555b1
Tree-SHA512: eec35745baa695f3f286d39b6a61fa0a9f34820b13d1dd4cfbd1efe707850283892c39bf7fe49c49c812e0c02465d64df11480b3f12aa7f21b59a71eeae7260e
This commit is contained in:
commit
6d426515a5
@ -192,7 +192,8 @@ public:
|
|||||||
consensus.DIP0024Height = 1737792; // 0000000000000001342be9c0b75ad40c276beaad91616423c4d9cb101b3db438
|
consensus.DIP0024Height = 1737792; // 0000000000000001342be9c0b75ad40c276beaad91616423c4d9cb101b3db438
|
||||||
consensus.DIP0024QuorumsHeight = 1738698; // 000000000000001aa25181e4c466e593992c98f9eb21c69ee757b8bb0af50244
|
consensus.DIP0024QuorumsHeight = 1738698; // 000000000000001aa25181e4c466e593992c98f9eb21c69ee757b8bb0af50244
|
||||||
consensus.V19Height = 1899072; // 0000000000000015e32e73052d663626327004c81c5c22cb8b42c361015c0eae
|
consensus.V19Height = 1899072; // 0000000000000015e32e73052d663626327004c81c5c22cb8b42c361015c0eae
|
||||||
consensus.MinBIP9WarningHeight = 1899072 + 2016; // V19 activation height + miner confirmation window
|
consensus.V20Height = 1987776; // 000000000000001bf41cff06b76780050682ca29e61a91c391893d4745579777
|
||||||
|
consensus.MinBIP9WarningHeight = 1987776 + 2016; // V20 activation height + miner confirmation window
|
||||||
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
|
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
|
||||||
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
||||||
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
||||||
@ -207,14 +208,6 @@ public:
|
|||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1700006400; // November 15, 2023
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nTimeout = 1731628800; // November 15, 2024
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize = 4032;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdStart = 3226; // 80% of 4032
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 2420; // 60% of 4032
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods
|
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1704067200; // January 1, 2024
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1704067200; // January 1, 2024
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 1767225600; // January 1, 2026
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 1767225600; // January 1, 2026
|
||||||
@ -394,7 +387,8 @@ public:
|
|||||||
consensus.DIP0024Height = 769700; // 0000008d84e4efd890ae95c70a7a6126a70a80e5c19e4cb264a5b3469aeef172
|
consensus.DIP0024Height = 769700; // 0000008d84e4efd890ae95c70a7a6126a70a80e5c19e4cb264a5b3469aeef172
|
||||||
consensus.DIP0024QuorumsHeight = 770730; // 0000003c43b3ae7fffe61278ca5537a0e256ebf4d709d45f0ab040271074d51e
|
consensus.DIP0024QuorumsHeight = 770730; // 0000003c43b3ae7fffe61278ca5537a0e256ebf4d709d45f0ab040271074d51e
|
||||||
consensus.V19Height = 850100; // 000004728b8ff2a16b9d4eebb0fd61eeffadc9c7fe4b0ec0b5a739869401ab5b
|
consensus.V19Height = 850100; // 000004728b8ff2a16b9d4eebb0fd61eeffadc9c7fe4b0ec0b5a739869401ab5b
|
||||||
consensus.MinBIP9WarningHeight = 850100 + 2016; // v19 activation height + miner confirmation window
|
consensus.V20Height = 905100; // 0000020c5e0f86f385cbf8e90210de9a9fd63633f01433bf47a6b3227a2851fd
|
||||||
|
consensus.MinBIP9WarningHeight = 905100 + 2016; // v19 activation height + miner confirmation window
|
||||||
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
|
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
|
||||||
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
||||||
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
||||||
@ -409,14 +403,6 @@ public:
|
|||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1693526400; // Friday, September 1, 2023 0:00:00
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize = 100;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdStart = 80; // 80% of 100
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 60; // 60% of 100
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods
|
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1693526400; // Friday, September 1, 2023 0:00:00
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1693526400; // Friday, September 1, 2023 0:00:00
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
@ -570,7 +556,8 @@ public:
|
|||||||
consensus.DIP0024Height = 300;
|
consensus.DIP0024Height = 300;
|
||||||
consensus.DIP0024QuorumsHeight = 300;
|
consensus.DIP0024QuorumsHeight = 300;
|
||||||
consensus.V19Height = 300;
|
consensus.V19Height = 300;
|
||||||
consensus.MinBIP9WarningHeight = 300 + 2016; // v19 activation height + miner confirmation window
|
consensus.V20Height = 300;
|
||||||
|
consensus.MinBIP9WarningHeight = 300 + 2016; // v20 activation height + miner confirmation window
|
||||||
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
|
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
|
||||||
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
||||||
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
|
||||||
@ -585,14 +572,6 @@ public:
|
|||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1661990400; // Sep 1st, 2022
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize = 120;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdStart = 80; // 80% of 100
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 60; // 60% of 100
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods
|
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1661990400; // Sep 1st, 2022
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1661990400; // Sep 1st, 2022
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
@ -810,6 +789,7 @@ public:
|
|||||||
consensus.DIP0024Height = 900;
|
consensus.DIP0024Height = 900;
|
||||||
consensus.DIP0024QuorumsHeight = 900;
|
consensus.DIP0024QuorumsHeight = 900;
|
||||||
consensus.V19Height = 900;
|
consensus.V19Height = 900;
|
||||||
|
consensus.V20Height = 1200;
|
||||||
consensus.MinBIP9WarningHeight = 0;
|
consensus.MinBIP9WarningHeight = 0;
|
||||||
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
|
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
|
||||||
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
|
||||||
@ -826,14 +806,6 @@ public:
|
|||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 0;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize = 400;
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdStart = 384; // 80% of 480
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 288; // 60% of 480
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods
|
|
||||||
|
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 0;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 0;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
@ -1062,6 +1034,8 @@ static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& conse
|
|||||||
consensus.DIP0008Height = int{height};
|
consensus.DIP0008Height = int{height};
|
||||||
} else if (name == "dip0020") {
|
} else if (name == "dip0020") {
|
||||||
consensus.DIP0020Height = int{height};
|
consensus.DIP0020Height = int{height};
|
||||||
|
} else if (name == "v20") {
|
||||||
|
consensus.V20Height = int{height};
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
|
throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
|
|||||||
argsman.AddArg("-dip3params=<activation>:<enforcement>", "Override DIP3 activation and enforcement heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-dip3params=<activation>:<enforcement>", "Override DIP3 activation and enforcement heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||||
argsman.AddArg("-dip8params=<activation>", "Override DIP8 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-dip8params=<activation>", "Override DIP8 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||||
argsman.AddArg("-bip147height=<activation>", "Override BIP147 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-bip147height=<activation>", "Override BIP147 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||||
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv, brr, dip0001, dip0008, dip0020). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv, brr, dip0001, dip0008, dip0020, v20). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-highsubsidyblocks=<n>", "The number of blocks with a higher than normal subsidy to mine at the start of a chain. Block after that height will have fixed subsidy base. (default: 0, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-highsubsidyblocks=<n>", "The number of blocks with a higher than normal subsidy to mine at the start of a chain. Block after that height will have fixed subsidy base. (default: 0, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||||
argsman.AddArg("-highsubsidyfactor=<n>", "The factor to multiply the normal block subsidy by while in the highsubsidyblocks window of a chain (default: 1, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-highsubsidyfactor=<n>", "The factor to multiply the normal block subsidy by while in the highsubsidyblocks window of a chain (default: 1, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||||
argsman.AddArg("-llmqchainlocks=<quorum name>", "Override the default LLMQ type used for ChainLocks. Allows using ChainLocks with smaller LLMQs. (default: llmq_devnet, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
argsman.AddArg("-llmqchainlocks=<quorum name>", "Override the default LLMQ type used for ChainLocks. Allows using ChainLocks with smaller LLMQs. (default: llmq_devnet, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||||
|
@ -32,12 +32,12 @@ enum BuriedDeployment : int16_t {
|
|||||||
DEPLOYMENT_DIP0024,
|
DEPLOYMENT_DIP0024,
|
||||||
DEPLOYMENT_BRR,
|
DEPLOYMENT_BRR,
|
||||||
DEPLOYMENT_V19,
|
DEPLOYMENT_V19,
|
||||||
|
DEPLOYMENT_V20,
|
||||||
};
|
};
|
||||||
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_V19; }
|
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_V20; }
|
||||||
|
|
||||||
enum DeploymentPos : uint16_t {
|
enum DeploymentPos : uint16_t {
|
||||||
DEPLOYMENT_TESTDUMMY,
|
DEPLOYMENT_TESTDUMMY,
|
||||||
DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon
|
|
||||||
DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation
|
DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation
|
||||||
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
|
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
|
||||||
MAX_VERSION_BITS_DEPLOYMENTS
|
MAX_VERSION_BITS_DEPLOYMENTS
|
||||||
@ -142,6 +142,8 @@ struct Params {
|
|||||||
int DIP0024QuorumsHeight;
|
int DIP0024QuorumsHeight;
|
||||||
/** Block height at which V19 (Basic BLS and EvoNodes) becomes active */
|
/** Block height at which V19 (Basic BLS and EvoNodes) becomes active */
|
||||||
int V19Height;
|
int V19Height;
|
||||||
|
/** Block height at which V20 (Deployment of EHF, LLMQ Randomness Beacon) becomes active */
|
||||||
|
int V20Height;
|
||||||
/** Don't warn about unknown BIP 9 activations below this height.
|
/** Don't warn about unknown BIP 9 activations below this height.
|
||||||
* This prevents us from warning about the CSV and DIP activations. */
|
* This prevents us from warning about the CSV and DIP activations. */
|
||||||
int MinBIP9WarningHeight;
|
int MinBIP9WarningHeight;
|
||||||
@ -205,6 +207,8 @@ struct Params {
|
|||||||
return BRRHeight;
|
return BRRHeight;
|
||||||
case DEPLOYMENT_V19:
|
case DEPLOYMENT_V19:
|
||||||
return V19Height;
|
return V19Height;
|
||||||
|
case DEPLOYMENT_V20:
|
||||||
|
return V20Height;
|
||||||
} // no default case, so the compiler can warn about missing cases
|
} // no default case, so the compiler can warn about missing cases
|
||||||
return std::numeric_limits<int>::max();
|
return std::numeric_limits<int>::max();
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
|
|||||||
/*.name =*/ "testdummy",
|
/*.name =*/ "testdummy",
|
||||||
/*.gbt_force =*/ true,
|
/*.gbt_force =*/ true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
/*.name =*/"v20",
|
|
||||||
/*.gbt_force =*/true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
/*.name =*/"mn_rr",
|
/*.name =*/"mn_rr",
|
||||||
/*.gbt_force =*/true,
|
/*.gbt_force =*/true,
|
||||||
@ -49,6 +45,8 @@ std::string DeploymentName(Consensus::BuriedDeployment dep)
|
|||||||
return "realloc";
|
return "realloc";
|
||||||
case Consensus::DEPLOYMENT_V19:
|
case Consensus::DEPLOYMENT_V19:
|
||||||
return "v19";
|
return "v19";
|
||||||
|
case Consensus::DEPLOYMENT_V20:
|
||||||
|
return "v20";
|
||||||
} // no default case, so the compiler can warn about missing cases
|
} // no default case, so the compiler can warn about missing cases
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ CMNHFManager::~CMNHFManager()
|
|||||||
|
|
||||||
CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pindexPrev)
|
CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pindexPrev)
|
||||||
{
|
{
|
||||||
|
if (!DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return {};
|
||||||
|
|
||||||
Signals signals = GetForBlock(pindexPrev);
|
Signals signals = GetForBlock(pindexPrev);
|
||||||
if (pindexPrev == nullptr) return {};
|
if (pindexPrev == nullptr) return {};
|
||||||
const int height = pindexPrev->nHeight + 1;
|
const int height = pindexPrev->nHeight + 1;
|
||||||
@ -116,6 +118,10 @@ bool CheckMNHFTx(const ChainstateManager& chainman, const llmq::CQuorumManager&
|
|||||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-version");
|
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Params().IsValidMNActivation(mnhfTx.signal.versionBit, pindexPrev->GetMedianTimePast())) {
|
||||||
|
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-non-ehf");
|
||||||
|
}
|
||||||
|
|
||||||
const CBlockIndex* pindexQuorum = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(mnhfTx.signal.quorumHash));
|
const CBlockIndex* pindexQuorum = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(mnhfTx.signal.quorumHash));
|
||||||
if (!pindexQuorum) {
|
if (!pindexQuorum) {
|
||||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-quorum-hash");
|
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-quorum-hash");
|
||||||
@ -139,10 +145,6 @@ bool CheckMNHFTx(const ChainstateManager& chainman, const llmq::CQuorumManager&
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Params().IsValidMNActivation(mnhfTx.signal.versionBit, pindexPrev->GetMedianTimePast())) {
|
|
||||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-non-ehf");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +321,7 @@ std::optional<CMNHFManager::Signals> CMNHFManager::GetFromCache(const CBlockInde
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
LOCK(cs_cache);
|
LOCK(cs_cache);
|
||||||
if (ThresholdState::ACTIVE != v20_activation.State(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) {
|
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) {
|
||||||
mnhfCache.insert(blockHash, signals);
|
mnhfCache.insert(blockHash, signals);
|
||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
@ -340,10 +342,8 @@ void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const p
|
|||||||
LOCK(cs_cache);
|
LOCK(cs_cache);
|
||||||
mnhfCache.insert(blockHash, signals);
|
mnhfCache.insert(blockHash, signals);
|
||||||
}
|
}
|
||||||
{
|
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
|
||||||
LOCK(cs_cache);
|
|
||||||
if (ThresholdState::ACTIVE != v20_activation.State(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
|
|
||||||
}
|
|
||||||
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
|
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,8 +109,6 @@ private:
|
|||||||
// versionBit <-> height
|
// versionBit <-> height
|
||||||
unordered_lru_cache<uint256, Signals, StaticSaltedHasher> mnhfCache GUARDED_BY(cs_cache) {MNHFCacheSize};
|
unordered_lru_cache<uint256, Signals, StaticSaltedHasher> mnhfCache GUARDED_BY(cs_cache) {MNHFCacheSize};
|
||||||
|
|
||||||
// This cache is used only for v20 activation to avoid double lock through VersionBitsConditionChecker::SignalHeight
|
|
||||||
VersionBitsCache v20_activation GUARDED_BY(cs_cache);
|
|
||||||
public:
|
public:
|
||||||
explicit CMNHFManager(CEvoDB& evoDb);
|
explicit CMNHFManager(CEvoDB& evoDb);
|
||||||
~CMNHFManager();
|
~CMNHFManager();
|
||||||
|
@ -278,6 +278,7 @@ bool CSpecialTxProcessor::CheckCreditPoolDiffForBlock(const CBlock& block, const
|
|||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_DIP0003)) return true;
|
||||||
if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_V20)) return true;
|
if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_V20)) return true;
|
||||||
|
|
||||||
auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_chainman.m_blockman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state);
|
auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_chainman.m_blockman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state);
|
||||||
|
@ -490,21 +490,7 @@ CAmount CSuperblock::GetPaymentsLimit(const CChain& active_chain, int nBlockHeig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CBlockIndex* pindex = active_chain.Tip();
|
const bool fV20Active{nBlockHeight >= consensusParams.V20Height};
|
||||||
if (pindex->nHeight > nBlockHeight) pindex = pindex->GetAncestor(nBlockHeight);
|
|
||||||
|
|
||||||
const auto v20_state = g_versionbitscache.State(pindex, consensusParams, Consensus::DEPLOYMENT_V20);
|
|
||||||
bool fV20Active{v20_state == ThresholdState::ACTIVE};
|
|
||||||
if (!fV20Active && nBlockHeight > pindex->nHeight) {
|
|
||||||
// If fV20Active isn't active yet and nBlockHeight refers to a future SuperBlock
|
|
||||||
// then we need to check if the fork is locked_in and see if it will be active by the time of the future SuperBlock
|
|
||||||
if (v20_state == ThresholdState::LOCKED_IN) {
|
|
||||||
int activation_height = g_versionbitscache.StateSinceHeight(pindex, consensusParams, Consensus::DEPLOYMENT_V20) + static_cast<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize);
|
|
||||||
if (nBlockHeight >= activation_height) {
|
|
||||||
fV20Active = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// min subsidy for high diff networks and vice versa
|
// min subsidy for high diff networks and vice versa
|
||||||
int nBits = consensusParams.fPowAllowMinDifficultyBlocks ? UintToArith256(consensusParams.powLimit).GetCompact() : 1;
|
int nBits = consensusParams.fPowAllowMinDifficultyBlocks ? UintToArith256(consensusParams.powLimit).GetCompact() : 1;
|
||||||
|
@ -1835,7 +1835,7 @@ RPCHelpMan getblockchaininfo()
|
|||||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0024);
|
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DIP0024);
|
||||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BRR);
|
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_BRR);
|
||||||
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V19);
|
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V19);
|
||||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_V20);
|
SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V20);
|
||||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_MN_RR);
|
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_MN_RR);
|
||||||
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||||
|
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <evo/mnhftx.h>
|
#include <evo/mnhftx.h>
|
||||||
#include <evo/specialtx.h>
|
#include <evo/specialtx.h>
|
||||||
|
#include <llmq/context.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <test/util/setup_common.h>
|
#include <test/util/setup_common.h>
|
||||||
@ -18,24 +20,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
bool VerifyMNHFTx(const CTransaction& tx, TxValidationState& state)
|
static CMutableTransaction CreateMNHFTx(const uint256& quorumHash, const CBLSSignature& cblSig, const uint16_t& versionBit)
|
||||||
{
|
|
||||||
if (const auto opt_mnhfTx_payload = GetTxPayload<MNHFTxPayload>(tx); !opt_mnhfTx_payload) {
|
|
||||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-payload");
|
|
||||||
} else if (opt_mnhfTx_payload->nVersion == 0 ||
|
|
||||||
opt_mnhfTx_payload->nVersion > MNHFTxPayload::CURRENT_VERSION) {
|
|
||||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-version");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CMutableTransaction CreateMNHFTx(const uint256& mnhfTxHash, const CBLSSignature& cblSig, const uint16_t& versionBit)
|
|
||||||
{
|
{
|
||||||
MNHFTxPayload extraPayload;
|
MNHFTxPayload extraPayload;
|
||||||
extraPayload.nVersion = 1;
|
extraPayload.nVersion = 1;
|
||||||
extraPayload.signal.versionBit = versionBit;
|
extraPayload.signal.versionBit = versionBit;
|
||||||
extraPayload.signal.quorumHash = mnhfTxHash;
|
extraPayload.signal.quorumHash = quorumHash;
|
||||||
extraPayload.signal.sig = cblSig;
|
extraPayload.signal.sig = cblSig;
|
||||||
|
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
@ -46,19 +36,18 @@ static CMutableTransaction CreateMNHFTx(const uint256& mnhfTxHash, const CBLSSig
|
|||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(evo_mnhf_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(evo_mnhf_tests, TestChain100Setup)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(verify_mnhf_specialtx_tests)
|
BOOST_AUTO_TEST_CASE(verify_mnhf_specialtx_tests)
|
||||||
{
|
{
|
||||||
int count = 10;
|
int count = 10;
|
||||||
uint16_t ver = 2;
|
uint16_t bit = 1;
|
||||||
|
|
||||||
std::vector<CBLSSignature> vec_sigs;
|
std::vector<CBLSSignature> vec_sigs;
|
||||||
std::vector<CBLSPublicKey> vec_pks;
|
std::vector<CBLSPublicKey> vec_pks;
|
||||||
std::vector<CBLSSecretKey> vec_sks;
|
std::vector<CBLSSecretKey> vec_sks;
|
||||||
|
|
||||||
CBLSSecretKey sk;
|
CBLSSecretKey sk;
|
||||||
uint256 hash = GetRandHash();
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
sk.MakeNewKey();
|
sk.MakeNewKey();
|
||||||
vec_pks.push_back(sk.GetPublicKey());
|
vec_pks.push_back(sk.GetPublicKey());
|
||||||
@ -71,13 +60,27 @@ BOOST_AUTO_TEST_CASE(verify_mnhf_specialtx_tests)
|
|||||||
BOOST_CHECK(ag_sk.IsValid());
|
BOOST_CHECK(ag_sk.IsValid());
|
||||||
BOOST_CHECK(ag_pk.IsValid());
|
BOOST_CHECK(ag_pk.IsValid());
|
||||||
|
|
||||||
uint256 verHash = uint256S(ToString(ver));
|
uint256 verHash = uint256S(ToString(bit));
|
||||||
auto sig = ag_sk.Sign(verHash);
|
auto sig = ag_sk.Sign(verHash);
|
||||||
BOOST_CHECK(sig.VerifyInsecure(ag_pk, verHash));
|
BOOST_CHECK(sig.VerifyInsecure(ag_pk, verHash));
|
||||||
|
|
||||||
const CMutableTransaction tx = CreateMNHFTx(hash, sig, ver);
|
auto& chainman = Assert(m_node.chainman);
|
||||||
|
auto& qman = *Assert(m_node.llmq_ctx)->qman;
|
||||||
|
const CBlockIndex* pindex = chainman->ActiveChain().Tip();
|
||||||
|
uint256 hash = GetRandHash();
|
||||||
TxValidationState state;
|
TxValidationState state;
|
||||||
BOOST_CHECK(VerifyMNHFTx(CTransaction(tx), state));
|
|
||||||
|
{ // wrong quorum (we don't have any indeed)
|
||||||
|
const CTransaction tx{CTransaction(CreateMNHFTx(hash, sig, bit))};
|
||||||
|
CheckMNHFTx(*chainman, qman, CTransaction(tx), pindex, state);
|
||||||
|
BOOST_CHECK_EQUAL(state.ToString(), "bad-mnhf-quorum-hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // non EHF fork
|
||||||
|
const CTransaction tx{CTransaction(CreateMNHFTx(hash, sig, 28))};
|
||||||
|
CheckMNHFTx(*chainman, qman, CTransaction(tx), pindex, state);
|
||||||
|
BOOST_CHECK_EQUAL(state.ToString(), "bad-mnhf-non-ehf");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -348,15 +348,15 @@ TestChainSetup::TestChainSetup(int num_blocks, const std::vector<const char*>& e
|
|||||||
/* TestChain100Setup */
|
/* TestChain100Setup */
|
||||||
{ 100, uint256S("0x6ffb83129c19ebdf1ae3771be6a67fe34b35f4c956326b9ba152fac1649f65ae") },
|
{ 100, uint256S("0x6ffb83129c19ebdf1ae3771be6a67fe34b35f4c956326b9ba152fac1649f65ae") },
|
||||||
/* TestChainDIP3BeforeActivationSetup */
|
/* TestChainDIP3BeforeActivationSetup */
|
||||||
{ 430, uint256S("0x592b23a8882162ea48606e40c9ee00b2166ddae092c691d7f1b1758ec13647d9") },
|
{ 430, uint256S("0x0bcefaa33fec56cd84d05d0e76cd6a78badcc20f627d91903646de6a07930a14") },
|
||||||
/* TestChainDIP3Setup */
|
/* TestChainDIP3Setup */
|
||||||
{ 431, uint256S("0x49db248651517f3fc3725fbbc7087db90552d487d11e0962b0148fc4788aeb77") },
|
{ 431, uint256S("0x5fd3aa5ef29464839499d7f847edd9362e3e73392b79d3bd88b1591f5fb17d4e") },
|
||||||
/* TestChainBRRBeforeActivationSetup */
|
/* TestChainBRRBeforeActivationSetup */
|
||||||
{ 497, uint256S("0x626036f6adff51fbbdd0c609e827ef6a3730ce2498a3eb33edeb27092d006170") },
|
{ 497, uint256S("0x23c31820ec5160b7181bfdf328e2b76cd12c9fa4544d892b7f01e74dd6220849") },
|
||||||
/* TestChainV19BeforeActivationSetup */
|
/* TestChainV19BeforeActivationSetup */
|
||||||
{ 894, uint256S("0x03cbf1871d7d915cda10aded00ced45f71a4e2acf6a3c7a77a1ff488267dd1cd") },
|
{ 894, uint256S("0x2885cf0fe8fdf29803b6c65002ba2570ff011531d8ea92be312a85d655e00c51") },
|
||||||
/* TestChainV19Setup */
|
/* TestChainV19Setup */
|
||||||
{ 899, uint256S("0x405a630e16d0ca0efe3abb0e24c9a157a69ec2e07b04333cc5d004efa634ac89") },
|
{ 899, uint256S("0x7df3c857ce647b3ecd0d4b389b6b0f16e2bdc60b20a8d01c4ad946fe5f15dbc2") },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
f'-testactivationheight=cltv@{CLTV_HEIGHT}',
|
f'-testactivationheight=cltv@{CLTV_HEIGHT}',
|
||||||
'-whitelist=noban@127.0.0.1',
|
'-whitelist=noban@127.0.0.1',
|
||||||
'-dip3params=9000:9000',
|
'-dip3params=9000:9000',
|
||||||
|
'-testactivationheight=v20@9000', # disabled for this test
|
||||||
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
||||||
'-acceptnonstdtxn=1', # cltv_invalidate is nonstandard
|
'-acceptnonstdtxn=1', # cltv_invalidate is nonstandard
|
||||||
'-vbparams=v20:0:999999999999:0:480:384:288:5:0' # Delay v20 for this test as we don't need it
|
|
||||||
]]
|
]]
|
||||||
self.setup_clean_chain = True
|
self.setup_clean_chain = True
|
||||||
self.rpc_timeout = 480
|
self.rpc_timeout = 480
|
||||||
|
@ -50,10 +50,11 @@ class BIP66Test(BitcoinTestFramework):
|
|||||||
self.num_nodes = 1
|
self.num_nodes = 1
|
||||||
self.extra_args = [[
|
self.extra_args = [[
|
||||||
f'-testactivationheight=dersig@{DERSIG_HEIGHT}',
|
f'-testactivationheight=dersig@{DERSIG_HEIGHT}',
|
||||||
|
'-testactivationheight=v20@9000', # due to changes in CbTx
|
||||||
'-whitelist=noban@127.0.0.1',
|
'-whitelist=noban@127.0.0.1',
|
||||||
'-dip3params=9000:9000',
|
'-dip3params=9000:9000',
|
||||||
'-par=1', # Use only one script thread to get the exact log msg for testing
|
'-par=1', # Use only one script thread to get the exact log msg for testing
|
||||||
'-vbparams=v20:0:999999999999:0:480:384:288:5:0']]
|
]]
|
||||||
self.setup_clean_chain = True
|
self.setup_clean_chain = True
|
||||||
self.rpc_timeout = 240
|
self.rpc_timeout = 240
|
||||||
|
|
||||||
|
@ -9,29 +9,24 @@ import json
|
|||||||
from test_framework.messages import uint256_to_string
|
from test_framework.messages import uint256_to_string
|
||||||
from test_framework.test_framework import DashTestFramework
|
from test_framework.test_framework import DashTestFramework
|
||||||
from test_framework.governance import have_trigger_for_height, prepare_object
|
from test_framework.governance import have_trigger_for_height, prepare_object
|
||||||
from test_framework.util import assert_equal, satoshi_round, set_node_times, wait_until_helper
|
from test_framework.util import assert_equal, satoshi_round, wait_until_helper
|
||||||
|
|
||||||
GOVERNANCE_UPDATE_MIN = 60 * 60 # src/governance/object.h
|
GOVERNANCE_UPDATE_MIN = 60 * 60 # src/governance/object.h
|
||||||
|
|
||||||
class DashGovernanceTest (DashTestFramework):
|
class DashGovernanceTest (DashTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
self.v20_start_time = 1417713500 + 80
|
self.set_dash_test_params(6, 5, [[
|
||||||
# using adjusted v20 deployment params to test an edge case where superblock maturity window is equal to deployment window size
|
"-budgetparams=10:10:10",
|
||||||
self.set_dash_test_params(6, 5, [["-budgetparams=10:10:10", f"-vbparams=v20:{self.v20_start_time}:999999999999:0:10:8:6:5:0"]] * 6, fast_dip3_enforcement=True)
|
'-testactivationheight=v20@240',
|
||||||
|
]] * 6, fast_dip3_enforcement=True)
|
||||||
|
|
||||||
def check_superblockbudget(self, v20_active):
|
def check_superblockbudget(self, v20_active):
|
||||||
v20_state = self.nodes[0].getblockchaininfo()["softforks"]["v20"]
|
v20_state = self.nodes[0].getblockchaininfo()["softforks"]["v20"]
|
||||||
assert_equal(v20_state["active"], v20_active)
|
assert_equal(v20_state["active"], v20_active)
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(200), self.expected_old_budget)
|
assert_equal(self.nodes[0].getsuperblockbudget(200), self.expected_old_budget)
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(220), self.expected_old_budget)
|
assert_equal(self.nodes[0].getsuperblockbudget(220), self.expected_old_budget)
|
||||||
if v20_state["bip9"]["status"] == "locked_in" or v20_state["bip9"]["status"] == "active":
|
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(240), self.expected_v20_budget)
|
assert_equal(self.nodes[0].getsuperblockbudget(240), self.expected_v20_budget)
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(260), self.expected_v20_budget)
|
assert_equal(self.nodes[0].getsuperblockbudget(260), self.expected_v20_budget)
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(280), self.expected_v20_budget)
|
|
||||||
else:
|
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(240), self.expected_old_budget)
|
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(260), self.expected_old_budget)
|
|
||||||
assert_equal(self.nodes[0].getsuperblockbudget(280), self.expected_old_budget)
|
|
||||||
|
|
||||||
def check_superblock(self):
|
def check_superblock(self):
|
||||||
# Make sure Superblock has only payments that fit into the budget
|
# Make sure Superblock has only payments that fit into the budget
|
||||||
@ -100,18 +95,14 @@ class DashGovernanceTest (DashTestFramework):
|
|||||||
self.bump_mocktime(3)
|
self.bump_mocktime(3)
|
||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
assert_equal(self.nodes[0].getblockcount(), 210)
|
assert_equal(self.nodes[0].getblockcount(), 210)
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["bip9"]["status"], "defined")
|
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||||
self.check_superblockbudget(False)
|
self.check_superblockbudget(False)
|
||||||
|
|
||||||
assert self.mocktime < self.v20_start_time
|
|
||||||
self.mocktime = self.v20_start_time
|
|
||||||
set_node_times(self.nodes, self.mocktime)
|
|
||||||
|
|
||||||
self.nodes[0].generate(10)
|
self.nodes[0].generate(10)
|
||||||
self.bump_mocktime(10)
|
self.bump_mocktime(10)
|
||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
assert_equal(self.nodes[0].getblockcount(), 220)
|
assert_equal(self.nodes[0].getblockcount(), 220)
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["bip9"]["status"], "started")
|
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||||
self.check_superblockbudget(False)
|
self.check_superblockbudget(False)
|
||||||
|
|
||||||
proposal_time = self.mocktime
|
proposal_time = self.mocktime
|
||||||
@ -215,7 +206,7 @@ class DashGovernanceTest (DashTestFramework):
|
|||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
self.bump_mocktime(1)
|
self.bump_mocktime(1)
|
||||||
assert_equal(self.nodes[0].getblockcount(), 230)
|
assert_equal(self.nodes[0].getblockcount(), 230)
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["bip9"]["status"], "locked_in")
|
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||||
self.check_superblockbudget(False)
|
self.check_superblockbudget(False)
|
||||||
|
|
||||||
# The "winner" should submit new trigger and vote for it, but it's isolated so no triggers should be found
|
# The "winner" should submit new trigger and vote for it, but it's isolated so no triggers should be found
|
||||||
@ -341,7 +332,7 @@ class DashGovernanceTest (DashTestFramework):
|
|||||||
self.bump_mocktime(1)
|
self.bump_mocktime(1)
|
||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
assert_equal(self.nodes[0].getblockcount(), 260)
|
assert_equal(self.nodes[0].getblockcount(), 260)
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["bip9"]["status"], "active")
|
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], True)
|
||||||
|
|
||||||
# Mine and check a couple more superblocks
|
# Mine and check a couple more superblocks
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
@ -357,7 +348,7 @@ class DashGovernanceTest (DashTestFramework):
|
|||||||
self.bump_mocktime(1)
|
self.bump_mocktime(1)
|
||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
assert_equal(self.nodes[0].getblockcount(), sb_block_height)
|
assert_equal(self.nodes[0].getblockcount(), sb_block_height)
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["bip9"]["status"], "active")
|
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], True)
|
||||||
self.check_superblockbudget(True)
|
self.check_superblockbudget(True)
|
||||||
self.check_superblock()
|
self.check_superblock()
|
||||||
|
|
||||||
|
@ -115,7 +115,6 @@ class LLMQEvoNodesTest(DashTestFramework):
|
|||||||
self.test_evo_payments(window_analysis=48)
|
self.test_evo_payments(window_analysis=48)
|
||||||
self.test_masternode_winners()
|
self.test_masternode_winners()
|
||||||
|
|
||||||
self.activate_v20()
|
|
||||||
self.activate_mn_rr()
|
self.activate_mn_rr()
|
||||||
self.log.info("Activated MN RewardReallocation at height:" + str(self.nodes[0].getblockcount()))
|
self.log.info("Activated MN RewardReallocation at height:" + str(self.nodes[0].getblockcount()))
|
||||||
|
|
||||||
@ -125,24 +124,24 @@ class LLMQEvoNodesTest(DashTestFramework):
|
|||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
|
|
||||||
self.log.info("Test that EvoNodes are paid 1 block in a row after MN RewardReallocation activation")
|
self.log.info("Test that EvoNodes are paid 1 block in a row after MN RewardReallocation activation")
|
||||||
self.test_evo_payments(window_analysis=48, v20active=True)
|
self.test_evo_payments(window_analysis=48, mnrr_active=True)
|
||||||
self.test_masternode_winners(mn_rr_active=True)
|
self.test_masternode_winners(mn_rr_active=True)
|
||||||
|
|
||||||
self.log.info(self.nodes[0].masternodelist())
|
self.log.info(self.nodes[0].masternodelist())
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def test_evo_payments(self, window_analysis, v20active=False):
|
def test_evo_payments(self, window_analysis, mnrr_active=False):
|
||||||
current_evo = None
|
current_evo = None
|
||||||
consecutive_payments = 0
|
consecutive_payments = 0
|
||||||
n_payments = 0 if v20active else 4
|
n_payments = 0 if mnrr_active else 4
|
||||||
for i in range(0, window_analysis):
|
for i in range(0, window_analysis):
|
||||||
payee = self.get_mn_payee_for_block(self.nodes[0].getbestblockhash())
|
payee = self.get_mn_payee_for_block(self.nodes[0].getbestblockhash())
|
||||||
if payee is not None and payee.evo:
|
if payee is not None and payee.evo:
|
||||||
if current_evo is not None and payee.proTxHash == current_evo.proTxHash:
|
if current_evo is not None and payee.proTxHash == current_evo.proTxHash:
|
||||||
# same EvoNode
|
# same EvoNode
|
||||||
assert consecutive_payments > 0
|
assert consecutive_payments > 0
|
||||||
if not v20active:
|
if not mnrr_active:
|
||||||
consecutive_payments += 1
|
consecutive_payments += 1
|
||||||
consecutive_payments_rpc = self.nodes[0].protx('info', current_evo.proTxHash)['state']['consecutivePayments']
|
consecutive_payments_rpc = self.nodes[0].protx('info', current_evo.proTxHash)['state']['consecutivePayments']
|
||||||
assert_equal(consecutive_payments, consecutive_payments_rpc)
|
assert_equal(consecutive_payments, consecutive_payments_rpc)
|
||||||
@ -157,7 +156,7 @@ class LLMQEvoNodesTest(DashTestFramework):
|
|||||||
consecutive_payments_rpc = self.nodes[0].protx('info', payee.proTxHash)['state']['consecutivePayments']
|
consecutive_payments_rpc = self.nodes[0].protx('info', payee.proTxHash)['state']['consecutivePayments']
|
||||||
# if EvoNode is the one we start "for" loop with,
|
# if EvoNode is the one we start "for" loop with,
|
||||||
# we have no idea how many times it was paid before - rely on rpc results here
|
# we have no idea how many times it was paid before - rely on rpc results here
|
||||||
new_payment_value = 0 if v20active else 1
|
new_payment_value = 0 if mnrr_active else 1
|
||||||
consecutive_payments = consecutive_payments_rpc if i == 0 and current_evo is None else new_payment_value
|
consecutive_payments = consecutive_payments_rpc if i == 0 and current_evo is None else new_payment_value
|
||||||
current_evo = payee
|
current_evo = payee
|
||||||
assert_equal(consecutive_payments, consecutive_payments_rpc)
|
assert_equal(consecutive_payments, consecutive_payments_rpc)
|
||||||
|
@ -18,7 +18,6 @@ from test_framework.p2p import P2PInterface
|
|||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
assert_greater_than_or_equal,
|
assert_greater_than_or_equal,
|
||||||
assert_greater_than, get_bip9_details,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -114,17 +113,14 @@ class LLMQQuorumRotationTest(DashTestFramework):
|
|||||||
expectedNew = [h_100_0, h_106_0, h_104_0, h_100_1, h_106_1, h_104_1]
|
expectedNew = [h_100_0, h_106_0, h_104_0, h_100_1, h_106_1, h_104_1]
|
||||||
quorumList = self.test_getmnlistdiff_quorums(b_h_0, b_h_1, {}, expectedDeleted, expectedNew, testQuorumsCLSigs=False)
|
quorumList = self.test_getmnlistdiff_quorums(b_h_0, b_h_1, {}, expectedDeleted, expectedNew, testQuorumsCLSigs=False)
|
||||||
|
|
||||||
self.log.info(f"Wait for v20 locked_in phase")
|
projected_activation_height = 1200
|
||||||
# Expected locked_in phase starts at 1200 - 400 (window size in regtest)
|
|
||||||
projected_activation_height = self.advance_to_locked_in_for_v20(expected_locked_in_height=800)
|
|
||||||
|
|
||||||
self.activate_v20(expected_activation_height=1200)
|
self.activate_v20(expected_activation_height=1200)
|
||||||
self.log.info("Activated v20 at height:" + str(self.nodes[0].getblockcount()))
|
self.log.info("Activated v20 at height:" + str(self.nodes[0].getblockcount()))
|
||||||
|
|
||||||
softfork_info = get_bip9_details(self.nodes[0], 'v20')
|
softfork_info = self.nodes[0].getblockchaininfo()['softforks']['v20']
|
||||||
assert_equal(softfork_info['status'], 'active')
|
assert_equal(softfork_info['active'], True)
|
||||||
assert 'since' in softfork_info
|
assert_equal(projected_activation_height, softfork_info['height'])
|
||||||
assert_equal(projected_activation_height, softfork_info['since'])
|
|
||||||
|
|
||||||
# v20 is active for the next block, not for the tip
|
# v20 is active for the next block, not for the tip
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
@ -393,51 +389,6 @@ class LLMQQuorumRotationTest(DashTestFramework):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def advance_to_locked_in_for_v20(self, expected_locked_in_height):
|
|
||||||
# disable spork17 while mining blocks to activate "name" to prevent accidental quorum formation
|
|
||||||
spork17_value = self.nodes[0].spork('show')['SPORK_17_QUORUM_DKG_ENABLED']
|
|
||||||
self.bump_mocktime(1)
|
|
||||||
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 4070908800)
|
|
||||||
self.wait_for_sporks_same()
|
|
||||||
|
|
||||||
# mine blocks in batches
|
|
||||||
batch_size = 10
|
|
||||||
height = self.nodes[0].getblockcount()
|
|
||||||
assert_greater_than(expected_locked_in_height, height)
|
|
||||||
# NOTE: getblockchaininfo shows softforks locked_in at block (window * 2 - 1)
|
|
||||||
# since it's returning whether a softwork is locked_in for the _next_ block.
|
|
||||||
# Hence the last block prior to the locked_in state is (expected_locked_in_height - 2).
|
|
||||||
while expected_locked_in_height - height - 2 >= batch_size:
|
|
||||||
self.bump_mocktime(batch_size)
|
|
||||||
self.nodes[0].generate(batch_size)
|
|
||||||
height += batch_size
|
|
||||||
self.sync_blocks()
|
|
||||||
blocks_left = expected_locked_in_height - height - 2
|
|
||||||
assert_greater_than(batch_size, blocks_left)
|
|
||||||
self.bump_mocktime(blocks_left)
|
|
||||||
self.nodes[0].generate(blocks_left)
|
|
||||||
self.sync_blocks()
|
|
||||||
|
|
||||||
softfork_info = get_bip9_details(self.nodes[0], 'v20')
|
|
||||||
assert_equal(softfork_info['status'], 'started')
|
|
||||||
assert 'activation_height' not in softfork_info
|
|
||||||
|
|
||||||
self.bump_mocktime(1)
|
|
||||||
self.nodes[0].generate(1)
|
|
||||||
self.sync_blocks()
|
|
||||||
|
|
||||||
softfork_info = get_bip9_details(self.nodes[0], 'v20')
|
|
||||||
assert_equal(softfork_info['status'], 'locked_in')
|
|
||||||
assert_equal(softfork_info['since'], expected_locked_in_height)
|
|
||||||
assert 'activation_height' in softfork_info
|
|
||||||
projected_activation_height = softfork_info['activation_height']
|
|
||||||
|
|
||||||
# revert spork17 changes
|
|
||||||
self.bump_mocktime(1)
|
|
||||||
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", spork17_value)
|
|
||||||
self.wait_for_sporks_same()
|
|
||||||
|
|
||||||
return projected_activation_height
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
LLMQQuorumRotationTest().main()
|
LLMQQuorumRotationTest().main()
|
||||||
|
@ -131,8 +131,8 @@ class MnehfTest(DashTestFramework):
|
|||||||
node = self.nodes[0]
|
node = self.nodes[0]
|
||||||
|
|
||||||
self.set_sporks()
|
self.set_sporks()
|
||||||
self.activate_v19()
|
self.activate_v20()
|
||||||
self.log.info(f"After v19 activation should be plenty of blocks: {node.getblockcount()}")
|
self.log.info(f"After v20 activation should be plenty of blocks: {node.getblockcount()}")
|
||||||
assert_greater_than(node.getblockcount(), 900)
|
assert_greater_than(node.getblockcount(), 900)
|
||||||
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
|
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
|
||||||
|
|
||||||
@ -145,7 +145,6 @@ class MnehfTest(DashTestFramework):
|
|||||||
pubkey = key.get_pubkey().get_bytes()
|
pubkey = key.get_pubkey().get_bytes()
|
||||||
ehf_tx = self.create_mnehf(28, pubkey)
|
ehf_tx = self.create_mnehf(28, pubkey)
|
||||||
ehf_unknown_tx = self.create_mnehf(27, pubkey)
|
ehf_unknown_tx = self.create_mnehf(27, pubkey)
|
||||||
ehf_invalid_tx = self.create_mnehf(9, pubkey) # deployment that is known as non-EHF
|
|
||||||
|
|
||||||
self.log.info("Checking deserialization of CMnEhf by python's code")
|
self.log.info("Checking deserialization of CMnEhf by python's code")
|
||||||
mnehf_payload = CMnEhf()
|
mnehf_payload = CMnEhf()
|
||||||
@ -155,10 +154,6 @@ class MnehfTest(DashTestFramework):
|
|||||||
self.log.info("Checking correctness of requestId and quorumHash")
|
self.log.info("Checking correctness of requestId and quorumHash")
|
||||||
assert_equal(mnehf_payload.quorumHash, int(self.mninfo[0].node.quorum("selectquorum", 100, 'a0eee872d7d3170dd20d5c5e8380c92b3aa887da5f63d8033289fafa35a90691')["quorumHash"], 16))
|
assert_equal(mnehf_payload.quorumHash, int(self.mninfo[0].node.quorum("selectquorum", 100, 'a0eee872d7d3170dd20d5c5e8380c92b3aa887da5f63d8033289fafa35a90691')["quorumHash"], 16))
|
||||||
|
|
||||||
self.send_tx(ehf_tx, expected_error='mnhf-before-v20')
|
|
||||||
|
|
||||||
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
|
|
||||||
self.activate_v20()
|
|
||||||
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
|
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
|
||||||
assert_equal(get_bip9_details(node, 'mn_rr')['status'], 'defined')
|
assert_equal(get_bip9_details(node, 'mn_rr')['status'], 'defined')
|
||||||
|
|
||||||
@ -166,7 +161,6 @@ class MnehfTest(DashTestFramework):
|
|||||||
self.log.info(f"ehf tx: {ehf_tx_sent}")
|
self.log.info(f"ehf tx: {ehf_tx_sent}")
|
||||||
ehf_unknown_tx_sent = self.send_tx(ehf_unknown_tx)
|
ehf_unknown_tx_sent = self.send_tx(ehf_unknown_tx)
|
||||||
self.log.info(f"unknown ehf tx: {ehf_unknown_tx_sent}")
|
self.log.info(f"unknown ehf tx: {ehf_unknown_tx_sent}")
|
||||||
self.send_tx(ehf_invalid_tx, expected_error='bad-mnhf-non-ehf')
|
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
ehf_blockhash = self.nodes[1].generate(1)[0]
|
ehf_blockhash = self.nodes[1].generate(1)[0]
|
||||||
self.sync_blocks()
|
self.sync_blocks()
|
||||||
|
@ -154,16 +154,7 @@ class BlockchainTest(BitcoinTestFramework):
|
|||||||
'dip0024': { 'type': 'buried', 'active': False, 'height': 900},
|
'dip0024': { 'type': 'buried', 'active': False, 'height': 900},
|
||||||
'realloc': { 'type': 'buried', 'active': True, 'height': 1},
|
'realloc': { 'type': 'buried', 'active': True, 'height': 1},
|
||||||
'v19': { 'type': 'buried', 'active': False, 'height': 900},
|
'v19': { 'type': 'buried', 'active': False, 'height': 900},
|
||||||
'v20': {
|
'v20': { 'type': 'buried', 'active': False, 'height': 1200},
|
||||||
'type': 'bip9',
|
|
||||||
'bip9': {
|
|
||||||
'status': 'defined',
|
|
||||||
'start_time': 0,
|
|
||||||
'timeout': 9223372036854775807,
|
|
||||||
'since': 0,
|
|
||||||
'min_activation_height': 0,
|
|
||||||
'ehf': False,
|
|
||||||
}, 'active': False},
|
|
||||||
'mn_rr': {
|
'mn_rr': {
|
||||||
'type': 'bip9',
|
'type': 'bip9',
|
||||||
'bip9': {
|
'bip9': {
|
||||||
|
Loading…
Reference in New Issue
Block a user