Multiple speed optimizations for deterministic MN list handling (#2972)

* Generalize CBLSLazyWrapper so that it can be used of pubkeys and secret keys

* Implement == and != operators for CBLSLazyWrapper

* Implement cached hash for CBLSLazyWrapper

* Use CBLSLazyPublicKey for CDeterministicMNState::pubKeyOperator

* Speed up GetProjectedMNPayees by sorting the MN list by last paid

Instead of updating a temporary list for each projected height and calling
GetMNPayee() on it.

* Cache intermediate lists in GetListForBlock

This avoids re-loading and applying diffs again and again.

* Only update masternode list UI max once every 3 seconds

This avoids updating the UI on every block, which turned out to be very
expensive.

* Fix compilation

* Drop time restrictions for mn list update in ClientModel

They are fully handled by MasternodeList now.
This commit is contained in:
Alexander Block 2019-06-13 11:01:26 +02:00
parent 11699f540f
commit c1f756fd90
28 changed files with 204 additions and 144 deletions

View File

@ -424,33 +424,6 @@ bool CBLSSignature::Recover(const std::vector<CBLSSignature>& sigs, const std::v
} }
#ifndef BUILD_BITCOIN_INTERNAL #ifndef BUILD_BITCOIN_INTERNAL
void CBLSLazySignature::SetSig(const CBLSSignature& _sig)
{
std::unique_lock<std::mutex> l(mutex);
bufValid = false;
sigInitialized = true;
sig = _sig;
}
const CBLSSignature& CBLSLazySignature::GetSig() const
{
std::unique_lock<std::mutex> l(mutex);
static CBLSSignature invalidSig;
if (!bufValid && !sigInitialized) {
return invalidSig;
}
if (!sigInitialized) {
sig.SetBuf(buf, sizeof(buf));
if (!sig.CheckMalleable(buf, sizeof(buf))) {
bufValid = false;
sigInitialized = false;
sig = invalidSig;
} else {
sigInitialized = true;
}
}
return sig;
}
static std::once_flag init_flag; static std::once_flag init_flag;
static mt_pooled_secure_allocator<uint8_t>* secure_allocator_instance; static mt_pooled_secure_allocator<uint8_t>* secure_allocator_instance;

View File

@ -310,29 +310,34 @@ protected:
}; };
#ifndef BUILD_BITCOIN_INTERNAL #ifndef BUILD_BITCOIN_INTERNAL
class CBLSLazySignature template<typename BLSObject>
class CBLSLazyWrapper
{ {
private: private:
mutable std::mutex mutex; mutable std::mutex mutex;
mutable char buf[BLS_CURVE_SIG_SIZE]; mutable char buf[BLSObject::SerSize];
mutable bool bufValid{false}; mutable bool bufValid{false};
mutable CBLSSignature sig; mutable BLSObject obj;
mutable bool sigInitialized{false}; mutable bool objInitialized{false};
mutable uint256 hash;
public: public:
CBLSLazySignature() CBLSLazyWrapper()
{ {
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
// the all-zero buf is considered a valid buf, but the resulting object will return false for IsValid
bufValid = true;
} }
CBLSLazySignature(const CBLSLazySignature& r) CBLSLazyWrapper(const CBLSLazyWrapper& r)
{ {
*this = r; *this = r;
} }
CBLSLazySignature& operator=(const CBLSLazySignature& r) CBLSLazyWrapper& operator=(const CBLSLazyWrapper& r)
{ {
std::unique_lock<std::mutex> l(r.mutex); std::unique_lock<std::mutex> l(r.mutex);
bufValid = r.bufValid; bufValid = r.bufValid;
@ -341,12 +346,13 @@ public:
} else { } else {
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
} }
sigInitialized = r.sigInitialized; objInitialized = r.objInitialized;
if (r.sigInitialized) { if (r.objInitialized) {
sig = r.sig; obj = r.obj;
} else { } else {
sig.Reset(); obj.Reset();
} }
hash = r.hash;
return *this; return *this;
} }
@ -354,12 +360,13 @@ public:
inline void Serialize(Stream& s) const inline void Serialize(Stream& s) const
{ {
std::unique_lock<std::mutex> l(mutex); std::unique_lock<std::mutex> l(mutex);
if (!sigInitialized && !bufValid) { if (!objInitialized && !bufValid) {
throw std::ios_base::failure("sig and buf not initialized"); throw std::ios_base::failure("obj and buf not initialized");
} }
if (!bufValid) { if (!bufValid) {
sig.GetBuf(buf, sizeof(buf)); obj.GetBuf(buf, sizeof(buf));
bufValid = true; bufValid = true;
hash = uint256();
} }
s.write(buf, sizeof(buf)); s.write(buf, sizeof(buf));
} }
@ -370,12 +377,78 @@ public:
std::unique_lock<std::mutex> l(mutex); std::unique_lock<std::mutex> l(mutex);
s.read(buf, sizeof(buf)); s.read(buf, sizeof(buf));
bufValid = true; bufValid = true;
sigInitialized = false; objInitialized = false;
hash = uint256();
} }
void SetSig(const CBLSSignature& _sig); void Set(const BLSObject& _obj)
const CBLSSignature& GetSig() const; {
std::unique_lock<std::mutex> l(mutex);
bufValid = false;
objInitialized = true;
obj = _obj;
hash = uint256();
}
const BLSObject& Get() const
{
std::unique_lock<std::mutex> l(mutex);
static BLSObject invalidObj;
if (!bufValid && !objInitialized) {
return invalidObj;
}
if (!objInitialized) {
obj.SetBuf(buf, sizeof(buf));
if (!obj.CheckMalleable(buf, sizeof(buf))) {
bufValid = false;
objInitialized = false;
obj = invalidObj;
} else {
objInitialized = true;
}
}
return obj;
}
bool operator==(const CBLSLazyWrapper& r) const
{
if (bufValid && r.bufValid) {
return memcmp(buf, r.buf, sizeof(buf)) == 0;
}
if (objInitialized && r.objInitialized) {
return obj == r.obj;
}
return Get() == r.Get();
}
bool operator!=(const CBLSLazyWrapper& r) const
{
return !(*this == r);
}
uint256 GetHash() const
{
std::unique_lock<std::mutex> l(mutex);
if (!bufValid) {
obj.GetBuf(buf, sizeof(buf));
bufValid = true;
hash = uint256();
}
if (hash.IsNull()) {
UpdateHash();
}
return hash;
}
private:
void UpdateHash() const
{
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss.write(buf, sizeof(buf));
hash = ss.GetHash();
}
}; };
typedef CBLSLazyWrapper<CBLSSignature> CBLSLazySignature;
typedef CBLSLazyWrapper<CBLSPublicKey> CBLSLazyPublicKey;
typedef CBLSLazyWrapper<CBLSSecretKey> CBLSLazySecretKey;
#endif #endif
typedef std::vector<CBLSId> BLSIdVector; typedef std::vector<CBLSId> BLSIdVector;

