From a5a94de6d82cb7003f57101afa9bff98ce3122d9 Mon Sep 17 00:00:00 2001 From: squid Date: Thu, 19 Oct 2023 00:04:11 -0400 Subject: [PATCH 1/5] patches to correct spork key update --- configure.ac | 2 +- src/chainparams.cpp | 11 ++++++--- src/chainparams.h | 2 ++ src/init.cpp | 16 ++++++++++++- src/spork.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++- src/spork.h | 16 +++++++++++++ 6 files changed, 97 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 0b0d93d266bc..0847f7de2ad3 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 4) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 3) +define(_CLIENT_VERSION_BUILD, 8) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2023) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 21f7eebe95d2..c2398b4fa90e 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -345,7 +345,8 @@ class CMainParams : public CChainParams { nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour vSporkAddressesV1 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb"}; - vSporkAddressesV2 = {"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; + vSporkAddressesV2 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; + vSporkAddressesV3 = {"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; nMinSporkKeys = 1; fBIP9CheckMasternodesUpgraded = true; @@ -411,7 +412,10 @@ class CMainParams : public CChainParams { {703355, uint256S("0000000002354cfaeb716435d7cfa632651f32ea22ef9796d25b893e264b2ea5")}, {703363, uint256S("00000000013b1c713a1ae71e6328f0f21efa08c7b8432d40bce681e4588645c4")}, // 2023/09 - {717100, uint256S("0000000003189edcd28335b5e8bbb00752bad82c01c87604f4614ef103b14b24")} + {717100, uint256S("0000000003189edcd28335b5e8bbb00752bad82c01c87604f4614ef103b14b24")}, + // 2023/10 + {750001, uint256S("00000000006ed565d981c2ba21d19fd1b655847fa156e8a1da4647a33bbb5b74")}, + {750222, uint256S("000000000106b46906143c81532016eb1dcccf9859f3e1fc4f249c797f0c36ac")} } }; @@ -589,7 +593,8 @@ class CTestNetParams : public CChainParams { nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"}; - vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; + vSporkAddressesV2 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55", "yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; + vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; nMinSporkKeys = 1; fBIP9CheckMasternodesUpgraded = true; diff --git a/src/chainparams.h b/src/chainparams.h index f4e1cac55d7c..d3e7b4654dc8 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -108,6 +108,7 @@ class CChainParams int FulfilledRequestExpireTime() const { return nFulfilledRequestExpireTime; } const std::vector& SporkAddressesV1() const { return vSporkAddressesV1; } const std::vector& SporkAddressesV2() const { return vSporkAddressesV2; } + const std::vector& SporkAddressesV3() const { return vSporkAddressesV3; } int MinSporkKeys() const { return nMinSporkKeys; } bool BIP9CheckMasternodesUpgraded() const { return fBIP9CheckMasternodesUpgraded; } const Consensus::LLMQParams& GetLLMQ(Consensus::LLMQType llmqType) const; @@ -144,6 +145,7 @@ class CChainParams int nFulfilledRequestExpireTime; std::vector vSporkAddressesV1; std::vector vSporkAddressesV2; + std::vector vSporkAddressesV3; int nMinSporkKeys; bool fBIP9CheckMasternodesUpgraded; diff --git a/src/init.cpp b/src/init.cpp index 65b72c4e5204..d9cba9ba37f7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2496,6 +2496,8 @@ bool AppInitMain(InitInterfaces& interfaces) std::vector vSporkAddresses; if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); + } else if (chain_active_height >= sporkManager.getNewSporkActHeight()) { + vSporkAddresses = Params().SporkAddressesV3(); } else { vSporkAddresses = Params().SporkAddressesV2(); } @@ -2505,7 +2507,19 @@ bool AppInitMain(InitInterfaces& interfaces) return InitError(_("Invalid spork address specified with -sporkaddr").translated); } } - LogPrintf("Using V2 Spork Addresses\n"); + if (!gArgs.IsArgSet("-sporkaddr")) { + if (!sporkManager.CheckSporkPubkeyIDs()) { + LogPrintf("CSporkManager -- WARN: mismatched spork addresses have been updated!\n"); + } + } + if (chain_active_height < sporkManager.getNewSporkLockHeight()) { + LogPrintf("CSporkManager -- Spork V3 Active Height: %d Lock Height: %d\n", sporkManager.getNewSporkActHeight(), sporkManager.getNewSporkLockHeight()); + } + if (chain_active_height >= sporkManager.getNewSporkActHeight()) { + LogPrintf("Using V3 Spork Addresses\n"); + } else { + LogPrintf("Using V2 Spork Addresses\n"); + } } if (chain_active_height >= 7500 && chainparams.NetworkIDString() == CBaseChainParams::TESTNET) { std::vector vSporkAddresses; diff --git a/src/spork.cpp b/src/spork.cpp index 9c66bb52e175..c74b33a60474 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -101,6 +101,9 @@ void CSporkManager::CheckAndRemove() void CSporkManager::ProcessSporkMessages(CNode* pfrom, std::string_view strCommand, CDataStream& vRecv, CConnman& connman) { + if (!CheckSporkPubkeyIDs()) { + LogPrintf("CSporkManager::ProcessSporkMessages -- WARN: updated mismatching spork addresses\n"); + } ProcessSpork(pfrom, strCommand, vRecv, connman); ProcessGetSporks(pfrom, strCommand, connman); } @@ -134,7 +137,11 @@ void CSporkManager::ProcessSpork(const CNode* pfrom, std::string_view strCommand if (!spork.GetSignerKeyID(keyIDSigner) || WITH_LOCK(cs, return !setSporkPubKeyIDs.count(keyIDSigner))) { LOCK(cs_main); LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n"); - Misbehaving(pfrom->GetId(), 100); + + int nHeight = ::ChainActive().Tip()->nHeight; + if (nHeight >= nNewSporkLockHeight) { + Misbehaving(pfrom->GetId(), 100); + } return; } @@ -329,6 +336,53 @@ bool CSporkManager::SetPrivKey(const std::string& strPrivKey) return true; } +bool CSporkManager::CheckSporkPubkeyIDs() +{ + if (!::ChainActive().Tip() || Params().NetworkIDString() != CBaseChainParams::MAIN) + { + return true; + } + + int nHeight = ::ChainActive().Tip()->nHeight; + if (nHeight > nNewSporkLockHeight) { + return true; + } + + //LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Checking Spork Addr\n"); + if (nHeight > nNewSporkActHeight) { + std::vector vSporkAddresses = Params().SporkAddressesV3(); + bool matches = true; + int nFound = 0; + LOCK(cs); + for (const auto& strAddress : vSporkAddresses) { + CTxDestination dest = DecodeDestination(strAddress); + const CKeyID* keyID = boost::get(&dest); + if (!keyID) { + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Failed to parse spork address\n"); + matches = false; + } else if (setSporkPubKeyIDs.find(*keyID) == setSporkPubKeyIDs.end()) { + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- ERROR: spork address not found\n"); + matches = false; + } else { + nFound++; + } + } + if (nFound != setSporkPubKeyIDs.size()) { + matches = false; + } + if (!matches) { + sporkManager.ClearSporkAddresses(); + for (const auto& address : vSporkAddresses) { + if (!sporkManager.SetSporkAddress(address)) { + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- ERROR: invalid spork address\n"); + } + } + return false; + } + } + return true; +} + std::string CSporkManager::ToString() const { LOCK(cs); diff --git a/src/spork.h b/src/spork.h index 0798fdd29f3f..f702be27d80a 100644 --- a/src/spork.h +++ b/src/spork.h @@ -180,6 +180,9 @@ class CSporkManager */ bool SporkValueIsActive(SporkId nSporkID, int64_t& nActiveValueRet) const EXCLUSIVE_LOCKS_REQUIRED(cs); + int nNewSporkActHeight = 755040; + int nNewSporkLockHeight = 760080; + public: CSporkManager() = default; @@ -317,6 +320,19 @@ class CSporkManager */ bool SetPrivKey(const std::string& strPrivKey); + /** + * CheckSporkPubkeyIDs is used to check the pubkeys for spork signers + * match the expected. Will update the list if there is mismatching. + * + * This will return true if there are no mismatches. + */ + bool CheckSporkPubkeyIDs(); + + /* Gets height the new sporks should become active. */ + int getNewSporkActHeight() { return nNewSporkActHeight; }; + /* Gets height the new sporks should lock. Used for ban control. */ + int getNewSporkLockHeight() { return nNewSporkLockHeight; }; + /** * ToString returns the string representation of the SporkManager. */ From 3d84505c732f8890cbf1ac9a423c0a29138575fd Mon Sep 17 00:00:00 2001 From: squid Date: Thu, 19 Oct 2023 01:22:10 -0400 Subject: [PATCH 2/5] cleanups --- src/chainparams.cpp | 4 ---- src/chainparams.h | 2 -- src/init.cpp | 21 +++------------------ src/spork.cpp | 6 +++--- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c2398b4fa90e..544e2f79f3e3 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -344,7 +344,6 @@ class CMainParams : public CChainParams { nPoolMaxParticipants = 5; nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour - vSporkAddressesV1 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb"}; vSporkAddressesV2 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; vSporkAddressesV3 = {"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; nMinSporkKeys = 1; @@ -592,7 +591,6 @@ class CTestNetParams : public CChainParams { nPoolMaxParticipants = 20; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes - vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"}; vSporkAddressesV2 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55", "yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; nMinSporkKeys = 1; @@ -783,7 +781,6 @@ class CDevNetParams : public CChainParams { nPoolMaxParticipants = 20; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes - vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"}; vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; nMinSporkKeys = 1; // devnets are started with no blocks and no MN, so we can't check for upgraded MN (as there are none) @@ -962,7 +959,6 @@ class CRegTestParams : public CChainParams { nPoolMaxParticipants = 20; // privKey: cP4EKFyJsHT39LDqgdcB43Y3YXjNyjb5Fuas1GQSeAtjnZWmZEQK - vSporkAddressesV1 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; vSporkAddressesV2 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; nMinSporkKeys = 1; // regtest usually has no masternodes in most tests, so don't check for upgraged MNs diff --git a/src/chainparams.h b/src/chainparams.h index d3e7b4654dc8..8df9c66e7d22 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -106,7 +106,6 @@ class CChainParams int PoolMinParticipants() const { return nPoolMinParticipants; } int PoolMaxParticipants() const { return nPoolMaxParticipants; } int FulfilledRequestExpireTime() const { return nFulfilledRequestExpireTime; } - const std::vector& SporkAddressesV1() const { return vSporkAddressesV1; } const std::vector& SporkAddressesV2() const { return vSporkAddressesV2; } const std::vector& SporkAddressesV3() const { return vSporkAddressesV3; } int MinSporkKeys() const { return nMinSporkKeys; } @@ -143,7 +142,6 @@ class CChainParams int nPoolMinParticipants; int nPoolMaxParticipants; int nFulfilledRequestExpireTime; - std::vector vSporkAddressesV1; std::vector vSporkAddressesV2; std::vector vSporkAddressesV3; int nMinSporkKeys; diff --git a/src/init.cpp b/src/init.cpp index d9cba9ba37f7..216c1f264162 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1685,7 +1685,7 @@ bool AppInitMain(InitInterfaces& interfaces) if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); } else { - vSporkAddresses = Params().SporkAddressesV1(); + vSporkAddresses = Params().SporkAddressesV2(); } for (const auto& address: vSporkAddresses) { if (!sporkManager.SetSporkAddress(address)) { @@ -2492,11 +2492,11 @@ bool AppInitMain(InitInterfaces& interfaces) // ********************************************************* Step 12.1: uprade sporks - if (chain_active_height >= 750000 && chainparams.NetworkIDString() == CBaseChainParams::MAIN) { + if (chain_active_height >= sporkManager.getNewSporkActHeight() && chainparams.NetworkIDString() == CBaseChainParams::MAIN) { std::vector vSporkAddresses; if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); - } else if (chain_active_height >= sporkManager.getNewSporkActHeight()) { + } else if (chain_active_height >= sporkManager.getNewSporkLockHeight()) { vSporkAddresses = Params().SporkAddressesV3(); } else { vSporkAddresses = Params().SporkAddressesV2(); @@ -2521,21 +2521,6 @@ bool AppInitMain(InitInterfaces& interfaces) LogPrintf("Using V2 Spork Addresses\n"); } } - if (chain_active_height >= 7500 && chainparams.NetworkIDString() == CBaseChainParams::TESTNET) { - std::vector vSporkAddresses; - if (gArgs.IsArgSet("-sporkaddr")) { - vSporkAddresses = gArgs.GetArgs("-sporkaddr"); - } else { - vSporkAddresses = Params().SporkAddressesV2(); - } - sporkManager.ClearSporkAddresses(); - for (const auto& address : vSporkAddresses) { - if (!sporkManager.SetSporkAddress(address)) { - return InitError(_("Invalid spork address specified with -sporkaddr").translated); - } - } - LogPrintf("Using V2 Spork Addresses\n"); - } // ********************************************************* Step 13: finished diff --git a/src/spork.cpp b/src/spork.cpp index c74b33a60474..adcba29498c6 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -139,7 +139,7 @@ void CSporkManager::ProcessSpork(const CNode* pfrom, std::string_view strCommand LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n"); int nHeight = ::ChainActive().Tip()->nHeight; - if (nHeight >= nNewSporkLockHeight) { + if (nHeight > nNewSporkLockHeight) { Misbehaving(pfrom->GetId(), 100); } return; @@ -344,12 +344,12 @@ bool CSporkManager::CheckSporkPubkeyIDs() } int nHeight = ::ChainActive().Tip()->nHeight; - if (nHeight > nNewSporkLockHeight) { + if (nHeight > nNewSporkLockHeight + 1) { return true; } //LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Checking Spork Addr\n"); - if (nHeight > nNewSporkActHeight) { + if (nHeight >= nNewSporkActHeight) { std::vector vSporkAddresses = Params().SporkAddressesV3(); bool matches = true; int nFound = 0; From 550d3220659d54fe798bfb7ea949045d74e1e42a Mon Sep 17 00:00:00 2001 From: squid Date: Thu, 19 Oct 2023 03:59:10 -0400 Subject: [PATCH 3/5] improvement to spork key signers, use 2 of 3; cleanups --- configure.ac | 2 +- src/chainparams.cpp | 25 +++++++++++++++++-------- src/init.cpp | 17 +++++++---------- src/spork.cpp | 5 +++-- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index 0847f7de2ad3..2c90587f703f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 4) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 8) +define(_CLIENT_VERSION_BUILD, 10) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2023) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 544e2f79f3e3..eb6669bb4ecb 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -108,6 +108,7 @@ static CBlock FindDevNetGenesisBlock(const CBlock &prevBlock, const CAmount& rew // iteration of the above loop will give a result already error("FindDevNetGenesisBlock: could not find devnet genesis block for %s", devNetName); assert(false); + return block; } void CChainParams::AddLLMQ(Consensus::LLMQType llmqType) @@ -344,9 +345,17 @@ class CMainParams : public CChainParams { nPoolMaxParticipants = 5; nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour - vSporkAddressesV2 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; - vSporkAddressesV3 = {"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"}; - nMinSporkKeys = 1; + vSporkAddressesV2 = { + "sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", // o + "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c + "seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s + }; + vSporkAddressesV3 = { + "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c + "seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s + "sKoWUUTADtxHAzpjzrmFzjAFoaapuoz3hs" // t + }; + nMinSporkKeys = 2; fBIP9CheckMasternodesUpgraded = true; /** @@ -410,8 +419,6 @@ class CMainParams : public CChainParams { {700000, uint256S("000000000361299a95ea6a73d9a202a94893b3ec4fb441330740e20f9748cf36")}, {703355, uint256S("0000000002354cfaeb716435d7cfa632651f32ea22ef9796d25b893e264b2ea5")}, {703363, uint256S("00000000013b1c713a1ae71e6328f0f21efa08c7b8432d40bce681e4588645c4")}, - // 2023/09 - {717100, uint256S("0000000003189edcd28335b5e8bbb00752bad82c01c87604f4614ef103b14b24")}, // 2023/10 {750001, uint256S("00000000006ed565d981c2ba21d19fd1b655847fa156e8a1da4647a33bbb5b74")}, {750222, uint256S("000000000106b46906143c81532016eb1dcccf9859f3e1fc4f249c797f0c36ac")} @@ -419,10 +426,10 @@ class CMainParams : public CChainParams { }; chainTxData = ChainTxData{ - 1692077442, // * UNIX timestamp of last known number of transactions (Block 1) - 703363, // * total number of transactions between genesis and that timestamp + 1697678866, // * UNIX timestamp of last known number of transactions (Block 1) + 1498527, // * total number of transactions between genesis and that timestamp // (the tx=... number in the SetBestChain debug.log lines) - 0.0153 // * estimated number of transactions per second after that timestamp + 0.0208 // * estimated number of transactions per second after that timestamp }; } }; @@ -782,6 +789,7 @@ class CDevNetParams : public CChainParams { nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; + vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; nMinSporkKeys = 1; // devnets are started with no blocks and no MN, so we can't check for upgraded MN (as there are none) fBIP9CheckMasternodesUpgraded = false; @@ -960,6 +968,7 @@ class CRegTestParams : public CChainParams { // privKey: cP4EKFyJsHT39LDqgdcB43Y3YXjNyjb5Fuas1GQSeAtjnZWmZEQK vSporkAddressesV2 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; + vSporkAddressesV3 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; nMinSporkKeys = 1; // regtest usually has no masternodes in most tests, so don't check for upgraged MNs fBIP9CheckMasternodesUpgraded = false; diff --git a/src/init.cpp b/src/init.cpp index 216c1f264162..690220f80eac 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1685,7 +1685,7 @@ bool AppInitMain(InitInterfaces& interfaces) if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); } else { - vSporkAddresses = Params().SporkAddressesV2(); + vSporkAddresses = chainparams.SporkAddressesV2(); } for (const auto& address: vSporkAddresses) { if (!sporkManager.SetSporkAddress(address)) { @@ -1693,7 +1693,7 @@ bool AppInitMain(InitInterfaces& interfaces) } } - int minsporkkeys = gArgs.GetArg("-minsporkkeys", Params().MinSporkKeys()); + int minsporkkeys = gArgs.GetArg("-minsporkkeys", chainparams.MinSporkKeys()); if (!sporkManager.SetMinSporkKeys(minsporkkeys)) { return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys").translated); } @@ -2492,14 +2492,19 @@ bool AppInitMain(InitInterfaces& interfaces) // ********************************************************* Step 12.1: uprade sporks + if (chain_active_height < sporkManager.getNewSporkLockHeight()) { + LogPrintf("[init] CSporkManager -- Spork V3 Activation Height: %d Lock Height: %d\n", sporkManager.getNewSporkActHeight(), sporkManager.getNewSporkLockHeight()); + } if (chain_active_height >= sporkManager.getNewSporkActHeight() && chainparams.NetworkIDString() == CBaseChainParams::MAIN) { std::vector vSporkAddresses; if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); } else if (chain_active_height >= sporkManager.getNewSporkLockHeight()) { vSporkAddresses = Params().SporkAddressesV3(); + LogPrintf("Using V3 Spork Addresses\n"); } else { vSporkAddresses = Params().SporkAddressesV2(); + LogPrintf("Using V2 Spork Addresses\n"); } sporkManager.ClearSporkAddresses(); for (const auto& address : vSporkAddresses) { @@ -2512,14 +2517,6 @@ bool AppInitMain(InitInterfaces& interfaces) LogPrintf("CSporkManager -- WARN: mismatched spork addresses have been updated!\n"); } } - if (chain_active_height < sporkManager.getNewSporkLockHeight()) { - LogPrintf("CSporkManager -- Spork V3 Active Height: %d Lock Height: %d\n", sporkManager.getNewSporkActHeight(), sporkManager.getNewSporkLockHeight()); - } - if (chain_active_height >= sporkManager.getNewSporkActHeight()) { - LogPrintf("Using V3 Spork Addresses\n"); - } else { - LogPrintf("Using V2 Spork Addresses\n"); - } } // ********************************************************* Step 13: finished diff --git a/src/spork.cpp b/src/spork.cpp index adcba29498c6..a2b3cbd1ba3a 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -344,7 +344,7 @@ bool CSporkManager::CheckSporkPubkeyIDs() } int nHeight = ::ChainActive().Tip()->nHeight; - if (nHeight > nNewSporkLockHeight + 1) { + if (nHeight > nNewSporkLockHeight) { return true; } @@ -361,13 +361,14 @@ bool CSporkManager::CheckSporkPubkeyIDs() LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Failed to parse spork address\n"); matches = false; } else if (setSporkPubKeyIDs.find(*keyID) == setSporkPubKeyIDs.end()) { - LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- ERROR: spork address not found\n"); + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address not found\n"); matches = false; } else { nFound++; } } if (nFound != setSporkPubKeyIDs.size()) { + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address set length mismatch\n"); matches = false; } if (!matches) { From 00197a11c8150037f51a97ed61df1c14837024d5 Mon Sep 17 00:00:00 2001 From: squid Date: Thu, 19 Oct 2023 04:06:47 -0400 Subject: [PATCH 4/5] update height note --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index eb6669bb4ecb..065a1660eb6c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -426,7 +426,7 @@ class CMainParams : public CChainParams { }; chainTxData = ChainTxData{ - 1697678866, // * UNIX timestamp of last known number of transactions (Block 1) + 1697678866, // * UNIX timestamp of last known number of transactions (Block 750222) 1498527, // * total number of transactions between genesis and that timestamp // (the tx=... number in the SetBestChain debug.log lines) 0.0208 // * estimated number of transactions per second after that timestamp From 6b3f0d3693c31a22a0dfb27423a70d521405d8bd Mon Sep 17 00:00:00 2001 From: squid Date: Thu, 19 Oct 2023 17:54:33 -0400 Subject: [PATCH 5/5] restructure spork key change process; extend new spork lock height and activation window; doc update; v3.4.2.11 --- configure.ac | 2 +- doc/build-unix.md | 4 ++-- src/chainparams.cpp | 22 +++++++++++++++++----- src/chainparams.h | 8 ++++++-- src/init.cpp | 10 +++++++--- src/spork.cpp | 21 ++++++++++++++++----- src/spork.h | 2 +- 7 files changed, 50 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 2c90587f703f..3b534ba2db2b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 4) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 10) +define(_CLIENT_VERSION_BUILD, 11) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2023) diff --git a/doc/build-unix.md b/doc/build-unix.md index a256fa10cc2e..aa4b6bb186cf 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -13,7 +13,7 @@ Run the following commands to install required packages: ##### Debian/Ubuntu: ```bash -$ sudo apt-get install curl build-essential libtool autotools-dev automake pkg-config python3 bsdmainutils +$ sudo apt-get install curl build-essential libtool autotools-dev automake pkg-config python3 bsdmainutils libevent-dev libgmp-dev ``` ##### Fedora: @@ -158,4 +158,4 @@ If your user is in the `staff` group the limit can be raised with: The change will only affect the current shell and processes spawned by it. To make the change system-wide, change `datasize-cur` and `datasize-max` in -`/etc/login.conf`, and reboot. \ No newline at end of file +`/etc/login.conf`, and reboot. diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 065a1660eb6c..1fec9d4d2309 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -345,17 +345,23 @@ class CMainParams : public CChainParams { nPoolMaxParticipants = 5; nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour + vSporkAddressesV1 = { + "sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb" // o + }; vSporkAddressesV2 = { "sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", // o "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c "seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s + "sMXHsSGHCVJAfsebfs3g3g1hRcTioWTjBo" // d }; vSporkAddressesV3 = { "sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c "seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s - "sKoWUUTADtxHAzpjzrmFzjAFoaapuoz3hs" // t + "sMXHsSGHCVJAfsebfs3g3g1hRcTioWTjBo" // d }; - nMinSporkKeys = 2; + nMinSporkKeysV1 = 1; + nMinSporkKeysV3 = 2; + fBIP9CheckMasternodesUpgraded = true; /** @@ -598,9 +604,11 @@ class CTestNetParams : public CChainParams { nPoolMaxParticipants = 20; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes + vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"}; vSporkAddressesV2 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55", "yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; - nMinSporkKeys = 1; + nMinSporkKeysV1 = 1; + nMinSporkKeysV3 = 1; fBIP9CheckMasternodesUpgraded = true; checkpointData = { @@ -788,9 +796,11 @@ class CDevNetParams : public CChainParams { nPoolMaxParticipants = 20; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes + vSporkAddressesV1 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"}; - nMinSporkKeys = 1; + nMinSporkKeysV1 = 1; + nMinSporkKeysV3 = 1; // devnets are started with no blocks and no MN, so we can't check for upgraded MN (as there are none) fBIP9CheckMasternodesUpgraded = false; @@ -967,9 +977,11 @@ class CRegTestParams : public CChainParams { nPoolMaxParticipants = 20; // privKey: cP4EKFyJsHT39LDqgdcB43Y3YXjNyjb5Fuas1GQSeAtjnZWmZEQK + vSporkAddressesV1 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; vSporkAddressesV2 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; vSporkAddressesV3 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"}; - nMinSporkKeys = 1; + nMinSporkKeysV1 = 1; + nMinSporkKeysV3 = 1; // regtest usually has no masternodes in most tests, so don't check for upgraged MNs fBIP9CheckMasternodesUpgraded = false; diff --git a/src/chainparams.h b/src/chainparams.h index 8df9c66e7d22..f72966d55a18 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -106,9 +106,11 @@ class CChainParams int PoolMinParticipants() const { return nPoolMinParticipants; } int PoolMaxParticipants() const { return nPoolMaxParticipants; } int FulfilledRequestExpireTime() const { return nFulfilledRequestExpireTime; } + const std::vector& SporkAddressesV1() const { return vSporkAddressesV1; } const std::vector& SporkAddressesV2() const { return vSporkAddressesV2; } const std::vector& SporkAddressesV3() const { return vSporkAddressesV3; } - int MinSporkKeys() const { return nMinSporkKeys; } + int MinSporkKeysV1() const { return nMinSporkKeysV1; } + int MinSporkKeysV3() const { return nMinSporkKeysV3; } bool BIP9CheckMasternodesUpgraded() const { return fBIP9CheckMasternodesUpgraded; } const Consensus::LLMQParams& GetLLMQ(Consensus::LLMQType llmqType) const; bool HasLLMQ(Consensus::LLMQType llmqType) const; @@ -142,9 +144,11 @@ class CChainParams int nPoolMinParticipants; int nPoolMaxParticipants; int nFulfilledRequestExpireTime; + std::vector vSporkAddressesV1; std::vector vSporkAddressesV2; std::vector vSporkAddressesV3; - int nMinSporkKeys; + int nMinSporkKeysV1; + int nMinSporkKeysV3; bool fBIP9CheckMasternodesUpgraded; void AddLLMQ(Consensus::LLMQType llmqType); diff --git a/src/init.cpp b/src/init.cpp index 690220f80eac..c4275a0e28e2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1685,7 +1685,7 @@ bool AppInitMain(InitInterfaces& interfaces) if (gArgs.IsArgSet("-sporkaddr")) { vSporkAddresses = gArgs.GetArgs("-sporkaddr"); } else { - vSporkAddresses = chainparams.SporkAddressesV2(); + vSporkAddresses = chainparams.SporkAddressesV1(); } for (const auto& address: vSporkAddresses) { if (!sporkManager.SetSporkAddress(address)) { @@ -1693,12 +1693,11 @@ bool AppInitMain(InitInterfaces& interfaces) } } - int minsporkkeys = gArgs.GetArg("-minsporkkeys", chainparams.MinSporkKeys()); + int minsporkkeys = gArgs.GetArg("-minsporkkeys", chainparams.MinSporkKeysV1()); if (!sporkManager.SetMinSporkKeys(minsporkkeys)) { return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys").translated); } - if (gArgs.IsArgSet("-sporkkey")) { // spork priv key if (!sporkManager.SetPrivKey(gArgs.GetArg("-sporkkey", ""))) { return InitError(_("Unable to sign spork message, wrong key?").translated); @@ -2517,6 +2516,11 @@ bool AppInitMain(InitInterfaces& interfaces) LogPrintf("CSporkManager -- WARN: mismatched spork addresses have been updated!\n"); } } + if (chain_active_height >= sporkManager.getNewSporkLockHeight()) { + if (!sporkManager.SetMinSporkKeys(Params().MinSporkKeysV3())) { + return InitError(_("Invalid minimum number of spork signers specified for V3!").translated); + } + } } // ********************************************************* Step 13: finished diff --git a/src/spork.cpp b/src/spork.cpp index a2b3cbd1ba3a..aa35fa52ad66 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -338,21 +338,27 @@ bool CSporkManager::SetPrivKey(const std::string& strPrivKey) bool CSporkManager::CheckSporkPubkeyIDs() { - if (!::ChainActive().Tip() || Params().NetworkIDString() != CBaseChainParams::MAIN) + const CChainParams& params = Params(); + if (!::ChainActive().Tip() || params.NetworkIDString() != CBaseChainParams::MAIN) { return true; } int nHeight = ::ChainActive().Tip()->nHeight; if (nHeight > nNewSporkLockHeight) { + // change completed. spork changes locked. return true; } - //LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Checking Spork Addr\n"); - if (nHeight >= nNewSporkActHeight) { - std::vector vSporkAddresses = Params().SporkAddressesV3(); + if (nHeight >= nNewSporkActHeight) { // start of checks + std::vector vSporkAddresses = params.SporkAddressesV2(); + bool fLocking = false; bool matches = true; int nFound = 0; + if (nHeight >= nNewSporkLockHeight - 200) { // act shortly before lockout + vSporkAddresses = params.SporkAddressesV3(); + fLocking = true; + } LOCK(cs); for (const auto& strAddress : vSporkAddresses) { CTxDestination dest = DecodeDestination(strAddress); @@ -361,7 +367,7 @@ bool CSporkManager::CheckSporkPubkeyIDs() LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Failed to parse spork address\n"); matches = false; } else if (setSporkPubKeyIDs.find(*keyID) == setSporkPubKeyIDs.end()) { - LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address not found\n"); + LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address %s not found\n", strAddress); matches = false; } else { nFound++; @@ -378,6 +384,11 @@ bool CSporkManager::CheckSporkPubkeyIDs() LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- ERROR: invalid spork address\n"); } } + if (fLocking) { + nMinSporkKeys = params.MinSporkKeysV3(); + } else { + nMinSporkKeys = params.MinSporkKeysV1(); + } return false; } } diff --git a/src/spork.h b/src/spork.h index f702be27d80a..4061dcc526e0 100644 --- a/src/spork.h +++ b/src/spork.h @@ -181,7 +181,7 @@ class CSporkManager bool SporkValueIsActive(SporkId nSporkID, int64_t& nActiveValueRet) const EXCLUSIVE_LOCKS_REQUIRED(cs); int nNewSporkActHeight = 755040; - int nNewSporkLockHeight = 760080; + int nNewSporkLockHeight = 775200; public: