// Copyright (c) 2018 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_DUMMYDKG_H #define DASH_QUORUMS_DUMMYDKG_H #include "llmq/quorums_commitment.h" #include "consensus/params.h" #include "net.h" #include "primitives/transaction.h" #include "sync.h" #include "bls/bls.h" #include class CNode; class CConnman; /** * Implementation of an insecure dummy DKG * * This is only used on testnet/devnet/regtest and will NEVER be used on * mainnet. It is NOT SECURE AT ALL! It will actually be removed later when the real DKG is introduced. * * It works by using a deterministic secure vector as the secure polynomial. Everyone can calculate this * polynomial by himself, which makes it insecure by definition. * * The purpose of this dummy implementation is to test final LLMQ commitments and simple PoSe on-chain. * The dummy DKG first creates dummy commitments and propagates these to all nodes. They can then create * a valid LLMQ commitment from these, which validates with the normal commitment validation code. * * After these have been mined on-chain, they are indistinguishable from commitments created from the real * DKG, making them good enough for testing. * * The validMembers bitset is created from information of past dummy DKG sessions. If nodes failed to provide * the dummy commitments, they will be marked as bad in the next session. This might create some chaos and * finalizable commitments, but this is ok and will sort itself out after some sessions. */ namespace llmq { // This is more like a PING than a contribution // We will later replace this message (reusing same inv type) for the real contribution // Deserialization will then be incompatible between peers, but that is fine (let them reject the messages) class CDummyContribution { public: uint8_t llmqType{Consensus::LLMQ_NONE}; uint256 quorumHash; uint16_t signer{(uint16_t)-1}; CBLSSignature sig; public: ADD_SERIALIZE_METHODS template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(llmqType); READWRITE(quorumHash); READWRITE(signer); READWRITE(sig); } uint256 GetSignHash() const { CDummyContribution tmp(*this); tmp.sig = CBLSSignature(); return ::SerializeHash(tmp); } }; // This message is only allowed on testnet/devnet/regtest // If any peer tries to send this message on mainnet, it is banned immediately // It is used to test commitments on testnet without actually running a full-blown DKG. class CDummyCommitment { public: uint8_t llmqType{Consensus::LLMQ_NONE}; uint256 quorumHash; uint16_t signer{(uint16_t)-1}; std::vector validMembers; CBLSSignature quorumSig; CBLSSignature membersSig; public: int CountValidMembers() const { return (int)std::count(validMembers.begin(), validMembers.end(), true); } public: ADD_SERIALIZE_METHODS template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(llmqType); READWRITE(quorumHash); READWRITE(signer); READWRITE(DYNBITSET(validMembers)); READWRITE(quorumSig); READWRITE(membersSig); } }; class CDummyDKGSession { public: std::map dummyContributions; std::map dummyCommitments; std::map dummyContributionsFromMembers; std::map> dummyCommitmentsFromMembers; }; // It simulates the result of a DKG session by deterministically calculating a secret/public key vector // !!!THIS IS NOT SECURE AT ALL AND WILL NEVER BE USED ON MAINNET!!! // The whole dummy DKG will be removed when we add the real DKG class CDummyDKG { private: CCriticalSection sessionCs; std::map curSessions; public: void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman); void ProcessDummyContribution(NodeId from, const CDummyContribution& qc); void ProcessDummyCommitment(NodeId from, const CDummyCommitment& qc); void UpdatedBlockTip(const CBlockIndex* pindex, bool fInitialDownload); void CreateDummyContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindex); void CreateDummyCommitment(Consensus::LLMQType llmqType, const CBlockIndex* pindex); void CreateFinalCommitment(Consensus::LLMQType llmqType, const CBlockIndex* pindex); bool HasDummyContribution(const uint256& hash); bool GetDummyContribution(const uint256& hash, CDummyContribution& ret); bool HasDummyCommitment(const uint256& hash); bool GetDummyCommitment(const uint256& hash, CDummyCommitment& ret); private: std::vector GetValidMembers(Consensus::LLMQType llmqType, const std::vector& members); BLSSecretKeyVector BuildDeterministicSvec(Consensus::LLMQType llmqType, const uint256& quorumHash); BLSPublicKeyVector BuildVvec(const BLSSecretKeyVector& svec); }; extern CDummyDKG* quorumDummyDKG; } #endif//DASH_QUORUMS_DUMMYDKG_H