View File

@ -38,7 +38,7 @@ std::string CDeterministicMNState::ToString() const
return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, " return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, "
"ownerAddress=%s, pubKeyOperator=%s, votingAddress=%s, addr=%s, payoutAddress=%s, operatorPayoutAddress=%s)", "ownerAddress=%s, pubKeyOperator=%s, votingAddress=%s, addr=%s, payoutAddress=%s, operatorPayoutAddress=%s)",
nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason, nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason,
CBitcoinAddress(keyIDOwner).ToString(), pubKeyOperator.ToString(), CBitcoinAddress(keyIDVoting).ToString(), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress); CBitcoinAddress(keyIDOwner).ToString(), pubKeyOperator.Get().ToString(), CBitcoinAddress(keyIDVoting).ToString(), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress);
} }
void CDeterministicMNState::ToJson(UniValue& obj) const void CDeterministicMNState::ToJson(UniValue& obj) const
@ -60,7 +60,7 @@ void CDeterministicMNState::ToJson(UniValue& obj) const
CBitcoinAddress payoutAddress(dest); CBitcoinAddress payoutAddress(dest);
obj.push_back(Pair("payoutAddress", payoutAddress.ToString())); obj.push_back(Pair("payoutAddress", payoutAddress.ToString()));
} }
obj.push_back(Pair("pubKeyOperator", pubKeyOperator.ToString())); obj.push_back(Pair("pubKeyOperator", pubKeyOperator.Get().ToString()));
if (ExtractDestination(scriptOperatorPayout, dest)) { if (ExtractDestination(scriptOperatorPayout, dest)) {
CBitcoinAddress operatorPayoutAddress(dest); CBitcoinAddress operatorPayoutAddress(dest);
obj.push_back(Pair("operatorPayoutAddress", operatorPayoutAddress.ToString())); obj.push_back(Pair("operatorPayoutAddress", operatorPayoutAddress.ToString()));
@ -147,7 +147,7 @@ CDeterministicMNCPtr CDeterministicMNList::GetValidMN(const uint256& proTxHash)
CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CBLSPublicKey& pubKey) CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CBLSPublicKey& pubKey)
{ {
for (const auto& p : mnMap) { for (const auto& p : mnMap) {
if (p.second->pdmnState->pubKeyOperator == pubKey) { if (p.second->pdmnState->pubKeyOperator.Get() == pubKey) {
return p.second; return p.second;
} }
} }
@ -226,21 +226,21 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee() const
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int nCount) const std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int nCount) const
{ {
if (nCount > GetValidMNsCount()) {
nCount = GetValidMNsCount();
}
std::vector<CDeterministicMNCPtr> result; std::vector<CDeterministicMNCPtr> result;
result.reserve(nCount); result.reserve(nCount);
CDeterministicMNList tmpMNList = *this; ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
for (int h = nHeight; h < nHeight + nCount; h++) { result.emplace_back(dmn);
tmpMNList.SetHeight(h); });
std::sort(result.begin(), result.end(), [&](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) {
return CompareByLastPaid(a, b);
});
CDeterministicMNCPtr payee = tmpMNList.GetMNPayee(); result.resize(nCount);
// push the original MN object instead of the one from the temporary list
result.push_back(GetMN(payee->proTxHash));
CDeterministicMNStatePtr newState = std::make_shared<CDeterministicMNState>(*payee->pdmnState);
newState->nLastPaidHeight = h;
tmpMNList.UpdateMN(payee->proTxHash, newState);
}
return result; return result;
} }
@ -429,7 +429,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn)
AddUniqueProperty(dmn, dmn->pdmnState->addr); AddUniqueProperty(dmn, dmn->pdmnState->addr);
} }
AddUniqueProperty(dmn, dmn->pdmnState->keyIDOwner); AddUniqueProperty(dmn, dmn->pdmnState->keyIDOwner);
if (dmn->pdmnState->pubKeyOperator.IsValid()) { if (dmn->pdmnState->pubKeyOperator.Get().IsValid()) {
AddUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator); AddUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator);
} }
} }
@ -457,7 +457,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
DeleteUniqueProperty(dmn, dmn->pdmnState->addr); DeleteUniqueProperty(dmn, dmn->pdmnState->addr);
} }
DeleteUniqueProperty(dmn, dmn->pdmnState->keyIDOwner); DeleteUniqueProperty(dmn, dmn->pdmnState->keyIDOwner);
if (dmn->pdmnState->pubKeyOperator.IsValid()) { if (dmn->pdmnState->pubKeyOperator.Get().IsValid()) {
DeleteUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator); DeleteUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator);
} }
mnMap = mnMap.erase(proTxHash); mnMap = mnMap.erase(proTxHash);
@ -701,7 +701,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
if (newState->nPoSeBanHeight != -1) { if (newState->nPoSeBanHeight != -1) {
// only revive when all keys are set // only revive when all keys are set
if (newState->pubKeyOperator.IsValid() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) { if (newState->pubKeyOperator.Get().IsValid() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) {
newState->nPoSePenalty = 0; newState->nPoSePenalty = 0;
newState->nPoSeBanHeight = -1; newState->nPoSeBanHeight = -1;
newState->nPoSeRevivedHeight = nHeight; newState->nPoSeRevivedHeight = nHeight;
@ -729,12 +729,12 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
return _state.DoS(100, false, REJECT_INVALID, "bad-protx-hash"); return _state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
} }
auto newState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState); auto newState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState);
if (newState->pubKeyOperator != proTx.pubKeyOperator) { if (newState->pubKeyOperator.Get() != proTx.pubKeyOperator) {
// reset all operator related fields and put MN into PoSe-banned state in case the operator key changes // reset all operator related fields and put MN into PoSe-banned state in case the operator key changes
newState->ResetOperatorFields(); newState->ResetOperatorFields();
newState->BanIfNotBanned(nHeight); newState->BanIfNotBanned(nHeight);
} }
newState->pubKeyOperator = proTx.pubKeyOperator; newState->pubKeyOperator.Set(proTx.pubKeyOperator);
newState->keyIDVoting = proTx.keyIDVoting; newState->keyIDVoting = proTx.keyIDVoting;
newState->scriptPayout = proTx.scriptPayout; newState->scriptPayout = proTx.scriptPayout;
@ -866,12 +866,14 @@ CDeterministicMNList CDeterministicMNManager::GetListForBlock(const uint256& blo
} }
if (evoDb.Read(std::make_pair(DB_LIST_SNAPSHOT, blockHashTmp), snapshot)) { if (evoDb.Read(std::make_pair(DB_LIST_SNAPSHOT, blockHashTmp), snapshot)) {
mnListsCache.emplace(blockHashTmp, snapshot);
break; break;
} }
CDeterministicMNListDiff diff; CDeterministicMNListDiff diff;
if (!evoDb.Read(std::make_pair(DB_LIST_DIFF, blockHashTmp), diff)) { if (!evoDb.Read(std::make_pair(DB_LIST_DIFF, blockHashTmp), diff)) {
snapshot = CDeterministicMNList(blockHashTmp, -1); snapshot = CDeterministicMNList(blockHashTmp, -1);
mnListsCache.emplace(blockHashTmp, snapshot);
break; break;
} }
@ -886,9 +888,10 @@ CDeterministicMNList CDeterministicMNManager::GetListForBlock(const uint256& blo
snapshot.SetBlockHash(diff.blockHash); snapshot.SetBlockHash(diff.blockHash);
snapshot.SetHeight(diff.nHeight); snapshot.SetHeight(diff.nHeight);
} }
mnListsCache.emplace(diff.blockHash, snapshot);
} }
mnListsCache.emplace(blockHash, snapshot);
return snapshot; return snapshot;
} }

