aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bitcoinrpc.cpp14
-rw-r--r--src/db.cpp16
-rw-r--r--src/init.cpp8
-rw-r--r--src/main.cpp38
-rw-r--r--src/main.h1
-rw-r--r--src/net.cpp108
-rw-r--r--src/net.h16
-rw-r--r--src/qt/bitcoin.qrc1
-rw-r--r--src/qt/bitcoingui.cpp17
-rw-r--r--src/qt/bitcoingui.h3
-rw-r--r--src/qt/res/icons/filesave.pngbin0 -> 1741 bytes
-rw-r--r--src/qt/walletmodel.cpp6
-rw-r--r--src/qt/walletmodel.h2
-rw-r--r--src/util.cpp32
14 files changed, 168 insertions, 94 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index cf5bc64bb..be40e937b 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -1816,7 +1816,7 @@ Value getwork(const Array& params, bool fHelp)
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
// Update nExtraNonce
@@ -1916,7 +1916,7 @@ Value getmemorypool(const Array& params, bool fHelp)
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
Array transactions;
@@ -2355,15 +2355,15 @@ void ThreadRPCServer(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
try
{
- vnThreadsRunning[4]++;
+ vnThreadsRunning[THREAD_RPCSERVER]++;
ThreadRPCServer2(parg);
- vnThreadsRunning[4]--;
+ vnThreadsRunning[THREAD_RPCSERVER]--;
}
catch (std::exception& e) {
- vnThreadsRunning[4]--;
+ vnThreadsRunning[THREAD_RPCSERVER]--;
PrintException(&e, "ThreadRPCServer()");
} catch (...) {
- vnThreadsRunning[4]--;
+ vnThreadsRunning[THREAD_RPCSERVER]--;
PrintException(NULL, "ThreadRPCServer()");
}
printf("ThreadRPCServer exiting\n");
@@ -2443,7 +2443,7 @@ void ThreadRPCServer2(void* parg)
#endif
ip::tcp::endpoint peer;
- vnThreadsRunning[4]--;
+ vnThreadsRunning[THREAD_RPCSERVER]--;
#ifdef USE_SSL
acceptor.accept(sslStream.lowest_layer(), peer);
#else
diff --git a/src/db.cpp b/src/db.cpp
index 3bdda6156..9a904ec2e 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -6,6 +6,7 @@
#include "headers.h"
#include "db.h"
#include "net.h"
+#include <boost/version.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -1064,14 +1065,19 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
filesystem::path pathDest(strDest);
if (filesystem::is_directory(pathDest))
pathDest = pathDest / wallet.strWalletFile;
+
+ try {
#if BOOST_VERSION >= 104000
- filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
+ filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
#else
- filesystem::copy_file(pathSrc, pathDest);
+ filesystem::copy_file(pathSrc, pathDest);
#endif
- printf("copied wallet.dat to %s\n", pathDest.string().c_str());
-
- return true;
+ printf("copied wallet.dat to %s\n", pathDest.string().c_str());
+ return true;
+ } catch(const filesystem::filesystem_error &e) {
+ printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what());
+ return false;
+ }
}
}
Sleep(100);
diff --git a/src/init.cpp b/src/init.cpp
index 95bf76495..0f2e10dab 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -210,10 +210,10 @@ bool AppInit2(int argc, char* argv[])
#endif
#endif
" -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send") + "\n" +
-#ifdef GUI
+#ifdef QT_GUI
" -server \t\t " + _("Accept command line and JSON-RPC commands") + "\n" +
#endif
-#if !defined(WIN32) && !defined(GUI)
+#if !defined(WIN32) && !defined(QT_GUI)
" -daemon \t\t " + _("Run in the background as a daemon and accept commands") + "\n" +
#endif
" -testnet \t\t " + _("Use the test network") + "\n" +
@@ -253,7 +253,7 @@ bool AppInit2(int argc, char* argv[])
fTestNet = GetBoolArg("-testnet");
fDebug = GetBoolArg("-debug");
-#if !defined(WIN32) && !defined(GUI)
+#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
#else
fDaemon = false;
@@ -284,7 +284,7 @@ bool AppInit2(int argc, char* argv[])
}
#endif
-#if !defined(WIN32) && !defined(GUI)
+#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
{
// Daemonize
diff --git a/src/main.cpp b/src/main.cpp
index e4c6714ea..b73037fb6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -922,6 +922,15 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
}
+void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
+{
+ nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ // Updating time can change work required on testnet:
+ if (fTestNet)
+ nBits = GetNextWorkRequired(pindexPrev, this);
+}
+
@@ -3168,7 +3177,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
pblock->nNonce = 0;
@@ -3326,6 +3335,7 @@ void static BitcoinMiner(CWallet *pwallet)
FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
+ unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
@@ -3390,7 +3400,7 @@ void static BitcoinMiner(CWallet *pwallet)
{
nLogTime = GetTime();
printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
- printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
+ printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0);
}
}
}
@@ -3401,7 +3411,7 @@ void static BitcoinMiner(CWallet *pwallet)
return;
if (!fGenerateBitcoins)
return;
- if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
+ if (fLimitProcessors && vnThreadsRunning[THREAD_MINER] > nLimitProcessors)
return;
if (vNodes.empty())
break;
@@ -3413,8 +3423,14 @@ void static BitcoinMiner(CWallet *pwallet)
break;
// Update nTime every few seconds
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
nBlockTime = ByteReverse(pblock->nTime);
+ if (fTestNet)
+ {
+ // Changing pblock->nTime can change work required on testnet:
+ nBlockBits = ByteReverse(pblock->nBits);
+ hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
+ }
}
}
}
@@ -3424,22 +3440,22 @@ void static ThreadBitcoinMiner(void* parg)
CWallet* pwallet = (CWallet*)parg;
try
{
- vnThreadsRunning[3]++;
+ vnThreadsRunning[THREAD_MINER]++;
BitcoinMiner(pwallet);
- vnThreadsRunning[3]--;
+ vnThreadsRunning[THREAD_MINER]--;
}
catch (std::exception& e) {
- vnThreadsRunning[3]--;
+ vnThreadsRunning[THREAD_MINER]--;
PrintException(&e, "ThreadBitcoinMiner()");
} catch (...) {
- vnThreadsRunning[3]--;
+ vnThreadsRunning[THREAD_MINER]--;
PrintException(NULL, "ThreadBitcoinMiner()");
}
UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
nHPSTimerStart = 0;
- if (vnThreadsRunning[3] == 0)
+ if (vnThreadsRunning[THREAD_MINER] == 0)
dHashesPerSec = 0;
- printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
+ printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]);
}
@@ -3459,7 +3475,7 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
nProcessors = 1;
if (fLimitProcessors && nProcessors > nLimitProcessors)
nProcessors = nLimitProcessors;
- int nAddThreads = nProcessors - vnThreadsRunning[3];
+ int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER];
printf("Starting %d BitcoinMiner threads\n", nAddThreads);
for (int i = 0; i < nAddThreads; i++)
{
diff --git a/src/main.h b/src/main.h
index 908ada7d4..d9f976c21 100644
--- a/src/main.h
+++ b/src/main.h
@@ -913,6 +913,7 @@ public:
return (int64)nTime;
}
+ void UpdateTime(const CBlockIndex* pindexPrev);
uint256 BuildMerkleTree() const
diff --git a/src/net.cpp b/src/net.cpp
index 3a1777f3f..fd488ce67 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -38,8 +38,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect);
-
-
//
// Global state variables
//
@@ -49,7 +47,7 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
static CNode* pnodeLocalHost = NULL;
uint64 nLocalHostNonce = 0;
-array<int, 10> vnThreadsRunning;
+array<int, THREAD_MAX> vnThreadsRunning;
static SOCKET hListenSocket = INVALID_SOCKET;
vector<CNode*> vNodes;
@@ -67,7 +65,6 @@ CCriticalSection cs_setservAddNodeAddresses;
-
unsigned short GetListenPort()
{
return (unsigned short)(GetArg("-port", GetDefaultPort()));
@@ -602,15 +599,15 @@ void ThreadSocketHandler(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
try
{
- vnThreadsRunning[0]++;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]++;
ThreadSocketHandler2(parg);
- vnThreadsRunning[0]--;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]--;
}
catch (std::exception& e) {
- vnThreadsRunning[0]--;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]--;
PrintException(&e, "ThreadSocketHandler()");
} catch (...) {
- vnThreadsRunning[0]--;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]--;
throw; // support pthread_cancel()
}
printf("ThreadSocketHandler exiting\n");
@@ -712,9 +709,9 @@ void ThreadSocketHandler2(void* parg)
}
}
- vnThreadsRunning[0]--;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]--;
int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
- vnThreadsRunning[0]++;
+ vnThreadsRunning[THREAD_SOCKETHANDLER]++;
if (fShutdown)
return;
if (nSelect == SOCKET_ERROR)
@@ -927,15 +924,15 @@ void ThreadMapPort(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
try
{
- vnThreadsRunning[5]++;
+ vnThreadsRunning[THREAD_UPNP]++;
ThreadMapPort2(parg);
- vnThreadsRunning[5]--;
+ vnThreadsRunning[THREAD_UPNP]--;
}
catch (std::exception& e) {
- vnThreadsRunning[5]--;
+ vnThreadsRunning[THREAD_UPNP]--;
PrintException(&e, "ThreadMapPort()");
} catch (...) {
- vnThreadsRunning[5]--;
+ vnThreadsRunning[THREAD_UPNP]--;
PrintException(NULL, "ThreadMapPort()");
}
printf("ThreadMapPort exiting\n");
@@ -1056,7 +1053,7 @@ void MapPort(bool fMapPort)
fUseUPnP = fMapPort;
WriteSetting("fUseUPnP", fUseUPnP);
}
- if (fUseUPnP && vnThreadsRunning[5] < 1)
+ if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
{
if (!CreateThread(ThreadMapPort, NULL))
printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
@@ -1090,15 +1087,15 @@ void ThreadDNSAddressSeed(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
try
{
- vnThreadsRunning[6]++;
+ vnThreadsRunning[THREAD_DNSSEED]++;
ThreadDNSAddressSeed2(parg);
- vnThreadsRunning[6]--;
+ vnThreadsRunning[THREAD_DNSSEED]--;
}
catch (std::exception& e) {
- vnThreadsRunning[6]--;
+ vnThreadsRunning[THREAD_DNSSEED]--;
PrintException(&e, "ThreadDNSAddressSeed()");
} catch (...) {
- vnThreadsRunning[6]--;
+ vnThreadsRunning[THREAD_DNSSEED]--;
throw; // support pthread_cancel()
}
printf("ThreadDNSAddressSeed exiting\n");
@@ -1236,15 +1233,15 @@ void ThreadOpenConnections(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
try
{
- vnThreadsRunning[1]++;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
ThreadOpenConnections2(parg);
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
}
catch (std::exception& e) {
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
PrintException(&e, "ThreadOpenConnections()");
} catch (...) {
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
PrintException(NULL, "ThreadOpenConnections()");
}
printf("ThreadOpenConnections exiting\n");
@@ -1278,9 +1275,9 @@ void ThreadOpenConnections2(void* parg)
int64 nStart = GetTime();
loop
{
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
Sleep(500);
- vnThreadsRunning[1]++;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return;
@@ -1296,9 +1293,9 @@ void ThreadOpenConnections2(void* parg)
nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
if (nOutbound < nMaxOutboundConnections)
break;
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
Sleep(2000);
- vnThreadsRunning[1]++;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return;
}
@@ -1410,15 +1407,15 @@ void ThreadOpenAddedConnections(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
try
{
- vnThreadsRunning[7]++;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
ThreadOpenAddedConnections2(parg);
- vnThreadsRunning[7]--;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
}
catch (std::exception& e) {
- vnThreadsRunning[7]--;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
PrintException(&e, "ThreadOpenAddedConnections()");
} catch (...) {
- vnThreadsRunning[7]--;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
PrintException(NULL, "ThreadOpenAddedConnections()");
}
printf("ThreadOpenAddedConnections exiting\n");
@@ -1467,9 +1464,9 @@ void ThreadOpenAddedConnections2(void* parg)
}
if (fShutdown)
return;
- vnThreadsRunning[7]--;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
Sleep(120000); // Retry every 2 minutes
- vnThreadsRunning[7]++;
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
if (fShutdown)
return;
}
@@ -1486,9 +1483,9 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
return false;
- vnThreadsRunning[1]--;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
CNode* pnode = ConnectNode(addrConnect);
- vnThreadsRunning[1]++;
+ vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return false;
if (!pnode)
@@ -1510,15 +1507,15 @@ void ThreadMessageHandler(void* parg)
IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
try
{
- vnThreadsRunning[2]++;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
ThreadMessageHandler2(parg);
- vnThreadsRunning[2]--;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
}
catch (std::exception& e) {
- vnThreadsRunning[2]--;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
PrintException(&e, "ThreadMessageHandler()");
} catch (...) {
- vnThreadsRunning[2]--;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
PrintException(NULL, "ThreadMessageHandler()");
}
printf("ThreadMessageHandler exiting\n");
@@ -1566,11 +1563,11 @@ void ThreadMessageHandler2(void* parg)
// Wait and allow messages to bunch up.
// Reduce vnThreadsRunning so StopNode has permission to exit while
// we're sleeping, but we must always check fShutdown after doing this.
- vnThreadsRunning[2]--;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
Sleep(100);
if (fRequestShutdown)
Shutdown(NULL);
- vnThreadsRunning[2]++;
+ vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
if (fShutdown)
return;
}
@@ -1773,23 +1770,26 @@ bool StopNode()
fShutdown = true;
nTransactionsUpdated++;
int64 nStart = GetTime();
- while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
- || (fHaveUPnP && vnThreadsRunning[5] > 0) || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0
- )
+ do
{
+ int nThreadsRunning = 0;
+ for (int n = 0; n < THREAD_MAX; n++)
+ nThreadsRunning += vnThreadsRunning[n];
+ if (nThreadsRunning == 0)
+ break;
if (GetTime() - nStart > 20)
break;
Sleep(20);
- }
- if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
- if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
- if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
- if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
- if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
- if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
- if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
- if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n");
- while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
+ } while(true);
+ if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
+ if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
+ if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
+ if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
+ if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
+ if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
+ if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
+ if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
+ while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
Sleep(20);
Sleep(50);
diff --git a/src/net.h b/src/net.h
index a66bc1543..0a3cf388e 100644
--- a/src/net.h
+++ b/src/net.h
@@ -68,14 +68,26 @@ public:
-
+enum threadId
+{
+ THREAD_SOCKETHANDLER,
+ THREAD_OPENCONNECTIONS,
+ THREAD_MESSAGEHANDLER,
+ THREAD_MINER,
+ THREAD_RPCSERVER,
+ THREAD_UPNP,
+ THREAD_DNSSEED,
+ THREAD_ADDEDCONNECTIONS,
+
+ THREAD_MAX
+};
extern bool fClient;
extern bool fAllowDNS;
extern uint64 nLocalServices;
extern CAddress addrLocalHost;
extern uint64 nLocalHostNonce;
-extern boost::array<int, 10> vnThreadsRunning;
+extern boost::array<int, THREAD_MAX> vnThreadsRunning;
extern std::vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index 5693ae187..d823752c9 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -37,6 +37,7 @@
<file alias="lock_closed">res/icons/lock_closed.png</file>
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
+ <file alias="filesave">res/icons/filesave.png</file>
</qresource>
<qresource prefix="/images">
<file alias="about">res/images/about.png</file>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 3fad4d926..c95afdcef 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -46,6 +46,8 @@
#include <QStackedWidget>
#include <QDateTime>
#include <QMovie>
+#include <QFileDialog>
+#include <QDesktopServices>
#include <QDragEnterEvent>
#include <QUrl>
@@ -243,6 +245,8 @@ void BitcoinGUI::createActions()
encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this);
encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
encryptWalletAction->setCheckable(true);
+ backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet"), this);
+ backupWalletAction->setToolTip(tr("Backup wallet to another location"));
changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
@@ -252,6 +256,7 @@ void BitcoinGUI::createActions()
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
+ connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
}
@@ -277,6 +282,7 @@ void BitcoinGUI::createMenuBar()
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
settings->addAction(encryptWalletAction);
settings->addAction(changePassphraseAction);
+ settings->addAction(backupWalletAction);
settings->addSeparator();
settings->addAction(optionsAction);
@@ -777,6 +783,17 @@ void BitcoinGUI::encryptWallet(bool status)
setEncryptionStatus(walletModel->getEncryptionStatus());
}
+void BitcoinGUI::backupWallet()
+{
+ QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+ QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
+ if(!filename.isEmpty()) {
+ if(!walletModel->backupWallet(filename)) {
+ QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."));
+ }
+ }
+}
+
void BitcoinGUI::changePassphrase()
{
AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 37ab12577..a52242900 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -86,6 +86,7 @@ private:
QAction *openBitcoinAction;
QAction *exportAction;
QAction *encryptWalletAction;
+ QAction *backupWalletAction;
QAction *changePassphraseAction;
QAction *aboutQtAction;
@@ -162,6 +163,8 @@ private slots:
void incomingTransaction(const QModelIndex & parent, int start, int end);
/** Encrypt the wallet */
void encryptWallet(bool status);
+ /** Backup the wallet */
+ void backupWallet();
/** Change encrypted wallet passphrase */
void changePassphrase();
/** Ask for pass phrase to unlock wallet temporarily */
diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png
new file mode 100644
index 000000000..ae13a151d
--- /dev/null
+++ b/src/qt/res/icons/filesave.png
Binary files differ
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index f028f10f6..8344a653d 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -5,6 +5,7 @@
#include "transactiontablemodel.h"
#include "headers.h"
+#include "db.h" // for BackupWallet
#include <QTimer>
#include <QSet>
@@ -239,6 +240,11 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri
return retval;
}
+bool WalletModel::backupWallet(const QString &filename)
+{
+ return BackupWallet(*wallet, filename.toLocal8Bit().data());
+}
+
// WalletModel::UnlockContext implementation
WalletModel::UnlockContext WalletModel::requestUnlock()
{
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 89e8cdd2a..4123240e9 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -77,6 +77,8 @@ public:
// Passphrase only needed when unlocking
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
+ // Wallet backup
+ bool backupWallet(const QString &filename);
// RAI object for unlocking wallet, returned by requestUnlock()
class UnlockContext
diff --git a/src/util.cpp b/src/util.cpp
index 12ac076f0..f1af91de2 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -454,6 +454,21 @@ vector<unsigned char> ParseHex(const string& str)
return ParseHex(str.c_str());
}
+static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
+{
+ // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
+ if (name.find("-no") == 0)
+ {
+ std::string positive("-");
+ positive.append(name.begin()+3, name.end());
+ if (mapSettingsRet.count(positive) == 0)
+ {
+ bool value = !GetBoolArg(name);
+ mapSettingsRet[positive] = (value ? "1" : "0");
+ }
+ }
+}
+
void ParseParameters(int argc, const char*const argv[])
{
mapArgs.clear();
@@ -494,17 +509,8 @@ void ParseParameters(int argc, const char*const argv[])
name = singleDash;
}
- // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1, as long as -foo not set)
- if (name.find("-no") == 0)
- {
- std::string positive("-");
- positive.append(name.begin()+3, name.end());
- if (mapArgs.count(positive) == 0)
- {
- bool value = !GetBoolArg(name);
- mapArgs[positive] = (value ? "1" : "0");
- }
- }
+ // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
+ InterpretNegativeSetting(name, mapArgs);
}
}
@@ -920,7 +926,11 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
if (mapSettingsRet.count(strKey) == 0)
+ {
mapSettingsRet[strKey] = it->value[0];
+ // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
+ InterpretNegativeSetting(strKey, mapSettingsRet);
+ }
mapMultiSettingsRet[strKey].push_back(it->value[0]);
}
}