dash/src/llmq/quorums_dkgsessionhandler.h
PastaPastaPasta 8a1ec935a0
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-20 01:46:56 +03:00

146 lines
4.8 KiB
C++

// Copyright (c) 2018-2020 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DASH_QUORUMS_DKGSESSIONHANDLER_H
#define DASH_QUORUMS_DKGSESSIONHANDLER_H
#include <llmq/quorums_dkgsession.h>
#include <validation.h>
#include <ctpl.h>
namespace llmq
{
enum QuorumPhase {
QuorumPhase_None = -1,
QuorumPhase_Initialized = 1,
QuorumPhase_Contribute,
QuorumPhase_Complain,
QuorumPhase_Justify,
QuorumPhase_Commit,
QuorumPhase_Finalize,
QuorumPhase_Idle,
};
/**
* Acts as a FIFO queue for incoming DKG messages. The reason we need this is that deserialization of these messages
* is too slow to be processed in the main message handler thread. So, instead of processing them directly from the
* main handler thread, we push them into a CDKGPendingMessages object and later pop+deserialize them in the DKG phase
* handler thread.
*
* Each message type has it's own instance of this class.
*/
class CDKGPendingMessages
{
public:
typedef std::pair<NodeId, std::shared_ptr<CDataStream>> BinaryMessage;
private:
mutable CCriticalSection cs;
size_t maxMessagesPerNode;
std::list<BinaryMessage> pendingMessages;
std::map<NodeId, size_t> messagesPerNode;
std::set<uint256> seenMessages;
public:
explicit CDKGPendingMessages(size_t _maxMessagesPerNode);
void PushPendingMessage(NodeId from, CDataStream& vRecv);
std::list<BinaryMessage> PopPendingMessages(size_t maxCount);
bool HasSeen(const uint256& hash) const;
void Clear();
template<typename Message>
void PushPendingMessage(NodeId from, Message& msg)
{
CDataStream ds(SER_NETWORK, PROTOCOL_VERSION);
ds << msg;
PushPendingMessage(from, ds);
}
// Might return nullptr messages, which indicates that deserialization failed for some reason
template<typename Message>
std::vector<std::pair<NodeId, std::shared_ptr<Message>>> PopAndDeserializeMessages(size_t maxCount)
{
auto binaryMessages = PopPendingMessages(maxCount);
if (binaryMessages.empty()) {
return {};
}
std::vector<std::pair<NodeId, std::shared_ptr<Message>>> ret;
ret.reserve(binaryMessages.size());
for (const auto& bm : binaryMessages) {
auto msg = std::make_shared<Message>();
try {
*bm.second >> *msg;
} catch (...) {
msg = nullptr;
}
ret.emplace_back(std::make_pair(bm.first, std::move(msg)));
}
return std::move(ret);
}
};
/**
* Handles multiple sequential sessions of one specific LLMQ type. There is one instance of this class per LLMQ type.
*
* It internally starts the phase handler thread, which constantly loops and sequentially processes one session at a
* time and waiting for the next phase if necessary.
*/
class CDKGSessionHandler
{
private:
friend class CDKGSessionManager;
private:
mutable CCriticalSection cs;
std::atomic<bool> stopRequested{false};
const Consensus::LLMQParams& params;
ctpl::thread_pool& messageHandlerPool;
CBLSWorker& blsWorker;
CDKGSessionManager& dkgManager;
QuorumPhase phase{QuorumPhase_Idle};
int currentHeight{-1};
int quorumHeight{-1};
uint256 quorumHash;
std::shared_ptr<CDKGSession> curSession;
std::thread phaseHandlerThread;
CDKGPendingMessages pendingContributions;
CDKGPendingMessages pendingComplaints;
CDKGPendingMessages pendingJustifications;
CDKGPendingMessages pendingPrematureCommitments;
public:
CDKGSessionHandler(const Consensus::LLMQParams& _params, ctpl::thread_pool& _messageHandlerPool, CBLSWorker& blsWorker, CDKGSessionManager& _dkgManager);
~CDKGSessionHandler();
void UpdatedBlockTip(const CBlockIndex *pindexNew);
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
private:
bool InitNewQuorum(const CBlockIndex* pindexQuorum);
std::pair<QuorumPhase, uint256> GetPhaseAndQuorumHash() const;
typedef std::function<void()> StartPhaseFunc;
typedef std::function<bool()> WhileWaitFunc;
void WaitForNextPhase(QuorumPhase curPhase, QuorumPhase nextPhase, const uint256& expectedQuorumHash, const WhileWaitFunc& runWhileWaiting);
void WaitForNewQuorum(const uint256& oldQuorumHash);
void SleepBeforePhase(QuorumPhase curPhase, const uint256& expectedQuorumHash, double randomSleepFactor, const WhileWaitFunc& runWhileWaiting);
void HandlePhase(QuorumPhase curPhase, QuorumPhase nextPhase, const uint256& expectedQuorumHash, double randomSleepFactor, const StartPhaseFunc& startPhaseFunc, const WhileWaitFunc& runWhileWaiting);
void HandleDKGRound();
void PhaseHandlerThread();
};
} // namespace llmq
#endif //DASH_QUORUMS_DKGSESSIONHANDLER_H