View File

@ -44,7 +44,7 @@ public:
uint256 confirmedHashWithProRegTxHash; uint256 confirmedHashWithProRegTxHash;
CKeyID keyIDOwner; CKeyID keyIDOwner;
CBLSPublicKey pubKeyOperator; CBLSLazyPublicKey pubKeyOperator;
CKeyID keyIDVoting; CKeyID keyIDVoting;
CService addr; CService addr;
CScript scriptPayout; CScript scriptPayout;
@ -55,7 +55,7 @@ public:
CDeterministicMNState(const CProRegTx& proTx) CDeterministicMNState(const CProRegTx& proTx)
{ {
keyIDOwner = proTx.keyIDOwner; keyIDOwner = proTx.keyIDOwner;
pubKeyOperator = proTx.pubKeyOperator; pubKeyOperator.Set(proTx.pubKeyOperator);
keyIDVoting = proTx.keyIDVoting; keyIDVoting = proTx.keyIDVoting;
addr = proTx.addr; addr = proTx.addr;
scriptPayout = proTx.scriptPayout; scriptPayout = proTx.scriptPayout;
@ -89,7 +89,7 @@ public:
void ResetOperatorFields() void ResetOperatorFields()
{ {
pubKeyOperator = CBLSPublicKey(); pubKeyOperator.Set(CBLSPublicKey());
addr = CService(); addr = CService();
scriptOperatorPayout = CScript(); scriptOperatorPayout = CScript();
nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED; nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED;

View File

@ -89,7 +89,7 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS
signHash = ::SerializeHash(std::make_tuple(dmn->pdmnState->pubKeyOperator, pnode->sentMNAuthChallenge, !pnode->fInbound)); signHash = ::SerializeHash(std::make_tuple(dmn->pdmnState->pubKeyOperator, pnode->sentMNAuthChallenge, !pnode->fInbound));
} }
if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, signHash)) { if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), signHash)) {
LOCK(cs_main); LOCK(cs_main);
// Same as above, MN seems to not know about his fate yet, so give him a chance to update. If this is a // Same as above, MN seems to not know about his fate yet, so give him a chance to update. If this is a
// malicious actor (DoSing us), we'll ban him soon. // malicious actor (DoSing us), we'll ban him soon.

View File

@ -257,7 +257,7 @@ bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVa
if (!CheckInputsHash(tx, ptx, state)) { if (!CheckInputsHash(tx, ptx, state)) {
return false; return false;
} }
if (!CheckHashSig(ptx, mn->pdmnState->pubKeyOperator, state)) { if (!CheckHashSig(ptx, mn->pdmnState->pubKeyOperator.Get(), state)) {
return false; return false;
} }
} }
@ -376,7 +376,7 @@ bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal
if (!CheckInputsHash(tx, ptx, state)) if (!CheckInputsHash(tx, ptx, state))
return false; return false;
if (!CheckHashSig(ptx, dmn->pdmnState->pubKeyOperator, state)) if (!CheckHashSig(ptx, dmn->pdmnState->pubKeyOperator.Get(), state))
return false; return false;
} }

