aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bitcoin-tx.cpp11
-rw-r--r--src/interfaces/wallet.cpp1
-rw-r--r--src/interfaces/wallet.h3
-rw-r--r--src/net.cpp6
-rw-r--r--src/net.h2
-rw-r--r--src/netbase.cpp20
-rw-r--r--src/netbase.h2
-rw-r--r--src/qt/walletview.cpp11
-rw-r--r--src/script/script.h9
-rw-r--r--src/wallet/rpcdump.cpp44
10 files changed, 74 insertions, 35 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index eb41e9a416..07ad09ea7b 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -545,12 +545,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
if (!findSighashFlags(nHashType, flagStr))
throw std::runtime_error("unknown sighash flag/sign option");
- std::vector<CTransaction> txVariants;
- txVariants.push_back(tx);
-
// mergedTx will end up with all the signatures; it
// starts as a clone of the raw tx:
- CMutableTransaction mergedTx(txVariants[0]);
+ CMutableTransaction mergedTx{tx};
+ const CTransaction txv{tx};
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
@@ -633,7 +631,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
- CTxIn& txin = mergedTx.vin[i];
+ const CTxIn& txin = mergedTx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsSpent()) {
continue;
@@ -647,8 +645,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
// ... and merge in other signatures:
- for (const CTransaction& txv : txVariants)
- sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i));
+ sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i));
UpdateTransaction(mergedTx, i, sigdata);
}
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
index fbf631f7da..3e6f0d6728 100644
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -130,6 +130,7 @@ public:
{
return m_wallet.ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase);
}
+ void abortRescan() override { m_wallet.AbortRescan(); }
bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); }
std::string getWalletName() override { return m_wallet.GetName(); }
bool getKeyFromPool(bool internal, CPubKey& pub_key) override
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 3e27242c2c..dfe3d5f711 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -65,6 +65,9 @@ public:
virtual bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
const SecureString& new_wallet_passphrase) = 0;
+ //! Abort a rescan.
+ virtual void abortRescan() = 0;
+
//! Back up wallet.
virtual bool backupWallet(const std::string& filename) = 0;
diff --git a/src/net.cpp b/src/net.cpp
index 342dfbaeb9..db40371772 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -368,7 +368,7 @@ static CAddress GetBindAddress(SOCKET sock)
return addr_bind;
}
-CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
+CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection)
{
if (pszDest == nullptr) {
if (IsLocal(addrConnect))
@@ -432,7 +432,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (hSocket == INVALID_SOCKET) {
return nullptr;
}
- connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
}
if (!proxyConnectionFailed) {
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
@@ -1992,7 +1992,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
} else if (FindNode(std::string(pszDest)))
return;
- CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
+ CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection);
if (!pnode)
return;
diff --git a/src/net.h b/src/net.h
index 7839b75a86..1bcc3cbb44 100644
--- a/src/net.h
+++ b/src/net.h
@@ -338,7 +338,7 @@ private:
CNode* FindNode(const CService& addr);
bool AttemptToEvictConnection();
- CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure);
+ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection);
bool IsWhitelistedRange(const CNetAddr &addr);
void DeleteNode(CNode* pnode);
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 92ac1c4c85..5d3d2f25c8 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -9,6 +9,7 @@
#include <sync.h>
#include <uint256.h>
#include <random.h>
+#include <tinyformat.h>
#include <util.h>
#include <utilstrencodings.h>
@@ -468,7 +469,17 @@ SOCKET CreateSocket(const CService &addrConnect)
return hSocket;
}
-bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout)
+template<typename... Args>
+static void LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args) {
+ std::string error_message = tfm::format(fmt, args...);
+ if (manual_connection) {
+ LogPrintf("%s\n", error_message);
+ } else {
+ LogPrint(BCLog::NET, "%s\n", error_message);
+ }
+}
+
+bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout, bool manual_connection)
{
struct sockaddr_storage sockaddr;
socklen_t len = sizeof(sockaddr);
@@ -513,7 +524,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
}
if (nRet != 0)
{
- LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
+ LogConnectFailure(manual_connection, "connect() to %s failed after select(): %s", addrConnect.ToString(), NetworkErrorString(nRet));
return false;
}
}
@@ -523,7 +534,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
else
#endif
{
- LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
+ LogConnectFailure(manual_connection, "connect() to %s failed: %s", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
return false;
}
}
@@ -581,7 +592,7 @@ bool IsProxy(const CNetAddr &addr) {
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool *outProxyConnectionFailed)
{
// first connect to proxy server
- if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
+ if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout, true)) {
if (outProxyConnectionFailed)
*outProxyConnectionFailed = true;
return false;
@@ -601,6 +612,7 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
}
return true;
}
+
bool LookupSubNet(const char* pszName, CSubNet& ret)
{
std::string strSubnet(pszName);
diff --git a/src/netbase.h b/src/netbase.h
index c0921b6441..50d4bc54fa 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -52,7 +52,7 @@ bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault,
CService LookupNumeric(const char *pszName, int portDefault = 0);
bool LookupSubNet(const char *pszName, CSubNet& subnet);
SOCKET CreateSocket(const CService &addrConnect);
-bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout);
+bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout, bool manual_connection);
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
/** Return readable error string for a network error code */
std::string NetworkErrorString(int err);
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 8b9b85c8c9..d529595dec 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -315,9 +315,9 @@ void WalletView::showProgress(const QString &title, int nProgress)
progressDialog = new QProgressDialog(title, "", 0, 100);
progressDialog->setWindowModality(Qt::ApplicationModal);
progressDialog->setMinimumDuration(0);
- progressDialog->setCancelButton(0);
progressDialog->setAutoClose(false);
progressDialog->setValue(0);
+ progressDialog->setCancelButtonText(tr("Cancel"));
}
else if (nProgress == 100)
{
@@ -327,8 +327,13 @@ void WalletView::showProgress(const QString &title, int nProgress)
progressDialog->deleteLater();
}
}
- else if (progressDialog)
- progressDialog->setValue(nProgress);
+ else if (progressDialog) {
+ if (progressDialog->wasCanceled()) {
+ getWalletModel()->wallet().abortRescan();
+ } else {
+ progressDialog->setValue(nProgress);
+ }
+ }
}
void WalletView::requestedSyncWarningInfo()
diff --git a/src/script/script.h b/src/script/script.h
index 8e5a792c7d..59ceff247c 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -615,15 +615,6 @@ public:
return nFound;
}
- int Find(opcodetype op) const
- {
- int nFound = 0;
- opcodetype opcode;
- for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)
- if (opcode == op)
- ++nFound;
- return nFound;
- }
/**
* Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index a3594aa692..b8533839a0 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -172,7 +172,13 @@ UniValue importprivkey(const JSONRPCRequest& request)
}
}
if (fRescan) {
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
}
return NullUniValue;
@@ -310,7 +316,13 @@ UniValue importaddress(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -479,7 +491,13 @@ UniValue importpubkey(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -534,9 +552,11 @@ UniValue importwallet(const JSONRPCRequest& request)
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
file.seekg(0, file.beg);
- pwallet->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
+ // Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which
+ // we don't want for this progress bar shoing the import progress. uiInterface.ShowProgress does not have a cancel button.
+ uiInterface.ShowProgress(_("Importing..."), 0, false); // show progress dialog in GUI
while (file.good()) {
- pwallet->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
+ uiInterface.ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);
std::string line;
std::getline(file, line);
if (line.empty() || line[0] == '#')
@@ -599,10 +619,17 @@ UniValue importwallet(const JSONRPCRequest& request)
}
}
file.close();
- pwallet->ShowProgress("", 100); // hide progress dialog in GUI
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
pwallet->UpdateTimeFirstKey(nTimeBegin);
}
- pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
+ int64_t scanned_time = pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > nTimeBegin) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->MarkDirty();
if (!fGood)
@@ -1212,6 +1239,9 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver, true /* update */);
pwallet->ReacceptWalletTransactions();
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
if (scannedTime > nLowestTimestamp) {
std::vector<UniValue> results = response.getValues();
response.clear();