Skip to content

Commit

Permalink
Merge pull request #5250 from PastaPastaPasta/v19/bump-rc.6
Browse files Browse the repository at this point in the history
[v19.x] backport: backports and rc.6 bump
  • Loading branch information
PastaPastaPasta committed Mar 13, 2023
2 parents 4f97133 + cdb9d68 commit c4cf446
Show file tree
Hide file tree
Showing 37 changed files with 515 additions and 191 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 19)
define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 5)
define(_CLIENT_VERSION_RC, 6)
define(_CLIENT_VERSION_IS_RELEASE, false)
define(_COPYRIGHT_YEAR, 2023)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
9 changes: 7 additions & 2 deletions src/bls/bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,19 +288,24 @@ void CBLSSignature::SubInsecure(const CBLSSignature& o)
cachedHash.SetNull();
}

bool CBLSSignature::VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash) const
bool CBLSSignature::VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash, const bool specificLegacyScheme) const
{
if (!IsValid() || !pubKey.IsValid()) {
return false;
}

try {
return Scheme(bls::bls_legacy_scheme.load())->Verify(pubKey.impl, bls::Bytes(hash.begin(), hash.size()), impl);
return Scheme(specificLegacyScheme)->Verify(pubKey.impl, bls::Bytes(hash.begin(), hash.size()), impl);
} catch (...) {
return false;
}
}

bool CBLSSignature::VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash) const
{
return VerifyInsecure(pubKey, hash, bls::bls_legacy_scheme.load());
}

bool CBLSSignature::VerifyInsecureAggregated(const std::vector<CBLSPublicKey>& pubKeys, const std::vector<uint256>& hashes) const
{
if (!IsValid()) {
Expand Down
14 changes: 12 additions & 2 deletions src/bls/bls.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,17 @@ class CBLSWrapper
SetByteVector(vecBytes, specificLegacyScheme);

if (checkMalleable && !CheckMalleable(vecBytes, specificLegacyScheme)) {
throw std::ios_base::failure("malleable BLS object");
// If CheckMalleable failed with specificLegacyScheme, we need to try again with the opposite scheme.
// Probably we received the BLS object sent with legacy scheme, but in the meanwhile the fork activated.
SetByteVector(vecBytes, !specificLegacyScheme);
if (!CheckMalleable(vecBytes, !specificLegacyScheme)) {
// Both attempts failed
throw std::ios_base::failure("malleable BLS object");
} else {
// Indeed the received vecBytes was in opposite scheme. But we can't keep it (mixing with the new scheme will lead to undefined behavior)
// Therefore, resetting current object (basically marking it as invalid).
Reset();
}
}
}

Expand Down Expand Up @@ -358,7 +368,7 @@ class CBLSSignature : public CBLSWrapper<bls::G2Element, BLS_CURVE_SIG_SIZE, CBL
static CBLSSignature AggregateSecure(const std::vector<CBLSSignature>& sigs, const std::vector<CBLSPublicKey>& pks, const uint256& hash);

void SubInsecure(const CBLSSignature& o);

[[nodiscard]] bool VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash, const bool specificLegacyScheme) const;
[[nodiscard]] bool VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash) const;
[[nodiscard]] bool VerifyInsecureAggregated(const std::vector<CBLSPublicKey>& pubKeys, const std::vector<uint256>& hashes) const;

Expand Down
41 changes: 21 additions & 20 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,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);
Expand All @@ -118,25 +118,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;
}

