mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Make CCoinsView use block hashes instead of indices
This commit is contained in:
parent
f76c122e2e
commit
84674082b0
57
src/main.cpp
57
src/main.cpp
@ -236,9 +236,9 @@ CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const {
|
|||||||
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
|
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
|
||||||
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
|
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
|
||||||
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
|
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
|
||||||
CBlockIndex *CCoinsView::GetBestBlock() { return NULL; }
|
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
|
||||||
bool CCoinsView::SetBestBlock(CBlockIndex *pindex) { return false; }
|
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
|
||||||
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return false; }
|
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return false; }
|
||||||
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
|
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
|
||||||
|
|
||||||
|
|
||||||
@ -246,13 +246,13 @@ CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
|
|||||||
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
|
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
|
||||||
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
|
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
|
||||||
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
|
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
|
||||||
CBlockIndex *CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
|
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
|
||||||
bool CCoinsViewBacked::SetBestBlock(CBlockIndex *pindex) { return base->SetBestBlock(pindex); }
|
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
|
||||||
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
||||||
bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return base->BatchWrite(mapCoins, pindex); }
|
bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
||||||
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
|
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
|
||||||
|
|
||||||
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), pindexTip(NULL) { }
|
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
|
||||||
|
|
||||||
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
|
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
|
||||||
if (cacheCoins.count(txid)) {
|
if (cacheCoins.count(txid)) {
|
||||||
@ -293,26 +293,26 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
|
|||||||
return FetchCoins(txid) != cacheCoins.end();
|
return FetchCoins(txid) != cacheCoins.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex *CCoinsViewCache::GetBestBlock() {
|
uint256 CCoinsViewCache::GetBestBlock() {
|
||||||
if (pindexTip == NULL)
|
if (hashBlock == uint256(0))
|
||||||
pindexTip = base->GetBestBlock();
|
hashBlock = base->GetBestBlock();
|
||||||
return pindexTip;
|
return hashBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::SetBestBlock(CBlockIndex *pindex) {
|
bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
|
||||||
pindexTip = pindex;
|
hashBlock = hashBlockIn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) {
|
bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlockIn) {
|
||||||
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
||||||
cacheCoins[it->first] = it->second;
|
cacheCoins[it->first] = it->second;
|
||||||
pindexTip = pindex;
|
hashBlock = hashBlockIn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::Flush() {
|
bool CCoinsViewCache::Flush() {
|
||||||
bool fOk = base->BatchWrite(cacheCoins, pindexTip);
|
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
|
||||||
if (fOk)
|
if (fOk)
|
||||||
cacheCoins.clear();
|
cacheCoins.clear();
|
||||||
return fOk;
|
return fOk;
|
||||||
@ -1498,7 +1498,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCach
|
|||||||
|
|
||||||
// While checking, GetBestBlock() refers to the parent block.
|
// While checking, GetBestBlock() refers to the parent block.
|
||||||
// This is also true for mempool checks.
|
// This is also true for mempool checks.
|
||||||
int nSpendHeight = inputs.GetBestBlock()->nHeight + 1;
|
CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
|
||||||
|
int nSpendHeight = pindexPrev->nHeight + 1;
|
||||||
int64_t nValueIn = 0;
|
int64_t nValueIn = 0;
|
||||||
int64_t nFees = 0;
|
int64_t nFees = 0;
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||||
@ -1568,7 +1569,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCach
|
|||||||
|
|
||||||
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
|
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
|
||||||
{
|
{
|
||||||
assert(pindex == view.GetBestBlock());
|
assert(pindex->GetBlockHash() == view.GetBestBlock());
|
||||||
|
|
||||||
if (pfClean)
|
if (pfClean)
|
||||||
*pfClean = false;
|
*pfClean = false;
|
||||||
@ -1644,7 +1645,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// move best block pointer to prevout block
|
// move best block pointer to prevout block
|
||||||
view.SetBestBlock(pindex->pprev);
|
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
||||||
|
|
||||||
if (pfClean) {
|
if (pfClean) {
|
||||||
*pfClean = fClean;
|
*pfClean = fClean;
|
||||||
@ -1693,12 +1694,13 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// verify that the view's current state corresponds to the previous block
|
// verify that the view's current state corresponds to the previous block
|
||||||
assert(pindex->pprev == view.GetBestBlock());
|
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash();
|
||||||
|
assert(hashPrevBlock == view.GetBestBlock());
|
||||||
|
|
||||||
// Special case for the genesis block, skipping connection of its transactions
|
// Special case for the genesis block, skipping connection of its transactions
|
||||||
// (its coinbase is unspendable)
|
// (its coinbase is unspendable)
|
||||||
if (block.GetHash() == Params().HashGenesisBlock()) {
|
if (block.GetHash() == Params().HashGenesisBlock()) {
|
||||||
view.SetBestBlock(pindex);
|
view.SetBestBlock(pindex->GetBlockHash());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1828,7 +1830,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
|||||||
return state.Abort(_("Failed to write transaction index"));
|
return state.Abort(_("Failed to write transaction index"));
|
||||||
|
|
||||||
// add this block to the view's block chain
|
// add this block to the view's block chain
|
||||||
assert(view.SetBestBlock(pindex));
|
assert(view.SetBestBlock(pindex->GetBlockHash()));
|
||||||
|
|
||||||
// Watch for transactions paying to me
|
// Watch for transactions paying to me
|
||||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||||
@ -1846,7 +1848,9 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
|||||||
CCoinsViewCache view(*pcoinsTip, true);
|
CCoinsViewCache view(*pcoinsTip, true);
|
||||||
|
|
||||||
// Find the fork (typically, there is none)
|
// Find the fork (typically, there is none)
|
||||||
CBlockIndex* pfork = view.GetBestBlock();
|
std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(view.GetBestBlock());
|
||||||
|
CBlockIndex* ptip = (it != mapBlockIndex.end()) ? it->second : NULL;
|
||||||
|
CBlockIndex* pfork = ptip;
|
||||||
CBlockIndex* plonger = pindexNew;
|
CBlockIndex* plonger = pindexNew;
|
||||||
while (pfork && pfork != plonger)
|
while (pfork && pfork != plonger)
|
||||||
{
|
{
|
||||||
@ -1862,7 +1866,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
|||||||
|
|
||||||
// List of what to disconnect (typically nothing)
|
// List of what to disconnect (typically nothing)
|
||||||
vector<CBlockIndex*> vDisconnect;
|
vector<CBlockIndex*> vDisconnect;
|
||||||
for (CBlockIndex* pindex = view.GetBestBlock(); pindex != pfork; pindex = pindex->pprev)
|
for (CBlockIndex* pindex = ptip; pindex != pfork; pindex = pindex->pprev)
|
||||||
vDisconnect.push_back(pindex);
|
vDisconnect.push_back(pindex);
|
||||||
|
|
||||||
// List of what to connect (typically only pindexNew)
|
// List of what to connect (typically only pindexNew)
|
||||||
@ -2687,9 +2691,10 @@ bool static LoadBlockIndexDB()
|
|||||||
LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
|
LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
|
||||||
|
|
||||||
// Load pointer to end of best chain
|
// Load pointer to end of best chain
|
||||||
chainActive.SetTip(pcoinsTip->GetBestBlock());
|
std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||||
if (chainActive.Tip() == NULL)
|
if (it == mapBlockIndex.end())
|
||||||
return true;
|
return true;
|
||||||
|
chainActive.SetTip(it->second);
|
||||||
LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n",
|
LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n",
|
||||||
chainActive.Tip()->GetBlockHash().ToString().c_str(), chainActive.Height(),
|
chainActive.Tip()->GetBlockHash().ToString().c_str(), chainActive.Height(),
|
||||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()).c_str());
|
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()).c_str());
|
||||||
|
24
src/main.h
24
src/main.h
@ -1062,14 +1062,14 @@ public:
|
|||||||
// This may (but cannot always) return true for fully spent transactions
|
// This may (but cannot always) return true for fully spent transactions
|
||||||
virtual bool HaveCoins(const uint256 &txid);
|
virtual bool HaveCoins(const uint256 &txid);
|
||||||
|
|
||||||
// Retrieve the block index whose state this CCoinsView currently represents
|
// Retrieve the block hash whose state this CCoinsView currently represents
|
||||||
virtual CBlockIndex *GetBestBlock();
|
virtual uint256 GetBestBlock();
|
||||||
|
|
||||||
// Modify the currently active block index
|
// Modify the currently active block hash
|
||||||
virtual bool SetBestBlock(CBlockIndex *pindex);
|
virtual bool SetBestBlock(const uint256 &hashBlock);
|
||||||
|
|
||||||
// Do a bulk modification (multiple SetCoins + one SetBestBlock)
|
// Do a bulk modification (multiple SetCoins + one SetBestBlock)
|
||||||
virtual bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
|
virtual bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock);
|
||||||
|
|
||||||
// Calculate statistics about the unspent transaction output set
|
// Calculate statistics about the unspent transaction output set
|
||||||
virtual bool GetStats(CCoinsStats &stats);
|
virtual bool GetStats(CCoinsStats &stats);
|
||||||
@ -1089,10 +1089,10 @@ public:
|
|||||||
bool GetCoins(const uint256 &txid, CCoins &coins);
|
bool GetCoins(const uint256 &txid, CCoins &coins);
|
||||||
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
||||||
bool HaveCoins(const uint256 &txid);
|
bool HaveCoins(const uint256 &txid);
|
||||||
CBlockIndex *GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(CBlockIndex *pindex);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
void SetBackend(CCoinsView &viewIn);
|
void SetBackend(CCoinsView &viewIn);
|
||||||
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
|
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock);
|
||||||
bool GetStats(CCoinsStats &stats);
|
bool GetStats(CCoinsStats &stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1100,7 +1100,7 @@ public:
|
|||||||
class CCoinsViewCache : public CCoinsViewBacked
|
class CCoinsViewCache : public CCoinsViewBacked
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CBlockIndex *pindexTip;
|
uint256 hashBlock;
|
||||||
std::map<uint256,CCoins> cacheCoins;
|
std::map<uint256,CCoins> cacheCoins;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1110,9 +1110,9 @@ public:
|
|||||||
bool GetCoins(const uint256 &txid, CCoins &coins);
|
bool GetCoins(const uint256 &txid, CCoins &coins);
|
||||||
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
||||||
bool HaveCoins(const uint256 &txid);
|
bool HaveCoins(const uint256 &txid);
|
||||||
CBlockIndex *GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(CBlockIndex *pindex);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
|
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock);
|
||||||
|
|
||||||
// Return a modifiable reference to a CCoins. Check HaveCoins first.
|
// Return a modifiable reference to a CCoins. Check HaveCoins first.
|
||||||
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
|
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
|
||||||
|
@ -245,11 +245,13 @@ Value gettxout(const Array& params, bool fHelp)
|
|||||||
if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
|
if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
|
||||||
return Value::null;
|
return Value::null;
|
||||||
|
|
||||||
ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
|
std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||||
|
CBlockIndex *pindex = it->second;
|
||||||
|
ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
|
||||||
if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
|
if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
|
||||||
ret.push_back(Pair("confirmations", 0));
|
ret.push_back(Pair("confirmations", 0));
|
||||||
else
|
else
|
||||||
ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
|
ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
|
||||||
ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
|
ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
|
||||||
Object o;
|
Object o;
|
||||||
ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
|
ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
|
||||||
|
23
src/txdb.cpp
23
src/txdb.cpp
@ -40,30 +40,27 @@ bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
|
|||||||
return db.Exists(make_pair('c', txid));
|
return db.Exists(make_pair('c', txid));
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex *CCoinsViewDB::GetBestBlock() {
|
uint256 CCoinsViewDB::GetBestBlock() {
|
||||||
uint256 hashBestChain;
|
uint256 hashBestChain;
|
||||||
if (!db.Read('B', hashBestChain))
|
if (!db.Read('B', hashBestChain))
|
||||||
return NULL;
|
return uint256(0);
|
||||||
std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hashBestChain);
|
return hashBestChain;
|
||||||
if (it == mapBlockIndex.end())
|
|
||||||
return NULL;
|
|
||||||
return it->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::SetBestBlock(CBlockIndex *pindex) {
|
bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) {
|
||||||
CLevelDBBatch batch;
|
CLevelDBBatch batch;
|
||||||
BatchWriteHashBestChain(batch, pindex->GetBlockHash());
|
BatchWriteHashBestChain(batch, hashBlock);
|
||||||
return db.WriteBatch(batch);
|
return db.WriteBatch(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) {
|
bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) {
|
||||||
LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
|
LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
|
||||||
|
|
||||||
CLevelDBBatch batch;
|
CLevelDBBatch batch;
|
||||||
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
||||||
BatchWriteCoins(batch, it->first, it->second);
|
BatchWriteCoins(batch, it->first, it->second);
|
||||||
if (pindex)
|
if (hashBlock != uint256(0))
|
||||||
BatchWriteHashBestChain(batch, pindex->GetBlockHash());
|
BatchWriteHashBestChain(batch, hashBlock);
|
||||||
|
|
||||||
return db.WriteBatch(batch);
|
return db.WriteBatch(batch);
|
||||||
}
|
}
|
||||||
@ -115,7 +112,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
|
|||||||
pcursor->SeekToFirst();
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||||
stats.hashBlock = GetBestBlock()->GetBlockHash();
|
stats.hashBlock = GetBestBlock();
|
||||||
ss << stats.hashBlock;
|
ss << stats.hashBlock;
|
||||||
int64_t nTotalAmount = 0;
|
int64_t nTotalAmount = 0;
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
@ -155,7 +152,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete pcursor;
|
delete pcursor;
|
||||||
stats.nHeight = GetBestBlock()->nHeight;
|
stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
|
||||||
stats.hashSerialized = ss.GetHash();
|
stats.hashSerialized = ss.GetHash();
|
||||||
stats.nTotalAmount = nTotalAmount;
|
stats.nTotalAmount = nTotalAmount;
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,9 +29,9 @@ public:
|
|||||||
bool GetCoins(const uint256 &txid, CCoins &coins);
|
bool GetCoins(const uint256 &txid, CCoins &coins);
|
||||||
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
bool SetCoins(const uint256 &txid, const CCoins &coins);
|
||||||
bool HaveCoins(const uint256 &txid);
|
bool HaveCoins(const uint256 &txid);
|
||||||
CBlockIndex *GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(CBlockIndex *pindex);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
|
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock);
|
||||||
bool GetStats(CCoinsStats &stats);
|
bool GetStats(CCoinsStats &stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user