aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2017-01-17 18:06:16 -0500
committerMatt Corallo <git@bluematt.me>2017-10-13 19:29:54 -0400
commit5ee31726360cbe343f5a1a50a5e440db736da5b7 (patch)
treed6e3cab34961e1875957bbec38742feccd01f778 /src/wallet/wallet.cpp
parent0b2f42d7376c5f7c1ba1ac5d17a30691989d9159 (diff)
downloadbitcoin-5ee31726360cbe343f5a1a50a5e440db736da5b7.tar.xz
Add CWallet::BlockUntilSyncedToCurrentChain()
This blocks until the wallet has synced up to the current height.
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 3672ecea5b..d6ca4fce60 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -33,6 +33,7 @@
#include "wallet/fees.h"
#include <assert.h>
+#include <future>
#include <boost/algorithm/string/replace.hpp>
#include <boost/thread.hpp>
@@ -1232,6 +1233,8 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
for (size_t i = 0; i < pblock->vtx.size(); i++) {
SyncTransaction(pblock->vtx[i], pindex, i);
}
+
+ m_last_block_processed = pindex;
}
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
@@ -1244,6 +1247,36 @@ void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
+void CWallet::BlockUntilSyncedToCurrentChain() {
+ AssertLockNotHeld(cs_main);
+ AssertLockNotHeld(cs_wallet);
+
+ {
+ // Skip the queue-draining stuff if we know we're caught up with
+ // chainActive.Tip()...
+ // We could also take cs_wallet here, and call m_last_block_processed
+ // protected by cs_wallet instead of cs_main, but as long as we need
+ // cs_main here anyway, its easier to just call it cs_main-protected.
+ LOCK(cs_main);
+ const CBlockIndex* initialChainTip = chainActive.Tip();
+
+ if (m_last_block_processed->GetAncestor(initialChainTip->nHeight) == initialChainTip) {
+ return;
+ }
+ }
+
+ // ...otherwise put a callback in the validation interface queue and wait
+ // for the queue to drain enough to execute it (indicating we are caught up
+ // at least with the time we entered this function).
+
+ std::promise<void> promise;
+ CallFunctionInValidationInterfaceQueue([&promise] {
+ promise.set_value();
+ });
+ promise.get_future().wait();
+}
+
+
isminetype CWallet::IsMine(const CTxIn &txin) const
{
{
@@ -3900,8 +3933,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
- RegisterValidationInterface(walletInstance);
-
// Try to top up keypool. No-op if the wallet is locked.
walletInstance->TopUpKeyPool();
@@ -3913,6 +3944,10 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
if (walletdb.ReadBestBlock(locator))
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
}
+
+ walletInstance->m_last_block_processed = chainActive.Tip();
+ RegisterValidationInterface(walletInstance);
+
if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
{
//We can't rescan beyond non-pruned blocks, stop and throw an error