/**
Expand Down Expand Up @@ -486,7 +475,7 @@ class CTestNetParams : public CChainParams {

// Deployment of Deployment of Basic BLS, AssetLocks, EHF
consensus.vDeployments[Consensus::DEPLOYMENT_V19].bit = 8;
consensus.vDeployments[Consensus::DEPLOYMENT_V19].nStartTime = 1678060800; // Tue, March 06, 2023 0:00:00
consensus.vDeployments[Consensus::DEPLOYMENT_V19].nStartTime = 1678838400; // Wed, March 15, 2023 0:00:00
consensus.vDeployments[Consensus::DEPLOYMENT_V19].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_V19].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_V19].nThresholdStart = 80; // 80% of 100
Expand Down Expand Up @@ -1279,7 +1268,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) {
Expand All @@ -1301,7 +1293,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) {
Expand All @@ -1323,7 +1318,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) {
Expand All @@ -1345,7 +1343,10 @@ void CDevNetParams::UpdateDevnetLLMQPlatformFromArgs(const ArgsManager& args)
{
if (!args.IsArgSet("-llmqplatform")) return;

std::string strLLMQType = gArgs.GetArg("-llmqplatform", std::string(GetLLMQ(consensus.llmqTypePlatform).name));
const auto& llmq_params_opt = GetLLMQ(consensus.llmqTypePlatform);
assert(llmq_params_opt.has_value());

std::string strLLMQType = gArgs.GetArg("-llmqplatform", std::string(llmq_params_opt->name));

Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE;
for (const auto& params : consensus.llmqs) {
Expand Down
3 changes: 1 addition & 2 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ class CChainParams
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() {}
Expand Down
17 changes: 12 additions & 5 deletions src/evo/cbtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,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];
Expand Down Expand Up @@ -253,12 +255,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
Expand All @@ -282,8 +288,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
Expand Down
61 changes: 57 additions & 4 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void CDeterministicMN::ToJson(UniValue& obj) const
obj.setObject();

UniValue stateObj;
pdmnState->ToJson(stateObj);
pdmnState->ToJson(stateObj, nType);

obj.pushKV("type", std::string(GetMnType(nType).description));
obj.pushKV("proTxHash", proTxHash.ToString());
Expand Down Expand Up @@ -435,6 +435,48 @@ CDeterministicMNList CDeterministicMNList::ApplyDiff(const CBlockIndex* pindex,
return result;
}

// RepopulateUniquePropertyMap clears internal mnUniquePropertyMap, and repopulate it with currently MNs unique properties.
// This is needed when the v19 fork activates, we need to store again pubKeyOperator in the mnUniquePropertyMap.
// pubKeyOperator don't differ between the two schemes (legacy and basic(v19)) but their serialisation do: hence their hash.
// And because mnUniquePropertyMap store only hashes, then we need to re-calculate hashes and repopulate.
void CDeterministicMNList::RepopulateUniquePropertyMap() {
decltype(mnUniquePropertyMap) mnUniquePropertyMapEmpty;
mnUniquePropertyMap = mnUniquePropertyMapEmpty;

for (const auto &p: mnMap) {
auto dmn = p.second;
if (!AddUniqueProperty(*dmn, dmn->collateralOutpoint)) {
throw (std::runtime_error(
strprintf("%s: Can't add a masternode %s with a duplicate collateralOutpoint=%s", __func__,
dmn->proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
}
if (dmn->pdmnState->addr != CService() && !AddUniqueProperty(*dmn, dmn->pdmnState->addr)) {
throw (std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate address=%s", __func__,
dmn->proTxHash.ToString(),
dmn->pdmnState->addr.ToStringIPPort(false))));
}
if (!AddUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) {
throw (std::runtime_error(
strprintf("%s: Can't add a masternode %s with a duplicate keyIDOwner=%s", __func__,
dmn->proTxHash.ToString(), EncodeDestination(PKHash(dmn->pdmnState->keyIDOwner)))));
}
if (dmn->pdmnState->pubKeyOperator.Get().IsValid() &&
!AddUniqueProperty(*dmn, dmn->pdmnState->pubKeyOperator)) {
throw (std::runtime_error(
strprintf("%s: Can't add a masternode %s with a duplicate pubKeyOperator=%s", __func__,
dmn->proTxHash.ToString(), dmn->pdmnState->pubKeyOperator.Get().ToString())));
}

if (dmn->nType == MnType::HighPerformance) {
if (!AddUniqueProperty(*dmn, dmn->pdmnState->platformNodeID)) {
throw (std::runtime_error(
strprintf("%s: Can't add a masternode %s with a duplicate platformNodeID=%s", __func__,
dmn->proTxHash.ToString(), dmn->pdmnState->platformNodeID.ToString())));
}
}
}
}

void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTotalCount)
{
assert(dmn != nullptr);
Expand Down Expand Up @@ -617,11 +659,19 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde

newList.SetBlockHash(block.GetHash());

// If the fork is active for pindex block, then we need to repopulate property map
// (Check documentation of CDeterministicMNList::RepopulateUniquePropertyMap()).
// This is needed only when base list is pre-v19 fork and pindex is post-v19 fork.
bool v19_just_activated = pindex == llmq::utils::V19ActivationIndex(pindex);
if (v19_just_activated) {
newList.RepopulateUniquePropertyMap();
}

oldList = GetListForBlock(pindex->pprev);
diff = oldList.BuildDiff(newList);

m_evoDb.Write(std::make_pair(DB_LIST_DIFF, newList.GetBlockHash()), diff);
if ((nHeight % DISK_SNAPSHOT_PERIOD) == 0 || oldList.GetHeight() == -1) {
if ((nHeight % DISK_SNAPSHOT_PERIOD) == 0 || oldList.GetHeight() == -1 || v19_just_activated) {
m_evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, newList.GetBlockHash()), newList);
mnListsCache.emplace(newList.GetBlockHash(), newList);
LogPrintf("CDeterministicMNManager::%s -- Wrote snapshot. nHeight=%d, mapCurMNs.allMNsCount=%d\n",
Expand Down Expand Up @@ -904,9 +954,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
Expand Down
2 changes: 2 additions & 0 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ class CDeterministicMNList
[[nodiscard]] CSimplifiedMNListDiff BuildSimplifiedDiff(const CDeterministicMNList& to, bool extended) const;
[[nodiscard]] CDeterministicMNList ApplyDiff(const CBlockIndex* pindex, const CDeterministicMNListDiff& diff) const;

void RepopulateUniquePropertyMap();

void AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTotalCount = true);
void UpdateMN(const CDeterministicMN& oldDmn, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
void UpdateMN(const uint256& proTxHash, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
Expand Down
7 changes: 6 additions & 1 deletion src/evo/dmnstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ std::string CDeterministicMNState::ToString() const
EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.Get().ToString(), EncodeDestination(PKHash(keyIDVoting)), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress);
}

void CDeterministicMNState::ToJson(UniValue& obj) const
void CDeterministicMNState::ToJson(UniValue& obj, MnType nType) const
{
obj.clear();
obj.setObject();
Expand All @@ -46,6 +46,11 @@ void CDeterministicMNState::ToJson(UniValue& obj) const
obj.pushKV("revocationReason", nRevocationReason);
obj.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner)));
obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
if (nType == MnType::HighPerformance) {
obj.pushKV("platformNodeID", platformNodeID.ToString());
obj.pushKV("platformP2PPort", platformP2PPort);
obj.pushKV("platformHTTPPort", platformHTTPPort);
}

CTxDestination dest;
if (ExtractDestination(scriptPayout, dest)) {
Expand Down
2 changes: 1 addition & 1 deletion src/evo/dmnstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class CDeterministicMNState

public:
std::string ToString() const;
void ToJson(UniValue& obj) const;
void ToJson(UniValue& obj, MnType nType) const;
};

class CDeterministicMNStateDiff
Expand Down
6 changes: 4 additions & 2 deletions src/evo/mnhftx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down Expand Up @@ -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");
}

Expand Down
2 changes: 1 addition & 1 deletion src/governance/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ bool CGovernanceObject::CheckSignature(const CBLSPublicKey& pubKey) const
const auto pindex = llmq::utils::V19ActivationIndex(::ChainActive().Tip());
bool is_bls_legacy_scheme = pindex == nullptr || nTime < pindex->nTime;
sig.SetByteVector(vchSig, is_bls_legacy_scheme);
if (!sig.VerifyInsecure(pubKey, GetSignatureHash())) {
if (!sig.VerifyInsecure(pubKey, GetSignatureHash(), is_bls_legacy_scheme)) {
LogPrintf("CGovernanceObject::CheckSignature -- VerifyInsecure() failed\n");
return false;
}
Expand Down

0 comments on commit c4cf446

Please sign in to comment.