aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2017-03-02 15:24:50 -0500
committerRussell Yanofsky <russ@yanofsky.org>2017-06-05 09:59:58 -0500
commit9bb66ab66013fc3024fad00bceeb22a330b5bc1b (patch)
treea4cf946a662c3d302685421a1b46935b8876ab58 /src/wallet
parentccf84bb9c10b4397f1a2aed6cf83fa0172c5cf7f (diff)
downloadbitcoin-9bb66ab66013fc3024fad00bceeb22a330b5bc1b.tar.xz
Add RescanFromTime method and use from rpcdump
No change in behavior.
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/rpcdump.cpp26
-rw-r--r--src/wallet/wallet.cpp32
-rw-r--r--src/wallet/wallet.h3
3 files changed, 44 insertions, 17 deletions
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 3efbeafe4f..9359887e0d 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -149,7 +149,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
pwallet->UpdateTimeFirstKey(1);
if (fRescan) {
- pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
}
}
@@ -279,7 +279,7 @@ UniValue importaddress(const JSONRPCRequest& request)
if (fRescan)
{
- pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
pwallet->ReacceptWalletTransactions();
}
@@ -437,7 +437,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
if (fRescan)
{
- pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
pwallet->ReacceptWalletTransactions();
}
@@ -537,11 +537,7 @@ UniValue importwallet(const JSONRPCRequest& request)
file.close();
pwallet->ShowProgress("", 100); // hide progress dialog in GUI
pwallet->UpdateTimeFirstKey(nTimeBegin);
-
- CBlockIndex *pindex = chainActive.FindEarliestAtLeast(nTimeBegin - TIMESTAMP_WINDOW);
-
- LogPrintf("Rescanning last %i blocks\n", pindex ? chainActive.Height() - pindex->nHeight + 1 : 0);
- pwallet->ScanForWalletTransactions(pindex);
+ pwallet->RescanFromTime(nTimeBegin - TIMESTAMP_WINDOW, false /* update */);
pwallet->MarkDirty();
if (!fGood)
@@ -1117,14 +1113,10 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
}
if (fRescan && fRunScan && requests.size()) {
- CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max<int64_t>(nLowestTimestamp - TIMESTAMP_WINDOW, 0)) : chainActive.Genesis();
- CBlockIndex* scanFailed = nullptr;
- if (pindex) {
- scanFailed = pwallet->ScanForWalletTransactions(pindex, true);
- pwallet->ReacceptWalletTransactions();
- }
+ int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp - TIMESTAMP_WINDOW, true /* update */);
+ pwallet->ReacceptWalletTransactions();
- if (scanFailed) {
+ if (scannedTime > nLowestTimestamp - TIMESTAMP_WINDOW) {
std::vector<UniValue> results = response.getValues();
response.clear();
response.setArray();
@@ -1134,7 +1126,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
// range, or if the import result already has an error set, let
// the result stand unmodified. Otherwise replace the result
// with an error message.
- if (GetImportTimestamp(request, now) - TIMESTAMP_WINDOW > scanFailed->GetBlockTimeMax() || results.at(i).exists("error")) {
+ if (scannedTime <= GetImportTimestamp(request, now) - TIMESTAMP_WINDOW || results.at(i).exists("error")) {
response.push_back(results.at(i));
} else {
UniValue result = UniValue(UniValue::VOBJ);
@@ -1150,7 +1142,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
"caused by pruning or data corruption (see bitcoind log for details) and could "
"be dealt with by downloading and rescanning the relevant blocks (see -reindex "
"and -rescan options).",
- GetImportTimestamp(request, now), scanFailed->GetBlockTimeMax(), TIMESTAMP_WINDOW)));
+ GetImportTimestamp(request, now), scannedTime - 1, TIMESTAMP_WINDOW)));
response.push_back(std::move(result));
}
++i;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 880a6a8bd7..06f8fc0458 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -221,6 +221,10 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
}
+/**
+ * Update wallet first key creation time. This should be called whenever keys
+ * are added to the wallet, with the oldest key creation time.
+ */
void CWallet::UpdateTimeFirstKey(int64_t nCreateTime)
{
AssertLockHeld(cs_wallet);
@@ -1459,6 +1463,34 @@ void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
}
/**
+ * Scan active chain for relevant transactions after importing keys. This should
+ * be called whenever new keys are added to the wallet, with the oldest key
+ * creation time minus TIMESTAMP_WINDOW.
+ *
+ * @return Earliest timestamp that could be successfully scanned from. Timestamp
+ * returned may be higher than startTime if some blocks could not be read.
+ */
+int64_t CWallet::RescanFromTime(int64_t startTime, bool update)
+{
+ AssertLockHeld(cs_main);
+ AssertLockHeld(cs_wallet);
+
+ // Find starting block. May be null if nCreateTime is greater than the
+ // highest blockchain timestamp, in which case there is nothing that needs
+ // to be scanned.
+ CBlockIndex* const startBlock = chainActive.FindEarliestAtLeast(startTime);
+ LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0);
+
+ if (startBlock) {
+ const CBlockIndex* const failedBlock = ScanForWalletTransactions(startBlock, update);
+ if (failedBlock) {
+ return failedBlock->GetBlockTimeMax() + 1;
+ }
+ }
+ return startTime;
+}
+
+/**
* Scan the block chain (starting in pindexStart) for transactions
* from or to us. If fUpdate is true, found transactions that already
* exist in the wallet will be updated.
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index a3974bf00b..b6459f765c 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -67,6 +67,8 @@ static const bool DEFAULT_USE_HD_WALLET = true;
extern const char * DEFAULT_WALLET_DAT;
+static const int64_t TIMESTAMP_MIN = 0;
+
class CBlockIndex;
class CCoinControl;
class COutput;
@@ -918,6 +920,7 @@ public:
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate);
+ int64_t RescanFromTime(int64_t startTime, bool update);
CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
void ReacceptWalletTransactions();
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override;