mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
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:
parent
11699f540f
commit
c1f756fd90
@ -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;
|
||||||
|
107
src/bls/bls.h
107
src/bls/bls.h
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
clientmodel->setMasternodeList(newList);
|
||||||
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);
|
|
||||||
nLastMasternodeUpdateNotification = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)
|
static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (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::updateDIP3ListForced()
|
void MasternodeList::updateDIP3List()
|
||||||
{
|
|
||||||
updateDIP3List(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MasternodeList::updateDIP3List(bool fForce)
|
|
||||||
{
|
{
|
||||||
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++) {
|
||||||
|
@ -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
|
||||||
|
@ -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 &&
|
||||||
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user