2023-01-12 22:26:21 +01:00
|
|
|
// Copyright (c) 2018-2023 The Dash Core developers
|
2018-11-23 15:42:09 +01:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2021-10-02 19:32:24 +02:00
|
|
|
#include <llmq/blockprocessor.h>
|
|
|
|
#include <llmq/commitment.h>
|
2022-08-02 19:14:25 +02:00
|
|
|
#include <llmq/utils.h>
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2021-04-16 05:41:16 +02:00
|
|
|
#include <evo/evodb.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <evo/specialtx.h>
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <chain.h>
|
|
|
|
#include <chainparams.h>
|
2021-04-16 05:41:16 +02:00
|
|
|
#include <consensus/params.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <consensus/validation.h>
|
|
|
|
#include <net.h>
|
|
|
|
#include <net_processing.h>
|
|
|
|
#include <primitives/block.h>
|
2021-04-16 05:41:16 +02:00
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <saltedhasher.h>
|
|
|
|
#include <sync.h>
|
2022-04-26 01:40:41 +02:00
|
|
|
#include <util/irange.h>
|
2023-02-20 11:12:12 +01:00
|
|
|
#include <util/underlying.h>
|
2022-04-26 01:40:41 +02:00
|
|
|
#include <validation.h>
|
2021-04-16 05:41:16 +02:00
|
|
|
|
|
|
|
#include <map>
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2023-07-10 17:13:42 +02:00
|
|
|
static void PreComputeQuorumMembers(const CBlockIndex* pindex, bool reset_cache = false)
|
|
|
|
{
|
|
|
|
for (const Consensus::LLMQParams& params : llmq::utils::GetEnabledQuorumParams(pindex->pprev)) {
|
|
|
|
if (llmq::utils::IsQuorumRotationEnabled(params, pindex) && (pindex->nHeight % params.dkgInterval == 0)) {
|
|
|
|
llmq::utils::GetAllQuorumMembers(params.type, pindex, reset_cache);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
namespace llmq
|
|
|
|
{
|
|
|
|
|
2022-08-26 23:52:53 +02:00
|
|
|
std::unique_ptr<CQuorumBlockProcessor> quorumBlockProcessor;
|
2018-11-23 15:42:09 +01:00
|
|
|
|
|
|
|
static const std::string DB_MINED_COMMITMENT = "q_mc";
|
2019-04-02 12:51:13 +02:00
|
|
|
static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT = "q_mcih";
|
2022-04-16 16:46:04 +02:00
|
|
|
static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED = "q_mcihi";
|
2019-04-02 12:51:13 +02:00
|
|
|
|
2019-04-05 13:39:29 +02:00
|
|
|
static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2";
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2023-08-23 19:11:26 +02:00
|
|
|
CQuorumBlockProcessor::CQuorumBlockProcessor(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb, const std::unique_ptr<PeerManager>& peerman) :
|
|
|
|
m_chainstate(chainstate), connman(_connman), m_evoDb(evoDb), m_peerman(peerman)
|
2021-01-25 10:22:28 +01:00
|
|
|
{
|
2022-08-02 19:14:25 +02:00
|
|
|
utils::InitQuorumsCache(mapHasMinedCommitmentCache);
|
2021-01-25 10:22:28 +01:00
|
|
|
}
|
|
|
|
|
2022-10-28 21:50:54 +02:00
|
|
|
void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2022-05-12 23:11:39 +02:00
|
|
|
if (msg_type != NetMsgType::QFCOMMITMENT) {
|
|
|
|
return;
|
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-05-12 23:11:39 +02:00
|
|
|
CFinalCommitment qc;
|
|
|
|
vRecv >> qc;
|
2019-02-27 14:10:12 +01:00
|
|
|
|
2022-10-28 21:50:54 +02:00
|
|
|
WITH_LOCK(cs_main, EraseObjectRequest(peer.GetId(), CInv(MSG_QUORUM_FINAL_COMMITMENT, ::SerializeHash(qc))));
|
2022-05-12 23:11:39 +02:00
|
|
|
|
|
|
|
if (qc.IsNull()) {
|
2022-10-28 21:50:54 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- null commitment from peer=%d\n", __func__, peer.GetId());
|
2023-04-28 07:17:42 +02:00
|
|
|
m_peerman->Misbehaving(peer.GetId(), 100);
|
2022-05-12 23:11:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
|
|
|
if (!llmq_params_opt.has_value()) {
|
2022-05-12 23:11:39 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- invalid commitment type %d from peer=%d\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
ToUnderlying(qc.llmqType), peer.GetId());
|
2023-04-28 07:17:42 +02:00
|
|
|
m_peerman->Misbehaving(peer.GetId(), 100);
|
2022-05-12 23:11:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto type = qc.llmqType;
|
|
|
|
|
|
|
|
// Verify that quorumHash is part of the active chain and that it's the first block in the DKG interval
|
|
|
|
const CBlockIndex* pQuorumBaseBlockIndex;
|
|
|
|
{
|
|
|
|
LOCK(cs_main);
|
2023-08-23 19:11:26 +02:00
|
|
|
pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash);
|
2022-05-12 23:11:39 +02:00
|
|
|
if (pQuorumBaseBlockIndex == nullptr) {
|
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- unknown block %s in commitment, peer=%d\n", __func__,
|
2022-10-28 21:50:54 +02:00
|
|
|
qc.quorumHash.ToString(), peer.GetId());
|
2022-05-12 23:11:39 +02:00
|
|
|
// can't really punish the node here, as we might simply be the one that is on the wrong chain or not
|
|
|
|
// fully synced
|
2018-11-23 15:42:09 +01:00
|
|
|
return;
|
|
|
|
}
|
2023-08-23 19:11:26 +02:00
|
|
|
if (m_chainstate.m_chain.Tip()->GetAncestor(pQuorumBaseBlockIndex->nHeight) != pQuorumBaseBlockIndex) {
|
2022-05-12 23:11:39 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__,
|
2022-10-28 21:50:54 +02:00
|
|
|
qc.quorumHash.ToString(), peer.GetId());
|
2022-05-12 23:11:39 +02:00
|
|
|
// same, can't punish
|
2018-11-23 15:42:09 +01:00
|
|
|
return;
|
|
|
|
}
|
2023-03-13 17:11:17 +01:00
|
|
|
int quorumHeight = pQuorumBaseBlockIndex->nHeight - (pQuorumBaseBlockIndex->nHeight % llmq_params_opt->dkgInterval) + int(qc.quorumIndex);
|
2022-05-12 23:11:39 +02:00
|
|
|
if (quorumHeight != pQuorumBaseBlockIndex->nHeight) {
|
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is not the first block in the DKG interval, peer=%d\n", __func__,
|
2022-10-28 21:50:54 +02:00
|
|
|
qc.quorumHash.ToString(), peer.GetId());
|
2023-04-28 07:17:42 +02:00
|
|
|
m_peerman->Misbehaving(peer.GetId(), 100);
|
2022-05-12 23:11:39 +02:00
|
|
|
return;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
2023-08-23 19:11:26 +02:00
|
|
|
if (pQuorumBaseBlockIndex->nHeight < (m_chainstate.m_chain.Height() - llmq_params_opt->dkgInterval)) {
|
fix: avoid re-propogating old qfcommit messages (#5145)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
This fixes an issue where qfcommit messages can be replayed from the
past, then are validated and propagated to other nodes. This patch
changes it so that old qfcommits are not relayed.
## What was done?
<!--- Describe your changes in detail -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
Deployed to a node, and ensured that the log messages are shown.
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] I have performed a self-review of my own code
- [ ] 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**
- [ ] I have assigned this pull request to a milestone
2023-01-08 03:26:32 +01:00
|
|
|
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
|
2023-04-28 07:17:42 +02:00
|
|
|
// m_peerman->Misbehaving(peer.GetId(), 100);
|
fix: avoid re-propogating old qfcommit messages (#5145)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
This fixes an issue where qfcommit messages can be replayed from the
past, then are validated and propagated to other nodes. This patch
changes it so that old qfcommits are not relayed.
## What was done?
<!--- Describe your changes in detail -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
Deployed to a node, and ensured that the log messages are shown.
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] I have performed a self-review of my own code
- [ ] 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**
- [ ] I have assigned this pull request to a milestone
2023-01-08 03:26:32 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (HasMinedCommitment(type, qc.quorumHash)) {
|
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- commitment for quorum hash[%s], type[%d], quorumIndex[%d] is already mined, peer=%d\n",
|
2023-02-20 11:12:12 +01:00
|
|
|
__func__, qc.quorumHash.ToString(), ToUnderlying(type), qc.quorumIndex, peer.GetId());
|
fix: avoid re-propogating old qfcommit messages (#5145)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
This fixes an issue where qfcommit messages can be replayed from the
past, then are validated and propagated to other nodes. This patch
changes it so that old qfcommits are not relayed.
## What was done?
<!--- Describe your changes in detail -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
Deployed to a node, and ensured that the log messages are shown.
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] I have performed a self-review of my own code
- [ ] 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**
- [ ] I have assigned this pull request to a milestone
2023-01-08 03:26:32 +01:00
|
|
|
// NOTE: do not punish here
|
|
|
|
return;
|
|
|
|
}
|
2022-05-12 23:11:39 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-05-12 23:11:39 +02:00
|
|
|
{
|
|
|
|
// Check if we already got a better one locally
|
|
|
|
// We do this before verifying the commitment to avoid DoS
|
|
|
|
LOCK(minableCommitmentsCs);
|
|
|
|
auto k = std::make_pair(type, qc.quorumHash);
|
|
|
|
auto it = minableCommitmentsByQuorum.find(k);
|
|
|
|
if (it != minableCommitmentsByQuorum.end()) {
|
|
|
|
auto jt = minableCommitments.find(it->second);
|
|
|
|
if (jt != minableCommitments.end() && jt->second.CountSigners() <= qc.CountSigners()) {
|
|
|
|
return;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
}
|
2022-05-12 23:11:39 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-05-12 23:11:39 +02:00
|
|
|
if (!qc.Verify(pQuorumBaseBlockIndex, true)) {
|
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- commitment for quorum %s:%d is not valid quorumIndex[%d] nversion[%d], peer=%d\n",
|
|
|
|
__func__, qc.quorumHash.ToString(),
|
2023-02-20 11:12:12 +01:00
|
|
|
ToUnderlying(qc.llmqType), qc.quorumIndex, qc.nVersion, peer.GetId());
|
2023-04-28 07:17:42 +02:00
|
|
|
m_peerman->Misbehaving(peer.GetId(), 100);
|
2022-05-12 23:11:39 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-05-12 23:11:39 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- received commitment for quorum %s:%d, validMembers=%d, signers=%d, peer=%d\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
qc.quorumHash.ToString(), ToUnderlying(qc.llmqType), qc.CountValidMembers(), qc.CountSigners(), peer.GetId());
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-05-12 23:11:39 +02:00
|
|
|
AddMineableCommitment(qc);
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2023-10-22 16:14:30 +02:00
|
|
|
bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state, bool fJustCheck, bool fBLSChecks)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2023-04-15 19:24:02 +02:00
|
|
|
const auto blockHash = pindex->GetBlockHash();
|
|
|
|
|
2019-04-25 17:39:04 +02:00
|
|
|
bool fDIP0003Active = pindex->nHeight >= Params().GetConsensus().DIP0003Height;
|
2018-11-23 15:42:09 +01:00
|
|
|
if (!fDIP0003Active) {
|
2023-04-15 19:24:02 +02:00
|
|
|
m_evoDb.Write(DB_BEST_BLOCK_UPGRADE, blockHash);
|
2018-11-23 15:42:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-07-10 17:13:42 +02:00
|
|
|
PreComputeQuorumMembers(pindex);
|
2022-04-16 16:46:04 +02:00
|
|
|
|
|
|
|
std::multimap<Consensus::LLMQType, CFinalCommitment> qcs;
|
2019-04-25 17:39:04 +02:00
|
|
|
if (!GetCommitmentsFromBlock(block, pindex, qcs, state)) {
|
2018-11-23 15:42:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The following checks make sure that there is always a (possibly null) commitment while in the mining phase
|
|
|
|
// until the first non-null commitment has been mined. After the non-null commitment, no other commitments are
|
|
|
|
// allowed, including null commitments.
|
2020-12-10 00:08:05 +01:00
|
|
|
// Note: must only check quorums that were enabled at the _previous_ block height to match mining logic
|
2022-08-02 19:14:25 +02:00
|
|
|
for (const Consensus::LLMQParams& params : utils::GetEnabledQuorumParams(pindex->pprev)) {
|
2020-05-11 14:33:21 +02:00
|
|
|
// skip these checks when replaying blocks after the crash
|
2023-08-23 19:11:26 +02:00
|
|
|
if (m_chainstate.m_chain.Tip() == nullptr) {
|
2020-05-11 14:33:21 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
const size_t numCommitmentsRequired = GetNumCommitmentsRequired(params, pindex->nHeight);
|
2022-04-16 16:46:04 +02:00
|
|
|
const auto numCommitmentsInNewBlock = qcs.count(params.type);
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
if (numCommitmentsRequired < numCommitmentsInNewBlock) {
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-not-allowed");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
if (numCommitmentsRequired > numCommitmentsInNewBlock) {
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-missing");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
2023-03-13 17:11:17 +01:00
|
|
|
if (llmq::utils::IsQuorumRotationEnabled(params, pindex)) {
|
2022-07-02 20:02:42 +02:00
|
|
|
LogPrintf("[ProcessBlock] h[%d] numCommitmentsRequired[%d] numCommitmentsInNewBlock[%d]\n", pindex->nHeight, numCommitmentsRequired, numCommitmentsInNewBlock);
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-06-26 15:10:53 +02:00
|
|
|
for (const auto& p : qcs) {
|
|
|
|
const auto& qc = p.second;
|
2022-03-30 03:13:33 +02:00
|
|
|
if (!ProcessCommitment(pindex->nHeight, blockHash, qc, state, fJustCheck, fBLSChecks)) {
|
2023-02-20 11:12:12 +01:00
|
|
|
LogPrintf("[ProcessBlock] failed h[%d] llmqType[%d] version[%d] quorumIndex[%d] quorumHash[%s]\n", pindex->nHeight, ToUnderlying(qc.llmqType), qc.nVersion, qc.quorumIndex, qc.quorumHash.ToString());
|
2018-11-23 15:42:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2019-04-04 17:58:51 +02:00
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Write(DB_BEST_BLOCK_UPGRADE, blockHash);
|
2019-04-04 17:58:51 +02:00
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-04-02 12:51:13 +02:00
|
|
|
// We store a mapping from minedHeight->quorumHeight in the DB
|
|
|
|
// minedHeight is inversed so that entries are traversable in reversed order
|
2019-05-28 15:34:41 +02:00
|
|
|
static std::tuple<std::string, Consensus::LLMQType, uint32_t> BuildInversedHeightKey(Consensus::LLMQType llmqType, int nMinedHeight)
|
2019-04-02 12:51:13 +02:00
|
|
|
{
|
2019-04-05 13:39:29 +02:00
|
|
|
// nMinedHeight must be converted to big endian to make it comparable when serialized
|
2019-05-28 15:34:41 +02:00
|
|
|
return std::make_tuple(DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT, llmqType, htobe32(std::numeric_limits<uint32_t>::max() - nMinedHeight));
|
2019-04-02 12:51:13 +02:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
static std::tuple<std::string, Consensus::LLMQType, int, uint32_t> BuildInversedHeightKeyIndexed(Consensus::LLMQType llmqType, int nMinedHeight, int quorumIndex)
|
|
|
|
{
|
|
|
|
// nMinedHeight must be converted to big endian to make it comparable when serialized
|
|
|
|
return std::make_tuple(DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED, llmqType, quorumIndex, htobe32(std::numeric_limits<uint32_t>::max() - nMinedHeight));
|
|
|
|
}
|
|
|
|
|
2019-10-30 15:27:22 +01:00
|
|
|
bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockHash, const CFinalCommitment& qc, BlockValidationState& state, bool fJustCheck, bool fBLSChecks)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2021-09-08 00:33:02 +02:00
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
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__, ToUnderlying(qc.llmqType));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const auto& llmq_params = llmq_params_opt.value();
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
uint256 quorumHash = GetQuorumBlockHash(llmq_params, nHeight, qc.quorumIndex);
|
|
|
|
|
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s fJustCheck[%d] processing commitment from block.\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString(), fJustCheck);
|
2020-05-11 14:33:21 +02:00
|
|
|
|
|
|
|
// skip `bad-qc-block` checks below when replaying blocks after the crash
|
2023-08-23 19:11:26 +02:00
|
|
|
if (m_chainstate.m_chain.Tip() == nullptr) {
|
2020-05-11 14:33:21 +02:00
|
|
|
quorumHash = qc.quorumHash;
|
|
|
|
}
|
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
if (quorumHash.IsNull()) {
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s quorumHash is null.\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString());
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-block");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
if (quorumHash != qc.quorumHash) {
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, qc.quorumHash=%s signers=%s, validMembers=%d, quorumPublicKey=%s non equal quorumHash.\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString());
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-block");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (qc.IsNull()) {
|
2018-11-27 08:04:08 +01:00
|
|
|
if (!qc.VerifyNull()) {
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%dqc verifynull failed.\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers());
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-invalid-null");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-07-15 22:28:58 +02:00
|
|
|
if (HasMinedCommitment(llmq_params.type, quorumHash)) {
|
2018-11-23 15:42:09 +01:00
|
|
|
// should not happen as it's already handled in ProcessBlock
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-dup");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-10-28 21:10:43 +02:00
|
|
|
if (!IsMiningPhase(llmq_params, nHeight)) {
|
2018-11-23 15:42:09 +01:00
|
|
|
// should not happen as it's already handled in ProcessBlock
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-height");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2023-08-23 19:11:26 +02:00
|
|
|
const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash);
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-03-30 03:13:33 +02:00
|
|
|
if (!qc.Verify(pQuorumBaseBlockIndex, fBLSChecks)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s qc verify failed.\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString());
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-invalid");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 04:01:26 +01:00
|
|
|
if (fJustCheck) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex);
|
2022-06-27 12:02:46 +02:00
|
|
|
|
|
|
|
if (rotation_enabled) {
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "[ProcessCommitment] height[%d] pQuorumBaseBlockIndex[%d] quorumIndex[%d] qversion[%d] Built\n",
|
|
|
|
nHeight, pQuorumBaseBlockIndex->nHeight, qc.quorumIndex, qc.nVersion);
|
|
|
|
}
|
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
// Store commitment in DB
|
2021-07-15 22:28:58 +02:00
|
|
|
auto cacheKey = std::make_pair(llmq_params.type, quorumHash);
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Write(std::make_pair(DB_MINED_COMMITMENT, cacheKey), std::make_pair(qc, blockHash));
|
2022-04-16 16:46:04 +02:00
|
|
|
|
2022-06-27 12:02:46 +02:00
|
|
|
if (rotation_enabled) {
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Write(BuildInversedHeightKeyIndexed(llmq_params.type, nHeight, int(qc.quorumIndex)), pQuorumBaseBlockIndex->nHeight);
|
2022-04-16 16:46:04 +02:00
|
|
|
} else {
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Write(BuildInversedHeightKey(llmq_params.type, nHeight), pQuorumBaseBlockIndex->nHeight);
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2019-02-26 07:20:47 +01:00
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
2021-01-25 10:22:28 +01:00
|
|
|
mapHasMinedCommitmentCache[qc.llmqType].erase(qc.quorumHash);
|
|
|
|
minableCommitmentsByQuorum.erase(cacheKey);
|
|
|
|
minableCommitments.erase(::SerializeHash(qc));
|
2019-02-26 07:20:47 +01:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- processed commitment from block. type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s\n", __func__,
|
2023-02-20 11:12:12 +01:00
|
|
|
ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString());
|
2018-11-23 15:42:09 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-10-22 16:14:30 +02:00
|
|
|
bool CQuorumBlockProcessor::UndoBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2023-07-10 17:13:42 +02:00
|
|
|
PreComputeQuorumMembers(pindex, true);
|
2022-08-13 18:10:32 +02:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
std::multimap<Consensus::LLMQType, CFinalCommitment> qcs;
|
2019-10-30 15:27:22 +01:00
|
|
|
BlockValidationState dummy;
|
2019-04-25 17:39:04 +02:00
|
|
|
if (!GetCommitmentsFromBlock(block, pindex, qcs, dummy)) {
|
2018-11-23 15:42:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& p : qcs) {
|
|
|
|
auto& qc = p.second;
|
|
|
|
if (qc.IsNull()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Erase(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)));
|
2022-04-16 16:46:04 +02:00
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
|
|
|
|
assert(llmq_params_opt.has_value());
|
|
|
|
|
|
|
|
if (llmq::utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pindex)) {
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Erase(BuildInversedHeightKeyIndexed(qc.llmqType, pindex->nHeight, int(qc.quorumIndex)));
|
2022-04-16 16:46:04 +02:00
|
|
|
} else {
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Erase(BuildInversedHeightKey(qc.llmqType, pindex->nHeight));
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
|
|
|
|
2019-02-26 07:20:47 +01:00
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
2021-01-25 10:22:28 +01:00
|
|
|
mapHasMinedCommitmentCache[qc.llmqType].erase(qc.quorumHash);
|
2019-02-26 07:20:47 +01:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2019-02-02 01:08:51 +01:00
|
|
|
// if a reorg happened, we should allow to mine this commitment later
|
2021-04-15 20:19:03 +02:00
|
|
|
AddMineableCommitment(qc);
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
m_evoDb.Write(DB_BEST_BLOCK_UPGRADE, pindex->pprev->GetBlockHash());
|
2019-04-04 17:58:51 +02:00
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-10-22 16:14:30 +02:00
|
|
|
bool CQuorumBlockProcessor::GetCommitmentsFromBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, std::multimap<Consensus::LLMQType, CFinalCommitment>& ret, BlockValidationState& state)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2021-08-06 23:55:51 +02:00
|
|
|
const auto& consensus = Params().GetConsensus();
|
2018-11-23 15:42:09 +01:00
|
|
|
|
|
|
|
ret.clear();
|
|
|
|
|
|
|
|
for (const auto& tx : block.vtx) {
|
|
|
|
if (tx->nType == TRANSACTION_QUORUM_COMMITMENT) {
|
2018-11-27 08:04:08 +01:00
|
|
|
CFinalCommitmentTxPayload qc;
|
2018-11-23 15:42:09 +01:00
|
|
|
if (!GetTxPayload(*tx, qc)) {
|
2018-11-27 08:04:08 +01:00
|
|
|
// should not happen as it was verified before processing the block
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d GetTxPayload fails\n", __func__, pindex->nHeight);
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-payload");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
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
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-commitment-type");
|
2023-03-13 17:11:17 +01:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
// only allow one commitment per type and per block (This was changed with rotation)
|
2023-03-13 17:11:17 +01:00
|
|
|
if (!utils::IsQuorumRotationEnabled(llmq_params_opt.value(), pindex)) {
|
2022-04-20 20:48:54 +02:00
|
|
|
if (ret.count(qc.commitment.llmqType) != 0) {
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-dup");
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-06-26 15:10:53 +02:00
|
|
|
ret.emplace(qc.commitment.llmqType, std::move(qc.commitment));
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
if (pindex->nHeight < consensus.DIP0003Height && !ret.empty()) {
|
2019-10-30 15:27:22 +01:00
|
|
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-premature");
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-20 20:48:54 +02:00
|
|
|
bool CQuorumBlockProcessor::IsMiningPhase(const Consensus::LLMQParams& llmqParams, int nHeight)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2022-04-16 16:46:04 +02:00
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
|
|
|
// Note: This function can be called for new blocks
|
|
|
|
assert(nHeight <= ::ChainActive().Height() + 1);
|
|
|
|
|
2022-06-27 12:02:46 +02:00
|
|
|
int quorumCycleStartHeight = nHeight - (nHeight % llmqParams.dkgInterval);
|
|
|
|
int quorumCycleMiningStartHeight = quorumCycleStartHeight + llmqParams.dkgMiningWindowStart;
|
|
|
|
int quorumCycleMiningEndHeight = quorumCycleStartHeight + llmqParams.dkgMiningWindowEnd;
|
2022-04-16 16:46:04 +02:00
|
|
|
|
2022-06-27 12:02:46 +02:00
|
|
|
if (nHeight >= quorumCycleMiningStartHeight && nHeight <= quorumCycleMiningEndHeight) {
|
2023-02-20 11:12:12 +01:00
|
|
|
LogPrint(BCLog::LLMQ, "[IsMiningPhase] nHeight[%d] llmqType[%d] quorumCycleStartHeight[%d] -- mining[%d-%d]\n", nHeight, ToUnderlying(llmqParams.type), quorumCycleStartHeight, quorumCycleMiningStartHeight, quorumCycleMiningEndHeight);
|
2022-06-27 12:02:46 +02:00
|
|
|
return true;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
2023-02-20 11:12:12 +01:00
|
|
|
LogPrint(BCLog::LLMQ, "[IsMiningPhase] nHeight[%d] llmqType[%d] quorumCycleStartHeight[%d] -- NOT mining[%d-%d]\n", nHeight, ToUnderlying(llmqParams.type), quorumCycleStartHeight, quorumCycleMiningStartHeight, quorumCycleMiningEndHeight);
|
2022-04-16 16:46:04 +02:00
|
|
|
|
2018-11-23 15:42:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
size_t CQuorumBlockProcessor::GetNumCommitmentsRequired(const Consensus::LLMQParams& llmqParams, int nHeight) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2021-09-08 00:33:02 +02:00
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
if (!IsMiningPhase(llmqParams, nHeight)) return 0;
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
// Note: This function can be called for new blocks
|
2023-08-23 19:11:26 +02:00
|
|
|
assert(nHeight <= m_chainstate.m_chain.Height() + 1);
|
|
|
|
const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight);
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
|
2022-06-27 12:02:46 +02:00
|
|
|
size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1;
|
2022-07-02 20:02:42 +02:00
|
|
|
size_t ret{0};
|
2022-06-27 12:02:46 +02:00
|
|
|
|
|
|
|
for (const auto quorumIndex : irange::range(quorums_num)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
uint256 quorumHash = GetQuorumBlockHash(llmqParams, nHeight, quorumIndex);
|
2022-07-02 20:02:42 +02:00
|
|
|
if (!quorumHash.IsNull() && !HasMinedCommitment(llmqParams.type, quorumHash)) ++ret;
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
return ret;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// WARNING: This method returns uint256() on the first block of the DKG interval (because the block hash is not known yet)
|
2022-04-16 16:46:04 +02:00
|
|
|
uint256 CQuorumBlockProcessor::GetQuorumBlockHash(const Consensus::LLMQParams& llmqParams, int nHeight, int quorumIndex)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2018-12-13 09:04:08 +01:00
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
int quorumStartHeight = nHeight - (nHeight % llmqParams.dkgInterval) + quorumIndex;
|
|
|
|
|
2018-12-13 09:04:08 +01:00
|
|
|
uint256 quorumBlockHash;
|
|
|
|
if (!GetBlockHash(quorumBlockHash, quorumStartHeight)) {
|
2023-02-20 11:12:12 +01:00
|
|
|
LogPrint(BCLog::LLMQ, "[GetQuorumBlockHash] llmqType[%d] h[%d] qi[%d] quorumStartHeight[%d] quorumHash[EMPTY]\n", ToUnderlying(llmqParams.type), nHeight, quorumIndex, quorumStartHeight);
|
2020-08-09 23:35:02 +02:00
|
|
|
return {};
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
2022-04-16 16:46:04 +02:00
|
|
|
|
2023-02-20 11:12:12 +01:00
|
|
|
LogPrint(BCLog::LLMQ, "[GetQuorumBlockHash] llmqType[%d] h[%d] qi[%d] quorumStartHeight[%d] quorumHash[%s]\n", ToUnderlying(llmqParams.type), nHeight, quorumIndex, quorumStartHeight, quorumBlockHash.ToString());
|
2018-12-13 09:04:08 +01:00
|
|
|
return quorumBlockHash;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 00:33:02 +02:00
|
|
|
bool CQuorumBlockProcessor::HasMinedCommitment(Consensus::LLMQType llmqType, const uint256& quorumHash) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2021-01-25 10:22:28 +01:00
|
|
|
bool fExists;
|
2019-02-26 07:20:47 +01:00
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
2021-01-25 10:22:28 +01:00
|
|
|
if (mapHasMinedCommitmentCache[llmqType].get(quorumHash, fExists)) {
|
|
|
|
return fExists;
|
2019-02-26 07:20:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
fExists = m_evoDb.Exists(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(llmqType, quorumHash)));
|
2019-02-26 07:20:47 +01:00
|
|
|
|
|
|
|
LOCK(minableCommitmentsCs);
|
2021-01-25 10:22:28 +01:00
|
|
|
mapHasMinedCommitmentCache[llmqType].insert(quorumHash, fExists);
|
|
|
|
|
|
|
|
return fExists;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 00:33:02 +02:00
|
|
|
CFinalCommitmentPtr CQuorumBlockProcessor::GetMinedCommitment(Consensus::LLMQType llmqType, const uint256& quorumHash, uint256& retMinedBlockHash) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
2019-05-28 15:34:41 +02:00
|
|
|
auto key = std::make_pair(DB_MINED_COMMITMENT, std::make_pair(llmqType, quorumHash));
|
2019-04-04 11:11:25 +02:00
|
|
|
std::pair<CFinalCommitment, uint256> p;
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
if (!m_evoDb.Read(key, p)) {
|
2021-04-16 05:41:16 +02:00
|
|
|
return nullptr;
|
2019-04-04 11:11:25 +02:00
|
|
|
}
|
|
|
|
retMinedBlockHash = p.second;
|
2021-11-29 06:12:09 +01:00
|
|
|
return std::make_unique<CFinalCommitment>(p.first);
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2019-06-18 13:34:16 +02:00
|
|
|
// The returned quorums are in reversed order, so the most recent one is at index 0
|
2023-10-22 16:14:30 +02:00
|
|
|
std::vector<const CBlockIndex*> CQuorumBlockProcessor::GetMinedCommitmentsUntilBlock(Consensus::LLMQType llmqType, gsl::not_null<const CBlockIndex*> pindex, size_t maxCount) const
|
2019-02-02 01:08:51 +01:00
|
|
|
{
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
AssertLockNotHeld(m_evoDb.cs);
|
|
|
|
LOCK(m_evoDb.cs);
|
2020-03-27 15:11:42 +01:00
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
auto dbIt = m_evoDb.GetCurTransaction().NewIteratorUniquePtr();
|
2019-04-04 10:18:31 +02:00
|
|
|
|
|
|
|
auto firstKey = BuildInversedHeightKey(llmqType, pindex->nHeight);
|
|
|
|
auto lastKey = BuildInversedHeightKey(llmqType, 0);
|
|
|
|
|
|
|
|
dbIt->Seek(firstKey);
|
|
|
|
|
|
|
|
std::vector<const CBlockIndex*> ret;
|
|
|
|
ret.reserve(maxCount);
|
|
|
|
|
|
|
|
while (dbIt->Valid() && ret.size() < maxCount) {
|
|
|
|
decltype(firstKey) curKey;
|
|
|
|
int quorumHeight;
|
|
|
|
if (!dbIt->GetKey(curKey) || curKey >= lastKey) {
|
|
|
|
break;
|
|
|
|
}
|
2019-05-28 15:34:41 +02:00
|
|
|
if (std::get<0>(curKey) != DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT || std::get<1>(curKey) != llmqType) {
|
2019-04-04 10:18:31 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-04-05 13:39:29 +02:00
|
|
|
uint32_t nMinedHeight = std::numeric_limits<uint32_t>::max() - be32toh(std::get<2>(curKey));
|
2023-02-11 03:25:11 +01:00
|
|
|
if (nMinedHeight > static_cast<uint32_t>(pindex->nHeight)) {
|
2019-04-04 10:18:31 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dbIt->GetValue(quorumHeight)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-04-20 20:48:54 +02:00
|
|
|
const auto* pQuorumBaseBlockIndex = pindex->GetAncestor(quorumHeight);
|
2021-10-26 18:08:38 +02:00
|
|
|
assert(pQuorumBaseBlockIndex);
|
|
|
|
ret.emplace_back(pQuorumBaseBlockIndex);
|
2019-04-04 10:18:31 +02:00
|
|
|
|
|
|
|
dbIt->Next();
|
2019-02-02 01:08:51 +01:00
|
|
|
}
|
2019-04-04 10:18:31 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
std::optional<const CBlockIndex*> CQuorumBlockProcessor::GetLastMinedCommitmentsByQuorumIndexUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, int quorumIndex, size_t cycle) const
|
|
|
|
{
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
AssertLockNotHeld(m_evoDb.cs);
|
|
|
|
LOCK(m_evoDb.cs);
|
2022-04-16 16:46:04 +02:00
|
|
|
|
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [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**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
|
|
|
auto dbIt = m_evoDb.GetCurTransaction().NewIteratorUniquePtr();
|
2022-04-16 16:46:04 +02:00
|
|
|
|
|
|
|
auto firstKey = BuildInversedHeightKeyIndexed(llmqType, pindex->nHeight, quorumIndex);
|
|
|
|
auto lastKey = BuildInversedHeightKeyIndexed(llmqType, 0, quorumIndex);
|
|
|
|
|
|
|
|
size_t currentCycle = 0;
|
|
|
|
|
|
|
|
dbIt->Seek(firstKey);
|
|
|
|
|
|
|
|
while (dbIt->Valid()) {
|
|
|
|
decltype(firstKey) curKey;
|
|
|
|
int quorumHeight;
|
|
|
|
if (!dbIt->GetKey(curKey) || curKey >= lastKey) {
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
if (std::get<0>(curKey) != DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED || std::get<1>(curKey) != llmqType) {
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t nMinedHeight = std::numeric_limits<uint32_t>::max() - be32toh(std::get<3>(curKey));
|
2023-02-11 03:25:11 +01:00
|
|
|
if (nMinedHeight > static_cast<uint32_t>(pindex->nHeight)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dbIt->GetValue(quorumHeight)) {
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
2022-04-20 20:48:54 +02:00
|
|
|
const auto* pQuorumBaseBlockIndex = pindex->GetAncestor(quorumHeight);
|
2022-04-16 16:46:04 +02:00
|
|
|
assert(pQuorumBaseBlockIndex);
|
|
|
|
|
2022-04-20 20:48:54 +02:00
|
|
|
if (currentCycle == cycle) {
|
2022-04-16 16:46:04 +02:00
|
|
|
return std::make_optional(pQuorumBaseBlockIndex);
|
2022-04-20 20:48:54 +02:00
|
|
|
}
|
2022-04-16 16:46:04 +02:00
|
|
|
|
|
|
|
currentCycle++;
|
|
|
|
|
|
|
|
dbIt->Next();
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::pair<int, const CBlockIndex*>> CQuorumBlockProcessor::GetLastMinedCommitmentsPerQuorumIndexUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, size_t cycle) const
|
|
|
|
{
|
2023-03-13 17:11:17 +01:00
|
|
|
const auto& llmq_params_opt = GetLLMQParams(llmqType);
|
|
|
|
assert(llmq_params_opt.has_value());
|
2022-04-16 16:46:04 +02:00
|
|
|
std::vector<std::pair<int, const CBlockIndex*>> ret;
|
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
for (const auto quorumIndex : irange::range(llmq_params_opt->signingActiveQuorumCount)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
std::optional<const CBlockIndex*> q = GetLastMinedCommitmentsByQuorumIndexUntilBlock(llmqType, pindex, quorumIndex, cycle);
|
|
|
|
if (q.has_value()) {
|
2022-04-20 20:48:54 +02:00
|
|
|
ret.emplace_back(quorumIndex, q.value());
|
2022-04-16 16:46:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<const CBlockIndex*> CQuorumBlockProcessor::GetMinedCommitmentsIndexedUntilBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, size_t maxCount) const
|
|
|
|
{
|
|
|
|
std::vector<const CBlockIndex*> ret;
|
|
|
|
|
|
|
|
size_t cycle = 0;
|
|
|
|
|
|
|
|
while (ret.size() < maxCount) {
|
|
|
|
std::vector<std::pair<int, const CBlockIndex*>> cycleRet = GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, pindex, cycle);
|
|
|
|
|
2022-04-20 20:48:54 +02:00
|
|
|
if (cycleRet.empty()) {
|
2022-04-16 16:46:04 +02:00
|
|
|
return ret;
|
2022-04-20 20:48:54 +02:00
|
|
|
}
|
2022-04-16 16:46:04 +02:00
|
|
|
|
|
|
|
std::vector<const CBlockIndex*> cycleRetTransformed;
|
|
|
|
std::transform(cycleRet.begin(),
|
|
|
|
cycleRet.end(),
|
|
|
|
std::back_inserter(cycleRetTransformed),
|
|
|
|
[](const std::pair<int, const CBlockIndex*>& p) { return p.second; });
|
|
|
|
|
|
|
|
size_t needToCopy = maxCount - ret.size();
|
|
|
|
|
|
|
|
std::copy_n(cycleRetTransformed.begin(),
|
|
|
|
std::min(needToCopy, cycleRetTransformed.size()),
|
|
|
|
std::back_inserter(ret));
|
|
|
|
cycle++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-06-18 13:34:16 +02:00
|
|
|
// The returned quorums are in reversed order, so the most recent one is at index 0
|
2023-10-22 16:14:30 +02:00
|
|
|
std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> CQuorumBlockProcessor::GetMinedAndActiveCommitmentsUntilBlock(gsl::not_null<const CBlockIndex*> pindex) const
|
2019-04-04 10:18:31 +02:00
|
|
|
{
|
|
|
|
std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> ret;
|
|
|
|
|
2022-01-10 19:36:18 +01:00
|
|
|
for (const auto& params : Params().GetConsensus().llmqs) {
|
|
|
|
auto& v = ret[params.type];
|
|
|
|
v.reserve(params.signingActiveQuorumCount);
|
2023-03-13 17:11:17 +01:00
|
|
|
if (utils::IsQuorumRotationEnabled(params, pindex)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
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; });
|
|
|
|
} else {
|
|
|
|
auto commitments = GetMinedCommitmentsUntilBlock(params.type, pindex, params.signingActiveQuorumCount);
|
|
|
|
std::copy(commitments.begin(), commitments.end(), std::back_inserter(v));
|
|
|
|
}
|
2019-04-04 10:18:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2019-02-02 01:08:51 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 00:33:02 +02:00
|
|
|
bool CQuorumBlockProcessor::HasMineableCommitment(const uint256& hash) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
|
|
|
return minableCommitments.count(hash) != 0;
|
|
|
|
}
|
|
|
|
|
2021-04-15 20:19:03 +02:00
|
|
|
void CQuorumBlockProcessor::AddMineableCommitment(const CFinalCommitment& fqc)
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
bool relay = false;
|
|
|
|
uint256 commitmentHash = ::SerializeHash(fqc);
|
|
|
|
|
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
|
|
|
|
2021-06-26 15:10:53 +02:00
|
|
|
auto k = std::make_pair(fqc.llmqType, fqc.quorumHash);
|
2018-11-23 15:42:09 +01:00
|
|
|
auto ins = minableCommitmentsByQuorum.emplace(k, commitmentHash);
|
|
|
|
if (ins.second) {
|
|
|
|
minableCommitments.emplace(commitmentHash, fqc);
|
|
|
|
relay = true;
|
|
|
|
} else {
|
2021-06-26 15:10:53 +02:00
|
|
|
const auto& oldFqc = minableCommitments.at(ins.first->second);
|
2018-11-23 15:42:09 +01:00
|
|
|
if (fqc.CountSigners() > oldFqc.CountSigners()) {
|
|
|
|
// new commitment has more signers, so override the known one
|
|
|
|
ins.first->second = commitmentHash;
|
|
|
|
minableCommitments.erase(ins.first->second);
|
|
|
|
minableCommitments.emplace(commitmentHash, fqc);
|
|
|
|
relay = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We only relay the new commitment if it's new or better then the old one
|
|
|
|
if (relay) {
|
|
|
|
CInv inv(MSG_QUORUM_FINAL_COMMITMENT, commitmentHash);
|
2022-01-09 12:38:21 +01:00
|
|
|
connman.RelayInv(inv);
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-08 00:33:02 +02:00
|
|
|
bool CQuorumBlockProcessor::GetMineableCommitmentByHash(const uint256& commitmentHash, llmq::CFinalCommitment& ret) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
LOCK(minableCommitmentsCs);
|
|
|
|
auto it = minableCommitments.find(commitmentHash);
|
|
|
|
if (it == minableCommitments.end()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
ret = it->second;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
// Will return nullopt if no commitment should be mined
|
|
|
|
// Will return a null commitment if no mineable commitment is known and none was mined yet
|
|
|
|
std::optional<std::vector<CFinalCommitment>> CQuorumBlockProcessor::GetMineableCommitments(const Consensus::LLMQParams& llmqParams, int nHeight) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
std::vector<CFinalCommitment> ret;
|
|
|
|
|
2022-07-02 20:02:42 +02:00
|
|
|
if (GetNumCommitmentsRequired(llmqParams, nHeight) == 0) {
|
2018-11-23 15:42:09 +01:00
|
|
|
// no commitment required
|
2022-04-16 16:46:04 +02:00
|
|
|
return std::nullopt;
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
// Note: This function can be called for new blocks
|
2023-08-23 19:11:26 +02:00
|
|
|
assert(nHeight <= m_chainstate.m_chain.Height() + 1);
|
|
|
|
const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight);
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2023-03-13 17:11:17 +01:00
|
|
|
bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
|
2022-12-30 06:45:31 +01:00
|
|
|
bool basic_bls_enabled = utils::IsV19Active(pindex);
|
2022-06-27 12:02:46 +02:00
|
|
|
size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1;
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
std::stringstream ss;
|
2022-06-27 12:02:46 +02:00
|
|
|
for (const auto quorumIndex : irange::range(quorums_num)) {
|
2022-04-16 16:46:04 +02:00
|
|
|
CFinalCommitment cf;
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
uint256 quorumHash = GetQuorumBlockHash(llmqParams, nHeight, quorumIndex);
|
|
|
|
if (quorumHash.IsNull()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-07-14 23:12:33 +02:00
|
|
|
if (HasMinedCommitment(llmqParams.type, quorumHash)) continue;
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
LOCK(minableCommitmentsCs);
|
|
|
|
|
|
|
|
auto k = std::make_pair(llmqParams.type, quorumHash);
|
|
|
|
auto it = minableCommitmentsByQuorum.find(k);
|
|
|
|
if (it == minableCommitmentsByQuorum.end()) {
|
|
|
|
// null commitment required
|
|
|
|
cf = CFinalCommitment(llmqParams, quorumHash);
|
|
|
|
cf.quorumIndex = static_cast<int16_t>(quorumIndex);
|
2022-12-30 06:45:31 +01:00
|
|
|
cf.nVersion = CFinalCommitment::GetVersion(rotation_enabled, basic_bls_enabled);
|
2022-04-16 16:46:04 +02:00
|
|
|
ss << "{ created nversion[" << cf.nVersion << "] quorumIndex[" << cf.quorumIndex << "] }";
|
|
|
|
} else {
|
|
|
|
cf = minableCommitments.at(it->second);
|
|
|
|
ss << "{ cached nversion[" << cf.nVersion << "] quorumIndex[" << cf.quorumIndex << "] }";
|
|
|
|
}
|
|
|
|
|
|
|
|
ret.push_back(std::move(cf));
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
LogPrint(BCLog::LLMQ, "GetMineableCommitments cf height[%d] content: %s\n", nHeight, ss.str());
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
if (ret.empty()) {
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
2022-04-20 20:48:54 +02:00
|
|
|
return std::make_optional(ret);
|
2018-11-23 15:42:09 +01:00
|
|
|
}
|
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
bool CQuorumBlockProcessor::GetMineableCommitmentsTx(const Consensus::LLMQParams& llmqParams, int nHeight, std::vector<CTransactionRef>& ret) const
|
2018-11-23 15:42:09 +01:00
|
|
|
{
|
|
|
|
AssertLockHeld(cs_main);
|
2022-04-16 16:46:04 +02:00
|
|
|
std::optional<std::vector<CFinalCommitment>> qcs = GetMineableCommitments(llmqParams, nHeight);
|
2022-04-20 20:48:54 +02:00
|
|
|
if (!qcs.has_value()) {
|
2018-11-23 15:42:09 +01:00
|
|
|
return false;
|
2022-04-20 20:48:54 +02:00
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
2022-04-16 16:46:04 +02:00
|
|
|
for (const auto& f : qcs.value()) {
|
|
|
|
CFinalCommitmentTxPayload qc;
|
|
|
|
qc.nHeight = nHeight;
|
|
|
|
qc.commitment = f;
|
|
|
|
CMutableTransaction tx;
|
|
|
|
tx.nVersion = 3;
|
|
|
|
tx.nType = TRANSACTION_QUORUM_COMMITMENT;
|
|
|
|
SetTxPayload(tx, qc);
|
|
|
|
ret.push_back(MakeTransactionRef(tx));
|
|
|
|
}
|
2018-11-23 15:42:09 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-15 20:55:01 +02:00
|
|
|
} // namespace llmq
|