View File

@ -37,7 +37,7 @@ uint256 CSimplifiedMNListEntry::CalcHash() const
std::string CSimplifiedMNListEntry::ToString() const std::string CSimplifiedMNListEntry::ToString() const
{ {
return strprintf("CSimplifiedMNListEntry(proRegTxHash=%s, confirmedHash=%s, service=%s, pubKeyOperator=%s, votingAddress=%s, isValid=%d)", return strprintf("CSimplifiedMNListEntry(proRegTxHash=%s, confirmedHash=%s, service=%s, pubKeyOperator=%s, votingAddress=%s, isValid=%d)",
proRegTxHash.ToString(), confirmedHash.ToString(), service.ToString(false), pubKeyOperator.ToString(), CBitcoinAddress(keyIDVoting).ToString(), isValid); proRegTxHash.ToString(), confirmedHash.ToString(), service.ToString(false), pubKeyOperator.Get().ToString(), CBitcoinAddress(keyIDVoting).ToString(), isValid);
} }
void CSimplifiedMNListEntry::ToJson(UniValue& obj) const void CSimplifiedMNListEntry::ToJson(UniValue& obj) const
@ -47,7 +47,7 @@ void CSimplifiedMNListEntry::ToJson(UniValue& obj) const
obj.push_back(Pair("proRegTxHash", proRegTxHash.ToString())); obj.push_back(Pair("proRegTxHash", proRegTxHash.ToString()));
obj.push_back(Pair("confirmedHash", confirmedHash.ToString())); obj.push_back(Pair("confirmedHash", confirmedHash.ToString()));
obj.push_back(Pair("service", service.ToString(false))); obj.push_back(Pair("service", service.ToString(false)));
obj.push_back(Pair("pubKeyOperator", pubKeyOperator.ToString())); obj.push_back(Pair("pubKeyOperator", pubKeyOperator.Get().ToString()));
obj.push_back(Pair("votingAddress", CBitcoinAddress(keyIDVoting).ToString())); obj.push_back(Pair("votingAddress", CBitcoinAddress(keyIDVoting).ToString()));
obj.push_back(Pair("isValid", isValid)); obj.push_back(Pair("isValid", isValid));
} }

View File

@ -27,7 +27,7 @@ public:
uint256 proRegTxHash; uint256 proRegTxHash;
uint256 confirmedHash; uint256 confirmedHash;
CService service; CService service;
CBLSPublicKey pubKeyOperator; CBLSLazyPublicKey pubKeyOperator;
CKeyID keyIDVoting; CKeyID keyIDVoting;
bool isValid; bool isValid;

View File

@ -500,8 +500,8 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
} }
// Check that we have a valid MN signature // Check that we have a valid MN signature
if (!CheckSignature(dmn->pdmnState->pubKeyOperator)) { if (!CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.ToString(); strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.Get().ToString();
return false; return false;
} }

View File

@ -280,7 +280,7 @@ bool CGovernanceVote::IsValid(bool useVotingKey) const
if (useVotingKey) { if (useVotingKey) {
return CheckSignature(dmn->pdmnState->keyIDVoting); return CheckSignature(dmn->pdmnState->keyIDVoting);
} else { } else {
return CheckSignature(dmn->pdmnState->pubKeyOperator); return CheckSignature(dmn->pdmnState->pubKeyOperator.Get());
} }
} }

View File

@ -1123,7 +1123,7 @@ bool CTxLockVote::CheckSignature() const
CBLSSignature sig; CBLSSignature sig;
sig.SetBuf(vchMasternodeSignature); sig.SetBuf(vchMasternodeSignature);
if (!sig.IsValid() || !sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, hash)) { if (!sig.IsValid() || !sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), hash)) {
LogPrintf("CTxLockVote::CheckSignature -- VerifyInsecure() failed\n"); LogPrintf("CTxLockVote::CheckSignature -- VerifyInsecure() failed\n");
return false; return false;
} }

View File

@ -551,7 +551,7 @@ void CChainLocksHandler::HandleNewRecoveredSig(const llmq::CRecoveredSig& recove
clsig.nHeight = lastSignedHeight; clsig.nHeight = lastSignedHeight;
clsig.blockHash = lastSignedMsgHash; clsig.blockHash = lastSignedMsgHash;
clsig.sig = recoveredSig.sig.GetSig(); clsig.sig = recoveredSig.sig.Get();
} }
ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig)); ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig));
} }

View File

