Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util: add ranges.h to emulate c++20 std::ranges #4622

Merged
merged 9 commits into from
Dec 21, 2021
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ BITCOIN_CORE_H = \
util/macros.h \
util/memory.h \
util/moneystr.h \
util/ranges.h \
util/serfloat.h \
util/string.h \
util/time.h \
Expand Down
3 changes: 2 additions & 1 deletion src/bls/bls.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <serialize.h>
#include <uint256.h>
#include <util/strencodings.h>
#include <util/ranges.h>

// bls-dash uses relic, which may define DEBUG and ERROR, which leads to many warnings in some build setups
#undef ERROR
Expand Down Expand Up @@ -108,7 +109,7 @@ class CBLSWrapper
return;
}

if (std::all_of(vecBytes.begin(), vecBytes.end(), [](uint8_t c) { return c == 0; })) {
if (ranges::all_of(vecBytes, [](uint8_t c) { return c == 0; })) {
Reset();
} else {
try {
Expand Down
13 changes: 5 additions & 8 deletions src/bls/bls_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <hash.h>
#include <serialize.h>

#include <util/ranges.h>
#include <util/system.h>

#include <memory>
Expand Down Expand Up @@ -111,7 +112,7 @@ bool CBLSWorker::GenerateContributions(int quorumThreshold, const BLSIdVector& i
};
futures.emplace_back(workerPool.push(f));
}
return std::all_of(futures.begin(), futures.end(), [](auto& f){
return ranges::all_of(futures, [](auto& f){
return f.get();
});
}
Expand Down Expand Up @@ -802,13 +803,9 @@ void CBLSWorker::AsyncVerifySig(const CBLSSignature& sig, const CBLSPublicKey& p

std::unique_lock<std::mutex> l(sigVerifyMutex);

bool foundDuplicate = false;
for (const auto& s : sigVerifyQueue) {
if (s.msgHash == msgHash) {
foundDuplicate = true;
break;
}
}
bool foundDuplicate = ranges::any_of(sigVerifyQueue, [&msgHash](const auto& job){
return job.msgHash == msgHash;
});

if (foundDuplicate) {
// batched/aggregated verification does not allow duplicate hashes, so we push what we currently have and start
Expand Down
29 changes: 10 additions & 19 deletions src/coinjoin/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <shutdown.h>
#include <txmempool.h>
#include <util/moneystr.h>
#include <util/ranges.h>
#include <util/system.h>
#include <validation.h>
#include <version.h>
Expand Down Expand Up @@ -87,13 +88,10 @@ void CCoinJoinClientQueueManager::ProcessMessage(CNode* pfrom, const std::string
}

// if the queue is ready, submit if we can
if (dsq.fReady) {
for (const auto& pair : coinJoinClientManagers) {
if (pair.second->TrySubmitDenominate(dmn->pdmnState->addr, connman)) {
LogPrint(BCLog::COINJOIN, "DSQUEUE -- CoinJoin queue (%s) is ready on masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
return;
}
}
if (dsq.fReady && ranges::any_of(coinJoinClientManagers,
[&dmn, &connman](const auto& pair){ return pair.second->TrySubmitDenominate(dmn->pdmnState->addr, connman); })) {
LogPrint(BCLog::COINJOIN, "DSQUEUE -- CoinJoin queue (%s) is ready on masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
return;
} else {
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
int64_t nDsqThreshold = mmetaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount());
Expand All @@ -108,11 +106,8 @@ void CCoinJoinClientQueueManager::ProcessMessage(CNode* pfrom, const std::string

LogPrint(BCLog::COINJOIN, "DSQUEUE -- new CoinJoin queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());

for (const auto& pair : coinJoinClientManagers) {
if (pair.second->MarkAlreadyJoinedQueueAsTried(dsq)) {
break;
}
}
ranges::any_of(coinJoinClientManagers,
[&dsq](const auto& pair){ return pair.second->MarkAlreadyJoinedQueueAsTried(dsq); });

TRY_LOCK(cs_vecqueue, lockRecv);
if (!lockRecv) return;
Expand Down Expand Up @@ -597,13 +592,9 @@ bool CCoinJoinClientSession::SignFinalTransaction(const CTransaction& finalTrans
for (const auto &entry: vecEntries) {
// Check that the final transaction has all our outputs
for (const auto &txout: entry.vecTxOut) {
bool fFound = false;
for (const auto &txoutFinal: finalMutableTransaction.vout) {
if (txoutFinal == txout) {
fFound = true;
break;
}
}
bool fFound = ranges::any_of(finalMutableTransaction.vout, [&txout](const auto& txoutFinal){
return txoutFinal == txout;
});
if (!fFound) {
// Something went wrong and we'll refuse to sign. It's possible we'll be charged collateral. But that's
// better than signing if the transaction doesn't look like what we wanted.
Expand Down
11 changes: 5 additions & 6 deletions src/coinjoin/coinjoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool CCoinJoinBroadcastTx::IsValidStructure() const
if (tx->vin.size() > CCoinJoin::GetMaxPoolParticipants() * COINJOIN_ENTRY_MAX_SIZE) {
return false;
}
return std::all_of(tx->vout.cbegin(), tx->vout.cend(), [] (const auto& txOut){
return ranges::all_of(tx->vout, [] (const auto& txOut){
return CCoinJoin::IsDenominatedAmount(txOut.nValue) && txOut.scriptPubKey.IsPayToPublicKeyHash();
});
}
Expand Down Expand Up @@ -389,11 +389,10 @@ bool CCoinJoin::IsCollateralAmount(CAmount nInputAmount)

int CCoinJoin::CalculateAmountPriority(CAmount nInputAmount)
{
for (const auto& d : GetStandardDenominations()) {
// large denoms have lower value
if (nInputAmount == d) {
return (float)COIN / d * 10000;
}
if (auto optDenom = ranges::find_if_opt(GetStandardDenominations(), [&nInputAmount](const auto& denom) {
return nInputAmount == denom;
})) {
return (float)COIN / *optDenom * 10000;
}
if (nInputAmount < COIN) {
return 20000;
Expand Down
63 changes: 29 additions & 34 deletions src/coinjoin/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <script/interpreter.h>
#include <shutdown.h>
#include <txmempool.h>
#include <util/ranges.h>
#include <util/system.h>
#include <util/moneystr.h>
#include <validation.h>
Expand Down Expand Up @@ -81,13 +82,14 @@ void CCoinJoinServer::ProcessDSACCEPT(CNode* pfrom, const std::string& strComman
TRY_LOCK(cs_vecqueue, lockRecv);
if (!lockRecv) return;

for (const auto& q : vecCoinJoinQueue) {
if (WITH_LOCK(activeMasternodeInfoCs, return q.masternodeOutpoint == activeMasternodeInfo.outpoint)) {
// refuse to create another queue this often
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq is still in queue, refuse to mix\n");
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
return;
}
auto mnOutpoint = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint);

if (ranges::any_of(vecCoinJoinQueue,
[&mnOutpoint](const auto& q){return q.masternodeOutpoint == mnOutpoint;})) {
// refuse to create another queue this often
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq is still in queue, refuse to mix\n");
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
return;
}
}

Expand Down Expand Up @@ -400,13 +402,9 @@ void CCoinJoinServer::ChargeFees(CConnman& connman) const
if (nState == POOL_STATE_ACCEPTING_ENTRIES) {
LOCK(cs_coinjoin);
for (const auto& txCollateral : vecSessionCollaterals) {
bool fFound = false;
for (const auto& entry : vecEntries) {
if (*entry.txCollateral == *txCollateral) {
fFound = true;
break;
}
}
bool fFound = ranges::any_of(vecEntries, [&txCollateral](const auto& entry){
return *entry.txCollateral == *txCollateral;
});

// This queue entry didn't send us the promised transaction
if (!fFound) {
Expand Down Expand Up @@ -608,15 +606,16 @@ bool CCoinJoinServer::AddEntry(CConnman& connman, const CCoinJoinEntry& entry, P
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- txin=%s\n", __func__, txin.ToString());
LOCK(cs_coinjoin);
for (const auto& inner_entry : vecEntries) {
for (const auto& txdsin : inner_entry.vecTxDSIn) {
if (txdsin.prevout == txin.prevout) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: already have this txin in entries\n", __func__);
nMessageIDRet = ERR_ALREADY_HAVE;
// Two peers sent the same input? Can't really say who is the malicious one here,
// could be that someone is picking someone else's inputs randomly trying to force
// collateral consumption. Do not punish.
return false;
}
if (ranges::any_of(inner_entry.vecTxDSIn,
[&txin](const auto& txdsin){
return txdsin.prevout == txin.prevout;
})) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: already have this txin in entries\n", __func__);
nMessageIDRet = ERR_ALREADY_HAVE;
// Two peers sent the same input? Can't really say who is the malicious one here,
// could be that someone is picking someone else's inputs randomly trying to force
// collateral consumption. Do not punish.
return false;
}
}
vin.emplace_back(txin);
Expand Down Expand Up @@ -647,11 +646,10 @@ bool CCoinJoinServer::AddScriptSig(const CTxIn& txinNew)

LOCK(cs_coinjoin);
for (const auto& entry : vecEntries) {
for (const auto& txdsin : entry.vecTxDSIn) {
if (txdsin.scriptSig == txinNew.scriptSig) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::AddScriptSig -- already exists\n");
return false;
}
if (ranges::any_of(entry.vecTxDSIn,
[&txinNew](const auto& txdsin){ return txdsin.scriptSig == txinNew.scriptSig; })){
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::AddScriptSig -- already exists\n");
return false;
}
}

Expand Down Expand Up @@ -683,13 +681,10 @@ bool CCoinJoinServer::AddScriptSig(const CTxIn& txinNew)
bool CCoinJoinServer::IsSignaturesComplete() const
{
LOCK(cs_coinjoin);
for (const auto& entry : vecEntries) {
for (const auto& txdsin : entry.vecTxDSIn) {
if (!txdsin.fHasSig) return false;
}
}

return true;
return ranges::all_of(vecEntries, [](const auto& entry){
return ranges::all_of(entry.vecTxDSIn, [](const auto& txdsin){return txdsin.fHasSig;});
});
}

bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const
Expand Down
10 changes: 5 additions & 5 deletions src/coinjoin/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <wallet/fees.h>
#include <wallet/wallet.h>

#include <numeric>

inline unsigned int GetSizeOfCompactSizeDiff(uint64_t nSizePrev, uint64_t nSizeNew)
{
assert(nSizePrev <= nSizeNew);
Expand Down Expand Up @@ -221,12 +223,10 @@ CAmount CTransactionBuilder::GetAmountLeft(const CAmount nAmountInitial, const C

CAmount CTransactionBuilder::GetAmountUsed() const
{
CAmount nAmountUsed{0};
LOCK(cs_outputs);
for (const auto& out : vecOutputs) {
nAmountUsed += out->GetAmount();
}
return nAmountUsed;
return std::accumulate(vecOutputs.begin(), vecOutputs.end(), CAmount{0}, [](const CAmount& a, const auto& b){
return a + b->GetAmount();
});
}

CAmount CTransactionBuilder::GetFee(unsigned int nBytes) const
Expand Down
43 changes: 19 additions & 24 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ CDeterministicMNCPtr CDeterministicMNList::GetValidMN(const uint256& proTxHash)

CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CBLSPublicKey& pubKey) const
{
for (const auto& p : mnMap) {
if (p.second->pdmnState->pubKeyOperator.Get() == pubKey) {
return p.second;
}
const auto it = ranges::find_if(mnMap,
[&pubKey](const auto& p){return p.second->pdmnState->pubKeyOperator.Get() == pubKey;});
if (it == mnMap.end()) {
return nullptr;
}
return nullptr;
return it->second;
}

CDeterministicMNCPtr CDeterministicMNList::GetMNByCollateral(const COutPoint& collateralOutpoint) const
Expand Down Expand Up @@ -1014,11 +1014,12 @@ CDeterministicMNList CDeterministicMNManager::GetListForBlock(const CBlockIndex*
mnListsCache.emplace(snapshot.GetBlockHash(), snapshot);
} else {
// keep snapshots for yet alive quorums
for (auto& p_llmq : Params().GetConsensus().llmqs) {
if ((snapshot.GetHeight() % p_llmq.second.dkgInterval == 0) && (snapshot.GetHeight() + p_llmq.second.dkgInterval * (p_llmq.second.keepOldConnections + 1) >= tipIndex->nHeight)) {
mnListsCache.emplace(snapshot.GetBlockHash(), snapshot);
break;
}
if (ranges::any_of(Params().GetConsensus().llmqs, [&snapshot, this](const auto& p_llmq){
const auto& [_, params] = p_llmq; LOCK(cs);
return (snapshot.GetHeight() % params.dkgInterval == 0) &&
(snapshot.GetHeight() + params.dkgInterval * (params.keepOldConnections + 1) >= tipIndex->nHeight);
})) {
mnListsCache.emplace(snapshot.GetBlockHash(), snapshot);
}
}
}
Expand Down Expand Up @@ -1084,27 +1085,21 @@ void CDeterministicMNManager::CleanupCache(int nHeight)
toDeleteLists.emplace_back(p.first);
continue;
}
bool fQuorumCache{false};
for (auto& p_llmq : Params().GetConsensus().llmqs) {
if ((p.second.GetHeight() % p_llmq.second.dkgInterval == 0) && (p.second.GetHeight() + p_llmq.second.dkgInterval * (p_llmq.second.keepOldConnections + 1) >= nHeight)) {
fQuorumCache = true;
break;
}
}
bool fQuorumCache = ranges::any_of(Params().GetConsensus().llmqs, [&nHeight, &p](const auto& p_llmq){
const auto& [_, params] = p_llmq;
return (p.second.GetHeight() % params.dkgInterval == 0) &&
(p.second.GetHeight() + params.dkgInterval * (params.keepOldConnections + 1) >= nHeight);
});
if (fQuorumCache) {
// at least one quorum could be using it, keep it
continue;
}
// no alive quorums using it, see if it was a cache for the tip or for a now outdated quorum
if (tipIndex && tipIndex->pprev && (p.first == tipIndex->pprev->GetBlockHash())) {
toDeleteLists.emplace_back(p.first);
} else {
for (auto& p_llmq : Params().GetConsensus().llmqs) {
if (p.second.GetHeight() % p_llmq.second.dkgInterval == 0) {
toDeleteLists.emplace_back(p.first);
break;
}
}
} else if (ranges::any_of(Params().GetConsensus().llmqs,
[&p](const auto& p_llmq){ return p.second.GetHeight() % p_llmq.second.dkgInterval == 0; })) {
toDeleteLists.emplace_back(p.first);
}
}
for (const auto& h : toDeleteLists) {
Expand Down
14 changes: 2 additions & 12 deletions src/llmq/dkgsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)

receivedVvecs[member->idx] = qc.vvec;

int receivedCount = 0;
for (const auto& m : members) {
if (!m->contributions.empty()) {
receivedCount++;
}
}
int receivedCount = ranges::count_if(members, [](const auto& m){return !m->contributions.empty();});

logger.Batch("received and relayed contribution. received=%d/%d, time=%d", receivedCount, members.size(), t1.count());

Expand Down Expand Up @@ -1174,12 +1169,7 @@ void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan
return true;
});

int receivedCount = 0;
for (const auto& m : members) {
if (!m->prematureCommitments.empty()) {
receivedCount++;
}
}
int receivedCount = ranges::count_if(members, [](const auto& m){ return !m->prematureCommitments.empty(); });

t1.stop();

Expand Down
2 changes: 1 addition & 1 deletion src/llmq/dkgsessionhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class CDKGPendingMessages
ret.emplace_back(std::make_pair(bm.first, std::move(msg)));
}

return std::move(ret);
return ret;
}
};

Expand Down
Loading