From fabc8edd6af7507a61a4e262cbb433a60ddc524c Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 25 May 2023 18:23:47 +0300 Subject: [PATCH 1/2] feat: store protx version in CSimplifiedMNListEntry and use it to ser/deser pubKeyOperator --- src/evo/cbtx.cpp | 3 +-- src/evo/simplifiedmns.cpp | 14 +++------- src/evo/simplifiedmns.h | 12 +++++---- src/version.h | 5 +++- test/functional/feature_dip3_v19.py | 2 +- .../feature_dip4_coinbasemerkleroots.py | 2 +- test/functional/feature_llmq_hpmn.py | 2 +- test/functional/test_framework/messages.py | 26 ++++++++++--------- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/evo/cbtx.cpp b/src/evo/cbtx.cpp index f93b20eaffda..4135ba7627b0 100644 --- a/src/evo/cbtx.cpp +++ b/src/evo/cbtx.cpp @@ -128,8 +128,7 @@ bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev int64_t nTime2 = GetTimeMicros(); nTimeDMN += nTime2 - nTime1; LogPrint(BCLog::BENCHMARK, " - BuildNewListFromBlock: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeDMN * 0.000001); - bool v19active = llmq::utils::IsV19Active(pindexPrev); - CSimplifiedMNList sml(tmpMNList, v19active); + CSimplifiedMNList sml(tmpMNList); int64_t nTime3 = GetTimeMicros(); nTimeSMNL += nTime3 - nTime2; LogPrint(BCLog::BENCHMARK, " - CSimplifiedMNList: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeSMNL * 0.000001); diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index 41514f87aa68..1399aa353a53 100644 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -33,6 +33,7 @@ CSimplifiedMNListEntry::CSimplifiedMNListEntry(const CDeterministicMN& dmn) : isValid(!dmn.pdmnState->IsBanned()), scriptPayout(dmn.pdmnState->scriptPayout), scriptOperatorPayout(dmn.pdmnState->scriptOperatorPayout), + nVersion(dmn.pdmnState->nVersion == CProRegTx::LEGACY_BLS_VERSION ? LEGACY_BLS_VERSION : BASIC_BLS_VERSION), nType(dmn.nType), platformHTTPPort(dmn.pdmnState->platformHTTPPort), platformNodeID(dmn.pdmnState->platformNodeID) @@ -104,15 +105,13 @@ CSimplifiedMNList::CSimplifiedMNList(const std::vector& }); } -CSimplifiedMNList::CSimplifiedMNList(const CDeterministicMNList& dmnList, bool isV19Active) +CSimplifiedMNList::CSimplifiedMNList(const CDeterministicMNList& dmnList) { mnList.resize(dmnList.GetAllMNsCount()); size_t i = 0; - dmnList.ForEachMN(false, [this, &i, isV19Active](auto& dmn) { - auto sme = std::make_unique(dmn); - sme->nVersion = isV19Active ? CSimplifiedMNListEntry::BASIC_BLS_VERSION : CSimplifiedMNListEntry::LEGACY_BLS_VERSION; - mnList[i++] = std::move(sme); + dmnList.ForEachMN(false, [this, &i](auto& dmn) { + mnList[i++] = std::make_unique(dmn); }); std::sort(mnList.begin(), mnList.end(), [&](const std::unique_ptr& a, const std::unique_ptr& b) { @@ -239,23 +238,18 @@ void CSimplifiedMNListDiff::ToJson(UniValue& obj, bool extended) const CSimplifiedMNListDiff BuildSimplifiedDiff(const CDeterministicMNList& from, const CDeterministicMNList& to, bool extended) { - bool v19active = llmq::utils::IsV19Active(::ChainActive().Tip()); CSimplifiedMNListDiff diffRet; diffRet.baseBlockHash = from.GetBlockHash(); diffRet.blockHash = to.GetBlockHash(); - diffRet.nVersion = v19active ? CSimplifiedMNListDiff::BASIC_BLS_VERSION : CSimplifiedMNListDiff::LEGACY_BLS_VERSION; to.ForEachMN(false, [&](const auto& toPtr) { auto fromPtr = from.GetMN(toPtr.proTxHash); if (fromPtr == nullptr) { CSimplifiedMNListEntry sme(toPtr); - sme.nVersion = diffRet.nVersion; diffRet.mnList.push_back(std::move(sme)); } else { CSimplifiedMNListEntry sme1(toPtr); CSimplifiedMNListEntry sme2(*fromPtr); - sme1.nVersion = diffRet.nVersion; - sme2.nVersion = diffRet.nVersion; if ((sme1 != sme2) || (extended && (sme1.scriptPayout != sme2.scriptPayout || sme1.scriptOperatorPayout != sme2.scriptOperatorPayout))) { diffRet.mnList.push_back(std::move(sme1)); diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 77165c56b638..dab50a2e9699 100644 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -39,7 +39,7 @@ class CSimplifiedMNListEntry uint160 platformNodeID{}; CScript scriptPayout; // mem-only CScript scriptOperatorPayout; // mem-only - uint16_t nVersion{LEGACY_BLS_VERSION}; // mem-only + uint16_t nVersion{LEGACY_BLS_VERSION}; CSimplifiedMNListEntry() = default; explicit CSimplifiedMNListEntry(const CDeterministicMN& dmn); @@ -65,6 +65,9 @@ class CSimplifiedMNListEntry SERIALIZE_METHODS(CSimplifiedMNListEntry, obj) { + if ((s.GetType() & SER_NETWORK) && s.GetVersion() >= SMNLE_VERSIONED_PROTO_VERSION) { + READWRITE(obj.nVersion); + } READWRITE( obj.proRegTxHash, obj.confirmedHash, @@ -98,7 +101,7 @@ class CSimplifiedMNList CSimplifiedMNList() = default; explicit CSimplifiedMNList(const std::vector& smlEntries); - explicit CSimplifiedMNList(const CDeterministicMNList& dmnList, bool isV19Active); + explicit CSimplifiedMNList(const CDeterministicMNList& dmnList); uint256 CalcMerkleRoot(bool* pmutated = nullptr) const; bool operator==(const CSimplifiedMNList& rhs) const; @@ -121,8 +124,7 @@ class CGetSimplifiedMNListDiff class CSimplifiedMNListDiff { public: - static constexpr uint16_t LEGACY_BLS_VERSION = 1; - static constexpr uint16_t BASIC_BLS_VERSION = 2; + static constexpr uint16_t CURRENT_VERSION = 1; uint256 baseBlockHash; uint256 blockHash; @@ -130,7 +132,7 @@ class CSimplifiedMNListDiff CTransactionRef cbTx; std::vector deletedMNs; std::vector mnList; - uint16_t nVersion{LEGACY_BLS_VERSION}; + uint16_t nVersion{CURRENT_VERSION}; std::vector> deletedQuorums; // p std::vector newQuorums; diff --git a/src/version.h b/src/version.h index 96bad2d23a0c..e1141c60e357 100644 --- a/src/version.h +++ b/src/version.h @@ -11,7 +11,7 @@ */ -static const int PROTOCOL_VERSION = 70227; +static const int PROTOCOL_VERSION = 70228; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -49,6 +49,9 @@ static const int COINJOIN_PROTX_HASH_PROTO_VERSION = 70226; //! Masternode type was introduced in this version static const int DMN_TYPE_PROTO_VERSION = 70227; +//! Versioned Simplified Masternode List Entries were introduced in this version +static const int SMNLE_VERSIONED_PROTO_VERSION = 70228; + // Make sure that none of the values above collide with `ADDRV2_FORMAT`. #endif // BITCOIN_VERSION_H diff --git a/test/functional/feature_dip3_v19.py b/test/functional/feature_dip3_v19.py index 497dc82fc39d..8bbf131818ad 100755 --- a/test/functional/feature_dip3_v19.py +++ b/test/functional/feature_dip3_v19.py @@ -166,7 +166,7 @@ def test_getmnlistdiff(self, base_block_hash, block_hash, base_mn_list, expected # Verify that the merkle root matches what we locally calculate hashes = [] for mn in sorted(new_mn_list.values(), key=lambda mn: ser_uint256(mn.proRegTxHash)): - hashes.append(hash256(mn.serialize())) + hashes.append(hash256(mn.serialize(with_version = False))) merkle_root = CBlock.get_merkle_root(hashes) assert_equal(merkle_root, cbtx.merkleRootMNList) diff --git a/test/functional/feature_dip4_coinbasemerkleroots.py b/test/functional/feature_dip4_coinbasemerkleroots.py index 27104e8221fb..ec0999cd56bf 100755 --- a/test/functional/feature_dip4_coinbasemerkleroots.py +++ b/test/functional/feature_dip4_coinbasemerkleroots.py @@ -180,7 +180,7 @@ def test_getmnlistdiff(self, baseBlockHash, blockHash, baseMNList, expectedDelet # Verify that the merkle root matches what we locally calculate hashes = [] for mn in sorted(newMNList.values(), key=lambda mn: ser_uint256(mn.proRegTxHash)): - hashes.append(hash256(mn.serialize())) + hashes.append(hash256(mn.serialize(with_version = False))) merkleRoot = CBlock.get_merkle_root(hashes) assert_equal(merkleRoot, cbtx.merkleRootMNList) diff --git a/test/functional/feature_llmq_hpmn.py b/test/functional/feature_llmq_hpmn.py index 24c85ddb1f5c..882a9203aaf0 100755 --- a/test/functional/feature_llmq_hpmn.py +++ b/test/functional/feature_llmq_hpmn.py @@ -253,7 +253,7 @@ def test_getmnlistdiff(self, baseBlockHash, blockHash, baseMNList, expectedDelet # Verify that the merkle root matches what we locally calculate hashes = [] for mn in sorted(newMNList.values(), key=lambda mn: ser_uint256(mn.proRegTxHash)): - hashes.append(hash256(mn.serialize())) + hashes.append(hash256(mn.serialize(with_version = False))) merkleRoot = CBlock.get_merkle_root(hashes) assert_equal(merkleRoot, cbtx.merkleRootMNList) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 236f6af63eba..455e1b324597 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -32,7 +32,7 @@ import dash_hash MIN_VERSION_SUPPORTED = 60001 -MY_VERSION = 70227 # DMN_TYPE_PROTO_VERSION +MY_VERSION = 70228 # SMNLE_VERSIONED_PROTO_VERSION MY_SUBVERSION = b"/python-mininode-tester:0.0.3%s/" MY_RELAY = 1 # from version 70001 onwards, fRelay should be appended to version messages (BIP37) @@ -1095,7 +1095,7 @@ def serialize(self): class CSimplifiedMNListEntry: - __slots__ = ("proRegTxHash", "confirmedHash", "service", "pubKeyOperator", "keyIDVoting", "isValid", "version", "type", "platformHTTPPort", "platformNodeID") + __slots__ = ("proRegTxHash", "confirmedHash", "service", "pubKeyOperator", "keyIDVoting", "isValid", "nVersion", "type", "platformHTTPPort", "platformNodeID") def __init__(self): self.set_null() @@ -1107,34 +1107,36 @@ def set_null(self): self.pubKeyOperator = b'\x00' * 48 self.keyIDVoting = 0 self.isValid = False - self.version = 0 + self.nVersion = 0 self.type = 0 self.platformHTTPPort = 0 self.platformNodeID = b'\x00' * 20 - def deserialize(self, f, version): - self.version = version # memory only + def deserialize(self, f): + self.nVersion = struct.unpack(" Date: Mon, 5 Jun 2023 00:40:16 +0300 Subject: [PATCH 2/2] feat: show pubKeyOperator using its internal bls scheme should also match the scheme it was created with in the original protx and match nVersion in CSimplifiedMNListEntry --- src/evo/simplifiedmns.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index 1399aa353a53..0c463c174c9f 100644 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -71,7 +71,7 @@ void CSimplifiedMNListEntry::ToJson(UniValue& obj, bool extended) const obj.pushKV("proRegTxHash", proRegTxHash.ToString()); obj.pushKV("confirmedHash", confirmedHash.ToString()); obj.pushKV("service", service.ToString(false)); - obj.pushKV("pubKeyOperator", pubKeyOperator.Get().ToString()); + obj.pushKV("pubKeyOperator", pubKeyOperator.ToString()); obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting))); obj.pushKV("isValid", isValid); obj.pushKV("nVersion", nVersion);