Skip to content

Commit

Permalink
Merge pull request #487 from aguycalled/cfunddb-migration
Browse files Browse the repository at this point in the history
Use of the CoinsDB for the Community Fund
  • Loading branch information
proletesseract authored May 30, 2019
2 parents f501b18 + 24b6f5a commit a8f425b
Show file tree
Hide file tree
Showing 25 changed files with 1,561 additions and 831 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,6 @@ ui_*.h
# IDE specific
.idea/*
.vscode
*.creator.user
*.cflags
*.cxxflags
*.creator.*
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,12 @@ def run_test(self):
# Paymentrequest must be accepted now
assert(self.nodes[0].getpaymentrequest(paymentrequestid0)["state"] == 1)
assert(self.nodes[0].getpaymentrequest(paymentrequestid0)["status"] == "accepted")


end_cycle(self.nodes[0])

# Locked amount should be 0, as this was the only payment request and the proposal was expired
print(self.nodes[0].cfundstats())
assert(self.nodes[0].cfundstats()["funds"]["locked"] == 0)
assert(self.nodes[0].getproposal(proposalid0)["status"] == "expired")

Expand Down
2 changes: 1 addition & 1 deletion qa/rpc-tests/cfund-vote.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def run_test(self):
assert(self.nodes[0].getproposal(proposalid0)["votingCycle"] == 2)

# Check the number of votes
assert(self.nodes[0].getproposal(proposalid0)["votesYes"] == 0 and self.nodes[0].getproposal(proposalid0)["votesNo"] == 0)
assert(self.nodes[0].getproposal(proposalid0)["votesYes"] == 1 and self.nodes[0].getproposal(proposalid0)["votesNo"] == 0)
assert(self.nodes[0].getproposal(proposalid0)["status"] == "pending" and self.nodes[0].getproposal(proposalid0)["state"] == 0)

# Move back to the end of the previous cycle
Expand Down
232 changes: 228 additions & 4 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include <assert.h>

using namespace CFund;

/**
* calculate number of bytes for the bitmask, and its number of non-zero bytes
* each bit in the bitmask represents the availability of one output, but the
Expand Down Expand Up @@ -42,18 +44,34 @@ bool CCoins::Spend(uint32_t nPos)
}

bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::GetProposal(const uint256 &pid, CProposal &proposal) const { return false; }
bool CCoinsView::GetAllProposals(CProposalMap& map) { return false; }
bool CCoinsView::GetPaymentRequest(const uint256 &prid, CPaymentRequest &prequest) const { return false; }
bool CCoinsView::GetAllPaymentRequests(CPaymentRequestMap& map) { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
bool CCoinsView::HaveProposal(const uint256 &pid) const { return false; }
bool CCoinsView::HavePaymentRequest(const uint256 &prid) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals,
CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }


CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
bool CCoinsViewBacked::GetProposal(const uint256 &pid, CProposal &proposal) const { return base->GetProposal(pid, proposal); }
bool CCoinsViewBacked::GetAllProposals(CProposalMap& map) { return base->GetAllProposals(map); }
bool CCoinsViewBacked::GetPaymentRequest(const uint256 &prid, CPaymentRequest &prequest) const { return base->GetPaymentRequest(prid, prequest); }
bool CCoinsViewBacked::GetAllPaymentRequests(CPaymentRequestMap& map) { return base->GetAllPaymentRequests(map); }
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
bool CCoinsViewBacked::HaveProposal(const uint256 &pid) const { return base->HaveProposal(pid); }
bool CCoinsViewBacked::HavePaymentRequest(const uint256 &prid) const { return base->HavePaymentRequest(prid); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals,
CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) {
return base->BatchWrite(mapCoins, mapProposals, mapPaymentRequests, hashBlock);
}
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }

SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
Expand Down Expand Up @@ -87,6 +105,41 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
return ret;
}

CProposalMap::const_iterator CCoinsViewCache::FetchProposal(const uint256 &pid) const {
CProposalMap::iterator it = cacheProposals.find(pid);

if (it != cacheProposals.end())
return it;

CProposal tmp;

if (!base->GetProposal(pid, tmp))
return cacheProposals.end();

CProposalMap::iterator ret = cacheProposals.insert(std::make_pair(pid, CProposal())).first;
tmp.swap(ret->second);

return ret;
}

CPaymentRequestMap::const_iterator CCoinsViewCache::FetchPaymentRequest(const uint256 &prid) const {
CPaymentRequestMap::iterator it = cachePaymentRequests.find(prid);

if (it != cachePaymentRequests.end())
return it;

CPaymentRequest tmp;

if (!base->GetPaymentRequest(prid, tmp))
return cachePaymentRequests.end();

CPaymentRequestMap::iterator ret = cachePaymentRequests.insert(std::make_pair(prid, CPaymentRequest())).first;
tmp.swap(ret->second);

return ret;
}


bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
CCoinsMap::const_iterator it = FetchCoins(txid);
if (it != cacheCoins.end()) {
Expand All @@ -96,6 +149,54 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
return false;
}

bool CCoinsViewCache::GetProposal(const uint256 &pid, CProposal &proposal) const {
CProposalMap::const_iterator it = FetchProposal(pid);
if (it != cacheProposals.end()) {
proposal = it->second;
return true;
}
return false;
}

bool CCoinsViewCache::GetAllProposals(CProposalMap& mapProposal) {
mapProposal.clear();
mapProposal.insert(cacheProposals.begin(), cacheProposals.end());

CProposalMap baseMap;

if (!base->GetAllProposals(baseMap))
return false;

for (CProposalMap::iterator it = baseMap.begin(); it != baseMap.end(); it++)
mapProposal.insert(make_pair(it->first, it->second));

return true;
}

bool CCoinsViewCache::GetPaymentRequest(const uint256 &pid, CPaymentRequest &prequest) const {
CPaymentRequestMap::const_iterator it = FetchPaymentRequest(pid);
if (it != cachePaymentRequests.end()) {
prequest = it->second;
return true;
}
return false;
}

bool CCoinsViewCache::GetAllPaymentRequests(CPaymentRequestMap& mapPaymentRequests) {
mapPaymentRequests.clear();
mapPaymentRequests.insert(cachePaymentRequests.begin(), cachePaymentRequests.end());

CPaymentRequestMap baseMap;

if (!base->GetAllPaymentRequests(baseMap))
return false;

for (CPaymentRequestMap::iterator it = baseMap.begin(); it != baseMap.end(); it++)
mapPaymentRequests.insert(make_pair(it->first, it->second));

return true;
}

CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
assert(!hasModifier);
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
Expand All @@ -117,6 +218,20 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
return CCoinsModifier(*this, ret.first, cachedCoinUsage);
}

CProposalModifier CCoinsViewCache::ModifyProposal(const uint256 &pid) {
assert(!hasModifier);
std::pair<CProposalMap::iterator, bool> ret = cacheProposals.insert(std::make_pair(pid, CProposal()));
ret.first->second.fDirty = true;
return CProposalModifier(*this, ret.first);
}

CPaymentRequestModifier CCoinsViewCache::ModifyPaymentRequest(const uint256 &prid) {
assert(!hasModifier);
std::pair<CPaymentRequestMap::iterator, bool> ret = cachePaymentRequests.insert(std::make_pair(prid, CPaymentRequest()));
ret.first->second.fDirty = true;
return CPaymentRequestModifier(*this, ret.first);
}

// ModifyNewCoins has to know whether the new outputs its creating are for a
// coinbase or not. If they are for a coinbase, it can not mark them as fresh.
// This is to ensure that the historical duplicate coinbases before BIP30 was
Expand All @@ -132,6 +247,46 @@ CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbas
return CCoinsModifier(*this, ret.first, 0);
}

bool CCoinsViewCache::AddProposal(const CProposal& proposal) const {
if (HaveProposal(proposal.hash))
return false;

cacheProposals.insert(std::make_pair(proposal.hash, proposal));

return true;
}

bool CCoinsViewCache::AddPaymentRequest(const CPaymentRequest& prequest) const {
if (HavePaymentRequest(prequest.hash))
return false;
cachePaymentRequests.insert(std::make_pair(prequest.hash, prequest));
return true;
}

bool CCoinsViewCache::RemoveProposal(const uint256 &pid) const {
if (!HaveProposal(pid))
return false;

cacheProposals[pid] = CProposal();
cacheProposals[pid].SetNull();

assert(cacheProposals[pid].IsNull());

return true;
}

bool CCoinsViewCache::RemovePaymentRequest(const uint256 &prid) const {
if (!HavePaymentRequest(prid))
return false;

cachePaymentRequests[prid] = CPaymentRequest();
cachePaymentRequests[prid].SetNull();

assert(cachePaymentRequests[prid].IsNull());

return true;
}

const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const {
CCoinsMap::const_iterator it = FetchCoins(txid);
if (it == cacheCoins.end()) {
Expand All @@ -150,6 +305,16 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
return (it != cacheCoins.end() && !it->second.coins.vout.empty());
}

bool CCoinsViewCache::HaveProposal(const uint256 &id) const {
CProposalMap::const_iterator it = FetchProposal(id);
return (it != cacheProposals.end() && !it->second.IsNull());
}

bool CCoinsViewCache::HavePaymentRequest(const uint256 &id) const {
CPaymentRequestMap::const_iterator it = FetchPaymentRequest(id);
return (it != cachePaymentRequests.end() && !it->second.IsNull());
}

bool CCoinsViewCache::HaveCoinsInCache(const uint256 &txid) const {
CCoinsMap::const_iterator it = cacheCoins.find(txid);
return it != cacheCoins.end();
Expand All @@ -165,7 +330,7 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
hashBlock = hashBlockIn;
}

bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals, CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlockIn) {
assert(!hasModifier);
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
Expand Down Expand Up @@ -206,12 +371,41 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld);
}

for (CProposalMap::iterator it = mapProposals.begin(); it != mapProposals.end();) {
if (it->second.IsNull()) {
CProposalMap::iterator itUs = cacheProposals.find(it->first);
if (itUs != cacheProposals.end()) {
cacheProposals.erase(itUs);
}
} else {
CProposal& entry = cacheProposals[it->first];
entry.swap(it->second);
}
CProposalMap::iterator itOld = it++;
mapProposals.erase(itOld);
}

for (CPaymentRequestMap::iterator it = mapPaymentRequests.begin(); it != mapPaymentRequests.end();) {
if (it->second.IsNull()) {
CPaymentRequestMap::iterator itUs = cachePaymentRequests.find(it->first);
if (itUs != cachePaymentRequests.end()) {
cachePaymentRequests.erase(itUs);
}
} else {
CPaymentRequest& entry = cachePaymentRequests[it->first];
entry.swap(it->second);
}
CPaymentRequestMap::iterator itOld = it++;
mapPaymentRequests.erase(itOld);
}

hashBlock = hashBlockIn;
return true;
}

bool CCoinsViewCache::Flush() {
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
bool fOk = base->BatchWrite(cacheCoins, cacheProposals, cachePaymentRequests, hashBlock);
cacheCoins.clear();
cachedCoinsUsage = 0;
return fOk;
Expand Down Expand Up @@ -301,6 +495,36 @@ CCoinsModifier::~CCoinsModifier()
}
}

CProposalModifier::CProposalModifier(CCoinsViewCache& cache_, CProposalMap::iterator it_) : cache(cache_), it(it_) {
assert(!cache.hasModifier);
cache.hasModifier = true;
}

CProposalModifier::~CProposalModifier()
{
assert(cache.hasModifier);
cache.hasModifier = false;

if (it->second.IsNull()) {
cache.cacheProposals.erase(it);
}
}

CPaymentRequestModifier::CPaymentRequestModifier(CCoinsViewCache& cache_, CPaymentRequestMap::iterator it_) : cache(cache_), it(it_) {
assert(!cache.hasModifier);
cache.hasModifier = true;
}

CPaymentRequestModifier::~CPaymentRequestModifier()
{
assert(cache.hasModifier);
cache.hasModifier = false;

if (it->second.IsNull()) {
cache.cachePaymentRequests.erase(it);
}
}

CCoinsViewCursor::~CCoinsViewCursor()
{
}
Loading

0 comments on commit a8f425b

Please sign in to comment.