dash/src/llmq/dkgsessionhandler.cpp

579 lines
23 KiB
C++
Raw Normal View History

// Copyright (c) 2018-2022 The Dash Core developers
2018-05-24 16:14:55 +02:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <llmq/dkgsessionhandler.h>
#include <llmq/commitment.h>
#include <llmq/dkgsession.h>
#include <llmq/blockprocessor.h>
#include <llmq/debug.h>
#include <llmq/utils.h>
2018-05-24 16:14:55 +02:00
#include <evo/deterministicmns.h>
#include <deploymentstatus.h>
#include <masternode/node.h>
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <chainparams.h>
#include <net_processing.h>
#include <validation.h>
#include <util/thread.h>
#include <util/underlying.h>
2018-05-24 16:14:55 +02:00
namespace llmq
{
CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGDebugManager& _dkgDebugManager,
CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor,
const Consensus::LLMQParams& _params, const std::unique_ptr<PeerManager>& peerman, int _quorumIndex) :
blsWorker(_blsWorker),
m_chainstate(chainstate),
connman(_connman),
dkgDebugManager(_dkgDebugManager),
dkgManager(_dkgManager),
quorumBlockProcessor(_quorumBlockProcessor),
params(_params),
m_peerman(peerman),
quorumIndex(_quorumIndex),
curSession(std::make_unique<CDKGSession>(_params, _blsWorker, _dkgManager, _dkgDebugManager, _connman)),
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
pendingPrematureCommitments((size_t)_params.size * 2, MSG_QUORUM_PREMATURE_COMMITMENT)
{
if (params.type == Consensus::LLMQType::LLMQ_NONE) {
throw std::runtime_error("Can't initialize CDKGSessionHandler with LLMQ_NONE type.");
}
}
2018-05-24 16:14:55 +02:00
void CDKGPendingMessages::PushPendingMessage(NodeId from, CDataStream& vRecv)
{
// this will also consume the data, even if we bail out early
auto pm = std::make_shared<CDataStream>(std::move(vRecv));
CHashWriter hw(SER_GETHASH, 0);
hw.write(reinterpret_cast<const char*>(pm->data()), pm->size());
2018-05-24 16:14:55 +02:00
uint256 hash = hw.GetHash();
if (from != -1) {
LOCK(cs_main);
EraseObjectRequest(from, CInv(invType, hash));
}
LOCK(cs);
if (messagesPerNode[from] >= maxMessagesPerNode) {
// TODO ban?
LogPrint(BCLog::LLMQ_DKG, "CDKGPendingMessages::%s -- too many messages, peer=%d\n", __func__, from);
return;
}
messagesPerNode[from]++;
2018-05-24 16:14:55 +02:00
if (!seenMessages.emplace(hash).second) {
LogPrint(BCLog::LLMQ_DKG, "CDKGPendingMessages::%s -- already seen %s, peer=%d\n", __func__, hash.ToString(), from);
2018-05-24 16:14:55 +02:00
return;
}
pendingMessages.emplace_back(std::make_pair(from, std::move(pm)));
}
std::list<CDKGPendingMessages::BinaryMessage> CDKGPendingMessages::PopPendingMessages(size_t maxCount)
{
LOCK(cs);
std::list<BinaryMessage> ret;
while (!pendingMessages.empty() && ret.size() < maxCount) {
ret.emplace_back(std::move(pendingMessages.front()));
pendingMessages.pop_front();
}
refactor: misc refactoring in instantsend, llmq, coinjoin (#4212) * instantsend: make stuff const where possible Signed-off-by: pasta <pasta@dashboost.org> * instantsend: remove unused `params` Signed-off-by: pasta <pasta@dashboost.org> * instantsend: combine two nested if's into one Signed-off-by: pasta <pasta@dashboost.org> * instantsend: use auto in spots where possible and clear Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: make IsValidStructure const Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: divide by an integer to avoid double implicit conversions Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: make unused parameter unnamed Signed-off-by: pasta <pasta@dashboost.org> * quorums.* use const and use references where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums.h don't return const when returning by value Signed-off-by: pasta <pasta@dashboost.org> * quorums_blockprocessor.cpp remove redundant casts and combine two if statements Signed-off-by: pasta <pasta@dashboost.org> * quorums_blockprocessor.cpp make values const Signed-off-by: pasta <pasta@dashboost.org> * quorums_chainlocks.cpp access static function statically Signed-off-by: pasta <pasta@dashboost.org> * quorums_chainlocks.h remove commented out include Signed-off-by: pasta <pasta@dashboost.org> * quorums_commitment.cpp remove redundant casts Signed-off-by: pasta <pasta@dashboost.org> * quorums_debug.cpp remove redundant casts and add const Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsession.cpp use const where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp use const where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp don't use std::move which apparently prevents "copy elision" in this instance Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp use const Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionmgr.cpp misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_signing.* misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_signing_shares.* misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_utils.cpp misc refactoring Signed-off-by: pasta <pasta@dashboost.org>
2021-06-26 15:10:53 +02:00
return ret;
2018-05-24 16:14:55 +02:00
}
bool CDKGPendingMessages::HasSeen(const uint256& hash) const
{
LOCK(cs);
return seenMessages.count(hash) != 0;
}
void CDKGPendingMessages::Clear()
{
LOCK(cs);
pendingMessages.clear();
messagesPerNode.clear();
seenMessages.clear();
}
//////
void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew)
2018-05-24 16:14:55 +02:00
{
feat: implement quorum rotation and updated LLMQ parameters (#4752) * Added GET_SNAPSHOT_INFO message handling * Quorum members by rotation * Quorum utils functions * Handle GET_QUORUM_ROTATION_INFO with baseBlockHash from client * Storing QuorumSnaphots in evoDB when requesting them * Added DIP Enforcement param * quorumIndex cache * Quorum Rotation deployment control * Usage of Bitsets for storing CQuorumSnapshots * Correct handling of early quorum quarters * More asserts * Corrections * Handling of quorumIndex * Refactoring of truncate mechanism * Various fixes * Interface correction * Added template type for indexed cache * Added quorumIndex into commitmenHash * Various changes * Needs to update maqQuorumsCache along with indexedQuorumsCache * Added CFinalCommitment version 2 * Renamed variables * Fixes * Refactoring & correct caching of quorumMembers by rotation * Added assertions * Refactoring * Interface change * Handling of previous DKG session failure * Applied refactoring * Build quarter members improvments * Merge Quorum Rotation and Decreased fee into one deployment (DIP24) * Added new LLMQ Type * Added functional tests + refactoring * Refactoring * Spreaded Quorum creation and Quorum Index adaptation * quorumIndex adaptations * Added quorumIndex in CFinalCommitment * Latest work * Final refactoring * Batch of refactoring * Fixes for tests * Fix for CFinalCommitment * Fix for Quorums * Fix * Small changes * Thread sync fic * Safety changes * Reuse mns when needed * Refactoring * More refactoring * Fixes for rotationinfo handling * Fix for rotation of members * Correct order of MNs lists in Quorum Snapshots * Adding extra logs * Sync rotation quorums + qrinfo changes * Fix + extra logs * Removed redundant field * Fix for null final commitment + refactoring * Added timers in tests * Fix for qrinfo message: quorumdiff and merkleRootQuorums * Small changes for rotation test * Remove reading from scanQuorumCache * Added quorum list output * Crash fix * Experimental commit * apply changes to specialtxman.cpp from specialtx.cpp * all the changes * substancially speed up feature_llmq_rotation.py * reenable asserts, add check for reorgs * Refactoring * Added extra logs * format * trivial * drop extra boost includes * drop ContainsMN * fix ScanQuorums * check quorum hash and index in CFinalCommitment::Verify * fix/tweak tests * IsQuorumRotationEnabled should be aware of the context * Calculating members based on earlier block. * Fix for Quorum Members Cache * Removed duplicate size of baseBlockHashes * Adaptations of qrinfo to -8 mn lists * Introduction of llmqTypeDIP24InstantSend * Adaptation for llmqTypeDIP24InstantSend * Adaptations for IS * bump protocol version * Added feature_llmq_is_migration test * Various cleanups * use unordered_lru_cache for quorumSnapshotCache * trivial refactor ComputeQuorumMembersByQuarterRotation * Reduced CFinalCommitment::quorumIndex from 32 to 16 bits * Keep verified LLMQ relay connections * Experimental Relay connection fix * Fix for EnsureQuorumConnections rotation * Using only valid Mns for checking * Override of nPowTargetSpacing (devnet only) * Show penalty score in masternode rpc * fixups * Rotation refactoring * Update src/chainparams.cpp * Replaced LogPrintf with LogPrint * IS locking fix once DIP24 activation * Various cleanup * Updated MIN_MASTERNODE_PROTO_VERSION * Introduce LLMQ_TEST_INSTANTSEND reg-test only quorum and actually test switching to dip0024 quorums * Renamed field lastQuorumHashPerIndex * Renamed to DIP0024 * chore: update nStartTime and nTimeout for mainnet / testnet for DEPLOYMENT_DIP0024 Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Co-authored-by: pasta <pasta@dashboost.org> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2022-04-16 16:46:04 +02:00
//AssertLockNotHeld(cs_main);
//Indexed quorums (greater than 0) are enabled with Quorum Rotation
if (quorumIndex > 0 && !utils::IsQuorumRotationEnabled(params, pindexNew)) {
feat: implement quorum rotation and updated LLMQ parameters (#4752) * Added GET_SNAPSHOT_INFO message handling * Quorum members by rotation * Quorum utils functions * Handle GET_QUORUM_ROTATION_INFO with baseBlockHash from client * Storing QuorumSnaphots in evoDB when requesting them * Added DIP Enforcement param * quorumIndex cache * Quorum Rotation deployment control * Usage of Bitsets for storing CQuorumSnapshots * Correct handling of early quorum quarters * More asserts * Corrections * Handling of quorumIndex * Refactoring of truncate mechanism * Various fixes * Interface correction * Added template type for indexed cache * Added quorumIndex into commitmenHash * Various changes * Needs to update maqQuorumsCache along with indexedQuorumsCache * Added CFinalCommitment version 2 * Renamed variables * Fixes * Refactoring & correct caching of quorumMembers by rotation * Added assertions * Refactoring * Interface change * Handling of previous DKG session failure * Applied refactoring * Build quarter members improvments * Merge Quorum Rotation and Decreased fee into one deployment (DIP24) * Added new LLMQ Type * Added functional tests + refactoring * Refactoring * Spreaded Quorum creation and Quorum Index adaptation * quorumIndex adaptations * Added quorumIndex in CFinalCommitment * Latest work * Final refactoring * Batch of refactoring * Fixes for tests * Fix for CFinalCommitment * Fix for Quorums * Fix * Small changes * Thread sync fic * Safety changes * Reuse mns when needed * Refactoring * More refactoring * Fixes for rotationinfo handling * Fix for rotation of members * Correct order of MNs lists in Quorum Snapshots * Adding extra logs * Sync rotation quorums + qrinfo changes * Fix + extra logs * Removed redundant field * Fix for null final commitment + refactoring * Added timers in tests * Fix for qrinfo message: quorumdiff and merkleRootQuorums * Small changes for rotation test * Remove reading from scanQuorumCache * Added quorum list output * Crash fix * Experimental commit * apply changes to specialtxman.cpp from specialtx.cpp * all the changes * substancially speed up feature_llmq_rotation.py * reenable asserts, add check for reorgs * Refactoring * Added extra logs * format * trivial * drop extra boost includes * drop ContainsMN * fix ScanQuorums * check quorum hash and index in CFinalCommitment::Verify * fix/tweak tests * IsQuorumRotationEnabled should be aware of the context * Calculating members based on earlier block. * Fix for Quorum Members Cache * Removed duplicate size of baseBlockHashes * Adaptations of qrinfo to -8 mn lists * Introduction of llmqTypeDIP24InstantSend * Adaptation for llmqTypeDIP24InstantSend * Adaptations for IS * bump protocol version * Added feature_llmq_is_migration test * Various cleanups * use unordered_lru_cache for quorumSnapshotCache * trivial refactor ComputeQuorumMembersByQuarterRotation * Reduced CFinalCommitment::quorumIndex from 32 to 16 bits * Keep verified LLMQ relay connections * Experimental Relay connection fix * Fix for EnsureQuorumConnections rotation * Using only valid Mns for checking * Override of nPowTargetSpacing (devnet only) * Show penalty score in masternode rpc * fixups * Rotation refactoring * Update src/chainparams.cpp * Replaced LogPrintf with LogPrint * IS locking fix once DIP24 activation * Various cleanup * Updated MIN_MASTERNODE_PROTO_VERSION * Introduce LLMQ_TEST_INSTANTSEND reg-test only quorum and actually test switching to dip0024 quorums * Renamed field lastQuorumHashPerIndex * Renamed to DIP0024 * chore: update nStartTime and nTimeout for mainnet / testnet for DEPLOYMENT_DIP0024 Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Co-authored-by: pasta <pasta@dashboost.org> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2022-04-16 16:46:04 +02:00
return;
}
2018-05-24 16:14:55 +02:00
LOCK(cs);
feat: implement quorum rotation and updated LLMQ parameters (#4752) * Added GET_SNAPSHOT_INFO message handling * Quorum members by rotation * Quorum utils functions * Handle GET_QUORUM_ROTATION_INFO with baseBlockHash from client * Storing QuorumSnaphots in evoDB when requesting them * Added DIP Enforcement param * quorumIndex cache * Quorum Rotation deployment control * Usage of Bitsets for storing CQuorumSnapshots * Correct handling of early quorum quarters * More asserts * Corrections * Handling of quorumIndex * Refactoring of truncate mechanism * Various fixes * Interface correction * Added template type for indexed cache * Added quorumIndex into commitmenHash * Various changes * Needs to update maqQuorumsCache along with indexedQuorumsCache * Added CFinalCommitment version 2 * Renamed variables * Fixes * Refactoring & correct caching of quorumMembers by rotation * Added assertions * Refactoring * Interface change * Handling of previous DKG session failure * Applied refactoring * Build quarter members improvments * Merge Quorum Rotation and Decreased fee into one deployment (DIP24) * Added new LLMQ Type * Added functional tests + refactoring * Refactoring * Spreaded Quorum creation and Quorum Index adaptation * quorumIndex adaptations * Added quorumIndex in CFinalCommitment * Latest work * Final refactoring * Batch of refactoring * Fixes for tests * Fix for CFinalCommitment * Fix for Quorums * Fix * Small changes * Thread sync fic * Safety changes * Reuse mns when needed * Refactoring * More refactoring * Fixes for rotationinfo handling * Fix for rotation of members * Correct order of MNs lists in Quorum Snapshots * Adding extra logs * Sync rotation quorums + qrinfo changes * Fix + extra logs * Removed redundant field * Fix for null final commitment + refactoring * Added timers in tests * Fix for qrinfo message: quorumdiff and merkleRootQuorums * Small changes for rotation test * Remove reading from scanQuorumCache * Added quorum list output * Crash fix * Experimental commit * apply changes to specialtxman.cpp from specialtx.cpp * all the changes * substancially speed up feature_llmq_rotation.py * reenable asserts, add check for reorgs * Refactoring * Added extra logs * format * trivial * drop extra boost includes * drop ContainsMN * fix ScanQuorums * check quorum hash and index in CFinalCommitment::Verify * fix/tweak tests * IsQuorumRotationEnabled should be aware of the context * Calculating members based on earlier block. * Fix for Quorum Members Cache * Removed duplicate size of baseBlockHashes * Adaptations of qrinfo to -8 mn lists * Introduction of llmqTypeDIP24InstantSend * Adaptation for llmqTypeDIP24InstantSend * Adaptations for IS * bump protocol version * Added feature_llmq_is_migration test * Various cleanups * use unordered_lru_cache for quorumSnapshotCache * trivial refactor ComputeQuorumMembersByQuarterRotation * Reduced CFinalCommitment::quorumIndex from 32 to 16 bits * Keep verified LLMQ relay connections * Experimental Relay connection fix * Fix for EnsureQuorumConnections rotation * Using only valid Mns for checking * Override of nPowTargetSpacing (devnet only) * Show penalty score in masternode rpc * fixups * Rotation refactoring * Update src/chainparams.cpp * Replaced LogPrintf with LogPrint * IS locking fix once DIP24 activation * Various cleanup * Updated MIN_MASTERNODE_PROTO_VERSION * Introduce LLMQ_TEST_INSTANTSEND reg-test only quorum and actually test switching to dip0024 quorums * Renamed field lastQuorumHashPerIndex * Renamed to DIP0024 * chore: update nStartTime and nTimeout for mainnet / testnet for DEPLOYMENT_DIP0024 Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Co-authored-by: pasta <pasta@dashboost.org> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2022-04-16 16:46:04 +02:00
int quorumStageInt = (pindexNew->nHeight - quorumIndex) % params.dkgInterval;
const CBlockIndex* pQuorumBaseBlockIndex = pindexNew->GetAncestor(pindexNew->nHeight - quorumStageInt);
2018-05-24 16:14:55 +02:00
currentHeight = pindexNew->nHeight;
quorumHash = pQuorumBaseBlockIndex->GetBlockHash();
2018-05-24 16:14:55 +02:00
bool fNewPhase = (quorumStageInt % params.dkgPhaseBlocks) == 0;
int phaseInt = quorumStageInt / params.dkgPhaseBlocks + 1;
QuorumPhase oldPhase = phase;
if (fNewPhase && phaseInt >= ToUnderlying(QuorumPhase::Initialized) && phaseInt <= ToUnderlying(QuorumPhase::Idle)) {
phase = static_cast<QuorumPhase>(phaseInt);
2018-05-24 16:14:55 +02:00
}
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] currentHeight=%d, pQuorumBaseBlockIndex->nHeight=%d, oldPhase=%d, newPhase=%d\n", __func__,
params.name, quorumIndex, currentHeight, pQuorumBaseBlockIndex->nHeight, ToUnderlying(oldPhase), ToUnderlying(phase));
2018-05-24 16:14:55 +02:00
}
void CDKGSessionHandler::ProcessMessage(const CNode& pfrom, const std::string& msg_type, CDataStream& vRecv)
2018-05-24 16:14:55 +02:00
{
// We don't handle messages in the calling thread as deserialization/processing of these would block everything
scripted-diff: Merge #18533 Replace strCommand with msg_type (#4761) -BEGIN VERIFY SCRIPT- sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.h sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.h sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.cpp sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.h sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.cpp sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.h sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.cpp sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.h sed -i 's/\<strCommand\>/msg_type/g' src/net_processing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.h -END VERIFY SCRIPT-
2022-04-18 18:47:26 +02:00
if (msg_type == NetMsgType::QCONTRIB) {
pendingContributions.PushPendingMessage(pfrom.GetId(), vRecv);
scripted-diff: Merge #18533 Replace strCommand with msg_type (#4761) -BEGIN VERIFY SCRIPT- sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.h sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.h sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.cpp sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.h sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.cpp sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.h sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.cpp sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.h sed -i 's/\<strCommand\>/msg_type/g' src/net_processing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.h -END VERIFY SCRIPT-
2022-04-18 18:47:26 +02:00
} else if (msg_type == NetMsgType::QCOMPLAINT) {
pendingComplaints.PushPendingMessage(pfrom.GetId(), vRecv);
scripted-diff: Merge #18533 Replace strCommand with msg_type (#4761) -BEGIN VERIFY SCRIPT- sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.h sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.h sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.cpp sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.h sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.cpp sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.h sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.cpp sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.h sed -i 's/\<strCommand\>/msg_type/g' src/net_processing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.h -END VERIFY SCRIPT-
2022-04-18 18:47:26 +02:00
} else if (msg_type == NetMsgType::QJUSTIFICATION) {
pendingJustifications.PushPendingMessage(pfrom.GetId(), vRecv);
scripted-diff: Merge #18533 Replace strCommand with msg_type (#4761) -BEGIN VERIFY SCRIPT- sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/client.h sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.cpp sed -i 's/\<strCommand\>/msg_type/g' src/coinjoin/server.h sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.cpp sed -i 's/\<strCommand\>/msg_type/g' src/evo/mnauth.h sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.cpp sed -i 's/\<strCommand\>/msg_type/g' src/governance/governance.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/blockprocessor.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/chainlocks.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionhandler.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/dkgsessionmgr.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/instantsend.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/quorums.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing.h sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.cpp sed -i 's/\<strCommand\>/msg_type/g' src/llmq/signing_shares.h sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.cpp sed -i 's/\<strCommand\>/msg_type/g' src/masternode/sync.h sed -i 's/\<strCommand\>/msg_type/g' src/net_processing.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.cpp sed -i 's/\<strCommand\>/msg_type/g' src/spork.h -END VERIFY SCRIPT-
2022-04-18 18:47:26 +02:00
} else if (msg_type == NetMsgType::QPCOMMITMENT) {
pendingPrematureCommitments.PushPendingMessage(pfrom.GetId(), vRecv);
2018-05-24 16:14:55 +02:00
}
}
void CDKGSessionHandler::StartThread()
{
if (phaseHandlerThread.joinable()) {
throw std::runtime_error("Tried to start an already started CDKGSessionHandler thread.");
}
m_thread_name = strprintf("llmq-%d-%d", ToUnderlying(params.type), quorumIndex);
phaseHandlerThread = std::thread(util::TraceThread, m_thread_name.c_str(), [this] { PhaseHandlerThread(); });
}
void CDKGSessionHandler::StopThread()
{
stopRequested = true;
if (phaseHandlerThread.joinable()) {
phaseHandlerThread.join();
}
}
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
2018-05-24 16:14:55 +02:00
{
curSession = std::make_unique<CDKGSession>(params, blsWorker, dkgManager, dkgDebugManager, connman);
2018-05-24 16:14:55 +02:00
if (!DeploymentDIP0003Enforced(pQuorumBaseBlockIndex->nHeight, Params().GetConsensus())) {
2018-05-24 16:14:55 +02:00
return false;
}
auto mns = utils::GetAllQuorumMembers(params.type, pQuorumBaseBlockIndex);
feat: implement quorum rotation and updated LLMQ parameters (#4752) * Added GET_SNAPSHOT_INFO message handling * Quorum members by rotation * Quorum utils functions * Handle GET_QUORUM_ROTATION_INFO with baseBlockHash from client * Storing QuorumSnaphots in evoDB when requesting them * Added DIP Enforcement param * quorumIndex cache * Quorum Rotation deployment control * Usage of Bitsets for storing CQuorumSnapshots * Correct handling of early quorum quarters * More asserts * Corrections * Handling of quorumIndex * Refactoring of truncate mechanism * Various fixes * Interface correction * Added template type for indexed cache * Added quorumIndex into commitmenHash * Various changes * Needs to update maqQuorumsCache along with indexedQuorumsCache * Added CFinalCommitment version 2 * Renamed variables * Fixes * Refactoring & correct caching of quorumMembers by rotation * Added assertions * Refactoring * Interface change * Handling of previous DKG session failure * Applied refactoring * Build quarter members improvments * Merge Quorum Rotation and Decreased fee into one deployment (DIP24) * Added new LLMQ Type * Added functional tests + refactoring * Refactoring * Spreaded Quorum creation and Quorum Index adaptation * quorumIndex adaptations * Added quorumIndex in CFinalCommitment * Latest work * Final refactoring * Batch of refactoring * Fixes for tests * Fix for CFinalCommitment * Fix for Quorums * Fix * Small changes * Thread sync fic * Safety changes * Reuse mns when needed * Refactoring * More refactoring * Fixes for rotationinfo handling * Fix for rotation of members * Correct order of MNs lists in Quorum Snapshots * Adding extra logs * Sync rotation quorums + qrinfo changes * Fix + extra logs * Removed redundant field * Fix for null final commitment + refactoring * Added timers in tests * Fix for qrinfo message: quorumdiff and merkleRootQuorums * Small changes for rotation test * Remove reading from scanQuorumCache * Added quorum list output * Crash fix * Experimental commit * apply changes to specialtxman.cpp from specialtx.cpp * all the changes * substancially speed up feature_llmq_rotation.py * reenable asserts, add check for reorgs * Refactoring * Added extra logs * format * trivial * drop extra boost includes * drop ContainsMN * fix ScanQuorums * check quorum hash and index in CFinalCommitment::Verify * fix/tweak tests * IsQuorumRotationEnabled should be aware of the context * Calculating members based on earlier block. * Fix for Quorum Members Cache * Removed duplicate size of baseBlockHashes * Adaptations of qrinfo to -8 mn lists * Introduction of llmqTypeDIP24InstantSend * Adaptation for llmqTypeDIP24InstantSend * Adaptations for IS * bump protocol version * Added feature_llmq_is_migration test * Various cleanups * use unordered_lru_cache for quorumSnapshotCache * trivial refactor ComputeQuorumMembersByQuarterRotation * Reduced CFinalCommitment::quorumIndex from 32 to 16 bits * Keep verified LLMQ relay connections * Experimental Relay connection fix * Fix for EnsureQuorumConnections rotation * Using only valid Mns for checking * Override of nPowTargetSpacing (devnet only) * Show penalty score in masternode rpc * fixups * Rotation refactoring * Update src/chainparams.cpp * Replaced LogPrintf with LogPrint * IS locking fix once DIP24 activation * Various cleanup * Updated MIN_MASTERNODE_PROTO_VERSION * Introduce LLMQ_TEST_INSTANTSEND reg-test only quorum and actually test switching to dip0024 quorums * Renamed field lastQuorumHashPerIndex * Renamed to DIP0024 * chore: update nStartTime and nTimeout for mainnet / testnet for DEPLOYMENT_DIP0024 Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Co-authored-by: pasta <pasta@dashboost.org> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2022-04-16 16:46:04 +02:00
if (!curSession->Init(pQuorumBaseBlockIndex, mns, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash), quorumIndex)) {
LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s qi[%d] mns[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex, mns.size());
2018-05-24 16:14:55 +02:00
return false;
}
LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization OK for %s qi[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
return true;
}
2019-01-11 10:00:40 +01:00
std::pair<QuorumPhase, uint256> CDKGSessionHandler::GetPhaseAndQuorumHash() const
2018-05-24 16:14:55 +02:00
{
LOCK(cs);
return std::make_pair(phase, quorumHash);
}
class AbortPhaseException : public std::exception {
};
void CDKGSessionHandler::WaitForNextPhase(std::optional<QuorumPhase> curPhase,
2018-05-24 16:14:55 +02:00
QuorumPhase nextPhase,
const uint256& expectedQuorumHash,
const WhileWaitFunc& shouldNotWait) const
2018-05-24 16:14:55 +02:00
{
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? ToUnderlying(*curPhase) : -1, ToUnderlying(nextPhase));
2018-05-24 16:14:55 +02:00
while (true) {
if (stopRequested) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
throw AbortPhaseException();
}
auto [_phase, _quorumHash] = GetPhaseAndQuorumHash();
if (!expectedQuorumHash.IsNull() && _quorumHash != expectedQuorumHash) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected expectedQuorumHash change\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
throw AbortPhaseException();
}
if (_phase == nextPhase) {
break;
2018-05-24 16:14:55 +02:00
}
if (curPhase.has_value() && _phase != curPhase) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected phase change, _phase=%d, curPhase=%d\n", __func__, params.name, quorumIndex, ToUnderlying(_phase), curPhase.has_value() ? ToUnderlying(*curPhase) : -1);
2018-05-24 16:14:55 +02:00
throw AbortPhaseException();
}
if (!shouldNotWait()) {
UninterruptibleSleep(std::chrono::milliseconds{100});
2018-05-24 16:14:55 +02:00
}
}
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? ToUnderlying(*curPhase) : -1, ToUnderlying(nextPhase));
if (nextPhase == QuorumPhase::Initialized) {
dkgDebugManager.ResetLocalSessionStatus(params.type, quorumIndex);
} else {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != nextPhase;
status.phase = nextPhase;
return changed;
});
}
2018-05-24 16:14:55 +02:00
}
refactor: misc refactoring in instantsend, llmq, coinjoin (#4212) * instantsend: make stuff const where possible Signed-off-by: pasta <pasta@dashboost.org> * instantsend: remove unused `params` Signed-off-by: pasta <pasta@dashboost.org> * instantsend: combine two nested if's into one Signed-off-by: pasta <pasta@dashboost.org> * instantsend: use auto in spots where possible and clear Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: make IsValidStructure const Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: divide by an integer to avoid double implicit conversions Signed-off-by: pasta <pasta@dashboost.org> * coinjoin: make unused parameter unnamed Signed-off-by: pasta <pasta@dashboost.org> * quorums.* use const and use references where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums.h don't return const when returning by value Signed-off-by: pasta <pasta@dashboost.org> * quorums_blockprocessor.cpp remove redundant casts and combine two if statements Signed-off-by: pasta <pasta@dashboost.org> * quorums_blockprocessor.cpp make values const Signed-off-by: pasta <pasta@dashboost.org> * quorums_chainlocks.cpp access static function statically Signed-off-by: pasta <pasta@dashboost.org> * quorums_chainlocks.h remove commented out include Signed-off-by: pasta <pasta@dashboost.org> * quorums_commitment.cpp remove redundant casts Signed-off-by: pasta <pasta@dashboost.org> * quorums_debug.cpp remove redundant casts and add const Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsession.cpp use const where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp use const where possible Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp don't use std::move which apparently prevents "copy elision" in this instance Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionhandler.cpp use const Signed-off-by: pasta <pasta@dashboost.org> * quorums_dkgsessionmgr.cpp misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_signing.* misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_signing_shares.* misc refactoring Signed-off-by: pasta <pasta@dashboost.org> * quorums_utils.cpp misc refactoring Signed-off-by: pasta <pasta@dashboost.org>
2021-06-26 15:10:53 +02:00
void CDKGSessionHandler::WaitForNewQuorum(const uint256& oldQuorumHash) const
2018-05-24 16:14:55 +02:00
{
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d]- starting\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
while (true) {
if (stopRequested) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
throw AbortPhaseException();
}
auto [_, _quorumHash] = GetPhaseAndQuorumHash();
if (_quorumHash != oldQuorumHash) {
break;
2018-05-24 16:14:55 +02:00
}
UninterruptibleSleep(std::chrono::milliseconds{100});
2018-05-24 16:14:55 +02:00
}
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
}
// Sleep some time to not fully overload the whole network
void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
const uint256& expectedQuorumHash,
double randomSleepFactor,
const WhileWaitFunc& runWhileWaiting) const
2018-05-24 16:14:55 +02:00
{
if (!curSession->AreWeMember()) {
// Non-members do not participate and do not create any network load, no need to sleep.
return;
}
if (Params().MineBlocksOnDemand()) {
// On regtest, blocks can be mined on demand without any significant time passing between these.
// We shouldn't wait before phases in this case.
return;
}
// Two blocks can come very close to each other, this happens pretty regularly. We don't want to be
// left behind and marked as a bad member. This means that we should not count the last block of the
// phase as a safe one to keep sleeping, that's why we calculate the phase sleep time as a time of
// the full phase minus one block here.
double phaseSleepTime = (params.dkgPhaseBlocks - 1) * Params().GetConsensus().nPowTargetSpacing * 1000;
// Expected phase sleep time per member
double phaseSleepTimePerMember = phaseSleepTime / params.size;
// Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex().value_or(0));
int64_t endTime = GetTimeMillis() + sleepTime;
int heightTmp{-1};
int heightStart{-1};
heightTmp = heightStart = WITH_LOCK(cs, return currentHeight);
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting sleep for %d ms, curPhase=%d\n", __func__, params.name, quorumIndex, sleepTime, ToUnderlying(curPhase));
2018-05-24 16:14:55 +02:00
while (GetTimeMillis() < endTime) {
if (stopRequested) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
throw AbortPhaseException();
}
{
LOCK(cs);
if (currentHeight > heightTmp) {
// New block(s) just came in
int64_t expectedBlockTime = (currentHeight - heightStart) * Params().GetConsensus().nPowTargetSpacing * 1000;
if (expectedBlockTime > sleepTime) {
// Blocks came faster than we expected, jump into the phase func asap
break;
}
heightTmp = currentHeight;
}
if (phase != curPhase || quorumHash != expectedQuorumHash) {
// Something went wrong and/or we missed quite a few blocks and it's just too late now
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected phase/expectedQuorumHash change\n", __func__, params.name, quorumIndex);
throw AbortPhaseException();
}
2018-05-24 16:14:55 +02:00
}
if (!runWhileWaiting()) {
UninterruptibleSleep(std::chrono::milliseconds{100});
2018-05-24 16:14:55 +02:00
}
}
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d\n", __func__, params.name, quorumIndex, ToUnderlying(curPhase));
2018-05-24 16:14:55 +02:00
}
void CDKGSessionHandler::HandlePhase(QuorumPhase curPhase,
QuorumPhase nextPhase,
const uint256& expectedQuorumHash,
2018-05-24 16:14:55 +02:00
double randomSleepFactor,
const StartPhaseFunc& startPhaseFunc,
const WhileWaitFunc& runWhileWaiting)
{
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, ToUnderlying(curPhase), ToUnderlying(nextPhase));
SleepBeforePhase(curPhase, expectedQuorumHash, randomSleepFactor, runWhileWaiting);
2018-05-24 16:14:55 +02:00
startPhaseFunc();
WaitForNextPhase(curPhase, nextPhase, expectedQuorumHash, runWhileWaiting);
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, ToUnderlying(curPhase), ToUnderlying(nextPhase));
2018-05-24 16:14:55 +02:00
}
// returns a set of NodeIds which sent invalid messages
template<typename Message>
std::set<NodeId> BatchVerifyMessageSigs(CDKGSession& session, const std::vector<std::pair<NodeId, std::shared_ptr<Message>>>& messages)
{
if (messages.empty()) {
return {};
}
std::set<NodeId> ret;
bool revertToSingleVerification = false;
CBLSSignature aggSig;
std::vector<CBLSPublicKey> pubKeys;
std::vector<uint256> messageHashes;
std::set<uint256> messageHashesSet;
pubKeys.reserve(messages.size());
messageHashes.reserve(messages.size());
bool first = true;
for (const auto& p : messages ) {
const auto& msg = *p.second;
auto member = session.GetMember(msg.proTxHash);
if (!member) {
// should not happen as it was verified before
ret.emplace(p.first);
continue;
}
if (first) {
aggSig = msg.sig;
} else {
aggSig.AggregateInsecure(msg.sig);
}
first = false;
auto msgHash = msg.GetSignHash();
if (!messageHashesSet.emplace(msgHash).second) {
// can only happen in 2 cases:
// 1. Someone sent us the same message twice but with differing signature, meaning that at least one of them
// must be invalid. In this case, we'd have to revert to single message verification nevertheless
// 2. Someone managed to find a way to create two different binary representations of a message that deserializes
// to the same object representation. This would be some form of malleability. However, this shouldn't be
// possible as only deterministic/unique BLS signatures and very simple data types are involved
revertToSingleVerification = true;
break;
}
pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator.Get());
2018-05-24 16:14:55 +02:00
messageHashes.emplace_back(msgHash);
}
if (!revertToSingleVerification) {
if (aggSig.VerifyInsecureAggregated(pubKeys, messageHashes)) {
2018-05-24 16:14:55 +02:00
// all good
return ret;
}
// are all messages from the same node?
bool nodeIdsAllSame = std::adjacent_find( messages.begin(), messages.end(), [](const auto& first, const auto& second){
return first.first != second.first;
}) == messages.end();
2018-05-24 16:14:55 +02:00
// if yes, take a short path and return a set with only him
if (nodeIdsAllSame) {
ret.emplace(messages[0].first);
2018-05-24 16:14:55 +02:00
return ret;
}
// different nodes, let's figure out who are the bad ones
}
for (const auto& p : messages) {
if (ret.count(p.first)) {
continue;
}
const auto& msg = *p.second;
auto member = session.GetMember(msg.proTxHash);
bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator.Get(), msg.GetSignHash());
2018-05-24 16:14:55 +02:00
if (!valid) {
ret.emplace(p.first);
}
}
return ret;
}
template<typename Message, int MessageType>
bool ProcessPendingMessageBatch(CDKGSession& session, PeerManager& peerman, CDKGPendingMessages& pendingMessages, size_t maxCount)
2018-05-24 16:14:55 +02:00
{
auto msgs = pendingMessages.PopAndDeserializeMessages<Message>(maxCount);
if (msgs.empty()) {
return false;
}
std::vector<std::pair<NodeId, std::shared_ptr<Message>>> preverifiedMessages;
preverifiedMessages.reserve(msgs.size());
for (const auto& p : msgs) {
const NodeId &nodeId = p.first;
2018-05-24 16:14:55 +02:00
if (!p.second) {
LogPrint(BCLog::LLMQ_DKG, "%s -- failed to deserialize message, peer=%d\n", __func__, nodeId);
2018-05-24 16:14:55 +02:00
{
peerman.Misbehaving(nodeId, 100);
2018-05-24 16:14:55 +02:00
}
continue;
}
bool ban = false;
if (!session.PreVerifyMessage(*p.second, ban)) {
2018-05-24 16:14:55 +02:00
if (ban) {
LogPrint(BCLog::LLMQ_DKG, "%s -- banning node due to failed preverification, peer=%d\n", __func__, nodeId);
2018-05-24 16:14:55 +02:00
{
peerman.Misbehaving(nodeId, 100);
2018-05-24 16:14:55 +02:00
}
}
LogPrint(BCLog::LLMQ_DKG, "%s -- skipping message due to failed preverification, peer=%d\n", __func__, nodeId);
2018-05-24 16:14:55 +02:00
continue;
}
preverifiedMessages.emplace_back(p);
}
if (preverifiedMessages.empty()) {
return true;
}
auto badNodes = BatchVerifyMessageSigs(session, preverifiedMessages);
if (!badNodes.empty()) {
LOCK(cs_main);
for (auto nodeId : badNodes) {
2020-01-28 11:04:47 +01:00
LogPrint(BCLog::LLMQ_DKG, "%s -- failed to verify signature, peer=%d\n", __func__, nodeId);
peerman.Misbehaving(nodeId, 100);
2018-05-24 16:14:55 +02:00
}
}
for (const auto& p : preverifiedMessages) {
const NodeId &nodeId = p.first;
2018-05-24 16:14:55 +02:00
if (badNodes.count(nodeId)) {
continue;
}
bool ban = false;
session.ReceiveMessage(*p.second, ban);
2018-05-24 16:14:55 +02:00
if (ban) {
2020-01-28 11:04:47 +01:00
LogPrint(BCLog::LLMQ_DKG, "%s -- banning node after ReceiveMessage failed, peer=%d\n", __func__, nodeId);
peerman.Misbehaving(nodeId, 100);
2018-05-24 16:14:55 +02:00
badNodes.emplace(nodeId);
}
}
return true;
}
void CDKGSessionHandler::HandleDKGRound()
{
uint256 curQuorumHash;
WaitForNextPhase(std::nullopt, QuorumPhase::Initialized);
2018-05-24 16:14:55 +02:00
{
LOCK(cs);
pendingContributions.Clear();
pendingComplaints.Clear();
pendingJustifications.Clear();
pendingPrematureCommitments.Clear();
curQuorumHash = quorumHash;
2018-05-24 16:14:55 +02:00
}
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(curQuorumHash));
Optimize on-disk deterministic masternode storage to reduce size of evodb (#3017) * Implement CompactFull() in CDBWrapper This allows to compact the whole DB in one go. * Implement more compact version of CDeterministicMNListDiff This introduces CDeterministicMNStateDiff which requires to only store fields on-disk which actually changed. * Avoid writing mnUniquePropertyMap to disk when storing snapshots This map can be rebuilt by simply using AddMN for each deserialized MN. * Implement Serialize/Unserialize in CScript This allows us to directly use READWRITE() on scripts and removes the need for the ugly cast to CScriptBase. This commit also changes all Dash specific uses of CScript to not use the cast. * Keep track of registeration counts and introduce internalID for masternodes The "internalId" is simply the number of MNs registered so far when the new MN is added. It is deterministic and stays the same forever. * Use internalId as keys in MN list diffs This reduces the used size on-disk. * Two simple speedups in MN list diff handling 1. Avoid full compare if dmn or state pointers match in BuildDiff 2. Use std::move when adding diff to listDiff in GetListForBlock * Implement upgrade code for old CDeterministicMNListDiff format to new format * Track tipIndex instead of tipHeight/tipBlockHash * Store and pass around CBlockIndex* instead of block hash and height This allows us to switch CDeterministicMNManager::GetListForBlock to work with CBlockIndex. * Refactor CDeterministicMNManager::GetListForBlock to require CBlockIndex* Instead of requiring a block hash. This allows us to remove blockHash and prevBlockHash from CDeterministicMNListDiff without the use of cs_main locks in GetListForBlock. * Remove prevBlockHash, blockHash and nHeight from CDeterministicMNListDiff * Remove access to determinisitcMNManager in CMasternodeMetaMan::ToString() The deterministic MN manager is not fully initialized yet at the time this is called, which results in an empty list being returned everytime. * Better logic to determine if an upgrade is needed Reuse the "best block" logic to figure out if an upgrade is needed. Also use it to ensure that older nodes are unable to start after the upgrade was performed. * Return null block hash if it was requested with getmnlistdiff * bump CGovernanceManager::SERIALIZATION_VERSION_STRING * Check SERIALIZATION_VERSION_STRING before deserializing anything else * Invoke Clear() before deserializing just to be sure
2019-07-09 07:59:57 +02:00
if (!InitNewQuorum(pQuorumBaseBlockIndex)) {
2018-05-24 16:14:55 +02:00
// should actually never happen
WaitForNewQuorum(curQuorumHash);
throw AbortPhaseException();
}
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != QuorumPhase::Initialized;
status.phase = QuorumPhase::Initialized;
return changed;
});
utils::EnsureQuorumConnections(params, pQuorumBaseBlockIndex, connman, curSession->myProTxHash);
if (curSession->AreWeMember()) {
utils::AddQuorumProbeConnections(params, pQuorumBaseBlockIndex, connman, curSession->myProTxHash);
}
2018-05-24 16:14:55 +02:00
WaitForNextPhase(QuorumPhase::Initialized, QuorumPhase::Contribute, curQuorumHash);
2018-05-24 16:14:55 +02:00
// Contribute
auto fContributeStart = [this]() {
curSession->Contribute(pendingContributions);
2018-05-24 16:14:55 +02:00
};
auto fContributeWait = [this] {
return ProcessPendingMessageBatch<CDKGContribution, MSG_QUORUM_CONTRIB>(*curSession, *m_peerman, pendingContributions, 8);
2018-05-24 16:14:55 +02:00
};
HandlePhase(QuorumPhase::Contribute, QuorumPhase::Complain, curQuorumHash, 0.05, fContributeStart, fContributeWait);
2018-05-24 16:14:55 +02:00
// Complain
auto fComplainStart = [this]() {
curSession->VerifyAndComplain(pendingComplaints);
2018-05-24 16:14:55 +02:00
};
auto fComplainWait = [this] {
return ProcessPendingMessageBatch<CDKGComplaint, MSG_QUORUM_COMPLAINT>(*curSession, *m_peerman, pendingComplaints, 8);
2018-05-24 16:14:55 +02:00
};
HandlePhase(QuorumPhase::Complain, QuorumPhase::Justify, curQuorumHash, 0.05, fComplainStart, fComplainWait);
2018-05-24 16:14:55 +02:00
// Justify
auto fJustifyStart = [this]() {
curSession->VerifyAndJustify(pendingJustifications);
2018-05-24 16:14:55 +02:00
};
auto fJustifyWait = [this] {
return ProcessPendingMessageBatch<CDKGJustification, MSG_QUORUM_JUSTIFICATION>(*curSession, *m_peerman, pendingJustifications, 8);
2018-05-24 16:14:55 +02:00
};
HandlePhase(QuorumPhase::Justify, QuorumPhase::Commit, curQuorumHash, 0.05, fJustifyStart, fJustifyWait);
2018-05-24 16:14:55 +02:00
// Commit
auto fCommitStart = [this]() {
curSession->VerifyAndCommit(pendingPrematureCommitments);
2018-05-24 16:14:55 +02:00
};
auto fCommitWait = [this] {
return ProcessPendingMessageBatch<CDKGPrematureCommitment, MSG_QUORUM_PREMATURE_COMMITMENT>(*curSession, *m_peerman, pendingPrematureCommitments, 8);
2018-05-24 16:14:55 +02:00
};
HandlePhase(QuorumPhase::Commit, QuorumPhase::Finalize, curQuorumHash, 0.1, fCommitStart, fCommitWait);
2018-05-24 16:14:55 +02:00
auto finalCommitments = curSession->FinalizeCommitments();
2019-01-11 10:00:40 +01:00
for (const auto& fqc : finalCommitments) {
quorumBlockProcessor.AddMineableCommitment(fqc);
2018-05-24 16:14:55 +02:00
}
}
void CDKGSessionHandler::PhaseHandlerThread()
{
while (!stopRequested) {
2018-05-24 16:14:55 +02:00
try {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - starting HandleDKGRound\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
HandleDKGRound();
} catch (AbortPhaseException& e) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.statusBits.aborted = true;
return true;
});
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - aborted current DKG session\n", __func__, params.name, quorumIndex);
2018-05-24 16:14:55 +02:00
}
}
}
} // namespace llmq