@ -88,7 +88,7 @@ bool CFinalCommitment::Verify(const std::vector<CDeterministicMNCPtr>& members,
if (!signers[i]) { if (!signers[i]) {
continue; continue;
} }
memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator); memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator.Get());
} }
if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) { if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) {

View File

@ -187,7 +187,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
skContrib.MakeNewKey(); skContrib.MakeNewKey();
} }
if (!qc.contributions->Encrypt(i, m->dmn->pdmnState->pubKeyOperator, skContrib, PROTOCOL_VERSION)) { if (!qc.contributions->Encrypt(i, m->dmn->pdmnState->pubKeyOperator.Get(), skContrib, PROTOCOL_VERSION)) {
logger.Batch("failed to encrypt contribution for %s", m->dmn->proTxHash.ToString()); logger.Batch("failed to encrypt contribution for %s", m->dmn->proTxHash.ToString());
return; return;
} }
@ -1219,7 +1219,7 @@ std::vector<CFinalCommitment> CDKGSession::FinalizeCommitments()
fqc.signers[signerIndex] = true; fqc.signers[signerIndex] = true;
aggSigs.emplace_back(qc.sig); aggSigs.emplace_back(qc.sig);
aggPks.emplace_back(m->dmn->pdmnState->pubKeyOperator); aggPks.emplace_back(m->dmn->pdmnState->pubKeyOperator.Get());
signerIds.emplace_back(m->id); signerIds.emplace_back(m->id);
thresholdSigs.emplace_back(qc.quorumSig); thresholdSigs.emplace_back(qc.quorumSig);

View File

@ -313,7 +313,7 @@ std::set<NodeId> BatchVerifyMessageSigs(CDKGSession& session, const std::vector<
break; break;
} }
pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator); pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator.Get());
messageHashes.emplace_back(msgHash); messageHashes.emplace_back(msgHash);
} }
if (!revertToSingleVerification) { if (!revertToSingleVerification) {
@ -353,7 +353,7 @@ std::set<NodeId> BatchVerifyMessageSigs(CDKGSession& session, const std::vector<
const auto& msg = *p.second; const auto& msg = *p.second;
auto member = session.GetMember(msg.proTxHash); auto member = session.GetMember(msg.proTxHash);
bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator, msg.GetSignHash()); bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator.Get(), msg.GetSignHash());
if (!valid) { if (!valid) {
ret.emplace(p.first); ret.emplace(p.first);
} }

View File

@ -747,7 +747,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks()
continue; continue;
} }
if (!islock.sig.GetSig().IsValid()) { if (!islock.sig.Get().IsValid()) {
batchVerifier.badSources.emplace(nodeId); batchVerifier.badSources.emplace(nodeId);
continue; continue;
} }
@ -765,7 +765,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks()
return false; return false;
} }
uint256 signHash = CLLMQUtils::BuildSignHash(llmqType, quorum->qc.quorumHash, id, islock.txid); uint256 signHash = CLLMQUtils::BuildSignHash(llmqType, quorum->qc.quorumHash, id, islock.txid);
batchVerifier.PushMessage(nodeId, hash, signHash, islock.sig.GetSig(), quorum->qc.quorumPublicKey); batchVerifier.PushMessage(nodeId, hash, signHash, islock.sig.Get(), quorum->qc.quorumPublicKey);
// We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which // 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 // avoids unnecessary double-verification of the signature. We however only do this when verification here

View File

@ -31,8 +31,8 @@ UniValue CRecoveredSig::ToJson() const
ret.push_back(Pair("quorumHash", quorumHash.ToString())); ret.push_back(Pair("quorumHash", quorumHash.ToString()));
ret.push_back(Pair("id", id.ToString())); ret.push_back(Pair("id", id.ToString()));
ret.push_back(Pair("msgHash", msgHash.ToString())); ret.push_back(Pair("msgHash", msgHash.ToString()));
ret.push_back(Pair("sig", sig.GetSig().ToString())); ret.push_back(Pair("sig", sig.Get().ToString()));
ret.push_back(Pair("hash", sig.GetSig().GetHash().ToString())); ret.push_back(Pair("hash", sig.Get().GetHash().ToString()));
return ret; return ret;
} }
@ -575,13 +575,13 @@ bool CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
for (auto& recSig : v) { for (auto& recSig : v) {
// we didn't verify the lazy signature until now // we didn't verify the lazy signature until now
if (!recSig.sig.GetSig().IsValid()) { if (!recSig.sig.Get().IsValid()) {
batchVerifier.badSources.emplace(nodeId); batchVerifier.badSources.emplace(nodeId);
break; break;
} }
const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash)); const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash));
batchVerifier.PushMessage(nodeId, recSig.GetHash(), CLLMQUtils::BuildSignHash(recSig), recSig.sig.GetSig(), quorum->qc.quorumPublicKey); batchVerifier.PushMessage(nodeId, recSig.GetHash(), CLLMQUtils::BuildSignHash(recSig), recSig.sig.Get(), quorum->qc.quorumPublicKey);
verifyCount++; verifyCount++;
} }
} }

View File

