Skip to content

Commit a8f425b

Browse files
Merge pull request #487 from aguycalled/cfunddb-migration
Use of the CoinsDB for the Community Fund
2 parents f501b18 + 24b6f5a commit a8f425b

25 files changed

+1561
-831
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,6 @@ ui_*.h
136136
# IDE specific
137137
.idea/*
138138
.vscode
139-
*.creator.user
139+
*.cflags
140+
*.cxxflags
141+
*.creator.*

qa/rpc-tests/cfund-paymentrequest-state-accept-expired-proposal.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,12 @@ def run_test(self):
180180
# Paymentrequest must be accepted now
181181
assert(self.nodes[0].getpaymentrequest(paymentrequestid0)["state"] == 1)
182182
assert(self.nodes[0].getpaymentrequest(paymentrequestid0)["status"] == "accepted")
183+
184+
185+
end_cycle(self.nodes[0])
186+
183187
# Locked amount should be 0, as this was the only payment request and the proposal was expired
188+
print(self.nodes[0].cfundstats())
184189
assert(self.nodes[0].cfundstats()["funds"]["locked"] == 0)
185190
assert(self.nodes[0].getproposal(proposalid0)["status"] == "expired")
186191

qa/rpc-tests/cfund-vote.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def run_test(self):
9898
assert(self.nodes[0].getproposal(proposalid0)["votingCycle"] == 2)
9999

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

104104
# Move back to the end of the previous cycle

src/coins.cpp

Lines changed: 228 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include <assert.h>
1111

12+
using namespace CFund;
13+
1214
/**
1315
* calculate number of bytes for the bitmask, and its number of non-zero bytes
1416
* each bit in the bitmask represents the availability of one output, but the
@@ -42,18 +44,34 @@ bool CCoins::Spend(uint32_t nPos)
4244
}
4345

4446
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
47+
bool CCoinsView::GetProposal(const uint256 &pid, CProposal &proposal) const { return false; }
48+
bool CCoinsView::GetAllProposals(CProposalMap& map) { return false; }
49+
bool CCoinsView::GetPaymentRequest(const uint256 &prid, CPaymentRequest &prequest) const { return false; }
50+
bool CCoinsView::GetAllPaymentRequests(CPaymentRequestMap& map) { return false; }
4551
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
52+
bool CCoinsView::HaveProposal(const uint256 &pid) const { return false; }
53+
bool CCoinsView::HavePaymentRequest(const uint256 &prid) const { return false; }
4654
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
47-
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
55+
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals,
56+
CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) { return false; }
4857
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
4958

5059

5160
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
5261
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
62+
bool CCoinsViewBacked::GetProposal(const uint256 &pid, CProposal &proposal) const { return base->GetProposal(pid, proposal); }
63+
bool CCoinsViewBacked::GetAllProposals(CProposalMap& map) { return base->GetAllProposals(map); }
64+
bool CCoinsViewBacked::GetPaymentRequest(const uint256 &prid, CPaymentRequest &prequest) const { return base->GetPaymentRequest(prid, prequest); }
65+
bool CCoinsViewBacked::GetAllPaymentRequests(CPaymentRequestMap& map) { return base->GetAllPaymentRequests(map); }
5366
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
67+
bool CCoinsViewBacked::HaveProposal(const uint256 &pid) const { return base->HaveProposal(pid); }
68+
bool CCoinsViewBacked::HavePaymentRequest(const uint256 &prid) const { return base->HavePaymentRequest(prid); }
5469
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
5570
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
56-
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
71+
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals,
72+
CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) {
73+
return base->BatchWrite(mapCoins, mapProposals, mapPaymentRequests, hashBlock);
74+
}
5775
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
5876

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

108+
CProposalMap::const_iterator CCoinsViewCache::FetchProposal(const uint256 &pid) const {
109+
CProposalMap::iterator it = cacheProposals.find(pid);
110+
111+
if (it != cacheProposals.end())
112+
return it;
113+
114+
CProposal tmp;
115+
116+
if (!base->GetProposal(pid, tmp))
117+
return cacheProposals.end();
118+
119+
CProposalMap::iterator ret = cacheProposals.insert(std::make_pair(pid, CProposal())).first;
120+
tmp.swap(ret->second);
121+
122+
return ret;
123+
}
124+
125+
CPaymentRequestMap::const_iterator CCoinsViewCache::FetchPaymentRequest(const uint256 &prid) const {
126+
CPaymentRequestMap::iterator it = cachePaymentRequests.find(prid);
127+
128+
if (it != cachePaymentRequests.end())
129+
return it;
130+
131+
CPaymentRequest tmp;
132+
133+
if (!base->GetPaymentRequest(prid, tmp))
134+
return cachePaymentRequests.end();
135+
136+
CPaymentRequestMap::iterator ret = cachePaymentRequests.insert(std::make_pair(prid, CPaymentRequest())).first;
137+
tmp.swap(ret->second);
138+
139+
return ret;
140+
}
141+
142+
90143
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
91144
CCoinsMap::const_iterator it = FetchCoins(txid);
92145
if (it != cacheCoins.end()) {
@@ -96,6 +149,54 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
96149
return false;
97150
}
98151

152+
bool CCoinsViewCache::GetProposal(const uint256 &pid, CProposal &proposal) const {
153+
CProposalMap::const_iterator it = FetchProposal(pid);
154+
if (it != cacheProposals.end()) {
155+
proposal = it->second;
156+
return true;
157+
}
158+
return false;
159+
}
160+
161+
bool CCoinsViewCache::GetAllProposals(CProposalMap& mapProposal) {
162+
mapProposal.clear();
163+
mapProposal.insert(cacheProposals.begin(), cacheProposals.end());
164+
165+
CProposalMap baseMap;
166+
167+
if (!base->GetAllProposals(baseMap))
168+
return false;
169+
170+
for (CProposalMap::iterator it = baseMap.begin(); it != baseMap.end(); it++)
171+
mapProposal.insert(make_pair(it->first, it->second));
172+
173+
return true;
174+
}
175+
176+
bool CCoinsViewCache::GetPaymentRequest(const uint256 &pid, CPaymentRequest &prequest) const {
177+
CPaymentRequestMap::const_iterator it = FetchPaymentRequest(pid);
178+
if (it != cachePaymentRequests.end()) {
179+
prequest = it->second;
180+
return true;
181+
}
182+
return false;
183+
}
184+
185+
bool CCoinsViewCache::GetAllPaymentRequests(CPaymentRequestMap& mapPaymentRequests) {
186+
mapPaymentRequests.clear();
187+
mapPaymentRequests.insert(cachePaymentRequests.begin(), cachePaymentRequests.end());
188+
189+
CPaymentRequestMap baseMap;
190+
191+
if (!base->GetAllPaymentRequests(baseMap))
192+
return false;
193+
194+
for (CPaymentRequestMap::iterator it = baseMap.begin(); it != baseMap.end(); it++)
195+
mapPaymentRequests.insert(make_pair(it->first, it->second));
196+
197+
return true;
198+
}
199+
99200
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
100201
assert(!hasModifier);
101202
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
@@ -117,6 +218,20 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
117218
return CCoinsModifier(*this, ret.first, cachedCoinUsage);
118219
}
119220

221+
CProposalModifier CCoinsViewCache::ModifyProposal(const uint256 &pid) {
222+
assert(!hasModifier);
223+
std::pair<CProposalMap::iterator, bool> ret = cacheProposals.insert(std::make_pair(pid, CProposal()));
224+
ret.first->second.fDirty = true;
225+
return CProposalModifier(*this, ret.first);
226+
}
227+
228+
CPaymentRequestModifier CCoinsViewCache::ModifyPaymentRequest(const uint256 &prid) {
229+
assert(!hasModifier);
230+
std::pair<CPaymentRequestMap::iterator, bool> ret = cachePaymentRequests.insert(std::make_pair(prid, CPaymentRequest()));
231+
ret.first->second.fDirty = true;
232+
return CPaymentRequestModifier(*this, ret.first);
233+
}
234+
120235
// ModifyNewCoins has to know whether the new outputs its creating are for a
121236
// coinbase or not. If they are for a coinbase, it can not mark them as fresh.
122237
// This is to ensure that the historical duplicate coinbases before BIP30 was
@@ -132,6 +247,46 @@ CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbas
132247
return CCoinsModifier(*this, ret.first, 0);
133248
}
134249

250+
bool CCoinsViewCache::AddProposal(const CProposal& proposal) const {
251+
if (HaveProposal(proposal.hash))
252+
return false;
253+
254+
cacheProposals.insert(std::make_pair(proposal.hash, proposal));
255+
256+
return true;
257+
}
258+
259+
bool CCoinsViewCache::AddPaymentRequest(const CPaymentRequest& prequest) const {
260+
if (HavePaymentRequest(prequest.hash))
261+
return false;
262+
cachePaymentRequests.insert(std::make_pair(prequest.hash, prequest));
263+
return true;
264+
}
265+
266+
bool CCoinsViewCache::RemoveProposal(const uint256 &pid) const {
267+
if (!HaveProposal(pid))
268+
return false;
269+
270+
cacheProposals[pid] = CProposal();
271+
cacheProposals[pid].SetNull();
272+
273+
assert(cacheProposals[pid].IsNull());
274+
275+
return true;
276+
}
277+
278+
bool CCoinsViewCache::RemovePaymentRequest(const uint256 &prid) const {
279+
if (!HavePaymentRequest(prid))
280+
return false;
281+
282+
cachePaymentRequests[prid] = CPaymentRequest();
283+
cachePaymentRequests[prid].SetNull();
284+
285+
assert(cachePaymentRequests[prid].IsNull());
286+
287+
return true;
288+
}
289+
135290
const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const {
136291
CCoinsMap::const_iterator it = FetchCoins(txid);
137292
if (it == cacheCoins.end()) {
@@ -150,6 +305,16 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
150305
return (it != cacheCoins.end() && !it->second.coins.vout.empty());
151306
}
152307

308+
bool CCoinsViewCache::HaveProposal(const uint256 &id) const {
309+
CProposalMap::const_iterator it = FetchProposal(id);
310+
return (it != cacheProposals.end() && !it->second.IsNull());
311+
}
312+
313+
bool CCoinsViewCache::HavePaymentRequest(const uint256 &id) const {
314+
CPaymentRequestMap::const_iterator it = FetchPaymentRequest(id);
315+
return (it != cachePaymentRequests.end() && !it->second.IsNull());
316+
}
317+
153318
bool CCoinsViewCache::HaveCoinsInCache(const uint256 &txid) const {
154319
CCoinsMap::const_iterator it = cacheCoins.find(txid);
155320
return it != cacheCoins.end();
@@ -165,7 +330,7 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
165330
hashBlock = hashBlockIn;
166331
}
167332

168-
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
333+
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, CProposalMap &mapProposals, CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlockIn) {
169334
assert(!hasModifier);
170335
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
171336
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
@@ -206,12 +371,41 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
206371
CCoinsMap::iterator itOld = it++;
207372
mapCoins.erase(itOld);
208373
}
374+
375+
for (CProposalMap::iterator it = mapProposals.begin(); it != mapProposals.end();) {
376+
if (it->second.IsNull()) {
377+
CProposalMap::iterator itUs = cacheProposals.find(it->first);
378+
if (itUs != cacheProposals.end()) {
379+
cacheProposals.erase(itUs);
380+
}
381+
} else {
382+
CProposal& entry = cacheProposals[it->first];
383+
entry.swap(it->second);
384+
}
385+
CProposalMap::iterator itOld = it++;
386+
mapProposals.erase(itOld);
387+
}
388+
389+
for (CPaymentRequestMap::iterator it = mapPaymentRequests.begin(); it != mapPaymentRequests.end();) {
390+
if (it->second.IsNull()) {
391+
CPaymentRequestMap::iterator itUs = cachePaymentRequests.find(it->first);
392+
if (itUs != cachePaymentRequests.end()) {
393+
cachePaymentRequests.erase(itUs);
394+
}
395+
} else {
396+
CPaymentRequest& entry = cachePaymentRequests[it->first];
397+
entry.swap(it->second);
398+
}
399+
CPaymentRequestMap::iterator itOld = it++;
400+
mapPaymentRequests.erase(itOld);
401+
}
402+
209403
hashBlock = hashBlockIn;
210404
return true;
211405
}
212406

213407
bool CCoinsViewCache::Flush() {
214-
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
408+
bool fOk = base->BatchWrite(cacheCoins, cacheProposals, cachePaymentRequests, hashBlock);
215409
cacheCoins.clear();
216410
cachedCoinsUsage = 0;
217411
return fOk;
@@ -301,6 +495,36 @@ CCoinsModifier::~CCoinsModifier()
301495
}
302496
}
303497

498+
CProposalModifier::CProposalModifier(CCoinsViewCache& cache_, CProposalMap::iterator it_) : cache(cache_), it(it_) {
499+
assert(!cache.hasModifier);
500+
cache.hasModifier = true;
501+
}
502+
503+
CProposalModifier::~CProposalModifier()
504+
{
505+
assert(cache.hasModifier);
506+
cache.hasModifier = false;
507+
508+
if (it->second.IsNull()) {
509+
cache.cacheProposals.erase(it);
510+
}
511+
}
512+
513+
CPaymentRequestModifier::CPaymentRequestModifier(CCoinsViewCache& cache_, CPaymentRequestMap::iterator it_) : cache(cache_), it(it_) {
514+
assert(!cache.hasModifier);
515+
cache.hasModifier = true;
516+
}
517+
518+
CPaymentRequestModifier::~CPaymentRequestModifier()
519+
{
520+
assert(cache.hasModifier);
521+
cache.hasModifier = false;
522+
523+
if (it->second.IsNull()) {
524+
cache.cachePaymentRequests.erase(it);
525+
}
526+
}
527+
304528
CCoinsViewCursor::~CCoinsViewCursor()
305529
{
306530
}

0 commit comments

Comments
 (0)