Skip to content

Commit

Permalink
Optimize memory use for blockindex (#682)
Browse files Browse the repository at this point in the history
* optimize memory use for blockindex

* use function reference
  • Loading branch information
alex v committed May 23, 2020
1 parent f13391f commit 99e27d6
Show file tree
Hide file tree
Showing 7 changed files with 812 additions and 670 deletions.
40 changes: 16 additions & 24 deletions src/chain.h
Expand Up @@ -222,21 +222,12 @@ class CBlockIndex
int64_t nCFSupply;
int64_t nCFLocked;

std::vector<std::pair<uint256, int>> vProposalVotes;
std::vector<std::pair<uint256, int>> vPaymentRequestVotes;
std::map<uint256, bool> mapSupport;
std::map<uint256, uint64_t> mapConsultationVotes;

std::string strDZeel;

unsigned int nFlags; // ppcoin: block index flags

uint64_t nStakeModifier; // hash modifier for proof-of-stake

// proof-of-stake specific fields
COutPoint prevoutStake;
unsigned int nStakeTime;

arith_uint256 hashProof;

//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
Expand All @@ -262,17 +253,11 @@ class CBlockIndex
nFlags = 0;
nStakeModifier = 0;
hashProof = arith_uint256();
prevoutStake.SetNull();
nStakeTime = 0;
nVersion = 0;
hashMerkleRoot = uint256();
nTime = 0;
nBits = 0;
nNonce = 0;
vProposalVotes.clear();
vPaymentRequestVotes.clear();
mapSupport.clear();
mapConsultationVotes.clear();
}

CBlockIndex()
Expand All @@ -298,13 +283,6 @@ class CBlockIndex
if (block.IsProofOfStake())
{
SetProofOfStake();
prevoutStake = block.vtx[1].vin[0].prevout;
nStakeTime = block.vtx[1].nTime;
}
else
{
prevoutStake.SetNull();
nStakeTime = 0;
}

nVersion = block.nVersion;
Expand Down Expand Up @@ -389,13 +367,12 @@ class CBlockIndex