@ -589,7 +589,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
// we didn't check this earlier because we use a lazy BLS signature and tried to avoid doing the expensive // we didn't check this earlier because we use a lazy BLS signature and tried to avoid doing the expensive
// deserialization in the message thread // deserialization in the message thread
if (!sigShare.sigShare.GetSig().IsValid()) { if (!sigShare.sigShare.Get().IsValid()) {
BanNode(nodeId); BanNode(nodeId);
// don't process any additional shares from this node // don't process any additional shares from this node
break; break;
@ -605,7 +605,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
assert(false); assert(false);
} }
batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.GetSig(), pubKeyShare); batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.Get(), pubKeyShare);
verifyCount++; verifyCount++;
} }
} }
@ -735,7 +735,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
idsForRecovery.reserve((size_t) quorum->params.threshold); idsForRecovery.reserve((size_t) quorum->params.threshold);
for (auto it = sigShares->begin(); it != sigShares->end() && sigSharesForRecovery.size() < quorum->params.threshold; ++it) { for (auto it = sigShares->begin(); it != sigShares->end() && sigSharesForRecovery.size() < quorum->params.threshold; ++it) {
auto& sigShare = it->second; auto& sigShare = it->second;
sigSharesForRecovery.emplace_back(sigShare.sigShare.GetSig()); sigSharesForRecovery.emplace_back(sigShare.sigShare.Get());
idsForRecovery.emplace_back(CBLSId::FromHash(quorum->members[sigShare.quorumMember]->proTxHash)); idsForRecovery.emplace_back(CBLSId::FromHash(quorum->members[sigShare.quorumMember]->proTxHash));
} }
@ -762,7 +762,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
rs.quorumHash = quorum->qc.quorumHash; rs.quorumHash = quorum->qc.quorumHash;
rs.id = id; rs.id = id;
rs.msgHash = msgHash; rs.msgHash = msgHash;
rs.sig.SetSig(recoveredSig); rs.sig.Set(recoveredSig);
rs.UpdateHash(); rs.UpdateHash();
// There should actually be no need to verify the self-recovered signatures as it should always succeed. Let's // There should actually be no need to verify the self-recovered signatures as it should always succeed. Let's
@ -1422,8 +1422,8 @@ void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const
sigShare.quorumMember = (uint16_t)memberIdx; sigShare.quorumMember = (uint16_t)memberIdx;
uint256 signHash = CLLMQUtils::BuildSignHash(sigShare); uint256 signHash = CLLMQUtils::BuildSignHash(sigShare);
sigShare.sigShare.SetSig(skShare.Sign(signHash)); sigShare.sigShare.Set(skShare.Sign(signHash));
if (!sigShare.sigShare.GetSig().IsValid()) { if (!sigShare.sigShare.Get().IsValid()) {
LogPrintf("CSigSharesManager::%s -- failed to sign sigShare. signHash=%s, id=%s, msgHash=%s, time=%s\n", __func__, LogPrintf("CSigSharesManager::%s -- failed to sign sigShare. signHash=%s, id=%s, msgHash=%s, time=%s\n", __func__,
signHash.ToString(), sigShare.id.ToString(), sigShare.msgHash.ToString(), t.count()); signHash.ToString(), sigShare.id.ToString(), sigShare.msgHash.ToString(), t.count());
return; return;

View File

@ -2174,7 +2174,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// we have no idea about (e.g we were offline)? How to handle them? // we have no idea about (e.g we were offline)? How to handle them?
} }
if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator)) { if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
LogPrint("privatesend", "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString()); LogPrint("privatesend", "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString());
return false; return false;
} }

View File

@ -66,7 +66,7 @@ void CPrivateSendClientManager::ProcessMessage(CNode* pfrom, const std::string&
auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint); auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint);
if (!dmn) return; if (!dmn) return;
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator)) { if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
LOCK(cs_main); LOCK(cs_main);
Misbehaving(pfrom->id, 10); Misbehaving(pfrom->id, 10);
return; return;

View File

@ -121,7 +121,7 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint); auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint);
if (!dmn) return; if (!dmn) return;
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator)) { if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
LOCK(cs_main); LOCK(cs_main);
Misbehaving(pfrom->id, 10); Misbehaving(pfrom->id, 10);
return; return;

View File

@ -355,14 +355,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
static void NotifyMasternodeListChanged(ClientModel *clientmodel, const CDeterministicMNList& newList) static void NotifyMasternodeListChanged(ClientModel *clientmodel, const CDeterministicMNList& newList)
{ {
static int64_t nLastMasternodeUpdateNotification = 0;
int64_t now = GetTimeMillis();
// if we are in-sync, update the UI regardless of last update time
// no need to refresh masternode list/stats as often as blocks etc.
if (masternodeSync.IsBlockchainSynced() || now - nLastMasternodeUpdateNotification > MODEL_UPDATE_DELAY*4*5) {
clientmodel->setMasternodeList(newList); clientmodel->setMasternodeList(newList);
nLastMasternodeUpdateNotification = now;
}
} }
static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress) static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)

View File

