Merge #11043: Use std::unique_ptr (C++11) where possible
a357293Use MakeUnique<Db>(...) (practicalswift)3e09b39Use MakeUnique<T>(...) instead of std::unique_ptr<T>(new T(...)) (practicalswift)8617989Add MakeUnique (substitute for C++14 std::make_unique) (practicalswift)d223bc9Use unique_ptr for pcoinscatcher/pcoinsdbview/pcoinsTip/pblocktree (practicalswift)b45c597Use unique_ptr for pdbCopy (Db) and fix potential memory leak (practicalswift)29ab96dUse unique_ptr for dbenv (DbEnv) (practicalswift)f72cbf9Use unique_ptr for pfilter (CBloomFilter) (practicalswift)8ccf1bbUse unique_ptr for sem{Addnode,Outbound} (CSemaphore) (practicalswift)73db063Use unique_ptr for upnp_thread (boost::thread) (practicalswift)0024531Use unique_ptr for dbw (CDBWrapper) (practicalswift)fa6d122Use unique_ptr:s for {fee,short,long}Stats (TxConfirmStats) (practicalswift)5a6f768Use unique_ptr for httpRPCTimerInterface (HTTPRPCTimerInterface) (practicalswift)860e912Use unique_ptr for pwalletMain (CWallet) (practicalswift) Pull request description: Use `std::unique_ptr` (C++11) where possible. Rationale: 1. Avoid resource leaks (specifically: forgetting to `delete` an object created using `new`) 2. Avoid undefined behaviour (specifically: double `delete`:s) **Note to reviewers:** Please let me know if I've missed any obvious `std::unique_ptr` candidates. Hopefully this PR should cover all the trivial cases. Tree-SHA512: 9fbeb47b800ab8ff4e0be9f2a22ab63c23d5c613a0c6716d9183db8d22ddbbce592fb8384a8b7874bf7375c8161efb13ca2197ad6f24b75967148037f0f7b20c
This commit is contained in:
20 files changed
+104
-131
No files matched your search
+5
-6
@@ -62,7 +62,7 @@ private:
|
|||||||
/* Pre-base64-encoded authentication token */
|
/* Pre-base64-encoded authentication token */
|
||||||
static std::string strRPCUserColonPass;
|
static std::string strRPCUserColonPass;
|
||||||
/* Stored RPC timer interface (for unregistration) */
|
/* Stored RPC timer interface (for unregistration) */
|
||||||
static HTTPRPCTimerInterface* httpRPCTimerInterface = nullptr;
|
static std::unique_ptr<HTTPRPCTimerInterface> httpRPCTimerInterface;
|
||||||
|
|
||||||
static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id)
|
static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id)
|
||||||
{
|
{
|
||||||
@@ -238,8 +238,8 @@ bool StartHTTPRPC()
|
|||||||
RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
|
RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
|
||||||
#endif
|
#endif
|
||||||
assert(EventBase());
|
assert(EventBase());
|
||||||
httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase());
|
httpRPCTimerInterface = MakeUnique<HTTPRPCTimerInterface>(EventBase());
|
||||||
RPCSetTimerInterface(httpRPCTimerInterface);
|
RPCSetTimerInterface(httpRPCTimerInterface.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,8 +253,7 @@ void StopHTTPRPC()
|
|||||||
LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
|
LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
|
||||||
UnregisterHTTPHandler("/", true);
|
UnregisterHTTPHandler("/", true);
|
||||||
if (httpRPCTimerInterface) {
|
if (httpRPCTimerInterface) {
|
||||||
RPCUnsetTimerInterface(httpRPCTimerInterface);
|
RPCUnsetTimerInterface(httpRPCTimerInterface.get());
|
||||||
delete httpRPCTimerInterface;
|
httpRPCTimerInterface.reset();
|
||||||
httpRPCTimerInterface = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-20
@@ -152,7 +152,7 @@ public:
|
|||||||
// Writes do not need similar protection, as failure to write is handled by the caller.
|
// Writes do not need similar protection, as failure to write is handled by the caller.
|
||||||
};
|
};
|
||||||
|
|
||||||
static CCoinsViewErrorCatcher *pcoinscatcher = nullptr;
|
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
|
||||||
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
||||||
|
|
||||||
void Interrupt(boost::thread_group& threadGroup)
|
void Interrupt(boost::thread_group& threadGroup)
|
||||||
@@ -235,14 +235,10 @@ void Shutdown()
|
|||||||
if (pcoinsTip != nullptr) {
|
if (pcoinsTip != nullptr) {
|
||||||
FlushStateToDisk();
|
FlushStateToDisk();
|
||||||
}
|
}
|
||||||
delete pcoinsTip;
|
pcoinsTip.reset();
|
||||||
pcoinsTip = nullptr;
|
pcoinscatcher.reset();
|
||||||
delete pcoinscatcher;
|
pcoinsdbview.reset();
|
||||||
pcoinscatcher = nullptr;
|
pblocktree.reset();
|
||||||
delete pcoinsdbview;
|
|
||||||
pcoinsdbview = nullptr;
|
|
||||||
delete pblocktree;
|
|
||||||
pblocktree = nullptr;
|
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
StopWallets();
|
StopWallets();
|
||||||
@@ -1406,12 +1402,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
UnloadBlockIndex();
|
UnloadBlockIndex();
|
||||||
delete pcoinsTip;
|
pcoinsTip.reset();
|
||||||
delete pcoinsdbview;
|
pcoinsdbview.reset();
|
||||||
delete pcoinscatcher;
|
pcoinscatcher.reset();
|
||||||
delete pblocktree;
|
pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
|
||||||
|
|
||||||
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReset);
|
|
||||||
|
|
||||||
if (fReset) {
|
if (fReset) {
|
||||||
pblocktree->WriteReindexing(true);
|
pblocktree->WriteReindexing(true);
|
||||||
@@ -1462,8 +1456,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
// At this point we're either in reindex or we've loaded a useful
|
// At this point we're either in reindex or we've loaded a useful
|
||||||
// block tree into mapBlockIndex!
|
// block tree into mapBlockIndex!
|
||||||
|
|
||||||
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState);
|
pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
|
||||||
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
|
pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
|
||||||
|
|
||||||
// If necessary, upgrade from older database format.
|
// If necessary, upgrade from older database format.
|
||||||
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
||||||
@@ -1473,13 +1467,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
|
||||||
if (!ReplayBlocks(chainparams, pcoinsdbview)) {
|
if (!ReplayBlocks(chainparams, pcoinsdbview.get())) {
|
||||||
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
|
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The on-disk coinsdb is now in a good state, create the cache
|
// The on-disk coinsdb is now in a good state, create the cache
|
||||||
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
|
pcoinsTip.reset(new CCoinsViewCache(pcoinscatcher.get()));
|
||||||
|
|
||||||
bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull();
|
bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull();
|
||||||
if (!is_coinsview_empty) {
|
if (!is_coinsview_empty) {
|
||||||
@@ -1521,7 +1515,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
|
if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
|
||||||
gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
|
gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
|
||||||
strLoadError = _("Corrupted block database detected");
|
strLoadError = _("Corrupted block database detected");
|
||||||
break;
|
break;
|
||||||
|
|||||||
+8
-16
@@ -1534,22 +1534,20 @@ void ThreadMapPort()
|
|||||||
|
|
||||||
void MapPort(bool fUseUPnP)
|
void MapPort(bool fUseUPnP)
|
||||||
{
|
{
|
||||||
static boost::thread* upnp_thread = nullptr;
|
static std::unique_ptr<boost::thread> upnp_thread;
|
||||||
|
|
||||||
if (fUseUPnP)
|
if (fUseUPnP)
|
||||||
{
|
{
|
||||||
if (upnp_thread) {
|
if (upnp_thread) {
|
||||||
upnp_thread->interrupt();
|
upnp_thread->interrupt();
|
||||||
upnp_thread->join();
|
upnp_thread->join();
|
||||||
delete upnp_thread;
|
|
||||||
}
|
}
|
||||||
upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
|
upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
|
||||||
}
|
}
|
||||||
else if (upnp_thread) {
|
else if (upnp_thread) {
|
||||||
upnp_thread->interrupt();
|
upnp_thread->interrupt();
|
||||||
upnp_thread->join();
|
upnp_thread->join();
|
||||||
delete upnp_thread;
|
upnp_thread.reset();
|
||||||
upnp_thread = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2224,8 +2222,6 @@ CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSe
|
|||||||
nLastNodeId = 0;
|
nLastNodeId = 0;
|
||||||
nSendBufferMaxSize = 0;
|
nSendBufferMaxSize = 0;
|
||||||
nReceiveFloodSize = 0;
|
nReceiveFloodSize = 0;
|
||||||
semOutbound = nullptr;
|
|
||||||
semAddnode = nullptr;
|
|
||||||
flagInterruptMsgProc = false;
|
flagInterruptMsgProc = false;
|
||||||
SetTryNewOutboundPeer(false);
|
SetTryNewOutboundPeer(false);
|
||||||
|
|
||||||
@@ -2331,11 +2327,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
|||||||
|
|
||||||
if (semOutbound == nullptr) {
|
if (semOutbound == nullptr) {
|
||||||
// initialize semaphore
|
// initialize semaphore
|
||||||
semOutbound = new CSemaphore(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
|
semOutbound = MakeUnique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
|
||||||
}
|
}
|
||||||
if (semAddnode == nullptr) {
|
if (semAddnode == nullptr) {
|
||||||
// initialize semaphore
|
// initialize semaphore
|
||||||
semAddnode = new CSemaphore(nMaxAddnode);
|
semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -2458,10 +2454,8 @@ void CConnman::Stop()
|
|||||||
vNodes.clear();
|
vNodes.clear();
|
||||||
vNodesDisconnected.clear();
|
vNodesDisconnected.clear();
|
||||||
vhListenSocket.clear();
|
vhListenSocket.clear();
|
||||||
delete semOutbound;
|
semOutbound.reset();
|
||||||
semOutbound = nullptr;
|
semAddnode.reset();
|
||||||
delete semAddnode;
|
|
||||||
semAddnode = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConnman::DeleteNode(CNode* pnode)
|
void CConnman::DeleteNode(CNode* pnode)
|
||||||
@@ -2747,7 +2741,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
|
|||||||
nNextInvSend = 0;
|
nNextInvSend = 0;
|
||||||
fRelayTxes = false;
|
fRelayTxes = false;
|
||||||
fSentAddr = false;
|
fSentAddr = false;
|
||||||
pfilter = new CBloomFilter();
|
pfilter = MakeUnique<CBloomFilter>();
|
||||||
timeLastMempoolReq = 0;
|
timeLastMempoolReq = 0;
|
||||||
nLastBlockTime = 0;
|
nLastBlockTime = 0;
|
||||||
nLastTXTime = 0;
|
nLastTXTime = 0;
|
||||||
@@ -2777,8 +2771,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
|
|||||||
CNode::~CNode()
|
CNode::~CNode()
|
||||||
{
|
{
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
|
|
||||||
delete pfilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNode::AskFor(const CInv& inv)
|
void CNode::AskFor(const CInv& inv)
|
||||||
|
|||||||
@@ -399,8 +399,8 @@ private:
|
|||||||
/** Services this instance offers */
|
/** Services this instance offers */
|
||||||
ServiceFlags nLocalServices;
|
ServiceFlags nLocalServices;
|
||||||
|
|
||||||
CSemaphore *semOutbound;
|
std::unique_ptr<CSemaphore> semOutbound;
|
||||||
CSemaphore *semAddnode;
|
std::unique_ptr<CSemaphore> semAddnode;
|
||||||
int nMaxConnections;
|
int nMaxConnections;
|
||||||
int nMaxOutbound;
|
int nMaxOutbound;
|
||||||
int nMaxAddnode;
|
int nMaxAddnode;
|
||||||
@@ -648,7 +648,7 @@ public:
|
|||||||
bool fSentAddr;
|
bool fSentAddr;
|
||||||
CSemaphoreGrant grantOutbound;
|
CSemaphoreGrant grantOutbound;
|
||||||
CCriticalSection cs_filter;
|
CCriticalSection cs_filter;
|
||||||
CBloomFilter* pfilter;
|
std::unique_ptr<CBloomFilter> pfilter;
|
||||||
std::atomic<int> nRefCount;
|
std::atomic<int> nRefCount;
|
||||||
|
|
||||||
const uint64_t nKeyedNetGroup;
|
const uint64_t nKeyedNetGroup;
|
||||||
|
|||||||
@@ -2102,7 +2102,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||||||
|
|
||||||
if (!AlreadyHave(inv) &&
|
if (!AlreadyHave(inv) &&
|
||||||
AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
|
AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
|
||||||
mempool.check(pcoinsTip);
|
mempool.check(pcoinsTip.get());
|
||||||
RelayTransaction(tx, connman);
|
RelayTransaction(tx, connman);
|
||||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||||
vWorkQueue.emplace_back(inv.hash, i);
|
vWorkQueue.emplace_back(inv.hash, i);
|
||||||
@@ -2169,7 +2169,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||||||
recentRejects->insert(orphanHash);
|
recentRejects->insert(orphanHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mempool.check(pcoinsTip);
|
mempool.check(pcoinsTip.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2751,8 +2751,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOCK(pfrom->cs_filter);
|
LOCK(pfrom->cs_filter);
|
||||||
delete pfrom->pfilter;
|
pfrom->pfilter.reset(new CBloomFilter(filter));
|
||||||
pfrom->pfilter = new CBloomFilter(filter);
|
|
||||||
pfrom->pfilter->UpdateEmptyFull();
|
pfrom->pfilter->UpdateEmptyFull();
|
||||||
pfrom->fRelayTxes = true;
|
pfrom->fRelayTxes = true;
|
||||||
}
|
}
|
||||||
@@ -2788,8 +2787,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||||||
{
|
{
|
||||||
LOCK(pfrom->cs_filter);
|
LOCK(pfrom->cs_filter);
|
||||||
if (pfrom->GetLocalServices() & NODE_BLOOM) {
|
if (pfrom->GetLocalServices() & NODE_BLOOM) {
|
||||||
delete pfrom->pfilter;
|
pfrom->pfilter.reset(new CBloomFilter());
|
||||||
pfrom->pfilter = new CBloomFilter();
|
|
||||||
}
|
}
|
||||||
pfrom->fRelayTxes = true;
|
pfrom->fRelayTxes = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-15
@@ -548,16 +548,13 @@ CBlockPolicyEstimator::CBlockPolicyEstimator()
|
|||||||
bucketMap[INF_FEERATE] = bucketIndex;
|
bucketMap[INF_FEERATE] = bucketIndex;
|
||||||
assert(bucketMap.size() == buckets.size());
|
assert(bucketMap.size() == buckets.size());
|
||||||
|
|
||||||
feeStats = new TxConfirmStats(buckets, bucketMap, MED_BLOCK_PERIODS, MED_DECAY, MED_SCALE);
|
feeStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, MED_BLOCK_PERIODS, MED_DECAY, MED_SCALE));
|
||||||
shortStats = new TxConfirmStats(buckets, bucketMap, SHORT_BLOCK_PERIODS, SHORT_DECAY, SHORT_SCALE);
|
shortStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, SHORT_BLOCK_PERIODS, SHORT_DECAY, SHORT_SCALE));
|
||||||
longStats = new TxConfirmStats(buckets, bucketMap, LONG_BLOCK_PERIODS, LONG_DECAY, LONG_SCALE);
|
longStats = std::unique_ptr<TxConfirmStats>(new TxConfirmStats(buckets, bucketMap, LONG_BLOCK_PERIODS, LONG_DECAY, LONG_SCALE));
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockPolicyEstimator::~CBlockPolicyEstimator()
|
CBlockPolicyEstimator::~CBlockPolicyEstimator()
|
||||||
{
|
{
|
||||||
delete feeStats;
|
|
||||||
delete shortStats;
|
|
||||||
delete longStats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
|
void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
|
||||||
@@ -690,16 +687,16 @@ CFeeRate CBlockPolicyEstimator::estimateRawFee(int confTarget, double successThr
|
|||||||
double sufficientTxs = SUFFICIENT_FEETXS;
|
double sufficientTxs = SUFFICIENT_FEETXS;
|
||||||
switch (horizon) {
|
switch (horizon) {
|
||||||
case FeeEstimateHorizon::SHORT_HALFLIFE: {
|
case FeeEstimateHorizon::SHORT_HALFLIFE: {
|
||||||
stats = shortStats;
|
stats = shortStats.get();
|
||||||
sufficientTxs = SUFFICIENT_TXS_SHORT;
|
sufficientTxs = SUFFICIENT_TXS_SHORT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FeeEstimateHorizon::MED_HALFLIFE: {
|
case FeeEstimateHorizon::MED_HALFLIFE: {
|
||||||
stats = feeStats;
|
stats = feeStats.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FeeEstimateHorizon::LONG_HALFLIFE: {
|
case FeeEstimateHorizon::LONG_HALFLIFE: {
|
||||||
stats = longStats;
|
stats = longStats.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -1002,12 +999,9 @@ bool CBlockPolicyEstimator::Read(CAutoFile& filein)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Destroy old TxConfirmStats and point to new ones that already reference buckets and bucketMap
|
// Destroy old TxConfirmStats and point to new ones that already reference buckets and bucketMap
|
||||||
delete feeStats;
|
feeStats = std::move(fileFeeStats);
|
||||||
delete shortStats;
|
shortStats = std::move(fileShortStats);
|
||||||
delete longStats;
|
longStats = std::move(fileLongStats);
|
||||||
feeStats = fileFeeStats.release();
|
|
||||||
shortStats = fileShortStats.release();
|
|
||||||
longStats = fileLongStats.release();
|
|
||||||
|
|
||||||
nBestSeenHeight = nFileBestSeenHeight;
|
nBestSeenHeight = nFileBestSeenHeight;
|
||||||
historicalFirst = nFileHistoricalFirst;
|
historicalFirst = nFileHistoricalFirst;
|
||||||
|
|||||||
+3
-3
@@ -245,9 +245,9 @@ private:
|
|||||||
std::map<uint256, TxStatsInfo> mapMemPoolTxs;
|
std::map<uint256, TxStatsInfo> mapMemPoolTxs;
|
||||||
|
|
||||||
/** Classes to track historical data on transaction confirmations */
|
/** Classes to track historical data on transaction confirmations */
|
||||||
TxConfirmStats* feeStats;
|
std::unique_ptr<TxConfirmStats> feeStats;
|
||||||
TxConfirmStats* shortStats;
|
std::unique_ptr<TxConfirmStats> shortStats;
|
||||||
TxConfirmStats* longStats;
|
std::unique_ptr<TxConfirmStats> longStats;
|
||||||
|
|
||||||
unsigned int trackedTxs;
|
unsigned int trackedTxs;
|
||||||
unsigned int untrackedTxs;
|
unsigned int untrackedTxs;
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ class RPCNestedTests : public QObject
|
|||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void rpcNestedTests();
|
void rpcNestedTests();
|
||||||
|
|
||||||
private:
|
|
||||||
CCoinsViewDB *pcoinsdbview;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
|
#endif // BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
|
||||||
@@ -928,7 +928,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
CCoinsStats stats;
|
CCoinsStats stats;
|
||||||
FlushStateToDisk();
|
FlushStateToDisk();
|
||||||
if (GetUTXOStats(pcoinsdbview, stats)) {
|
if (GetUTXOStats(pcoinsdbview.get(), stats)) {
|
||||||
ret.push_back(Pair("height", (int64_t)stats.nHeight));
|
ret.push_back(Pair("height", (int64_t)stats.nHeight));
|
||||||
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
|
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
|
||||||
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
|
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
|
||||||
@@ -996,7 +996,7 @@ UniValue gettxout(const JSONRPCRequest& request)
|
|||||||
Coin coin;
|
Coin coin;
|
||||||
if (fMempool) {
|
if (fMempool) {
|
||||||
LOCK(mempool.cs);
|
LOCK(mempool.cs);
|
||||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
CCoinsViewMemPool view(pcoinsTip.get(), mempool);
|
||||||
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
|
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
@@ -1048,7 +1048,7 @@ UniValue verifychain(const JSONRPCRequest& request)
|
|||||||
if (!request.params[1].isNull())
|
if (!request.params[1].isNull())
|
||||||
nCheckDepth = request.params[1].get_int();
|
nCheckDepth = request.params[1].get_int();
|
||||||
|
|
||||||
return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);
|
return CVerifyDB().VerifyDB(Params(), pcoinsTip.get(), nCheckLevel, nCheckDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Implementation of IsSuperMajority with better feedback */
|
/** Implementation of IsSuperMajority with better feedback */
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
|
|||||||
create_directories(ph);
|
create_directories(ph);
|
||||||
|
|
||||||
// Set up a non-obfuscated wrapper to write some initial data.
|
// Set up a non-obfuscated wrapper to write some initial data.
|
||||||
CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false);
|
std::unique_ptr<CDBWrapper> dbw = MakeUnique<CDBWrapper>(ph, (1 << 10), false, false, false);
|
||||||
char key = 'k';
|
char key = 'k';
|
||||||
uint256 in = InsecureRand256();
|
uint256 in = InsecureRand256();
|
||||||
uint256 res;
|
uint256 res;
|
||||||
@@ -135,8 +135,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
|
|||||||
BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
|
BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
|
||||||
|
|
||||||
// Call the destructor to free leveldb LOCK
|
// Call the destructor to free leveldb LOCK
|
||||||
delete dbw;
|
dbw.reset();
|
||||||
dbw = nullptr;
|
|
||||||
|
|
||||||
// Now, set up another wrapper that wants to obfuscate the same directory
|
// Now, set up another wrapper that wants to obfuscate the same directory
|
||||||
CDBWrapper odbw(ph, (1 << 10), false, false, true);
|
CDBWrapper odbw(ph, (1 << 10), false, false, true);
|
||||||
@@ -167,7 +166,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
|
|||||||
create_directories(ph);
|
create_directories(ph);
|
||||||
|
|
||||||
// Set up a non-obfuscated wrapper to write some initial data.
|
// Set up a non-obfuscated wrapper to write some initial data.
|
||||||
CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false);
|
std::unique_ptr<CDBWrapper> dbw = MakeUnique<CDBWrapper>(ph, (1 << 10), false, false, false);
|
||||||
char key = 'k';
|
char key = 'k';
|
||||||
uint256 in = InsecureRand256();
|
uint256 in = InsecureRand256();
|
||||||
uint256 res;
|
uint256 res;
|
||||||
@@ -177,8 +176,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
|
|||||||
BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
|
BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
|
||||||
|
|
||||||
// Call the destructor to free leveldb LOCK
|
// Call the destructor to free leveldb LOCK
|
||||||
delete dbw;
|
dbw.reset();
|
||||||
dbw = nullptr;
|
|
||||||
|
|
||||||
// Simulate a -reindex by wiping the existing data store
|
// Simulate a -reindex by wiping the existing data store
|
||||||
CDBWrapper odbw(ph, (1 << 10), false, true, true);
|
CDBWrapper odbw(ph, (1 << 10), false, true, true);
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
|||||||
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
|
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
|
||||||
|
|
||||||
mempool.setSanityCheck(1.0);
|
mempool.setSanityCheck(1.0);
|
||||||
pblocktree = new CBlockTreeDB(1 << 20, true);
|
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
|
||||||
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
|
||||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
|
||||||
if (!LoadGenesisBlock(chainparams)) {
|
if (!LoadGenesisBlock(chainparams)) {
|
||||||
throw std::runtime_error("LoadGenesisBlock failed.");
|
throw std::runtime_error("LoadGenesisBlock failed.");
|
||||||
}
|
}
|
||||||
@@ -110,9 +110,9 @@ TestingSetup::~TestingSetup()
|
|||||||
g_connman.reset();
|
g_connman.reset();
|
||||||
peerLogic.reset();
|
peerLogic.reset();
|
||||||
UnloadBlockIndex();
|
UnloadBlockIndex();
|
||||||
delete pcoinsTip;
|
pcoinsTip.reset();
|
||||||
delete pcoinsdbview;
|
pcoinsdbview.reset();
|
||||||
delete pblocktree;
|
pblocktree.reset();
|
||||||
fs::remove_all(pathTemp);
|
fs::remove_all(pathTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ struct CConnmanTest {
|
|||||||
|
|
||||||
class PeerLogicValidation;
|
class PeerLogicValidation;
|
||||||
struct TestingSetup: public BasicTestingSetup {
|
struct TestingSetup: public BasicTestingSetup {
|
||||||
CCoinsViewDB *pcoinsdbview;
|
|
||||||
fs::path pathTemp;
|
fs::path pathTemp;
|
||||||
boost::thread_group threadGroup;
|
boost::thread_group threadGroup;
|
||||||
CConnman* connman;
|
CConnman* connman;
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void ValidateCheckInputsForAllFlags(CMutableTransaction &tx, uint32_t failing_fl
|
|||||||
// WITNESS requires P2SH
|
// WITNESS requires P2SH
|
||||||
test_flags |= SCRIPT_VERIFY_P2SH;
|
test_flags |= SCRIPT_VERIFY_P2SH;
|
||||||
}
|
}
|
||||||
bool ret = CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, nullptr);
|
bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, nullptr);
|
||||||
// CheckInputs should succeed iff test_flags doesn't intersect with
|
// CheckInputs should succeed iff test_flags doesn't intersect with
|
||||||
// failing_flags
|
// failing_flags
|
||||||
bool expected_return_value = !(test_flags & failing_flags);
|
bool expected_return_value = !(test_flags & failing_flags);
|
||||||
@@ -135,13 +135,13 @@ void ValidateCheckInputsForAllFlags(CMutableTransaction &tx, uint32_t failing_fl
|
|||||||
if (ret && add_to_cache) {
|
if (ret && add_to_cache) {
|
||||||
// Check that we get a cache hit if the tx was valid
|
// Check that we get a cache hit if the tx was valid
|
||||||
std::vector<CScriptCheck> scriptchecks;
|
std::vector<CScriptCheck> scriptchecks;
|
||||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||||
BOOST_CHECK(scriptchecks.empty());
|
BOOST_CHECK(scriptchecks.empty());
|
||||||
} else {
|
} else {
|
||||||
// Check that we get script executions to check, if the transaction
|
// Check that we get script executions to check, if the transaction
|
||||||
// was invalid, or we didn't add to cache.
|
// was invalid, or we didn't add to cache.
|
||||||
std::vector<CScriptCheck> scriptchecks;
|
std::vector<CScriptCheck> scriptchecks;
|
||||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||||
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
|
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,13 +201,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
PrecomputedTransactionData ptd_spend_tx(spend_tx);
|
PrecomputedTransactionData ptd_spend_tx(spend_tx);
|
||||||
|
|
||||||
BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
|
BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
|
||||||
|
|
||||||
// If we call again asking for scriptchecks (as happens in
|
// If we call again asking for scriptchecks (as happens in
|
||||||
// ConnectBlock), we should add a script check object for this -- we're
|
// ConnectBlock), we should add a script check object for this -- we're
|
||||||
// not caching invalidity (if that changes, delete this test case).
|
// not caching invalidity (if that changes, delete this test case).
|
||||||
std::vector<CScriptCheck> scriptchecks;
|
std::vector<CScriptCheck> scriptchecks;
|
||||||
BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
|
BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
|
||||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 1);
|
BOOST_CHECK_EQUAL(scriptchecks.size(), 1);
|
||||||
|
|
||||||
// Test that CheckInputs returns true iff DERSIG-enforcing flags are
|
// Test that CheckInputs returns true iff DERSIG-enforcing flags are
|
||||||
@@ -268,7 +268,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||||||
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
PrecomputedTransactionData txdata(invalid_with_cltv_tx);
|
PrecomputedTransactionData txdata(invalid_with_cltv_tx);
|
||||||
BOOST_CHECK(CheckInputs(invalid_with_cltv_tx, state, pcoinsTip, true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
|
BOOST_CHECK(CheckInputs(invalid_with_cltv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST CHECKSEQUENCEVERIFY
|
// TEST CHECKSEQUENCEVERIFY
|
||||||
@@ -296,7 +296,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||||||
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
PrecomputedTransactionData txdata(invalid_with_csv_tx);
|
PrecomputedTransactionData txdata(invalid_with_csv_tx);
|
||||||
BOOST_CHECK(CheckInputs(invalid_with_csv_tx, state, pcoinsTip, true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
|
BOOST_CHECK(CheckInputs(invalid_with_csv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add tests for remaining script flags
|
// TODO: add tests for remaining script flags
|
||||||
@@ -358,12 +358,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
PrecomputedTransactionData txdata(tx);
|
PrecomputedTransactionData txdata(tx);
|
||||||
// This transaction is now invalid under segwit, because of the second input.
|
// This transaction is now invalid under segwit, because of the second input.
|
||||||
BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
|
BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
|
||||||
|
|
||||||
std::vector<CScriptCheck> scriptchecks;
|
std::vector<CScriptCheck> scriptchecks;
|
||||||
// Make sure this transaction was not cached (ie because the first
|
// Make sure this transaction was not cached (ie because the first
|
||||||
// input was valid)
|
// input was valid)
|
||||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
|
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
|
||||||
// Should get 2 script checks back -- caching is on a whole-transaction basis.
|
// Should get 2 script checks back -- caching is on a whole-transaction basis.
|
||||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 2);
|
BOOST_CHECK_EQUAL(scriptchecks.size(), 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,4 +326,11 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
|
|||||||
|
|
||||||
std::string CopyrightHolders(const std::string& strPrefix);
|
std::string CopyrightHolders(const std::string& strPrefix);
|
||||||
|
|
||||||
|
//! Substitute for C++14 std::make_unique.
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
std::unique_ptr<T> MakeUnique(Args&&... args)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_UTIL_H
|
#endif // BITCOIN_UTIL_H
|
||||||
+10
-10
@@ -201,9 +201,9 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc
|
|||||||
return chain.Genesis();
|
return chain.Genesis();
|
||||||
}
|
}
|
||||||
|
|
||||||
CCoinsViewDB *pcoinsdbview = nullptr;
|
std::unique_ptr<CCoinsViewDB> pcoinsdbview;
|
||||||
CCoinsViewCache *pcoinsTip = nullptr;
|
std::unique_ptr<CCoinsViewCache> pcoinsTip;
|
||||||
CBlockTreeDB *pblocktree = nullptr;
|
std::unique_ptr<CBlockTreeDB> pblocktree;
|
||||||
|
|
||||||
enum FlushStateMode {
|
enum FlushStateMode {
|
||||||
FLUSH_STATE_NONE,
|
FLUSH_STATE_NONE,
|
||||||
@@ -295,7 +295,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// pcoinsTip contains the UTXO set for chainActive.Tip()
|
// pcoinsTip contains the UTXO set for chainActive.Tip()
|
||||||
CCoinsViewMemPool viewMemPool(pcoinsTip, mempool);
|
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), mempool);
|
||||||
std::vector<int> prevheights;
|
std::vector<int> prevheights;
|
||||||
prevheights.resize(tx.vin.size());
|
prevheights.resize(tx.vin.size());
|
||||||
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
||||||
@@ -424,7 +424,7 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f
|
|||||||
mempool.UpdateTransactionsFromBlock(vHashUpdate);
|
mempool.UpdateTransactionsFromBlock(vHashUpdate);
|
||||||
|
|
||||||
// We also need to remove any now-immature transactions
|
// We also need to remove any now-immature transactions
|
||||||
mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
mempool.removeForReorg(pcoinsTip.get(), chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
||||||
// Re-limit mempool size, in case we added any transactions
|
// Re-limit mempool size, in case we added any transactions
|
||||||
LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
|
LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
|
||||||
}
|
}
|
||||||
@@ -557,7 +557,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
|||||||
LockPoints lp;
|
LockPoints lp;
|
||||||
{
|
{
|
||||||
LOCK(pool.cs);
|
LOCK(pool.cs);
|
||||||
CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
|
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
|
||||||
view.SetBackend(viewMemPool);
|
view.SetBackend(viewMemPool);
|
||||||
|
|
||||||
// do all inputs exist?
|
// do all inputs exist?
|
||||||
@@ -2105,7 +2105,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
|
|||||||
// Apply the block atomically to the chain state.
|
// Apply the block atomically to the chain state.
|
||||||
int64_t nStart = GetTimeMicros();
|
int64_t nStart = GetTimeMicros();
|
||||||
{
|
{
|
||||||
CCoinsViewCache view(pcoinsTip);
|
CCoinsViewCache view(pcoinsTip.get());
|
||||||
assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
|
assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
|
||||||
if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
|
if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
|
||||||
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
|
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
|
||||||
@@ -2235,7 +2235,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
|
|||||||
int64_t nTime3;
|
int64_t nTime3;
|
||||||
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
|
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
|
||||||
{
|
{
|
||||||
CCoinsViewCache view(pcoinsTip);
|
CCoinsViewCache view(pcoinsTip.get());
|
||||||
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
|
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
|
||||||
GetMainSignals().BlockChecked(blockConnecting, state);
|
GetMainSignals().BlockChecked(blockConnecting, state);
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
@@ -2413,7 +2413,7 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
|
|||||||
// any disconnected transactions back to the mempool.
|
// any disconnected transactions back to the mempool.
|
||||||
UpdateMempoolForReorg(disconnectpool, true);
|
UpdateMempoolForReorg(disconnectpool, true);
|
||||||
}
|
}
|
||||||
mempool.check(pcoinsTip);
|
mempool.check(pcoinsTip.get());
|
||||||
|
|
||||||
// Callbacks/notifications for a new best chain.
|
// Callbacks/notifications for a new best chain.
|
||||||
if (fInvalidFound)
|
if (fInvalidFound)
|
||||||
@@ -3275,7 +3275,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
|
|||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
assert(pindexPrev && pindexPrev == chainActive.Tip());
|
assert(pindexPrev && pindexPrev == chainActive.Tip());
|
||||||
CCoinsViewCache viewNew(pcoinsTip);
|
CCoinsViewCache viewNew(pcoinsTip.get());
|
||||||
CBlockIndex indexDummy(block);
|
CBlockIndex indexDummy(block);
|
||||||
indexDummy.pprev = pindexPrev;
|
indexDummy.pprev = pindexPrev;
|
||||||
indexDummy.nHeight = pindexPrev->nHeight + 1;
|
indexDummy.nHeight = pindexPrev->nHeight + 1;
|
||||||
|
|||||||
+3
-3
@@ -444,13 +444,13 @@ bool ResetBlockFailureFlags(CBlockIndex *pindex);
|
|||||||
extern CChain chainActive;
|
extern CChain chainActive;
|
||||||
|
|
||||||
/** Global variable that points to the coins database (protected by cs_main) */
|
/** Global variable that points to the coins database (protected by cs_main) */
|
||||||
extern CCoinsViewDB *pcoinsdbview;
|
extern std::unique_ptr<CCoinsViewDB> pcoinsdbview;
|
||||||
|
|
||||||
/** Global variable that points to the active CCoinsView (protected by cs_main) */
|
/** Global variable that points to the active CCoinsView (protected by cs_main) */
|
||||||
extern CCoinsViewCache *pcoinsTip;
|
extern std::unique_ptr<CCoinsViewCache> pcoinsTip;
|
||||||
|
|
||||||
/** Global variable that points to the active block tree (protected by cs_main) */
|
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||||
extern CBlockTreeDB *pblocktree;
|
extern std::unique_ptr<CBlockTreeDB> pblocktree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the spend height, which is one more than the inputs.GetBestBlock().
|
* Return the spend height, which is one more than the inputs.GetBestBlock().
|
||||||
|
|||||||
+9
-13
@@ -75,13 +75,12 @@ void CDBEnv::EnvShutdown()
|
|||||||
|
|
||||||
void CDBEnv::Reset()
|
void CDBEnv::Reset()
|
||||||
{
|
{
|
||||||
delete dbenv;
|
dbenv.reset(new DbEnv(DB_CXX_NO_EXCEPTIONS));
|
||||||
dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
|
|
||||||
fDbEnvInit = false;
|
fDbEnvInit = false;
|
||||||
fMockDb = false;
|
fMockDb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDBEnv::CDBEnv() : dbenv(nullptr)
|
CDBEnv::CDBEnv()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
@@ -89,8 +88,6 @@ CDBEnv::CDBEnv() : dbenv(nullptr)
|
|||||||
CDBEnv::~CDBEnv()
|
CDBEnv::~CDBEnv()
|
||||||
{
|
{
|
||||||
EnvShutdown();
|
EnvShutdown();
|
||||||
delete dbenv;
|
|
||||||
dbenv = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDBEnv::Close()
|
void CDBEnv::Close()
|
||||||
@@ -182,7 +179,7 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type
|
|||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
assert(mapFileUseCount.count(strFile) == 0);
|
assert(mapFileUseCount.count(strFile) == 0);
|
||||||
|
|
||||||
Db db(dbenv, 0);
|
Db db(dbenv.get(), 0);
|
||||||
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
|
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
return VERIFY_OK;
|
return VERIFY_OK;
|
||||||
@@ -225,7 +222,7 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco
|
|||||||
}
|
}
|
||||||
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
|
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
|
||||||
|
|
||||||
std::unique_ptr<Db> pdbCopy(new Db(bitdb.dbenv, 0));
|
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(bitdb.dbenv.get(), 0);
|
||||||
int ret = pdbCopy->open(nullptr, // Txn pointer
|
int ret = pdbCopy->open(nullptr, // Txn pointer
|
||||||
filename.c_str(), // Filename
|
filename.c_str(), // Filename
|
||||||
"main", // Logical db name
|
"main", // Logical db name
|
||||||
@@ -334,7 +331,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
|
|||||||
|
|
||||||
std::stringstream strDump;
|
std::stringstream strDump;
|
||||||
|
|
||||||
Db db(dbenv, 0);
|
Db db(dbenv.get(), 0);
|
||||||
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags);
|
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags);
|
||||||
if (result == DB_VERIFY_BAD) {
|
if (result == DB_VERIFY_BAD) {
|
||||||
LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
|
LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
|
||||||
@@ -416,7 +413,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
|||||||
pdb = env->mapDb[strFilename];
|
pdb = env->mapDb[strFilename];
|
||||||
if (pdb == nullptr) {
|
if (pdb == nullptr) {
|
||||||
int ret;
|
int ret;
|
||||||
std::unique_ptr<Db> pdb_temp(new Db(env->dbenv, 0));
|
std::unique_ptr<Db> pdb_temp = MakeUnique<Db>(env->dbenv.get(), 0);
|
||||||
|
|
||||||
bool fMockDb = env->IsMock();
|
bool fMockDb = env->IsMock();
|
||||||
if (fMockDb) {
|
if (fMockDb) {
|
||||||
@@ -525,7 +522,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
|||||||
std::string strFileRes = strFile + ".rewrite";
|
std::string strFileRes = strFile + ".rewrite";
|
||||||
{ // surround usage of db with extra {}
|
{ // surround usage of db with extra {}
|
||||||
CDB db(dbw, "r");
|
CDB db(dbw, "r");
|
||||||
Db* pdbCopy = new Db(env->dbenv, 0);
|
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
|
||||||
|
|
||||||
int ret = pdbCopy->open(nullptr, // Txn pointer
|
int ret = pdbCopy->open(nullptr, // Txn pointer
|
||||||
strFileRes.c_str(), // Filename
|
strFileRes.c_str(), // Filename
|
||||||
@@ -574,13 +571,12 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
|||||||
} else {
|
} else {
|
||||||
pdbCopy->close(0);
|
pdbCopy->close(0);
|
||||||
}
|
}
|
||||||
delete pdbCopy;
|
|
||||||
}
|
}
|
||||||
if (fSuccess) {
|
if (fSuccess) {
|
||||||
Db dbA(env->dbenv, 0);
|
Db dbA(env->dbenv.get(), 0);
|
||||||
if (dbA.remove(strFile.c_str(), nullptr, 0))
|
if (dbA.remove(strFile.c_str(), nullptr, 0))
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
Db dbB(env->dbenv, 0);
|
Db dbB(env->dbenv.get(), 0);
|
||||||
if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0))
|
if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0))
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
mutable CCriticalSection cs_db;
|
mutable CCriticalSection cs_db;
|
||||||
DbEnv *dbenv;
|
std::unique_ptr<DbEnv> dbenv;
|
||||||
std::map<std::string, int> mapFileUseCount;
|
std::map<std::string, int> mapFileUseCount;
|
||||||
std::map<std::string, Db*> mapDb;
|
std::map<std::string, Db*> mapDb;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "wallet/db.h"
|
#include "wallet/db.h"
|
||||||
#include "wallet/wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
CWallet *pwalletMain;
|
std::unique_ptr<CWallet> pwalletMain;
|
||||||
|
|
||||||
WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
||||||
TestingSetup(chainName)
|
TestingSetup(chainName)
|
||||||
@@ -17,18 +17,17 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
|||||||
|
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
|
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
|
||||||
pwalletMain = new CWallet(std::move(dbw));
|
pwalletMain = MakeUnique<CWallet>(std::move(dbw));
|
||||||
pwalletMain->LoadWallet(fFirstRun);
|
pwalletMain->LoadWallet(fFirstRun);
|
||||||
RegisterValidationInterface(pwalletMain);
|
RegisterValidationInterface(pwalletMain.get());
|
||||||
|
|
||||||
RegisterWalletRPCCommands(tableRPC);
|
RegisterWalletRPCCommands(tableRPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletTestingSetup::~WalletTestingSetup()
|
WalletTestingSetup::~WalletTestingSetup()
|
||||||
{
|
{
|
||||||
UnregisterValidationInterface(pwalletMain);
|
UnregisterValidationInterface(pwalletMain.get());
|
||||||
delete pwalletMain;
|
pwalletMain.reset();
|
||||||
pwalletMain = nullptr;
|
|
||||||
|
|
||||||
bitdb.Flush(true);
|
bitdb.Flush(true);
|
||||||
bitdb.Reset();
|
bitdb.Reset();
|
||||||
|
|||||||
@@ -3806,7 +3806,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
|
|||||||
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
||||||
|
|
||||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
|
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
|
||||||
std::unique_ptr<CWallet> tempWallet(new CWallet(std::move(dbw)));
|
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(std::move(dbw));
|
||||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||||
if (nZapWalletRet != DB_LOAD_OK) {
|
if (nZapWalletRet != DB_LOAD_OK) {
|
||||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||||
|
|||||||
Reference in new issue
Block a user