std::string ToString() const
{
return strprintf("CBlockIndex(nprev=%p, nFile=%u, nHeight=%d, nMint=%s, nCFSupply=%s, nCFLocked=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016x, hashProof=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
return strprintf("CBlockIndex(nprev=%p, nFile=%u, nHeight=%d, nMint=%s, nCFSupply=%s, nCFLocked=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016x, hashProof=%s, merkle=%s, hashBlock=%s)",
pprev, nFile, nHeight,
FormatMoney(nMint), FormatMoney(nCFSupply), FormatMoney(nCFLocked),
GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW",
nStakeModifier,
hashProof.ToString(),
prevoutStake.ToString(), nStakeTime,
hashMerkleRoot.ToString(),
GetBlockHash().ToString());
}
Expand Down Expand Up @@ -484,10 +461,25 @@ class CDiskBlockIndex : public CBlockIndex
uint256 hashPrev;
uint256 hashNext;

std::vector<std::pair<uint256, int>> vProposalVotes;
std::vector<std::pair<uint256, int>> vPaymentRequestVotes;
std::map<uint256, bool> mapSupport;
std::map<uint256, uint64_t> mapConsultationVotes;

// proof-of-stake specific fields
COutPoint prevoutStake;
unsigned int nStakeTime;

CDiskBlockIndex() {
hashPrev = uint256();
hashNext = uint256();
blockHash = uint256();
prevoutStake.SetNull();
nStakeTime = 0;
vProposalVotes.clear();
vPaymentRequestVotes.clear();
mapSupport.clear();
mapConsultationVotes.clear();
}

explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
Expand Down
140 changes: 79 additions & 61 deletions src/consensus/dao.cpp
Expand Up @@ -377,103 +377,121 @@ bool VoteStep(const CValidationState& state, CBlockIndex *pindexNew, const bool

if (fCFund)
{
for(unsigned int i = 0; i < pindexblock->vProposalVotes.size(); i++)
auto pVotes = GetProposalVotes(pindexblock->GetBlockHash());
if (pVotes != nullptr)
{
if(mapSeen.count(pindexblock->vProposalVotes[i].first) == 0)
for(unsigned int i = 0; i < pVotes->size(); i++)
{
LogPrint("daoextra", "%s: Found vote %d for proposal %s at block height %d\n", __func__,
pindexblock->vProposalVotes[i].second, pindexblock->vProposalVotes[i].first.ToString(),
pindexblock->nHeight);
if(mapSeen.count((*pVotes)[i].first) == 0)
{
LogPrint("daoextra", "%s: Found vote %d for proposal %s at block height %d\n", __func__,
(*pVotes)[i].second, (*pVotes)[i].first.ToString(),
pindexblock->nHeight);

if(mapCacheProposalsToUpdate.count(pindexblock->vProposalVotes[i].first) == 0)
mapCacheProposalsToUpdate[pindexblock->vProposalVotes[i].first] = make_pair(make_pair(0, 0), 0);
if(mapCacheProposalsToUpdate.count((*pVotes)[i].first) == 0)
mapCacheProposalsToUpdate[(*pVotes)[i].first] = make_pair(make_pair(0, 0), 0);

if(pindexblock->vProposalVotes[i].second == VoteFlags::VOTE_YES)
mapCacheProposalsToUpdate[pindexblock->vProposalVotes[i].first].first.first += 1;
else if(pindexblock->vProposalVotes[i].second == VoteFlags::VOTE_ABSTAIN)
mapCacheProposalsToUpdate[pindexblock->vProposalVotes[i].first].second += 1;
else if(pindexblock->vProposalVotes[i].second == VoteFlags::VOTE_NO)
mapCacheProposalsToUpdate[pindexblock->vProposalVotes[i].first].first.second += 1;
if((*pVotes)[i].second == VoteFlags::VOTE_YES)
mapCacheProposalsToUpdate[(*pVotes)[i].first].first.first += 1;
else if((*pVotes)[i].second == VoteFlags::VOTE_ABSTAIN)
mapCacheProposalsToUpdate[(*pVotes)[i].first].second += 1;
else if((*pVotes)[i].second == VoteFlags::VOTE_NO)
mapCacheProposalsToUpdate[(*pVotes)[i].first].first.second += 1;

mapSeen[pindexblock->vProposalVotes[i].first]=true;
mapSeen[(*pVotes)[i].first]=true;
}
}
}

for(unsigned int i = 0; i < pindexblock->vPaymentRequestVotes.size(); i++)
auto prVotes = GetPaymentRequestVotes(pindexblock->GetBlockHash());
if (prVotes != nullptr)
{
if(mapSeen.count(pindexblock->vPaymentRequestVotes[i].first) == 0)
for(unsigned int i = 0; i < prVotes->size(); i++)
{
LogPrint("daoextra", "%s: Found vote %d for payment request %s at block height %d\n", __func__,
pindexblock->vPaymentRequestVotes[i].second, pindexblock->vPaymentRequestVotes[i].first.ToString(),
pindexblock->nHeight);
if(mapSeen.count((*prVotes)[i].first) == 0)
{
LogPrint("daoextra", "%s: Found vote %d for payment request %s at block height %d\n", __func__,
(*prVotes)[i].second, (*prVotes)[i].first.ToString(),
pindexblock->nHeight);

if(mapCachePaymentRequestToUpdate.count(pindexblock->vPaymentRequestVotes[i].first) == 0)
mapCachePaymentRequestToUpdate[pindexblock->vPaymentRequestVotes[i].first] = make_pair(make_pair(0, 0), 0);
if(mapCachePaymentRequestToUpdate.count((*prVotes)[i].first) == 0)
mapCachePaymentRequestToUpdate[(*prVotes)[i].first] = make_pair(make_pair(0, 0), 0);

if(pindexblock->vPaymentRequestVotes[i].second == VoteFlags::VOTE_YES)
mapCachePaymentRequestToUpdate[pindexblock->vPaymentRequestVotes[i].first].first.first += 1;
else if(pindexblock->vPaymentRequestVotes[i].second == VoteFlags::VOTE_ABSTAIN)
mapCachePaymentRequestToUpdate[pindexblock->vPaymentRequestVotes[i].first].second += 1;
else if(pindexblock->vPaymentRequestVotes[i].second == VoteFlags::VOTE_NO)
mapCachePaymentRequestToUpdate[pindexblock->vPaymentRequestVotes[i].first].first.second += 1;
if((*prVotes)[i].second == VoteFlags::VOTE_YES)
mapCachePaymentRequestToUpdate[(*prVotes)[i].first].first.first += 1;
else if((*prVotes)[i].second == VoteFlags::VOTE_ABSTAIN)
mapCachePaymentRequestToUpdate[(*prVotes)[i].first].second += 1;
else if((*prVotes)[i].second == VoteFlags::VOTE_NO)
mapCachePaymentRequestToUpdate[(*prVotes)[i].first].first.second += 1;

mapSeen[pindexblock->vPaymentRequestVotes[i].first]=true;
mapSeen[(*prVotes)[i].first]=true;
}
}
}
}

if (fDAOConsultations)
{
for (auto& it: pindexblock->mapSupport)
{
if (!it.second)
continue;
auto supp = GetSupport(pindexblock->GetBlockHash());

if (!mapSeenSupport.count(it.first))
if (supp != nullptr)
{
for (auto& it: *supp)
{
LogPrint("daoextra", "%s: Found support vote for %s at block height %d\n", __func__,
it.first.ToString(),
pindexblock->nHeight);
if (!it.second)
continue;

if(mapCacheSupportToUpdate.count(it.first) == 0)
mapCacheSupportToUpdate[it.first] = 0;
if (!mapSeenSupport.count(it.first))
{
LogPrint("daoextra", "%s: Found support vote for %s at block height %d\n", __func__,
it.first.ToString(),
pindexblock->nHeight);

mapCacheSupportToUpdate[it.first] += 1;
mapSeenSupport[it.first]=true;
if(mapCacheSupportToUpdate.count(it.first) == 0)
mapCacheSupportToUpdate[it.first] = 0;

mapCacheSupportToUpdate[it.first] += 1;
mapSeenSupport[it.first]=true;
}
}
}

for (auto&it: pindexblock->mapConsultationVotes)
{
if (mapSeen.count(it.first))
continue;
auto cVotes = GetConsultationVotes(pindexblock->GetBlockHash());

if (view.HaveConsultation(it.first) || view.HaveConsultationAnswer(it.first))
if (cVotes != nullptr)
{
for (auto&it: *cVotes)
{
if (mapSeen.count(it.first))
continue;

if (it.second == VoteFlags::VOTE_ABSTAIN && view.GetConsultationAnswer(it.first, answer))
if (view.HaveConsultation(it.first) || view.HaveConsultationAnswer(it.first))
{
if(mapCacheConsultationToUpdate.count(std::make_pair(answer.parent,it.second)) == 0)
mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)] = 0;

mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)] += 1;
if (it.second == VoteFlags::VOTE_ABSTAIN && view.GetConsultationAnswer(it.first, answer))
{
if(mapCacheConsultationToUpdate.count(std::make_pair(answer.parent,it.second)) == 0)
mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)] = 0;

mapSeen[it.first]=true;
mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)] += 1;

LogPrint("daoextra", "%s: Found consultation answer vote %d for %s at block height %d (total %d)\n", __func__,
it.second, answer.parent.ToString(), pindexblock->nHeight, mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)]);
}
else
{
if(mapCacheConsultationToUpdate.count(std::make_pair(it.first,it.second)) == 0)
mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)] = 0;
mapSeen[it.first]=true;

mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)] += 1;
LogPrint("daoextra", "%s: Found consultation answer vote %d for %s at block height %d (total %d)\n", __func__,
it.second, answer.parent.ToString(), pindexblock->nHeight, mapCacheConsultationToUpdate[std::make_pair(answer.parent,it.second)]);
}
else
{
if(mapCacheConsultationToUpdate.count(std::make_pair(it.first,it.second)) == 0)
mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)] = 0;

mapSeen[it.first]=true;
mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)] += 1;

LogPrint("daoextra", "%s: Found consultation vote %d for %s at block height %d (total %d)\n", __func__,
it.second, it.first.ToString(), pindexblock->nHeight, mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)]);
mapSeen[it.first]=true;

LogPrint("daoextra", "%s: Found consultation vote %d for %s at block height %d (total %d)\n", __func__,
it.second, it.first.ToString(), pindexblock->nHeight, mapCacheConsultationToUpdate[std::make_pair(it.first,it.second)]);
}
}
}
}
Expand Down

0 comments on commit 99e27d6

Please sign in to comment.