@ -35,7 +35,9 @@ MasternodeList::MasternodeList(const PlatformStyle* platformStyle, QWidget* pare
clientModel(0), clientModel(0),
walletModel(0), walletModel(0),
fFilterUpdatedDIP3(true), fFilterUpdatedDIP3(true),
nTimeFilterUpdatedDIP3(0) nTimeFilterUpdatedDIP3(0),
nTimeUpdatedDIP3(0),
mnListChanged(true)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -89,7 +91,7 @@ void MasternodeList::setClientModel(ClientModel* model)
this->clientModel = model; this->clientModel = model;
if (model) { if (model) {
// try to update list when masternode count changes // try to update list when masternode count changes
connect(clientModel, SIGNAL(masternodeListChanged()), this, SLOT(updateDIP3ListForced())); connect(clientModel, SIGNAL(masternodeListChanged()), this, SLOT(handleMasternodeListChanged()));
} }
} }
@ -104,37 +106,48 @@ void MasternodeList::showContextMenuDIP3(const QPoint& point)
if (item) contextMenuDIP3->exec(QCursor::pos()); if (item) contextMenuDIP3->exec(QCursor::pos());
} }
void MasternodeList::handleMasternodeListChanged()
{
LOCK(cs_dip3list);
mnListChanged = true;
}
void MasternodeList::updateDIP3ListScheduled() void MasternodeList::updateDIP3ListScheduled()
{ {
updateDIP3List(false); TRY_LOCK(cs_dip3list, fLockAcquired);
if (!fLockAcquired) return;
if (!clientModel || ShutdownRequested()) {
return;
} }
void MasternodeList::updateDIP3ListForced() // To prevent high cpu usage update only once in MASTERNODELIST_FILTER_COOLDOWN_SECONDS seconds
{ // after filter was last changed unless we want to force the update.
updateDIP3List(true); if (fFilterUpdatedDIP3) {
int64_t nSecondsToWait = nTimeFilterUpdatedDIP3 - GetTime() + MASTERNODELIST_FILTER_COOLDOWN_SECONDS;
ui->countLabelDIP3->setText(QString::fromStdString(strprintf("Please wait... %d", nSecondsToWait)));
if (nSecondsToWait <= 0) {
updateDIP3List();
fFilterUpdatedDIP3 = false;
}
} else if (mnListChanged) {
int64_t nSecondsToWait = nTimeUpdatedDIP3 - GetTime() + MASTERNODELIST_UPDATE_SECONDS;
if (nSecondsToWait <= 0) {
updateDIP3List();
mnListChanged = false;
}
}
} }
void MasternodeList::updateDIP3List(bool fForce) void MasternodeList::updateDIP3List()
{ {
if (!clientModel || ShutdownRequested()) { if (!clientModel || ShutdownRequested()) {
return; return;
} }
TRY_LOCK(cs_dip3list, fLockAcquired); LOCK(cs_dip3list);
if (!fLockAcquired) return;
// To prevent high cpu usage update only once in MASTERNODELIST_FILTER_COOLDOWN_SECONDS seconds
// after filter was last changed unless we want to force the update.
if (!fForce) {
if (!fFilterUpdatedDIP3) return;
int64_t nSecondsToWait = nTimeFilterUpdatedDIP3 - GetTime() + MASTERNODELIST_FILTER_COOLDOWN_SECONDS;
ui->countLabelDIP3->setText(QString::fromStdString(strprintf("Please wait... %d", nSecondsToWait)));
if (nSecondsToWait > 0) return;
}
fFilterUpdatedDIP3 = false;
QString strToFilter; QString strToFilter;
ui->countLabelDIP3->setText("Updating..."); ui->countLabelDIP3->setText("Updating...");
@ -143,6 +156,8 @@ void MasternodeList::updateDIP3List(bool fForce)
ui->tableWidgetMasternodesDIP3->setRowCount(0); ui->tableWidgetMasternodesDIP3->setRowCount(0);
auto mnList = clientModel->getMasternodeList(); auto mnList = clientModel->getMasternodeList();
nTimeUpdatedDIP3 = GetTime();
auto projectedPayees = mnList.GetProjectedMNPayees(mnList.GetValidMNsCount()); auto projectedPayees = mnList.GetProjectedMNPayees(mnList.GetValidMNsCount());
std::map<uint256, int> nextPayments; std::map<uint256, int> nextPayments;
for (size_t i = 0; i < projectedPayees.size(); i++) { for (size_t i = 0; i < projectedPayees.size(); i++) {

View File

@ -12,7 +12,7 @@
#include <QTimer> #include <QTimer>
#include <QWidget> #include <QWidget>
#define MASTERNODELIST_UPDATE_SECONDS 15 #define MASTERNODELIST_UPDATE_SECONDS 3
#define MASTERNODELIST_FILTER_COOLDOWN_SECONDS 3 #define MASTERNODELIST_FILTER_COOLDOWN_SECONDS 3
namespace Ui namespace Ui
@ -42,6 +42,7 @@ public:
private: private:
QMenu* contextMenuDIP3; QMenu* contextMenuDIP3;
int64_t nTimeFilterUpdatedDIP3; int64_t nTimeFilterUpdatedDIP3;
int64_t nTimeUpdatedDIP3;
bool fFilterUpdatedDIP3; bool fFilterUpdatedDIP3;
QTimer* timer; QTimer* timer;
@ -54,9 +55,11 @@ private:
QString strCurrentFilterDIP3; QString strCurrentFilterDIP3;
bool mnListChanged;
CDeterministicMNCPtr GetSelectedDIP3MN(); CDeterministicMNCPtr GetSelectedDIP3MN();
void updateDIP3List(bool fForce); void updateDIP3List();
Q_SIGNALS: Q_SIGNALS:
void doubleClicked(const QModelIndex&); void doubleClicked(const QModelIndex&);
@ -70,7 +73,7 @@ private Q_SLOTS:
void copyProTxHash_clicked(); void copyProTxHash_clicked();
void copyCollateralOutpoint_clicked(); void copyCollateralOutpoint_clicked();
void handleMasternodeListChanged();
void updateDIP3ListScheduled(); void updateDIP3ListScheduled();
void updateDIP3ListForced();
}; };
#endif // MASTERNODELIST_H #endif // MASTERNODELIST_H

View File

@ -574,7 +574,7 @@ UniValue masternodelist(const JSONRPCRequest& request)
CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString() << " " << CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString() << " " <<
CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString() << " " << CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString() << " " <<
collateralAddressStr << " " << collateralAddressStr << " " <<
dmn->pdmnState->pubKeyOperator.ToString(); dmn->pdmnState->pubKeyOperator.Get().ToString();
std::string strInfo = streamInfo.str(); std::string strInfo = streamInfo.str();
if (strFilter !="" && strInfo.find(strFilter) == std::string::npos && if (strFilter !="" && strInfo.find(strFilter) == std::string::npos &&
strOutpoint.find(strFilter) == std::string::npos) return; strOutpoint.find(strFilter) == std::string::npos) return;
@ -588,7 +588,7 @@ UniValue masternodelist(const JSONRPCRequest& request)
objMN.push_back(Pair("owneraddress", CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString())); objMN.push_back(Pair("owneraddress", CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString()));
objMN.push_back(Pair("votingaddress", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString())); objMN.push_back(Pair("votingaddress", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString()));
objMN.push_back(Pair("collateraladdress", collateralAddressStr)); objMN.push_back(Pair("collateraladdress", collateralAddressStr));
objMN.push_back(Pair("pubkeyoperator", dmn->pdmnState->pubKeyOperator.ToString())); objMN.push_back(Pair("pubkeyoperator", dmn->pdmnState->pubKeyOperator.Get().ToString()));
obj.push_back(Pair(strOutpoint, objMN)); obj.push_back(Pair(strOutpoint, objMN));
} else if (strMode == "lastpaidblock") { } else if (strMode == "lastpaidblock") {
if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return; if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return;
@ -605,7 +605,7 @@ UniValue masternodelist(const JSONRPCRequest& request)
obj.push_back(Pair(strOutpoint, CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString())); obj.push_back(Pair(strOutpoint, CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString()));
} else if (strMode == "pubkeyoperator") { } else if (strMode == "pubkeyoperator") {
if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return; if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return;
obj.push_back(Pair(strOutpoint, dmn->pdmnState->pubKeyOperator.ToString())); obj.push_back(Pair(strOutpoint, dmn->pdmnState->pubKeyOperator.Get().ToString()));
} else if (strMode == "status") { } else if (strMode == "status") {
std::string strStatus = dmnToStatus(dmn); std::string strStatus = dmnToStatus(dmn);
if (strFilter !="" && strStatus.find(strFilter) == std::string::npos && if (strFilter !="" && strStatus.find(strFilter) == std::string::npos &&

View File

@ -623,7 +623,7 @@ UniValue protx_update_service(const JSONRPCRequest& request)
throw std::runtime_error(strprintf("masternode with proTxHash %s not found", ptx.proTxHash.ToString())); throw std::runtime_error(strprintf("masternode with proTxHash %s not found", ptx.proTxHash.ToString()));
} }
if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator) { if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator.Get()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key")); throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key"));
} }
@ -713,7 +713,7 @@ UniValue protx_update_registrar(const JSONRPCRequest& request)
if (!dmn) { if (!dmn) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString())); throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString()));
} }
ptx.pubKeyOperator = dmn->pdmnState->pubKeyOperator; ptx.pubKeyOperator = dmn->pdmnState->pubKeyOperator.Get();
ptx.keyIDVoting = dmn->pdmnState->keyIDVoting; ptx.keyIDVoting = dmn->pdmnState->keyIDVoting;
ptx.scriptPayout = dmn->pdmnState->scriptPayout; ptx.scriptPayout = dmn->pdmnState->scriptPayout;
@ -808,7 +808,7 @@ UniValue protx_revoke(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString())); throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString()));
} }
if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator) { if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator.Get()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key")); throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key"));
} }

