mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 11:32:46 +01:00
Merge pull request #5253 from UdjinM6/bp_18.2.2
[v18.2.x] backport: backports and version bump to 18.2.2
This commit is contained in:
commit
1f3f0e00f4
@ -1,7 +1,7 @@
|
||||
AC_PREREQ([2.69])
|
||||
define(_CLIENT_VERSION_MAJOR, 18)
|
||||
define(_CLIENT_VERSION_MINOR, 2)
|
||||
define(_CLIENT_VERSION_BUILD, 1)
|
||||
define(_CLIENT_VERSION_BUILD, 2)
|
||||
define(_CLIENT_VERSION_RC, 0)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||
define(_COPYRIGHT_YEAR, 2023)
|
||||
|
@ -1,17 +1,15 @@
|
||||
Dash Core version v18.2.1
|
||||
Dash Core version v18.2.2
|
||||
=========================
|
||||
|
||||
Release is now available from:
|
||||
|
||||
<https://www.dash.org/downloads/#wallets>
|
||||
|
||||
This is a new hotfix version release, bringing various bugfixes.
|
||||
This is a new hotfix version release.
|
||||
|
||||
Please note that v18.2.0 was revoked due to a bug; this version fixes that bug.
|
||||
|
||||
This release is optional for all nodes; however, v18.2.1 is required to be
|
||||
able to use both mainnet and testnet. Currently, v18.2.0 is not working on mainnet,
|
||||
and v18.1.1 is not working on testnet; v18.2.1 will work on both networks.
|
||||
This release is optional for all nodes; however, v18.2.2 or higher is required
|
||||
to be able to use testnet right until v19 hard fork activation. Earlier
|
||||
versions will not be able to sync past block 847000 on testnet.
|
||||
|
||||
Please report bugs using the issue tracker at GitHub:
|
||||
|
||||
@ -41,9 +39,9 @@ downgrade to an older version is only possible with a reindex
|
||||
Downgrade warning
|
||||
-----------------
|
||||
|
||||
### Downgrade to a version < v18.2.1
|
||||
### Downgrade to a version < v18.2.2
|
||||
|
||||
Downgrading to a version older than v18.2.1 is supported.
|
||||
Downgrading to a version older than v18.2.2 is supported.
|
||||
|
||||
### Downgrade to a version < v18.0.1
|
||||
|
||||
@ -51,35 +49,19 @@ Downgrading to a version older than v18.0.1 is not supported due to changes in
|
||||
the indexes database folder. If you need to use an older version, you must
|
||||
either reindex or re-sync the whole chain.
|
||||
|
||||
### Downgrade of masternodes to < 18.2.1
|
||||
|
||||
It is highly recommended not to downgrade masternodes below 18.2.1, as 18.2.1 (and 18.1.1)
|
||||
fix important bugs which may result in your masternode being PoSe banned.
|
||||
|
||||
### Downgrade of masternodes to < v18.0.1
|
||||
|
||||
Starting with the 0.16 release, masternodes verify the protocol version of other
|
||||
masternodes. This results in PoSe punishment/banning for outdated masternodes,
|
||||
so downgrading even prior to the activation of the introduced hard-fork changes
|
||||
is not recommended.
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Dash Core imperfectly follows semantic versioning. Breaking changes should be
|
||||
expected in a major release. The number and severity of breaking changes in minor
|
||||
releases are minimized, however we do not guarantee there are no breaking changes.
|
||||
Bitcoin backports often introduce breaking changes, and are a likely source of
|
||||
breaking changes in minor releases. Patch releases should never contain breaking changes.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
See #5145 and #5142; these 2 PR fix important bugs in previous versions. Specifically,
|
||||
#5145 fixes an issue where qfcommit messages can be replayed from the past, then are
|
||||
validated and propagated to other nodes. This patch prevents old qfcommits
|
||||
from being relayed. #5142 is a fix which enables this version to function both on testnet
|
||||
and mainnet.
|
||||
|
||||
Testnet Breaking Changes
|
||||
------------------------
|
||||
|
||||
A new testnet only LLMQ has been added. This LLMQ is of the type LLMQ_25_67; this LLMQ is only active on testnet.
|
||||
This LLMQ will not remove the LLMQ_100_67 from testnet; however that quorum (likely) will not form and will perform no role.
|
||||
See the [diff](https://github.com/dashpay/dash/pull/5225/files#diff-e70a38a3e8c2a63ca0494627301a5c7042141ad301193f78338d97cb1b300ff9R451-R469) for specific parameters of the LLMQ.
|
||||
|
||||
This LLMQ will become active at the height of 847000. **This will be a breaking change and a hard fork for testnet**
|
||||
This LLMQ is not activated with the v19 hardfork; as such testnet will experience two hardforks. One at height 847000,
|
||||
and the other to be determined by the BIP9 hard fork process.
|
||||
|
||||
Remote Procedure Call (RPC) Changes
|
||||
-----------------------------------
|
||||
@ -109,20 +91,21 @@ Backports from Bitcoin Core
|
||||
---------------------------
|
||||
None
|
||||
|
||||
v18.2.1 Change log
|
||||
Other changes
|
||||
-------------
|
||||
#5247 is backported to improve debugging experience.
|
||||
|
||||
v18.2.2 Change log
|
||||
==================
|
||||
|
||||
See detailed [set of changes](https://github.com/dashpay/dash/compare/v18.2.0...dashpay:v18.2.1).
|
||||
See detailed [set of changes](https://github.com/dashpay/dash/compare/v18.2.1...dashpay:v18.2.2).
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
- Kittywhiskers Van Gogh
|
||||
- Konstantin Akimov
|
||||
- Odysseas Gabrielides
|
||||
- PastaPastaPasta
|
||||
- UdjinM6
|
||||
|
||||
As well as everyone that submitted issues, reviewed pull requests, helped debug the release candidates, and write DIPs that were implemented in this release.
|
||||
@ -150,6 +133,7 @@ Dash Core tree 0.12.1.x was a fork of Bitcoin Core tree 0.12.
|
||||
|
||||
These release are considered obsolete. Old release notes can be found here:
|
||||
|
||||
- [v18.2.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.2.2.md) released Jan/17/2023
|
||||
- [v18.2.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.2.0.md) released Jan/01/2023
|
||||
- [v18.1.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.1.1.md) released January/08/2023
|
||||
- [v18.1.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.1.0.md) released October/09/2022
|
||||
|
187
doc/release-notes/dash/release-notes-18.2.1.md
Normal file
187
doc/release-notes/dash/release-notes-18.2.1.md
Normal file
@ -0,0 +1,187 @@
|
||||
Dash Core version v18.2.1
|
||||
=========================
|
||||
|
||||
Release is now available from:
|
||||
|
||||
<https://www.dash.org/downloads/#wallets>
|
||||
|
||||
This is a new hotfix version release, bringing various bugfixes.
|
||||
|
||||
Please note that v18.2.0 was revoked due to a bug; this version fixes that bug.
|
||||
|
||||
This release is optional for all nodes; however, v18.2.1 is required to be
|
||||
able to use both mainnet and testnet. Currently, v18.2.0 is not working on mainnet,
|
||||
and v18.1.1 is not working on testnet; v18.2.1 will work on both networks.
|
||||
|
||||
Please report bugs using the issue tracker at GitHub:
|
||||
|
||||
<https://github.com/dashpay/dash/issues>
|
||||
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Dash-Qt (on Mac) or
|
||||
dashd/dash-qt (on Linux). If you upgrade after DIP0003 activation and you were
|
||||
using version < 0.13 you will have to reindex (start with -reindex-chainstate
|
||||
or -reindex) to make sure your wallet has all the new data synced. Upgrading
|
||||
from version 0.13 should not require any additional actions.
|
||||
|
||||
When upgrading from a version prior to 18.0.1, the
|
||||
first startup of Dash Core will run a migration process which can take anywhere
|
||||
from a few minutes to thirty minutes to finish. After the migration, a
|
||||
downgrade to an older version is only possible with a reindex
|
||||
(or reindex-chainstate).
|
||||
|
||||
Downgrade warning
|
||||
-----------------
|
||||
|
||||
### Downgrade to a version < v18.2.1
|
||||
|
||||
Downgrading to a version older than v18.2.1 is supported.
|
||||
|
||||
### Downgrade to a version < v18.0.1
|
||||
|
||||
Downgrading to a version older than v18.0.1 is not supported due to changes in
|
||||
the indexes database folder. If you need to use an older version, you must
|
||||
either reindex or re-sync the whole chain.
|
||||
|
||||
### Downgrade of masternodes to < 18.2.1
|
||||
|
||||
It is highly recommended not to downgrade masternodes below 18.2.1, as 18.2.1 (and 18.1.1)
|
||||
fix important bugs which may result in your masternode being PoSe banned.
|
||||
|
||||
### Downgrade of masternodes to < v18.0.1
|
||||
|
||||
Starting with the 0.16 release, masternodes verify the protocol version of other
|
||||
masternodes. This results in PoSe punishment/banning for outdated masternodes,
|
||||
so downgrading even prior to the activation of the introduced hard-fork changes
|
||||
is not recommended.
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Dash Core imperfectly follows semantic versioning. Breaking changes should be
|
||||
expected in a major release. The number and severity of breaking changes in minor
|
||||
releases are minimized, however we do not guarantee there are no breaking changes.
|
||||
Bitcoin backports often introduce breaking changes, and are a likely source of
|
||||
breaking changes in minor releases. Patch releases should never contain breaking changes.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
See #5145 and #5142; these 2 PR fix important bugs in previous versions. Specifically,
|
||||
#5145 fixes an issue where qfcommit messages can be replayed from the past, then are
|
||||
validated and propagated to other nodes. This patch prevents old qfcommits
|
||||
from being relayed. #5142 is a fix which enables this version to function both on testnet
|
||||
and mainnet.
|
||||
|
||||
|
||||
Remote Procedure Call (RPC) Changes
|
||||
-----------------------------------
|
||||
|
||||
### The new RPCs are:
|
||||
None
|
||||
|
||||
### The removed RPCs are:
|
||||
None
|
||||
|
||||
### Changes in existing RPCs introduced through bitcoin backports:
|
||||
None
|
||||
|
||||
### Dash-specific changes in existing RPCs:
|
||||
None
|
||||
|
||||
Please check `help <command>` for more detailed information on specific RPCs.
|
||||
|
||||
Command-line options
|
||||
--------------------
|
||||
None
|
||||
|
||||
Please check `Help -> Command-line options` in Qt wallet or `dashd --help` for
|
||||
more information.
|
||||
|
||||
Backports from Bitcoin Core
|
||||
---------------------------
|
||||
None
|
||||
|
||||
v18.2.1 Change log
|
||||
==================
|
||||
|
||||
See detailed [set of changes](https://github.com/dashpay/dash/compare/v18.2.0...dashpay:v18.2.1).
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
- Kittywhiskers Van Gogh
|
||||
- Konstantin Akimov
|
||||
- Odysseas Gabrielides
|
||||
- PastaPastaPasta
|
||||
- UdjinM6
|
||||
|
||||
As well as everyone that submitted issues, reviewed pull requests, helped debug the release candidates, and write DIPs that were implemented in this release.
|
||||
|
||||
Older releases
|
||||
==============
|
||||
|
||||
Dash was previously known as Darkcoin.
|
||||
|
||||
Darkcoin tree 0.8.x was a fork of Litecoin tree 0.8, original name was XCoin
|
||||
which was first released on Jan/18/2014.
|
||||
|
||||
Darkcoin tree 0.9.x was the open source implementation of masternodes based on
|
||||
the 0.8.x tree and was first released on Mar/13/2014.
|
||||
|
||||
Darkcoin tree 0.10.x used to be the closed source implementation of Darksend
|
||||
which was released open source on Sep/25/2014.
|
||||
|
||||
Dash Core tree 0.11.x was a fork of Bitcoin Core tree 0.9,
|
||||
Darkcoin was rebranded to Dash.
|
||||
|
||||
Dash Core tree 0.12.0.x was a fork of Bitcoin Core tree 0.10.
|
||||
|
||||
Dash Core tree 0.12.1.x was a fork of Bitcoin Core tree 0.12.
|
||||
|
||||
These release are considered obsolete. Old release notes can be found here:
|
||||
|
||||
- [v18.2.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.2.0.md) released Jan/01/2023
|
||||
- [v18.1.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.1.1.md) released January/08/2023
|
||||
- [v18.1.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.1.0.md) released October/09/2022
|
||||
- [v18.0.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.0.2.md) released October/09/2022
|
||||
- [v18.0.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-18.0.1.md) released August/17/2022
|
||||
- [v0.17.0.3](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.17.0.3.md) released June/07/2021
|
||||
- [v0.17.0.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.17.0.2.md) released May/19/2021
|
||||
- [v0.16.1.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.16.1.1.md) released November/17/2020
|
||||
- [v0.16.1.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.16.1.0.md) released November/14/2020
|
||||
- [v0.16.0.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.16.0.1.md) released September/30/2020
|
||||
- [v0.15.0.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.15.0.0.md) released Febrary/18/2020
|
||||
- [v0.14.0.5](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.5.md) released December/08/2019
|
||||
- [v0.14.0.4](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.4.md) released November/22/2019
|
||||
- [v0.14.0.3](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.3.md) released August/15/2019
|
||||
- [v0.14.0.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.2.md) released July/4/2019
|
||||
- [v0.14.0.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.1.md) released May/31/2019
|
||||
- [v0.14.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.14.0.md) released May/22/2019
|
||||
- [v0.13.3](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.13.3.md) released Apr/04/2019
|
||||
- [v0.13.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.13.2.md) released Mar/15/2019
|
||||
- [v0.13.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.13.1.md) released Feb/9/2019
|
||||
- [v0.13.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.13.0.md) released Jan/14/2019
|
||||
- [v0.12.3.4](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.3.4.md) released Dec/14/2018
|
||||
- [v0.12.3.3](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.3.3.md) released Sep/19/2018
|
||||
- [v0.12.3.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.3.2.md) released Jul/09/2018
|
||||
- [v0.12.3.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.3.1.md) released Jul/03/2018
|
||||
- [v0.12.2.3](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.2.3.md) released Jan/12/2018
|
||||
- [v0.12.2.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.2.2.md) released Dec/17/2017
|
||||
- [v0.12.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.2.md) released Nov/08/2017
|
||||
- [v0.12.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.1.md) released Feb/06/2017
|
||||
- [v0.12.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.12.0.md) released Aug/15/2015
|
||||
- [v0.11.2](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.11.2.md) released Mar/04/2015
|
||||
- [v0.11.1](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.11.1.md) released Feb/10/2015
|
||||
- [v0.11.0](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.11.0.md) released Jan/15/2015
|
||||
- [v0.10.x](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.10.0.md) released Sep/25/2014
|
||||
- [v0.9.x](https://github.com/dashpay/dash/blob/master/doc/release-notes/dash/release-notes-0.9.0.md) released Mar/13/2014
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -523,10 +512,11 @@ public:
|
||||
AddLLMQ(Consensus::LLMQType::LLMQ_400_60);
|
||||
AddLLMQ(Consensus::LLMQType::LLMQ_400_85);
|
||||
AddLLMQ(Consensus::LLMQType::LLMQ_100_67);
|
||||
AddLLMQ(Consensus::LLMQType::LLMQ_25_67);
|
||||
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60;
|
||||
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
||||
consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75;
|
||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_25_67;
|
||||
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60;
|
||||
|
||||
fDefaultConsistencyChecks = false;
|
||||
@ -1230,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) {
|
||||
@ -1252,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) {
|
||||
@ -1274,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>,
|
||||
|
@ -19,6 +19,7 @@ enum class LLMQType : uint8_t {
|
||||
LLMQ_400_85 = 3, // 400 members, 340 (85%) threshold, one every 24 hours
|
||||
LLMQ_100_67 = 4, // 100 members, 67 (67%) threshold, one per hour
|
||||
LLMQ_60_75 = 5, // 60 members, 45 (75%) threshold, one every 12 hours
|
||||
LLMQ_25_67 = 6, // 25 members, 67 (67%) threshold, one per hour
|
||||
|
||||
// for testing only
|
||||
LLMQ_TEST = 100, // 3 members, 2 (66%) threshold, one per hour. Params might differ when -llmqtestparams is used
|
||||
@ -105,8 +106,13 @@ 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, 11> available_llmqs = {
|
||||
|
||||
static constexpr std::array<LLMQParams, 12> available_llmqs = {
|
||||
|
||||
/**
|
||||
* llmq_test
|
||||
@ -388,6 +394,33 @@ static constexpr std::array<LLMQParams, 11> available_llmqs = {
|
||||
.recoveryMembers = 50,
|
||||
},
|
||||
|
||||
/**
|
||||
* llmq_25_67
|
||||
* This quorum is deployed on Testnet and requires
|
||||
* 25 participants
|
||||
*
|
||||
* Used by Dash Platform
|
||||
*/
|
||||
LLMQParams{
|
||||
.type = LLMQType::LLMQ_25_67,
|
||||
.name = "llmq_25_67",
|
||||
.useRotation = false,
|
||||
.size = 25,
|
||||
.minSize = 22,
|
||||
.threshold = 17,
|
||||
|
||||
.dkgInterval = 24, // one DKG per hour
|
||||
.dkgPhaseBlocks = 2,
|
||||
.dkgMiningWindowStart = 10, // dkgPhaseBlocks * 5 = after finalization
|
||||
.dkgMiningWindowEnd = 18,
|
||||
.dkgBadVotesThreshold = 22,
|
||||
|
||||
.signingActiveQuorumCount = 24, // a full day worth of LLMQs
|
||||
|
||||
.keepOldConnections = 25,
|
||||
.recoveryMembers = 12,
|
||||
},
|
||||
|
||||
}; // available_llmqs
|
||||
|
||||
} // namespace Consensus
|
||||
|
@ -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);
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <optional>
|
||||
|
||||
static constexpr int TESTNET_LLMQ_25_67_ACTIVATION_HEIGHT = 847000;
|
||||
|
||||
namespace llmq
|
||||
{
|
||||
|
||||
@ -36,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);
|
||||
}
|
||||
}
|
||||
@ -64,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);
|
||||
}
|
||||
@ -77,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;
|
||||
@ -98,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]);
|
||||
@ -118,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);
|
||||
|
||||
@ -134,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);
|
||||
|
||||
@ -591,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;
|
||||
}
|
||||
@ -863,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; });
|
||||
}
|
||||
|
||||
@ -915,6 +922,11 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumMana
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Consensus::LLMQType::LLMQ_25_67:
|
||||
if (pindex->nHeight < TESTNET_LLMQ_25_67_ACTIVATION_HEIGHT) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(strprintf("%s: Unknown LLMQ type %d", __func__, static_cast<uint8_t>(llmqType)));
|
||||
}
|
||||
@ -1018,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