mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
852adb56ae
## Issue being fixed or feature implemented `llmq/utils` has simple util code that used all over code base and also have too heavy code for calculation quorums such as: `GetAllQuorumMembers`, `EnsureQuorumConnections` and other. These helpers for calculation quorums are used only by evo/deterministicmns, evo/simplifiedmns and llmq/* modules, but llmq/utils is included in many other modules for various trivial helpers. ## What was done? Prior work: - https://github.com/dashpay/dash/pull/5753 - #5486 See also #4798 This PR remove all non-quorum calculation code from llmq/utils. Eventually it happens that easier to take everything out rather than move Quorum Calculation to new place atm: - new module llmq/options have a code related to various params, command line options, spork-related etc - llmq/utils is not included in various files which do not use any llmq/utils code - helper `BuildCommitmentHash` goes to llmq/commitment - helper `BuildSignHash` goes to llmq/signing - helper `GetLLMQParam` inlined since it's trivial (it has not been trivial when introduced ages ago) - removed dependency of `IsQuorumEnabled` on CQuorumManager which means `quorumManager` deglobalization is done for 90% ## How Has This Been Tested? - Run unit functional tests - updated circular dependencies `test/lint/lint-circular-dependencies.sh` - check that llmq/utils is not included without needs to calculate Quorums Members ``` $ grep -r include src/ 2> /dev/null | grep -v .Po: | grep -vE 'llmq/utils.(h|cpp)': | grep llmq/utils src/evo/mnauth.cpp:#include <llmq/utils.h> src/evo/deterministicmns.cpp:#include <llmq/utils.h> src/llmq/quorums.cpp:#include <llmq/utils.h> src/llmq/blockprocessor.cpp:#include <llmq/utils.h> src/llmq/commitment.cpp:#include <llmq/utils.h> src/llmq/debug.cpp:#include <llmq/utils.h> src/llmq/dkgsessionhandler.cpp:#include <llmq/utils.h> src/llmq/dkgsession.cpp:#include <llmq/utils.h> src/llmq/dkgsessionmgr.cpp:#include <llmq/utils.h> src/rpc/quorums.cpp:#include <llmq/utils.h> ``` ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone
181 lines
6.6 KiB
C++
181 lines
6.6 KiB
C++
// Copyright (c) 2018-2022 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 BITCOIN_LLMQ_COMMITMENT_H
|
|
#define BITCOIN_LLMQ_COMMITMENT_H
|
|
|
|
#include <bls/bls.h>
|
|
#include <consensus/params.h>
|
|
#include <primitives/transaction.h>
|
|
#include <util/irange.h>
|
|
#include <util/strencodings.h>
|
|
#include <util/underlying.h>
|
|
|
|
#include <gsl/pointers.h>
|
|
|
|
#include <univalue.h>
|
|
|
|
class CBlockIndex;
|
|
class TxValidationState;
|
|
|
|
namespace llmq
|
|
{
|
|
|
|
// This message is an aggregation of all received premature commitments and only valid if
|
|
// enough (>=threshold) premature commitments were aggregated
|
|
// This is mined on-chain as part of TRANSACTION_QUORUM_COMMITMENT
|
|
class CFinalCommitment
|
|
{
|
|
public:
|
|
static constexpr auto SPECIALTX_TYPE = TRANSACTION_PROVIDER_REGISTER;
|
|
|
|
static constexpr uint16_t LEGACY_BLS_NON_INDEXED_QUORUM_VERSION = 1;
|
|
static constexpr uint16_t LEGACY_BLS_INDEXED_QUORUM_VERSION = 2;
|
|
static constexpr uint16_t BASIC_BLS_NON_INDEXED_QUORUM_VERSION = 3;
|
|
static constexpr uint16_t BASIC_BLS_INDEXED_QUORUM_VERSION = 4;
|
|
|
|
uint16_t nVersion{LEGACY_BLS_NON_INDEXED_QUORUM_VERSION};
|
|
Consensus::LLMQType llmqType{Consensus::LLMQType::LLMQ_NONE};
|
|
uint256 quorumHash;
|
|
int16_t quorumIndex{0};
|
|
std::vector<bool> signers;
|
|
std::vector<bool> validMembers;
|
|
|
|
CBLSPublicKey quorumPublicKey;
|
|
uint256 quorumVvecHash;
|
|
|
|
CBLSSignature quorumSig; // recovered threshold sig of blockHash+validMembers+pubKeyHash+vvecHash
|
|
CBLSSignature membersSig; // aggregated member sig of blockHash+validMembers+pubKeyHash+vvecHash
|
|
|
|
public:
|
|
CFinalCommitment() = default;
|
|
CFinalCommitment(const Consensus::LLMQParams& params, const uint256& _quorumHash);
|
|
|
|
int CountSigners() const
|
|
{
|
|
return int(std::count(signers.begin(), signers.end(), true));
|
|
}
|
|
int CountValidMembers() const
|
|
{
|
|
return int(std::count(validMembers.begin(), validMembers.end(), true));
|
|
}
|
|
|
|
bool Verify(gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, bool checkSigs) const;
|
|
bool VerifyNull() const;
|
|
bool VerifySizes(const Consensus::LLMQParams& params) const;
|
|
|
|
[[nodiscard]] static constexpr uint16_t GetVersion(const bool is_rotation_enabled, const bool is_basic_scheme_active)
|
|
{
|
|
if (is_rotation_enabled)
|
|
return is_basic_scheme_active ? BASIC_BLS_INDEXED_QUORUM_VERSION : LEGACY_BLS_INDEXED_QUORUM_VERSION;
|
|
else
|
|
return is_basic_scheme_active ? BASIC_BLS_NON_INDEXED_QUORUM_VERSION : LEGACY_BLS_NON_INDEXED_QUORUM_VERSION;
|
|
}
|
|
|
|
public:
|
|
|
|
SERIALIZE_METHODS(CFinalCommitment, obj)
|
|
{
|
|
READWRITE(
|
|
obj.nVersion,
|
|
obj.llmqType,
|
|
obj.quorumHash
|
|
);
|
|
if (obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION || obj.nVersion == BASIC_BLS_INDEXED_QUORUM_VERSION) {
|
|
READWRITE(
|
|
obj.quorumIndex
|
|
);
|
|
}
|
|
READWRITE(
|
|
DYNBITSET(obj.signers),
|
|
DYNBITSET(obj.validMembers),
|
|
CBLSPublicKeyVersionWrapper(const_cast<CBLSPublicKey&>(obj.quorumPublicKey), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION)),
|
|
obj.quorumVvecHash,
|
|
CBLSSignatureVersionWrapper(const_cast<CBLSSignature&>(obj.quorumSig), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION)),
|
|
CBLSSignatureVersionWrapper(const_cast<CBLSSignature&>(obj.membersSig), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION))
|
|
);
|
|
}
|
|
|
|
public:
|
|
bool IsNull() const
|
|
{
|
|
if (std::count(signers.begin(), signers.end(), true) ||
|
|
std::count(validMembers.begin(), validMembers.end(), true)) {
|
|
return false;
|
|
}
|
|
if (quorumPublicKey.IsValid() ||
|
|
!quorumVvecHash.IsNull() ||
|
|
membersSig.IsValid() ||
|
|
quorumSig.IsValid()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
[[nodiscard]] UniValue ToJson() const
|
|
{
|
|
UniValue obj;
|
|
obj.setObject();
|
|
obj.pushKV("version", int{nVersion});
|
|
obj.pushKV("llmqType", ToUnderlying(llmqType));
|
|
obj.pushKV("quorumHash", quorumHash.ToString());
|
|
obj.pushKV("quorumIndex", quorumIndex);
|
|
obj.pushKV("signersCount", CountSigners());
|
|
obj.pushKV("signers", BitsVectorToHexStr(signers));
|
|
obj.pushKV("validMembersCount", CountValidMembers());
|
|
obj.pushKV("validMembers", BitsVectorToHexStr(validMembers));
|
|
obj.pushKV("quorumPublicKey", quorumPublicKey.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
|
|
obj.pushKV("quorumVvecHash", quorumVvecHash.ToString());
|
|
obj.pushKV("quorumSig", quorumSig.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
|
|
obj.pushKV("membersSig", membersSig.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
|
|
return obj;
|
|
}
|
|
|
|
private:
|
|
static std::string BitsVectorToHexStr(const std::vector<bool>& vBits)
|
|
{
|
|
std::vector<uint8_t> vBytes((vBits.size() + 7) / 8);
|
|
for (const auto i : irange::range(vBits.size())) {
|
|
vBytes[i / 8] |= vBits[i] << (i % 8);
|
|
}
|
|
return HexStr(vBytes);
|
|
}
|
|
};
|
|
using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
|
|
|
|
class CFinalCommitmentTxPayload
|
|
{
|
|
public:
|
|
static constexpr auto SPECIALTX_TYPE = TRANSACTION_QUORUM_COMMITMENT;
|
|
static constexpr uint16_t CURRENT_VERSION = 1;
|
|
public:
|
|
uint16_t nVersion{CURRENT_VERSION};
|
|
uint32_t nHeight{std::numeric_limits<uint32_t>::max()};
|
|
CFinalCommitment commitment;
|
|
|
|
public:
|
|
SERIALIZE_METHODS(CFinalCommitmentTxPayload, obj)
|
|
{
|
|
READWRITE(obj.nVersion, obj.nHeight, obj.commitment);
|
|
}
|
|
|
|
[[nodiscard]] UniValue ToJson() const
|
|
{
|
|
UniValue obj;
|
|
obj.setObject();
|
|
obj.pushKV("version", int{nVersion});
|
|
obj.pushKV("height", int(nHeight));
|
|
obj.pushKV("commitment", commitment.ToJson());
|
|
return obj;
|
|
}
|
|
};
|
|
|
|
bool CheckLLMQCommitment(const CTransaction& tx, gsl::not_null<const CBlockIndex*> pindexPrev, TxValidationState& state);
|
|
|
|
uint256 BuildCommitmentHash(Consensus::LLMQType llmqType, const uint256& blockHash, const std::vector<bool>& validMembers, const CBLSPublicKey& pubKey, const uint256& vvecHash);
|
|
|
|
} // namespace llmq
|
|
|
|
#endif // BITCOIN_LLMQ_COMMITMENT_H
|