mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
refactor: tweak GetLLMQ to fail gracefully and let caller handle results accordingly (#5247)
This allows us to have a bit more granular control over GetLLMQ results, removes code duplication and also optimises things a tiny bit by replacing "HasLLMQ + GetLLMQParams" calls with simply "GetLLMQParams". Use `optional` in `GetLLMQ`, drop `HasLLMQ`. run tests, reindex on testnet/mainnet n/a - [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 **For repository code-owners and collaborators only** - [x] I have assigned this pull request to a milestone
This commit is contained in:
parent
0fa86b3446
commit
f08488d0cb
@ -110,7 +110,7 @@ static CBlock FindDevNetGenesisBlock(const CBlock &prevBlock, const CAmount& rew
|
||||
|
||||
void CChainParams::AddLLMQ(Consensus::LLMQType llmqType)
|
||||
{
|
||||
assert(!HasLLMQ(llmqType));
|
||||
assert(!GetLLMQ(llmqType).has_value());
|
||||
for (const auto& llmq_param : Consensus::available_llmqs) {
|
||||
if (llmq_param.type == llmqType) {
|
||||
consensus.llmqs.push_back(llmq_param);
|
||||
@ -121,25 +121,14 @@ void CChainParams::AddLLMQ(Consensus::LLMQType llmqType)
|
||||
assert(false);
|
||||
}
|
||||
|
||||
const Consensus::LLMQParams& CChainParams::GetLLMQ(Consensus::LLMQType llmqType) const
|
||||
std::optional<Consensus::LLMQParams> CChainParams::GetLLMQ(Consensus::LLMQType llmqType) const
|
||||
{
|
||||
for (const auto& llmq_param : consensus.llmqs) {
|
||||
if (llmq_param.type == llmqType) {
|
||||
return llmq_param;
|
||||
return std::make_optional(llmq_param);
|
||||
}
|
||||
}
|
||||
error("CChainParams::%s: unknown LLMQ type %d", __func__, static_cast<uint8_t>(llmqType));
|
||||
assert(false);
|
||||
}
|
||||
|
||||
bool CChainParams::HasLLMQ(Consensus::LLMQType llmqType) const
|
||||
{
|
||||
for (const auto& llmq_param : consensus.llmqs) {
|
||||
if (llmq_param.type == llmqType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1231,7 +1220,10 @@ void CDevNetParams::UpdateDevnetLLMQChainLocksFromArgs(const ArgsManager& args)
|
||||
{
|
||||
if (!args.IsArgSet("-llmqchainlocks")) return;
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqchainlocks", std::string(GetLLMQ(consensus.llmqTypeChainLocks).name));
|
||||
const auto& llmq_params_opt = GetLLMQ(consensus.llmqTypeChainLocks);
|
||||
assert(llmq_params_opt.has_value());
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqchainlocks", std::string(llmq_params_opt->name));
|
||||
|
||||
Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE;
|
||||
for (const auto& params : consensus.llmqs) {
|
||||
@ -1253,7 +1245,10 @@ void CDevNetParams::UpdateDevnetLLMQInstantSendFromArgs(const ArgsManager& args)
|
||||
{
|
||||
if (!args.IsArgSet("-llmqinstantsend")) return;
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqinstantsend", std::string(GetLLMQ(consensus.llmqTypeInstantSend).name));
|
||||
const auto& llmq_params_opt = GetLLMQ(consensus.llmqTypeInstantSend);
|
||||
assert(llmq_params_opt.has_value());
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqinstantsend", std::string(llmq_params_opt->name));
|
||||
|
||||
Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE;
|
||||
for (const auto& params : consensus.llmqs) {
|
||||
@ -1275,7 +1270,10 @@ void CDevNetParams::UpdateDevnetLLMQInstantSendDIP0024FromArgs(const ArgsManager
|
||||
{
|
||||
if (!args.IsArgSet("-llmqinstantsenddip0024")) return;
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqinstantsenddip0024", std::string(GetLLMQ(consensus.llmqTypeDIP0024InstantSend).name));
|
||||
const auto& llmq_params_opt = GetLLMQ(consensus.llmqTypeDIP0024InstantSend);
|
||||
assert(llmq_params_opt.has_value());
|
||||
|
||||
std::string strLLMQType = gArgs.GetArg("-llmqinstantsenddip0024", std::string(llmq_params_opt->name));
|
||||
|
||||
Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE;
|
||||
for (const auto& params : consensus.llmqs) {
|
||||
|
@ -110,8 +110,7 @@ public:
|
||||
const std::vector<std::string>& SporkAddresses() const { return vSporkAddresses; }
|
||||
int MinSporkKeys() const { return nMinSporkKeys; }
|
||||
bool BIP9CheckMasternodesUpgraded() const { return fBIP9CheckMasternodesUpgraded; }
|
||||
const Consensus::LLMQParams& GetLLMQ(Consensus::LLMQType llmqType) const;
|
||||
bool HasLLMQ(Consensus::LLMQType llmqType) const;
|
||||
std::optional<Consensus::LLMQParams> GetLLMQ(Consensus::LLMQType llmqType) const;
|
||||
|
||||
protected:
|
||||
CChainParams() {}
|
||||
|
@ -188,7 +188,9 @@ auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev, const llmq:
|
||||
qcIndexedHashes_cached.clear();
|
||||
|
||||
for (const auto& [llmqType, vecBlockIndexes] : quorums) {
|
||||
bool rotation_enabled = llmq::utils::IsQuorumRotationEnabled(llmqType, pindexPrev);
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
bool rotation_enabled = llmq::utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pindexPrev);
|
||||
auto& vec_hashes = qcHashes_cached[llmqType];
|
||||
vec_hashes.reserve(vecBlockIndexes.size());
|
||||
auto& map_indexed_hashes = qcIndexedHashes_cached[llmqType];
|
||||
@ -252,12 +254,16 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
|
||||
// having null commitments is ok but we don't use them here, move to the next tx
|
||||
continue;
|
||||
}
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(qc.commitment.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-commitment-type-calc-cbtx-quorummerkleroot");
|
||||
}
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
auto qcHash = ::SerializeHash(qc.commitment);
|
||||
if (llmq::utils::IsQuorumRotationEnabled(qc.commitment.llmqType, pindexPrev)) {
|
||||
if (llmq::utils::IsQuorumRotationEnabled(llmq_params, pindexPrev)) {
|
||||
auto& map_indexed_hashes = qcIndexedHashes[qc.commitment.llmqType];
|
||||
map_indexed_hashes[qc.commitment.quorumIndex] = qcHash;
|
||||
} else {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(qc.commitment.llmqType);
|
||||
auto& vec_hashes = qcHashes[llmq_params.type];
|
||||
if (vec_hashes.size() == size_t(llmq_params.signingActiveQuorumCount)) {
|
||||
// we pop the last entry, which is actually the oldest quorum as GetMinedAndActiveCommitmentsUntilBlock
|
||||
@ -281,8 +287,9 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
|
||||
vec_hashes_final.reserve(CalcHashCountFromQCHashes(qcHashes));
|
||||
|
||||
for (const auto& [llmqType, vec_hashes] : qcHashes) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(llmqType);
|
||||
if (vec_hashes.size() > size_t(llmq_params.signingActiveQuorumCount)) {
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
if (vec_hashes.size() > size_t(llmq_params_opt->signingActiveQuorumCount)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "excess-quorums-calc-cbtx-quorummerkleroot");
|
||||
}
|
||||
// Copy vec_hashes into vec_hashes_final
|
||||
|
@ -829,9 +829,12 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
|
||||
return _state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-payload");
|
||||
}
|
||||
if (!qc.commitment.IsNull()) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(qc.commitment.llmqType);
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(qc.commitment.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
return _state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-commitment-type");
|
||||
}
|
||||
int qcnHeight = int(qc.nHeight);
|
||||
int quorumHeight = qcnHeight - (qcnHeight % llmq_params.dkgInterval) + int(qc.commitment.quorumIndex);
|
||||
int quorumHeight = qcnHeight - (qcnHeight % llmq_params_opt->dkgInterval) + int(qc.commitment.quorumIndex);
|
||||
auto pQuorumBaseBlockIndex = pindexPrev->GetAncestor(quorumHeight);
|
||||
if (!pQuorumBaseBlockIndex || pQuorumBaseBlockIndex->GetBlockHash() != qc.commitment.quorumHash) {
|
||||
// we should actually never get into this case as validation should have caught it...but let's be sure
|
||||
|
@ -25,7 +25,9 @@ bool MNHFTx::Verify(const CBlockIndex* pQuorumIndex) const
|
||||
}
|
||||
|
||||
Consensus::LLMQType llmqType = Params().GetConsensus().llmqTypeMnhf;
|
||||
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
int signOffset{llmq_params_opt->dkgInterval};
|
||||
|
||||
const uint256 requestId = ::SerializeHash(std::make_pair(CBLSIG_REQUESTID_PREFIX, pQuorumIndex->nHeight));
|
||||
return llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) ||
|
||||
@ -53,7 +55,7 @@ bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidat
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-mnhf-quorum-hash");
|
||||
}
|
||||
|
||||
if (!Params().HasLLMQ(Params().GetConsensus().llmqTypeMnhf)) {
|
||||
if (!llmq::GetLLMQParams(Params().GetConsensus().llmqTypeMnhf).has_value()) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-mnhf-type");
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,8 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Params().HasLLMQ(qc.llmqType)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- invalid commitment type %d from peer=%d\n", __func__,
|
||||
uint8_t(qc.llmqType), peer.GetId());
|
||||
WITH_LOCK(cs_main, Misbehaving(peer.GetId(), 100));
|
||||
@ -84,14 +85,14 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
|
||||
// same, can't punish
|
||||
return;
|
||||
}
|
||||
int quorumHeight = pQuorumBaseBlockIndex->nHeight - (pQuorumBaseBlockIndex->nHeight % GetLLMQParams(type).dkgInterval) + int(qc.quorumIndex);
|
||||
int quorumHeight = pQuorumBaseBlockIndex->nHeight - (pQuorumBaseBlockIndex->nHeight % llmq_params_opt->dkgInterval) + int(qc.quorumIndex);
|
||||
if (quorumHeight != pQuorumBaseBlockIndex->nHeight) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is not the first block in the DKG interval, peer=%d\n", __func__,
|
||||
qc.quorumHash.ToString(), peer.GetId());
|
||||
Misbehaving(peer.GetId(), 100);
|
||||
return;
|
||||
}
|
||||
if (pQuorumBaseBlockIndex->nHeight < (::ChainActive().Height() - GetLLMQParams(type).dkgInterval)) {
|
||||
if (pQuorumBaseBlockIndex->nHeight < (::ChainActive().Height() - llmq_params_opt->dkgInterval)) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is too old, peer=%d\n", __func__,
|
||||
qc.quorumHash.ToString(), peer.GetId());
|
||||
// TODO: enable punishment in some future version when all/most nodes are running with this fix
|
||||
@ -173,7 +174,7 @@ bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, const CBlockIndex*
|
||||
if (numCommitmentsRequired > numCommitmentsInNewBlock) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-missing");
|
||||
}
|
||||
if (llmq::utils::IsQuorumRotationEnabled(params.type, pindex)) {
|
||||
if (llmq::utils::IsQuorumRotationEnabled(params, pindex)) {
|
||||
LogPrintf("[ProcessBlock] h[%d] numCommitmentsRequired[%d] numCommitmentsInNewBlock[%d]\n", pindex->nHeight, numCommitmentsRequired, numCommitmentsInNewBlock);
|
||||
}
|
||||
}
|
||||
@ -209,7 +210,12 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
const auto& llmq_params = GetLLMQParams(qc.llmqType);
|
||||
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- invalid commitment type %d\n", __func__, static_cast<uint8_t>(qc.llmqType));
|
||||
return false;
|
||||
}
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
|
||||
uint256 quorumHash = GetQuorumBlockHash(llmq_params, nHeight, qc.quorumIndex);
|
||||
|
||||
@ -263,7 +269,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmq_params.type, pQuorumBaseBlockIndex);
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex);
|
||||
|
||||
if (rotation_enabled) {
|
||||
LogPrint(BCLog::LLMQ, "[ProcessCommitment] height[%d] pQuorumBaseBlockIndex[%d] quorumIndex[%d] qversion[%d] Built\n",
|
||||
@ -313,7 +319,10 @@ bool CQuorumBlockProcessor::UndoBlock(const CBlock& block, const CBlockIndex* pi
|
||||
|
||||
evoDb.Erase(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)));
|
||||
|
||||
if (llmq::utils::IsQuorumRotationEnabled(qc.llmqType, pindex)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
|
||||
if (llmq::utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pindex)) {
|
||||
evoDb.Erase(BuildInversedHeightKeyIndexed(qc.llmqType, pindex->nHeight, int(qc.quorumIndex)));
|
||||
} else {
|
||||
evoDb.Erase(BuildInversedHeightKey(qc.llmqType, pindex->nHeight));
|
||||
@ -372,7 +381,9 @@ bool CQuorumBlockProcessor::UpgradeDB()
|
||||
}
|
||||
const auto* pQuorumBaseBlockIndex = LookupBlockIndex(qc.quorumHash);
|
||||
evoDb.GetRawDB().Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)), std::make_pair(qc, pindex->GetBlockHash()));
|
||||
if (llmq::utils::IsQuorumRotationEnabled(qc.llmqType, pQuorumBaseBlockIndex)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
if (llmq::utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pQuorumBaseBlockIndex)) {
|
||||
evoDb.GetRawDB().Write(BuildInversedHeightKeyIndexed(qc.llmqType, pindex->nHeight, int(qc.quorumIndex)), pQuorumBaseBlockIndex->nHeight);
|
||||
} else {
|
||||
evoDb.GetRawDB().Write(BuildInversedHeightKey(qc.llmqType, pindex->nHeight), pQuorumBaseBlockIndex->nHeight);
|
||||
@ -406,8 +417,14 @@ bool CQuorumBlockProcessor::GetCommitmentsFromBlock(const CBlock& block, const C
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-payload");
|
||||
}
|
||||
|
||||
const auto& llmq_params_opt = GetLLMQParams(qc.commitment.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
// should not happen as it was verified before processing the block
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-commitment-type");
|
||||
}
|
||||
|
||||
// only allow one commitment per type and per block (This was changed with rotation)
|
||||
if (!utils::IsQuorumRotationEnabled(qc.commitment.llmqType, pindex)) {
|
||||
if (!utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pindex)) {
|
||||
if (ret.count(qc.commitment.llmqType) != 0) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-dup");
|
||||
}
|
||||
@ -454,7 +471,7 @@ size_t CQuorumBlockProcessor::GetNumCommitmentsRequired(const Consensus::LLMQPar
|
||||
assert(nHeight <= ::ChainActive().Height() + 1);
|
||||
const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight);
|
||||
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams.type, pindex);
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
|
||||
size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1;
|
||||
size_t ret{0};
|
||||
|
||||
@ -607,10 +624,11 @@ std::optional<const CBlockIndex*> CQuorumBlockProcessor::GetLastMinedCommitments
|
||||
|
||||
std::vector<std::pair<int, const CBlockIndex*>> CQuorumBlockProcessor::GetLastMinedCommitmentsPerQuorumIndexUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, size_t cycle) const
|
||||
{
|
||||
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
std::vector<std::pair<int, const CBlockIndex*>> ret;
|
||||
|
||||
for (const auto quorumIndex : irange::range(llmqParams.signingActiveQuorumCount)) {
|
||||
for (const auto quorumIndex : irange::range(llmq_params_opt->signingActiveQuorumCount)) {
|
||||
std::optional<const CBlockIndex*> q = GetLastMinedCommitmentsByQuorumIndexUntilBlock(llmqType, pindex, quorumIndex, cycle);
|
||||
if (q.has_value()) {
|
||||
ret.emplace_back(quorumIndex, q.value());
|
||||
@ -658,7 +676,7 @@ std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> CQuorumBlockProce
|
||||
for (const auto& params : Params().GetConsensus().llmqs) {
|
||||
auto& v = ret[params.type];
|
||||
v.reserve(params.signingActiveQuorumCount);
|
||||
if (utils::IsQuorumRotationEnabled(params.type, pindex)) {
|
||||
if (utils::IsQuorumRotationEnabled(params, pindex)) {
|
||||
std::vector<std::pair<int, const CBlockIndex*>> commitments = GetLastMinedCommitmentsPerQuorumIndexUntilBlock(params.type, pindex, 0);
|
||||
std::transform(commitments.begin(), commitments.end(), std::back_inserter(v),
|
||||
[](const std::pair<int, const CBlockIndex*>& p) { return p.second; });
|
||||
@ -737,7 +755,7 @@ std::optional<std::vector<CFinalCommitment>> CQuorumBlockProcessor::GetMineableC
|
||||
assert(nHeight <= ::ChainActive().Height() + 1);
|
||||
const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight);
|
||||
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams.type, pindex);
|
||||
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
|
||||
size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1;
|
||||
|
||||
std::stringstream ss;
|
||||
|
@ -30,16 +30,17 @@ CFinalCommitment::CFinalCommitment(const Consensus::LLMQParams& params, const ui
|
||||
|
||||
bool CFinalCommitment::Verify(const CBlockIndex* pQuorumBaseBlockIndex, bool checkSigs) const
|
||||
{
|
||||
if (nVersion == 0 || nVersion != (utils::IsQuorumRotationEnabled(llmqType, pQuorumBaseBlockIndex) ? INDEXED_QUORUM_VERSION : CURRENT_VERSION)) {
|
||||
LogPrintfFinalCommitment("q[%s] invalid nVersion=%d\n", quorumHash.ToString(), nVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LogPrintfFinalCommitment("q[%s] invalid llmqType=%d\n", quorumHash.ToString(), static_cast<uint8_t>(llmqType));
|
||||
return false;
|
||||
}
|
||||
const auto& llmq_params = GetLLMQParams(llmqType);
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
|
||||
if (nVersion == 0 || nVersion != (utils::IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex) ? INDEXED_QUORUM_VERSION : CURRENT_VERSION)) {
|
||||
LogPrintfFinalCommitment("q[%s] invalid nVersion=%d\n", quorumHash.ToString(), nVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pQuorumBaseBlockIndex->GetBlockHash() != quorumHash) {
|
||||
LogPrintfFinalCommitment("q[%s] invalid quorumHash\n", quorumHash.ToString());
|
||||
@ -138,12 +139,13 @@ bool CFinalCommitment::Verify(const CBlockIndex* pQuorumBaseBlockIndex, bool che
|
||||
|
||||
bool CFinalCommitment::VerifyNull() const
|
||||
{
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LogPrintfFinalCommitment("q[%s]invalid llmqType=%d\n", quorumHash.ToString(), static_cast<uint8_t>(llmqType));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsNull() || !VerifySizes(GetLLMQParams(llmqType))) {
|
||||
if (!IsNull() || !VerifySizes(llmq_params_opt.value())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -170,10 +172,16 @@ bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev,
|
||||
LogPrintfFinalCommitment("h[%d] GetTxPayload failed\n", pindexPrev->nHeight);
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-payload");
|
||||
}
|
||||
const auto& llmq_params = GetLLMQParams(qcTx.commitment.llmqType);
|
||||
|
||||
const auto& llmq_params_opt = GetLLMQParams(qcTx.commitment.llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LogPrintfFinalCommitment("h[%d] GetLLMQParams failed for llmqType[%d]\n", pindexPrev->nHeight, static_cast<uint8_t>(qcTx.commitment.llmqType));
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-commitment-type");
|
||||
}
|
||||
|
||||
if (LogAcceptCategory(BCLog::LLMQ)) {
|
||||
std::stringstream ss;
|
||||
for (const auto i: irange::range(llmq_params.size)) {
|
||||
for (const auto i: irange::range(llmq_params_opt->size)) {
|
||||
ss << "v[" << i << "]=" << qcTx.commitment.validMembers[i];
|
||||
}
|
||||
LogPrintfFinalCommitment("%s llmqType[%d] validMembers[%s] signers[]\n", __func__,
|
||||
@ -201,10 +209,6 @@ bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev,
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-quorum-hash");
|
||||
}
|
||||
|
||||
if (!Params().HasLLMQ(qcTx.commitment.llmqType)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-qc-type");
|
||||
}
|
||||
|
||||
if (qcTx.commitment.IsNull()) {
|
||||
if (!qcTx.commitment.VerifyNull()) {
|
||||
LogPrintfFinalCommitment("h[%d] invalid qcTx.commitment[%s] VerifyNull failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString());
|
||||
|
@ -18,7 +18,7 @@ UniValue CDKGDebugSessionStatus::ToJson(int quorumIndex, int detailLevel) const
|
||||
{
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (!Params().HasLLMQ(llmqType) || quorumHash.IsNull()) {
|
||||
if (!GetLLMQParams(llmqType).has_value() || quorumHash.IsNull()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -117,11 +117,12 @@ UniValue CDKGDebugStatus::ToJson(int detailLevel) const
|
||||
// TODO Support array of sessions
|
||||
UniValue sessionsArrJson(UniValue::VARR);
|
||||
for (const auto& p : sessions) {
|
||||
if (!Params().HasLLMQ(p.first.first)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(p.first.first);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
continue;
|
||||
}
|
||||
UniValue s(UniValue::VOBJ);
|
||||
s.pushKV("llmqType", std::string(GetLLMQParams(p.first.first).name));
|
||||
s.pushKV("llmqType", std::string(llmq_params_opt->name));
|
||||
s.pushKV("quorumIndex", p.first.second);
|
||||
s.pushKV("status", p.second.ToJson(p.first.second, detailLevel));
|
||||
|
||||
|
@ -85,7 +85,7 @@ bool CDKGSession::Init(const CBlockIndex* _pQuorumBaseBlockIndex, const std::vec
|
||||
|
||||
CDKGLogger logger(*this, __func__);
|
||||
|
||||
if (LogAcceptCategory(BCLog::LLMQ) && utils::IsQuorumRotationEnabled(params.type, m_quorum_base_block_index)) {
|
||||
if (LogAcceptCategory(BCLog::LLMQ) && utils::IsQuorumRotationEnabled(params, m_quorum_base_block_index)) {
|
||||
int cycleQuorumBaseHeight = m_quorum_base_block_index->nHeight - quorumIndex;
|
||||
const CBlockIndex* pCycleQuorumBaseBlockIndex = m_quorum_base_block_index->GetAncestor(cycleQuorumBaseHeight);
|
||||
std::stringstream ss;
|
||||
@ -1206,7 +1206,7 @@ std::vector<CFinalCommitment> CDKGSession::FinalizeCommitments()
|
||||
fqc.quorumPublicKey = first.quorumPublicKey;
|
||||
fqc.quorumVvecHash = first.quorumVvecHash;
|
||||
|
||||
if (utils::IsQuorumRotationEnabled(fqc.llmqType, m_quorum_base_block_index)) {
|
||||
if (utils::IsQuorumRotationEnabled(params, m_quorum_base_block_index)) {
|
||||
fqc.nVersion = CFinalCommitment::INDEXED_QUORUM_VERSION;
|
||||
fqc.quorumIndex = quorumIndex;
|
||||
} else {
|
||||
|
@ -256,7 +256,7 @@ class CDKGSession
|
||||
friend class CDKGLogger;
|
||||
|
||||
private:
|
||||
const Consensus::LLMQParams& params;
|
||||
const Consensus::LLMQParams params;
|
||||
|
||||
CBLSWorker& blsWorker;
|
||||
CBLSWorkerCache cache;
|
||||
|
@ -84,7 +84,7 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew)
|
||||
{
|
||||
//AssertLockNotHeld(cs_main);
|
||||
//Indexed quorums (greater than 0) are enabled with Quorum Rotation
|
||||
if (quorumIndex > 0 && !utils::IsQuorumRotationEnabled(params.type, pindexNew)) {
|
||||
if (quorumIndex > 0 && !utils::IsQuorumRotationEnabled(params, pindexNew)) {
|
||||
return;
|
||||
}
|
||||
LOCK(cs);
|
||||
|
@ -109,7 +109,7 @@ private:
|
||||
mutable CCriticalSection cs;
|
||||
std::atomic<bool> stopRequested{false};
|
||||
|
||||
const Consensus::LLMQParams& params;
|
||||
const Consensus::LLMQParams params;
|
||||
CConnman& connman;
|
||||
const int quorumIndex;
|
||||
CBLSWorker& blsWorker;
|
||||
|
@ -196,12 +196,14 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const CQuorumManager& quor
|
||||
vRecv.Rewind(sizeof(uint256));
|
||||
vRecv.Rewind(sizeof(uint8_t));
|
||||
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
LOCK(cs_main);
|
||||
LogPrintf("CDKGSessionManager -- invalid llmqType [%d]\n", uint8_t(llmqType));
|
||||
Misbehaving(pfrom->GetId(), 100);
|
||||
return;
|
||||
}
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
|
||||
int quorumIndex{-1};
|
||||
|
||||
@ -232,10 +234,9 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const CQuorumManager& quor
|
||||
return;
|
||||
}
|
||||
|
||||
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
|
||||
quorumIndex = pQuorumBaseBlockIndex->nHeight % llmqParams.dkgInterval;
|
||||
int quorumIndexMax = utils::IsQuorumRotationEnabled(llmqType, pQuorumBaseBlockIndex) ?
|
||||
llmqParams.signingActiveQuorumCount - 1 : 0;
|
||||
quorumIndex = pQuorumBaseBlockIndex->nHeight % llmq_params.dkgInterval;
|
||||
int quorumIndexMax = utils::IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex) ?
|
||||
llmq_params.signingActiveQuorumCount - 1 : 0;
|
||||
|
||||
if (quorumIndex > quorumIndexMax) {
|
||||
LOCK(cs_main);
|
||||
|
@ -706,8 +706,10 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
|
||||
|
||||
// compute and set cycle hash if islock is deterministic
|
||||
if (islock.IsDeterministic()) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt);
|
||||
LOCK(cs_main);
|
||||
const auto dkgInterval = GetLLMQParams(llmqType).dkgInterval;
|
||||
const auto dkgInterval = llmq_params_opt->dkgInterval;
|
||||
const auto quorumHeight = ::ChainActive().Height() - (::ChainActive().Height() % dkgInterval);
|
||||
islock.cycleHash = ::ChainActive()[quorumHeight]->GetBlockHash();
|
||||
}
|
||||
@ -804,7 +806,9 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode* pfrom, cons
|
||||
|
||||
// Deterministic islocks MUST use rotation based llmq
|
||||
auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
||||
if (blockIndex->nHeight % GetLLMQParams(llmqType).dkgInterval != 0) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt);
|
||||
if (blockIndex->nHeight % llmq_params_opt->dkgInterval != 0) {
|
||||
WITH_LOCK(cs_main, Misbehaving(pfrom->GetId(), 100));
|
||||
return;
|
||||
}
|
||||
@ -905,10 +909,13 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks(bool deterministic)
|
||||
|
||||
//TODO Investigate if leaving this is ok
|
||||
auto llmqType = utils::GetInstantSendLLMQType(deterministic);
|
||||
auto dkgInterval = GetLLMQParams(llmqType).dkgInterval;
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt);
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
auto dkgInterval = llmq_params.dkgInterval;
|
||||
|
||||
// First check against the current active set and don't ban
|
||||
auto badISLocks = ProcessPendingInstantSendLocks(llmqType, 0, pend, false);
|
||||
auto badISLocks = ProcessPendingInstantSendLocks(llmq_params, 0, pend, false);
|
||||
if (!badISLocks.empty()) {
|
||||
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- doing verification on old active set\n", __func__);
|
||||
|
||||
@ -921,13 +928,13 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks(bool deterministic)
|
||||
}
|
||||
}
|
||||
// Now check against the previous active set and perform banning if this fails
|
||||
ProcessPendingInstantSendLocks(llmqType, dkgInterval, pend, true);
|
||||
ProcessPendingInstantSendLocks(llmq_params, dkgInterval, pend, true);
|
||||
}
|
||||
|
||||
return fMoreWork;
|
||||
}
|
||||
|
||||
std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPendingInstantSendLocks(const Consensus::LLMQType llmqType, int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLockPtr>, StaticSaltedHasher>& pend, bool ban)
|
||||
std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params, int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLockPtr>, StaticSaltedHasher>& pend, bool ban)
|
||||
{
|
||||
CBLSBatchVerifier<NodeId, uint256> batchVerifier(false, true, 8);
|
||||
std::unordered_map<uint256, CRecoveredSig, StaticSaltedHasher> recSigs;
|
||||
@ -951,7 +958,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
|
||||
auto id = islock->GetRequestId();
|
||||
|
||||
// no need to verify an ISLOCK if we already have verified the recovered sig that belongs to it
|
||||
if (sigman.HasRecoveredSig(llmqType, id, islock->txid)) {
|
||||
if (sigman.HasRecoveredSig(llmq_params.type, id, islock->txid)) {
|
||||
alreadyVerified++;
|
||||
continue;
|
||||
}
|
||||
@ -966,26 +973,26 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto dkgInterval = GetLLMQParams(llmqType).dkgInterval;
|
||||
const auto dkgInterval = llmq_params.dkgInterval;
|
||||
if (blockIndex->nHeight + dkgInterval < ::ChainActive().Height()) {
|
||||
nSignHeight = blockIndex->nHeight + dkgInterval - 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmqType, qman, id, nSignHeight, signOffset);
|
||||
auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmq_params, qman, id, nSignHeight, signOffset);
|
||||
if (!quorum) {
|
||||
// should not happen, but if one fails to select, all others will also fail to select
|
||||
return {};
|
||||
}
|
||||
uint256 signHash = utils::BuildSignHash(llmqType, quorum->qc->quorumHash, id, islock->txid);
|
||||
uint256 signHash = utils::BuildSignHash(llmq_params.type, quorum->qc->quorumHash, id, islock->txid);
|
||||
batchVerifier.PushMessage(nodeId, hash, signHash, islock->sig.Get(), quorum->qc->quorumPublicKey);
|
||||
verifyCount++;
|
||||
|
||||
// We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which
|
||||
// avoids unnecessary double-verification of the signature. We however only do this when verification here
|
||||
// turns out to be good (which is checked further down)
|
||||
if (!sigman.HasRecoveredSigForId(llmqType, id)) {
|
||||
recSigs.try_emplace(hash, CRecoveredSig(llmqType, quorum->qc->quorumHash, id, islock->txid, islock->sig));
|
||||
if (!sigman.HasRecoveredSigForId(llmq_params.type, id)) {
|
||||
recSigs.try_emplace(hash, CRecoveredSig(llmq_params.type, quorum->qc->quorumHash, id, islock->txid, islock->sig));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1025,7 +1032,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
|
||||
auto it = recSigs.find(hash);
|
||||
if (it != recSigs.end()) {
|
||||
auto recSig = std::make_shared<CRecoveredSig>(std::move(it->second));
|
||||
if (!sigman.HasRecoveredSigForId(llmqType, recSig->getId())) {
|
||||
if (!sigman.HasRecoveredSigForId(llmq_params.type, recSig->getId())) {
|
||||
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: passing reconstructed recSig to signing mgr, peer=%d\n", __func__,
|
||||
islock->txid.ToString(), hash.ToString(), nodeId);
|
||||
sigman.PushReconstructedRecoveredSig(recSig);
|
||||
|
@ -284,7 +284,7 @@ private:
|
||||
bool ProcessPendingInstantSendLocks();
|
||||
bool ProcessPendingInstantSendLocks(bool deterministic) LOCKS_EXCLUDED(cs_pendingLocks);
|
||||
|
||||
std::unordered_set<uint256, StaticSaltedHasher> ProcessPendingInstantSendLocks(const Consensus::LLMQType llmqType,
|
||||
std::unordered_set<uint256, StaticSaltedHasher> ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params,
|
||||
int signOffset,
|
||||
const std::unordered_map<uint256,
|
||||
std::pair<NodeId, CInstantSendLockPtr>,
|
||||
|
@ -106,6 +106,11 @@ struct LLMQParams {
|
||||
int recoveryMembers;
|
||||
};
|
||||
|
||||
//static_assert(std::is_trivial_v<Consensus::LLMQParams>, "LLMQParams is not a trivial type");
|
||||
static_assert(std::is_trivially_copyable_v<Consensus::LLMQParams>, "LLMQParams is not trivially copyable");
|
||||
//static_assert(std::is_trivially_default_constructible_v<Consensus::LLMQParams>, "LLMQParams is not trivially default constructible");
|
||||
static_assert(std::is_trivially_assignable_v<Consensus::LLMQParams, Consensus::LLMQParams>, "LLMQParams is not trivially assignable");
|
||||
|
||||
|
||||
static constexpr std::array<LLMQParams, 12> available_llmqs = {
|
||||
|
||||
|
@ -299,7 +299,7 @@ void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqPar
|
||||
auto connmanQuorumsToDelete = connman.GetMasternodeQuorums(llmqParams.type);
|
||||
|
||||
// don't remove connections for the currently in-progress DKG round
|
||||
if (utils::IsQuorumRotationEnabled(llmqParams.type, pindexNew)) {
|
||||
if (utils::IsQuorumRotationEnabled(llmqParams, pindexNew)) {
|
||||
int cycleIndexTipHeight = pindexNew->nHeight % llmqParams.dkgInterval;
|
||||
int cycleQuorumBaseHeight = pindexNew->nHeight - cycleIndexTipHeight;
|
||||
std::stringstream ss;
|
||||
@ -371,7 +371,9 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
|
||||
}
|
||||
assert(qc->quorumHash == pQuorumBaseBlockIndex->GetBlockHash());
|
||||
|
||||
auto quorum = std::make_shared<CQuorum>(llmq::GetLLMQParams(llmqType), blsWorker);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
auto quorum = std::make_shared<CQuorum>(llmq_params_opt.value(), blsWorker);
|
||||
auto members = utils::GetAllQuorumMembers(qc->llmqType, pQuorumBaseBlockIndex);
|
||||
|
||||
quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members);
|
||||
@ -450,7 +452,7 @@ bool CQuorumManager::RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqTyp
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- pFrom is neither a verified masternode nor a qwatch connection\n", __func__);
|
||||
return false;
|
||||
}
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
if (!GetLLMQParams(llmqType).has_value()) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Invalid llmqType: %d\n", __func__, static_cast<uint8_t>(llmqType));
|
||||
return false;
|
||||
}
|
||||
@ -523,7 +525,9 @@ std::vector<CQuorumCPtr> CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp
|
||||
}
|
||||
|
||||
// Get the block indexes of the mined commitments to build the required quorums from
|
||||
std::vector<const CBlockIndex*> pQuorumBaseBlockIndexes{ GetLLMQParams(llmqType).useRotation ?
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
std::vector<const CBlockIndex*> pQuorumBaseBlockIndexes{ llmq_params_opt->useRotation ?
|
||||
quorumBlockProcessor.GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) :
|
||||
quorumBlockProcessor.GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments)
|
||||
};
|
||||
@ -648,7 +652,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C
|
||||
}
|
||||
}
|
||||
|
||||
if (!Params().HasLLMQ(request.GetLLMQType())) {
|
||||
if (!GetLLMQParams(request.GetLLMQType()).has_value()) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID);
|
||||
return;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ class CQuorum
|
||||
{
|
||||
friend class CQuorumManager;
|
||||
public:
|
||||
const Consensus::LLMQParams& params;
|
||||
const Consensus::LLMQParams params;
|
||||
CFinalCommitmentPtr qc;
|
||||
const CBlockIndex* m_quorum_base_block_index{nullptr};
|
||||
uint256 minedBlockHash;
|
||||
|
@ -606,7 +606,7 @@ bool CSigningManager::PreVerifyRecoveredSig(const CQuorumManager& quorum_manager
|
||||
retBan = false;
|
||||
|
||||
auto llmqType = recoveredSig.getLlmqType();
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
if (!GetLLMQParams(llmqType).has_value()) {
|
||||
retBan = true;
|
||||
return false;
|
||||
}
|
||||
@ -882,7 +882,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigShares
|
||||
// This gives a slight risk of not getting enough shares to recover a signature
|
||||
// But at least it shouldn't be possible to get conflicting recovered signatures
|
||||
// TODO fix this by re-signing when the next block arrives, but only when that block results in a change of the quorum list and no recovered signature has been created in the mean time
|
||||
quorum = SelectQuorumForSigning(llmqType, qman, id);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
quorum = SelectQuorumForSigning(llmq_params_opt.value(), qman, id);
|
||||
} else {
|
||||
quorum = qman.GetQuorum(llmqType, quorumHash);
|
||||
}
|
||||
@ -979,9 +981,9 @@ bool CSigningManager::GetVoteForId(Consensus::LLMQType llmqType, const uint256&
|
||||
return db.GetVoteForId(llmqType, id, msgHashRet);
|
||||
}
|
||||
|
||||
CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight, int signOffset)
|
||||
CQuorumCPtr CSigningManager::SelectQuorumForSigning(const Consensus::LLMQParams& llmq_params, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight, int signOffset)
|
||||
{
|
||||
size_t poolSize = GetLLMQParams(llmqType).signingActiveQuorumCount;
|
||||
size_t poolSize = llmq_params.signingActiveQuorumCount;
|
||||
|
||||
CBlockIndex* pindexStart;
|
||||
{
|
||||
@ -996,13 +998,13 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
|
||||
pindexStart = ::ChainActive()[startBlockHeight];
|
||||
}
|
||||
|
||||
if (utils::IsQuorumRotationEnabled(llmqType, pindexStart)) {
|
||||
auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
|
||||
if (utils::IsQuorumRotationEnabled(llmq_params, pindexStart)) {
|
||||
auto quorums = quorum_manager.ScanQuorums(llmq_params.type, pindexStart, poolSize);
|
||||
if (quorums.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
//log2 int
|
||||
int n = std::log2(GetLLMQParams(llmqType).signingActiveQuorumCount);
|
||||
int n = std::log2(llmq_params.signingActiveQuorumCount);
|
||||
//Extract last 64 bits of selectionHash
|
||||
uint64_t b = selectionHash.GetUint64(3);
|
||||
//Take last n bits of b
|
||||
@ -1021,7 +1023,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
|
||||
}
|
||||
return *itQuorum;
|
||||
} else {
|
||||
auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
|
||||
auto quorums = quorum_manager.ScanQuorums(llmq_params.type, pindexStart, poolSize);
|
||||
if (quorums.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1030,7 +1032,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
|
||||
scores.reserve(quorums.size());
|
||||
for (const auto i : irange::range(quorums.size())) {
|
||||
CHashWriter h(SER_NETWORK, 0);
|
||||
h << llmqType;
|
||||
h << llmq_params.type;
|
||||
h << quorums[i]->qc->quorumHash;
|
||||
h << selectionHash;
|
||||
scores.emplace_back(h.GetHash(), i);
|
||||
@ -1042,7 +1044,9 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
|
||||
|
||||
bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, const int signOffset)
|
||||
{
|
||||
auto quorum = SelectQuorumForSigning(llmqType, quorum_manager, id, signedAtHeight, signOffset);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
auto quorum = SelectQuorumForSigning(llmq_params_opt.value(), quorum_manager, id, signedAtHeight, signOffset);
|
||||
if (!quorum) {
|
||||
return false;
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ public:
|
||||
bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet) const;
|
||||
|
||||
static std::vector<CQuorumCPtr> GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight);
|
||||
static CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET);
|
||||
static CQuorumCPtr SelectQuorumForSigning(const Consensus::LLMQParams& llmq_params, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET);
|
||||
|
||||
// Verifies a recovered sig that was signed while the chain tip was at signedAtTip
|
||||
static bool VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, int signOffset = SIGN_HEIGHT_OFFSET);
|
||||
|
@ -96,7 +96,9 @@ std::string CBatchedSigShares::ToInvString() const
|
||||
|
||||
static void InitSession(CSigSharesNodeState::Session& s, const uint256& signHash, CSigBase from)
|
||||
{
|
||||
const auto& llmq_params = GetLLMQParams((Consensus::LLMQType)from.getLlmqType());
|
||||
const auto& llmq_params_opt = GetLLMQParams((Consensus::LLMQType)from.getLlmqType());
|
||||
assert(llmq_params_opt.has_value());
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
|
||||
s.llmqType = from.getLlmqType();
|
||||
s.quorumHash = from.getQuorumHash();
|
||||
@ -296,7 +298,7 @@ void CSigSharesManager::ProcessMessage(const CNode* pfrom, const std::string& ms
|
||||
bool CSigSharesManager::ProcessMessageSigSesAnn(const CNode* pfrom, const CSigSesAnn& ann)
|
||||
{
|
||||
auto llmqType = ann.getLlmqType();
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
if (!GetLLMQParams(llmqType).has_value()) {
|
||||
return false;
|
||||
}
|
||||
if (ann.getSessionId() == UNINITIALIZED_SESSION_ID || ann.getQuorumHash().IsNull() || ann.getId().IsNull() || ann.getMsgHash().IsNull()) {
|
||||
@ -327,7 +329,8 @@ bool CSigSharesManager::ProcessMessageSigSesAnn(const CNode* pfrom, const CSigSe
|
||||
|
||||
bool CSigSharesManager::VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv)
|
||||
{
|
||||
return inv.inv.size() == size_t(GetLLMQParams(llmqType).size);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
return llmq_params_opt.has_value() && (inv.inv.size() == size_t(llmq_params_opt->size));
|
||||
}
|
||||
|
||||
bool CSigSharesManager::ProcessMessageSigSharesInv(const CNode* pfrom, const CSigSharesInv& inv)
|
||||
@ -899,7 +902,9 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, std
|
||||
}
|
||||
auto& inv = (*invMap)[signHash];
|
||||
if (inv.inv.empty()) {
|
||||
inv.Init(GetLLMQParams(session.llmqType).size);
|
||||
const auto& llmq_params_opt = GetLLMQParams(session.llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
inv.Init(llmq_params_opt->size);
|
||||
}
|
||||
inv.inv[k.second] = true;
|
||||
|
||||
@ -1046,7 +1051,9 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
|
||||
|
||||
auto& inv = sigSharesToAnnounce[nodeId][signHash];
|
||||
if (inv.inv.empty()) {
|
||||
inv.Init(GetLLMQParams(sigShare->getLlmqType()).size);
|
||||
const auto& llmq_params_opt = GetLLMQParams(sigShare->getLlmqType());
|
||||
assert(llmq_params_opt.has_value());
|
||||
inv.Init(llmq_params_opt->size);
|
||||
}
|
||||
inv.inv[quorumMember] = true;
|
||||
session.knows.inv[quorumMember] = true;
|
||||
|
@ -168,8 +168,10 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
|
||||
Consensus::LLMQType llmqType = utils::GetInstantSendLLMQType(qman, blockIndex);
|
||||
|
||||
// Since the returned quorums are in reversed order, the most recent one is at index 0
|
||||
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
|
||||
const int cycleLength = llmqParams.dkgInterval;
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
|
||||
const int cycleLength = llmq_params_opt->dkgInterval;
|
||||
constexpr int workDiff = 8;
|
||||
|
||||
const CBlockIndex* hBlockIndex = blockIndex->GetAncestor(blockIndex->nHeight - (blockIndex->nHeight % cycleLength));
|
||||
@ -307,7 +309,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
|
||||
}
|
||||
response.lastCommitmentPerIndex.push_back(*qc);
|
||||
|
||||
int quorumCycleStartHeight = obj.second->nHeight - (obj.second->nHeight % llmqParams.dkgInterval);
|
||||
int quorumCycleStartHeight = obj.second->nHeight - (obj.second->nHeight % llmq_params_opt->dkgInterval);
|
||||
snapshotHeightsNeeded.insert(quorumCycleStartHeight - cycleLength);
|
||||
snapshotHeightsNeeded.insert(quorumCycleStartHeight - 2 * cycleLength);
|
||||
snapshotHeightsNeeded.insert(quorumCycleStartHeight - 3 * cycleLength);
|
||||
|
@ -38,7 +38,7 @@ namespace utils
|
||||
void PreComputeQuorumMembers(const CBlockIndex* pQuorumBaseBlockIndex, bool reset_cache)
|
||||
{
|
||||
for (const Consensus::LLMQParams& params : GetEnabledQuorumParams(pQuorumBaseBlockIndex->pprev)) {
|
||||
if (IsQuorumRotationEnabled(params.type, pQuorumBaseBlockIndex) && (pQuorumBaseBlockIndex->nHeight % params.dkgInterval == 0)) {
|
||||
if (IsQuorumRotationEnabled(params, pQuorumBaseBlockIndex) && (pQuorumBaseBlockIndex->nHeight % params.dkgInterval == 0)) {
|
||||
GetAllQuorumMembers(params.type, pQuorumBaseBlockIndex, reset_cache);
|
||||
}
|
||||
}
|
||||
@ -66,7 +66,11 @@ std::vector<CDeterministicMNCPtr> GetAllQuorumMembers(Consensus::LLMQType llmqTy
|
||||
}
|
||||
}
|
||||
|
||||
if (IsQuorumRotationEnabled(llmqType, pQuorumBaseBlockIndex)) {
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
|
||||
if (IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex)) {
|
||||
if (LOCK(cs_indexed_members); mapIndexedQuorumMembers.empty()) {
|
||||
InitQuorumsCache(mapIndexedQuorumMembers);
|
||||
}
|
||||
@ -79,9 +83,8 @@ std::vector<CDeterministicMNCPtr> GetAllQuorumMembers(Consensus::LLMQType llmqTy
|
||||
* Quorum Q with quorumIndex is created at height CycleQuorumBaseBlock + quorumIndex
|
||||
*/
|
||||
|
||||
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
|
||||
int quorumIndex = pQuorumBaseBlockIndex->nHeight % llmqParams.dkgInterval;
|
||||
if (quorumIndex >= llmqParams.signingActiveQuorumCount) {
|
||||
int quorumIndex = pQuorumBaseBlockIndex->nHeight % llmq_params.dkgInterval;
|
||||
if (quorumIndex >= llmq_params.signingActiveQuorumCount) {
|
||||
return {};
|
||||
}
|
||||
int cycleQuorumBaseHeight = pQuorumBaseBlockIndex->nHeight - quorumIndex;
|
||||
@ -100,7 +103,7 @@ std::vector<CDeterministicMNCPtr> GetAllQuorumMembers(Consensus::LLMQType llmqTy
|
||||
return quorumMembers;
|
||||
}
|
||||
|
||||
auto q = ComputeQuorumMembersByQuarterRotation(llmqType, pCycleQuorumBaseBlockIndex);
|
||||
auto q = ComputeQuorumMembersByQuarterRotation(llmq_params, pCycleQuorumBaseBlockIndex);
|
||||
LOCK(cs_indexed_members);
|
||||
for (int i = 0; i < static_cast<int>(q.size()); ++i) {
|
||||
mapIndexedQuorumMembers[llmqType].insert(std::make_pair(pCycleQuorumBaseBlockIndex->GetBlockHash(), i), q[i]);
|
||||
@ -120,13 +123,13 @@ std::vector<CDeterministicMNCPtr> ComputeQuorumMembers(Consensus::LLMQType llmqT
|
||||
{
|
||||
auto allMns = deterministicMNManager->GetListForBlock(pQuorumBaseBlockIndex);
|
||||
auto modifier = ::SerializeHash(std::make_pair(llmqType, pQuorumBaseBlockIndex->GetBlockHash()));
|
||||
return allMns.CalculateQuorum(GetLLMQParams(llmqType).size, modifier);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
return allMns.CalculateQuorum(llmq_params_opt->size, modifier);
|
||||
}
|
||||
|
||||
std::vector<std::vector<CDeterministicMNCPtr>> ComputeQuorumMembersByQuarterRotation(Consensus::LLMQType llmqType, const CBlockIndex* pCycleQuorumBaseBlockIndex)
|
||||
std::vector<std::vector<CDeterministicMNCPtr>> ComputeQuorumMembersByQuarterRotation(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pCycleQuorumBaseBlockIndex)
|
||||
{
|
||||
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
|
||||
|
||||
const int cycleLength = llmqParams.dkgInterval;
|
||||
assert(pCycleQuorumBaseBlockIndex->nHeight % cycleLength == 0);
|
||||
|
||||
@ -136,7 +139,7 @@ std::vector<std::vector<CDeterministicMNCPtr>> ComputeQuorumMembersByQuarterRota
|
||||
LOCK(deterministicMNManager->cs);
|
||||
const CBlockIndex* pWorkBlockIndex = pCycleQuorumBaseBlockIndex->GetAncestor(pCycleQuorumBaseBlockIndex->nHeight - 8);
|
||||
auto allMns = deterministicMNManager->GetListForBlock(pWorkBlockIndex);
|
||||
LogPrint(BCLog::LLMQ, "ComputeQuorumMembersByQuarterRotation llmqType[%d] nHeight[%d] allMns[%d]\n", static_cast<int>(llmqType), pCycleQuorumBaseBlockIndex->nHeight, allMns.GetValidMNsCount());
|
||||
LogPrint(BCLog::LLMQ, "ComputeQuorumMembersByQuarterRotation llmqType[%d] nHeight[%d] allMns[%d]\n", static_cast<int>(llmqParams.type), pCycleQuorumBaseBlockIndex->nHeight, allMns.GetValidMNsCount());
|
||||
|
||||
PreviousQuorumQuarters previousQuarters = GetPreviousQuorumQuarterMembers(llmqParams, pBlockHMinusCIndex, pBlockHMinus2CIndex, pBlockHMinus3CIndex, pCycleQuorumBaseBlockIndex->nHeight);
|
||||
|
||||
@ -593,16 +596,16 @@ bool IsQuorumPoseEnabled(Consensus::LLMQType llmqType)
|
||||
return EvalSpork(llmqType, sporkManager->GetSporkValue(SPORK_23_QUORUM_POSE));
|
||||
}
|
||||
|
||||
bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex)
|
||||
bool IsQuorumRotationEnabled(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindex)
|
||||
{
|
||||
assert(pindex);
|
||||
|
||||
if (!GetLLMQParams(llmqType).useRotation) {
|
||||
if (!llmqParams.useRotation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs_llmq_vbc);
|
||||
int cycleQuorumBaseHeight = pindex->nHeight - (pindex->nHeight % GetLLMQParams(llmqType).dkgInterval);
|
||||
int cycleQuorumBaseHeight = pindex->nHeight - (pindex->nHeight % llmqParams.dkgInterval);
|
||||
if (cycleQuorumBaseHeight < 1) {
|
||||
return false;
|
||||
}
|
||||
@ -865,7 +868,9 @@ bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, co
|
||||
// sig shares and recovered sigs are only accepted from recent/active quorums
|
||||
// we allow one more active quorum as specified in consensus, as otherwise there is a small window where things could
|
||||
// fail while we are on the brink of a new quorum
|
||||
auto quorums = qman.ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections);
|
||||
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
||||
assert(llmq_params_opt.has_value());
|
||||
auto quorums = qman.ScanQuorums(llmqType, llmq_params_opt->keepOldConnections);
|
||||
return ranges::any_of(quorums, [&quorumHash](const auto& q){ return q->qc->quorumHash == quorumHash; });
|
||||
}
|
||||
|
||||
@ -1025,7 +1030,7 @@ template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache
|
||||
|
||||
} // namespace utils
|
||||
|
||||
const Consensus::LLMQParams& GetLLMQParams(Consensus::LLMQType llmqType)
|
||||
const std::optional<Consensus::LLMQParams> GetLLMQParams(Consensus::LLMQType llmqType)
|
||||
{
|
||||
return Params().GetLLMQ(llmqType);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ std::vector<CDeterministicMNCPtr> GetAllQuorumMembers(Consensus::LLMQType llmqTy
|
||||
|
||||
void PreComputeQuorumMembers(const CBlockIndex* pQuorumBaseBlockIndex, bool reset_cache = false);
|
||||
static std::vector<CDeterministicMNCPtr> ComputeQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex);
|
||||
static std::vector<std::vector<CDeterministicMNCPtr>> ComputeQuorumMembersByQuarterRotation(Consensus::LLMQType llmqType, const CBlockIndex* pCycleQuorumBaseBlockIndex);
|
||||
static std::vector<std::vector<CDeterministicMNCPtr>> ComputeQuorumMembersByQuarterRotation(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pCycleQuorumBaseBlockIndex);
|
||||
|
||||
static std::vector<std::vector<CDeterministicMNCPtr>> BuildNewQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, const PreviousQuorumQuarters& quarters);
|
||||
|
||||
@ -89,7 +89,7 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumMana
|
||||
std::vector<Consensus::LLMQType> GetEnabledQuorumTypes(const CBlockIndex* pindex);
|
||||
std::vector<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuorumParams(const CBlockIndex* pindex);
|
||||
|
||||
bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex);
|
||||
bool IsQuorumRotationEnabled(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindex);
|
||||
Consensus::LLMQType GetInstantSendLLMQType(const CQuorumManager& qman, const CBlockIndex* pindex);
|
||||
Consensus::LLMQType GetInstantSendLLMQType(bool deterministic);
|
||||
bool IsDIP0024Active(const CBlockIndex* pindex);
|
||||
@ -139,7 +139,7 @@ void InitQuorumsCache(CacheType& cache);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
const Consensus::LLMQParams& GetLLMQParams(Consensus::LLMQType llmqType);
|
||||
[[ nodiscard ]] const std::optional<Consensus::LLMQParams> GetLLMQParams(Consensus::LLMQType llmqType);
|
||||
|
||||
} // namespace llmq
|
||||
|
||||
|
@ -70,15 +70,16 @@ static UniValue quorum_list(const JSONRPCRequest& request)
|
||||
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return ::ChainActive().Tip());
|
||||
|
||||
for (const auto& type : llmq::utils::GetEnabledQuorumTypes(pindexTip)) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(type);
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(type);
|
||||
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||
UniValue v(UniValue::VARR);
|
||||
|
||||
auto quorums = llmq_ctx.qman->ScanQuorums(type, pindexTip, count > -1 ? count : llmq_params.signingActiveQuorumCount);
|
||||
auto quorums = llmq_ctx.qman->ScanQuorums(type, pindexTip, count > -1 ? count : llmq_params_opt->signingActiveQuorumCount);
|
||||
for (const auto& q : quorums) {
|
||||
v.push_back(q->qc->quorumHash.ToString());
|
||||
}
|
||||
|
||||
ret.pushKV(std::string(llmq_params.name), v);
|
||||
ret.pushKV(std::string(llmq_params_opt->name), v);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -135,7 +136,9 @@ static UniValue quorum_list_extended(const JSONRPCRequest& request)
|
||||
CBlockIndex* pblockindex = nHeight != -1 ? WITH_LOCK(cs_main, return ::ChainActive()[nHeight]) : WITH_LOCK(cs_main, return ::ChainActive().Tip());
|
||||
|
||||
for (const auto& type : llmq::utils::GetEnabledQuorumTypes(pblockindex)) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(type);
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(type);
|
||||
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
UniValue v(UniValue::VARR);
|
||||
|
||||
auto quorums = llmq_ctx.qman->ScanQuorums(type, pblockindex, llmq_params.signingActiveQuorumCount);
|
||||
@ -222,7 +225,7 @@ static UniValue quorum_info(const JSONRPCRequest& request)
|
||||
quorum_info_help(request);
|
||||
|
||||
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
if (!llmq::GetLLMQParams(llmqType).has_value()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||
}
|
||||
|
||||
@ -282,8 +285,10 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request)
|
||||
UniValue minableCommitments(UniValue::VARR);
|
||||
UniValue quorumArrConnections(UniValue::VARR);
|
||||
for (const auto& type : llmq::utils::GetEnabledQuorumTypes(pindexTip)) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(type);
|
||||
bool rotation_enabled = llmq::utils::IsQuorumRotationEnabled(type, pindexTip);
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(type);
|
||||
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||
const auto& llmq_params = llmq_params_opt.value();
|
||||
bool rotation_enabled = llmq::utils::IsQuorumRotationEnabled(llmq_params, pindexTip);
|
||||
size_t quorums_num = rotation_enabled ? llmq_params.signingActiveQuorumCount : 1;
|
||||
|
||||
for (int quorumIndex = 0; quorumIndex < quorums_num; ++quorumIndex) {
|
||||
@ -386,12 +391,13 @@ static UniValue quorum_memberof(const JSONRPCRequest& request)
|
||||
|
||||
UniValue result(UniValue::VARR);
|
||||
for (const auto& type : llmq::utils::GetEnabledQuorumTypes(pindexTip)) {
|
||||
const auto& llmq_params = llmq::GetLLMQParams(type);
|
||||
size_t count = llmq_params.signingActiveQuorumCount;
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(type);
|
||||
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||
size_t count = llmq_params_opt->signingActiveQuorumCount;
|
||||
if (scanQuorumsCount != -1) {
|
||||
count = (size_t)scanQuorumsCount;
|
||||
}
|
||||
auto quorums = llmq_ctx.qman->ScanQuorums(llmq_params.type, count);
|
||||
auto quorums = llmq_ctx.qman->ScanQuorums(llmq_params_opt->type, count);
|
||||
for (auto& quorum : quorums) {
|
||||
if (quorum->IsMember(dmn->proTxHash)) {
|
||||
auto json = BuildQuorumInfo(quorum, false, false);
|
||||
@ -508,7 +514,8 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request)
|
||||
LLMQContext& llmq_ctx = EnsureLLMQContext(request.context);
|
||||
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
|
||||
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||
}
|
||||
|
||||
@ -530,7 +537,7 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request)
|
||||
llmq::CQuorumCPtr pQuorum;
|
||||
|
||||
if (quorumHash.IsNull()) {
|
||||
pQuorum = llmq_ctx.sigman->SelectQuorumForSigning(llmqType, *llmq_ctx.qman, id);
|
||||
pQuorum = llmq_ctx.sigman->SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id);
|
||||
} else {
|
||||
pQuorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash);
|
||||
}
|
||||
@ -568,7 +575,7 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request)
|
||||
signHeight = ParseInt32V(request.params[5], "signHeight");
|
||||
}
|
||||
// First check against the current active set, if it fails check against the last active set
|
||||
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
|
||||
int signOffset{llmq_params_opt->dkgInterval};
|
||||
return llmq_ctx.sigman->VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) ||
|
||||
llmq_ctx.sigman->VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset);
|
||||
} else {
|
||||
@ -619,7 +626,8 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request)
|
||||
quorum_selectquorum_help(request);
|
||||
|
||||
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
|
||||
if (!Params().HasLLMQ(llmqType)) {
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
if (!llmq_params_opt.has_value()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||
}
|
||||
|
||||
@ -628,7 +636,7 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request)
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
LLMQContext& llmq_ctx = EnsureLLMQContext(request.context);
|
||||
auto quorum = llmq_ctx.sigman->SelectQuorumForSigning(llmqType, *llmq_ctx.qman, id);
|
||||
auto quorum = llmq_ctx.sigman->SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id);
|
||||
if (!quorum) {
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
|
||||
}
|
||||
@ -944,7 +952,9 @@ static UniValue verifyislock(const JSONRPCRequest& request)
|
||||
|
||||
auto llmqType = llmq::utils::GetInstantSendLLMQType(*llmq_ctx.qman, pBlockIndex);
|
||||
// First check against the current active set, if it fails check against the last active set
|
||||
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
|
||||
const auto& llmq_params_opt = llmq::GetLLMQParams(llmqType);
|
||||
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||
int signOffset{llmq_params_opt->dkgInterval};
|
||||
return llmq_ctx.sigman->VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, 0) ||
|
||||
llmq_ctx.sigman->VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, signOffset);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user