View File

@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(simplifiedmns_merkleroots)
CBLSSecretKey sk; CBLSSecretKey sk;
sk.SetBuf(skBuf, sizeof(skBuf)); sk.SetBuf(skBuf, sizeof(skBuf));
smle.pubKeyOperator = sk.GetPublicKey(); smle.pubKeyOperator.Set(sk.GetPublicKey());
smle.keyIDVoting.SetHex(strprintf("%040x", i)); smle.keyIDVoting.SetHex(strprintf("%040x", i));
smle.isValid = true; smle.isValid = true;

View File

@ -459,7 +459,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash);
assert(dmn); assert(dmn);
newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator);
if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { if (dmn->pdmnState->pubKeyOperator.Get() != proTx.pubKeyOperator) {
newit->isKeyChangeProTx = true; newit->isKeyChangeProTx = true;
} }
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
@ -470,7 +470,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash);
assert(dmn); assert(dmn);
newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator);
if (dmn->pdmnState->pubKeyOperator != CBLSPublicKey()) { if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) {
newit->isKeyChangeProTx = true; newit->isKeyChangeProTx = true;
} }
} }
@ -1294,7 +1294,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
return true; // i.e. failed to find validated ProTx == conflict return true; // i.e. failed to find validated ProTx == conflict
} }
// only allow one operator key change in the mempool // only allow one operator key change in the mempool
if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { if (dmn->pdmnState->pubKeyOperator.Get() != proTx.pubKeyOperator) {
if (hasKeyChangeInMempool(proTx.proTxHash)) { if (hasKeyChangeInMempool(proTx.proTxHash)) {
return true; return true;
} }
@ -1316,7 +1316,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
return true; // i.e. failed to find validated ProTx == conflict return true; // i.e. failed to find validated ProTx == conflict
} }
// only allow one operator key change in the mempool // only allow one operator key change in the mempool
if (dmn->pdmnState->pubKeyOperator != CBLSPublicKey()) { if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) {
if (hasKeyChangeInMempool(proTx.proTxHash)) { if (hasKeyChangeInMempool(proTx.proTxHash)) {
return true; return true;
} }