aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.qt.include4
-rw-r--r--src/Makefile.qttest.include6
-rw-r--r--src/addrman.cpp5
-rw-r--r--src/bitcoin-cli.cpp42
-rw-r--r--src/init.cpp63
-rw-r--r--src/main.cpp9
-rw-r--r--src/net.cpp30
-rw-r--r--src/net.h18
-rw-r--r--src/primitives/transaction.cpp5
-rw-r--r--src/primitives/transaction.h7
-rw-r--r--src/qt/addressbookpage.cpp16
-rw-r--r--src/qt/addresstablemodel.cpp12
-rw-r--r--src/qt/askpassphrasedialog.cpp8
-rw-r--r--src/qt/bitcoingui.cpp109
-rw-r--r--src/qt/bitcoingui.h4
-rw-r--r--src/qt/clientmodel.cpp22
-rw-r--r--src/qt/clientmodel.h3
-rw-r--r--src/qt/coincontroldialog.cpp12
-rw-r--r--src/qt/csvmodelwriter.cpp8
-rw-r--r--src/qt/editaddressdialog.cpp18
-rw-r--r--src/qt/forms/modaloverlay.ui373
-rw-r--r--src/qt/forms/overviewpage.ui4
-rw-r--r--src/qt/guiutil.cpp40
-rw-r--r--src/qt/guiutil.h2
-rw-r--r--src/qt/intro.cpp4
-rw-r--r--src/qt/modaloverlay.cpp158
-rw-r--r--src/qt/modaloverlay.h44
-rw-r--r--src/qt/networkstyle.cpp6
-rw-r--r--src/qt/notificator.cpp12
-rw-r--r--src/qt/optionsdialog.cpp12
-rw-r--r--src/qt/overviewpage.cpp11
-rw-r--r--src/qt/overviewpage.h2
-rw-r--r--src/qt/paymentrequest.proto2
-rw-r--r--src/qt/paymentserver.cpp4
-rw-r--r--src/qt/platformstyle.cpp10
-rw-r--r--src/qt/qvalidatedlineedit.cpp8
-rw-r--r--src/qt/qvaluecombobox.cpp4
-rw-r--r--src/qt/receivecoinsdialog.cpp26
-rw-r--r--src/qt/receiverequestdialog.cpp12
-rwxr-xr-xsrc/qt/res/movies/makespinner.sh4
-rw-r--r--src/qt/rpcconsole.cpp237
-rw-r--r--src/qt/rpcconsole.h2
-rw-r--r--src/qt/sendcoinsdialog.cpp46
-rw-r--r--src/qt/sendcoinsentry.cpp12
-rw-r--r--src/qt/signverifymessagedialog.cpp8
-rw-r--r--src/qt/test/rpcnestedtests.cpp93
-rw-r--r--src/qt/test/rpcnestedtests.h25
-rw-r--r--src/qt/test/test_main.cpp16
-rw-r--r--src/qt/transactiondesc.cpp1
-rw-r--r--src/qt/transactionfilterproxy.cpp8
-rw-r--r--src/qt/transactionrecord.h12
-rw-r--r--src/qt/transactiontablemodel.cpp18
-rw-r--r--src/qt/transactionview.cpp16
-rw-r--r--src/qt/walletframe.cpp14
-rw-r--r--src/qt/walletframe.h6
-rw-r--r--src/qt/walletmodel.cpp17
-rw-r--r--src/qt/walletmodel.h10
-rw-r--r--src/qt/walletmodeltransaction.cpp4
-rw-r--r--src/qt/walletview.cpp50
-rw-r--r--src/qt/walletview.h5
-rw-r--r--src/rpc/misc.cpp2
-rw-r--r--src/test/DoS_tests.cpp8
-rw-r--r--src/test/addrman_tests.cpp5
-rw-r--r--src/test/net_tests.cpp4
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/ui_interface.cpp5
-rw-r--r--src/ui_interface.h2
-rw-r--r--src/univalue/include/univalue.h26
-rw-r--r--src/univalue/lib/univalue.cpp25
-rw-r--r--src/util.cpp12
-rw-r--r--src/util.h2
-rw-r--r--src/wallet/rpcdump.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp3
-rw-r--r--src/wallet/test/accounting_tests.cpp24
-rw-r--r--src/wallet/wallet.cpp66
-rw-r--r--src/wallet/wallet.h7
76 files changed, 1480 insertions, 454 deletions
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 8947aeaca0..ea9be82717 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -96,6 +96,7 @@ QT_FORMS_UI = \
qt/forms/editaddressdialog.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
+ qt/forms/modaloverlay.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/overviewpage.ui \
@@ -125,6 +126,7 @@ QT_MOC_CPP = \
qt/moc_intro.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
+ qt/moc_modaloverlay.cpp \
qt/moc_notificator.cpp \
qt/moc_openuridialog.cpp \
qt/moc_optionsdialog.cpp \
@@ -192,6 +194,7 @@ BITCOIN_QT_H = \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
+ qt/modaloverlay.h \
qt/networkstyle.h \
qt/notificator.h \
qt/openuridialog.h \
@@ -292,6 +295,7 @@ BITCOIN_QT_CPP = \
qt/csvmodelwriter.cpp \
qt/guiutil.cpp \
qt/intro.cpp \
+ qt/modaloverlay.cpp \
qt/networkstyle.cpp \
qt/notificator.cpp \
qt/optionsdialog.cpp \
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index 813a343ffa..0a7efb5d5b 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -1,13 +1,16 @@
bin_PROGRAMS += qt/test/test_bitcoin-qt
TESTS += qt/test/test_bitcoin-qt
-TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
+TEST_QT_MOC_CPP = \
+ qt/test/moc_rpcnestedtests.cpp \
+ qt/test/moc_uritests.cpp
if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
endif
TEST_QT_H = \
+ qt/test/rpcnestedtests.h \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h
@@ -16,6 +19,7 @@ qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
qt_test_test_bitcoin_qt_SOURCES = \
+ qt/test/rpcnestedtests.cpp \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
$(TEST_QT_H)
diff --git a/src/addrman.cpp b/src/addrman.cpp
index cebb1c8e5e..bfb8e94575 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -255,6 +255,11 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
int nId;
CAddrInfo* pinfo = Find(addr, &nId);
+ // Do not set a penality for a source's self-announcement
+ if (addr == source) {
+ nTimePenalty = 0;
+ }
+
if (pinfo) {
// periodically update nTime
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index a04101d3ed..68f5d90f51 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -116,17 +116,42 @@ static bool AppInitRPC(int argc, char* argv[])
/** Reply structure for request_done to fill in */
struct HTTPReply
{
+ HTTPReply(): status(0), error(-1) {}
+
int status;
+ int error;
std::string body;
};
+const char *http_errorstring(int code)
+{
+ switch(code) {
+#if LIBEVENT_VERSION_NUMBER >= 0x02010300
+ case EVREQ_HTTP_TIMEOUT:
+ return "timeout reached";
+ case EVREQ_HTTP_EOF:
+ return "EOF reached";
+ case EVREQ_HTTP_INVALID_HEADER:
+ return "error while reading header, or invalid header";
+ case EVREQ_HTTP_BUFFER_ERROR:
+ return "error encountered while reading or writing";
+ case EVREQ_HTTP_REQUEST_CANCEL:
+ return "request was canceled";
+ case EVREQ_HTTP_DATA_TOO_LONG:
+ return "response body is larger than allowed";
+#endif
+ default:
+ return "unknown";
+ }
+}
+
static void http_request_done(struct evhttp_request *req, void *ctx)
{
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
if (req == NULL) {
- /* If req is NULL, it means an error occurred while connecting, but
- * I'm not sure how to find out which one. We also don't really care.
+ /* If req is NULL, it means an error occurred while connecting: the
+ * error code will have been passed to http_error_cb.
*/
reply->status = 0;
return;
@@ -145,6 +170,14 @@ static void http_request_done(struct evhttp_request *req, void *ctx)
}
}
+#if LIBEVENT_VERSION_NUMBER >= 0x02010300
+static void http_error_cb(enum evhttp_request_error err, void *ctx)
+{
+ HTTPReply *reply = static_cast<HTTPReply*>(ctx);
+ reply->error = err;
+}
+#endif
+
UniValue CallRPC(const string& strMethod, const UniValue& params)
{
std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT);
@@ -165,6 +198,9 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
if (req == NULL)
throw runtime_error("create http request failed");
+#if LIBEVENT_VERSION_NUMBER >= 0x02010300
+ evhttp_request_set_error_cb(req, http_error_cb);
+#endif
// Get credentials
std::string strRPCUserColonPass;
@@ -204,7 +240,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
event_base_free(base);
if (response.status == 0)
- throw CConnectionFailed("couldn't connect to server");
+ throw CConnectionFailed(strprintf("couldn't connect to server (%d %s)", response.error, http_errorstring(response.error)));
else if (response.status == HTTP_UNAUTHORIZED)
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
diff --git a/src/init.cpp b/src/init.cpp
index 8d1e330a05..b20675dd9e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -759,10 +759,7 @@ void InitParameterInteraction()
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
if (SoftSetBoolArg("-whitelistrelay", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
-#ifdef ENABLE_WALLET
- if (SoftSetBoolArg("-walletbroadcast", false))
- LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
-#endif
+ // walletbroadcast is disabled in CWallet::ParameterInteraction()
}
// Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
@@ -821,12 +818,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError("Initializing networking failed");
#ifndef WIN32
- if (GetBoolArg("-sysperms", false)) {
-#ifdef ENABLE_WALLET
- if (!GetBoolArg("-disablewallet", false))
- return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
-#endif
- } else {
+ if (!GetBoolArg("-sysperms", false)) {
umask(077);
}
@@ -854,15 +846,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// also see: InitParameterInteraction()
- // if using block pruning, then disable txindex
+ // if using block pruning, then disallow txindex
if (GetArg("-prune", 0)) {
if (GetBoolArg("-txindex", DEFAULT_TXINDEX))
return InitError(_("Prune mode is incompatible with -txindex."));
-#ifdef ENABLE_WALLET
- if (GetBoolArg("-rescan", false)) {
- return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
- }
-#endif
}
// Make sure enough file descriptors are available
@@ -948,9 +935,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterAllCoreRPCCommands(tableRPC);
#ifdef ENABLE_WALLET
- bool fDisableWallet = GetBoolArg("-disablewallet", false);
- if (!fDisableWallet)
- RegisterWalletRPCCommands(tableRPC);
+ RegisterWalletRPCCommands(tableRPC);
#endif
nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
@@ -966,10 +951,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (mapArgs.count("-minrelaytxfee"))
{
CAmount n = 0;
- if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
- ::minRelayTxFee = CFeeRate(n);
- else
+ if (!ParseMoney(mapArgs["-minrelaytxfee"], n))
return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"]));
+ // High fee check is done afterward in CWallet::ParameterInteraction()
+ ::minRelayTxFee = CFeeRate(n);
}
fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard());
@@ -980,7 +965,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_WALLET
if (!CWallet::ParameterInteraction())
return false;
-#endif // ENABLE_WALLET
+#endif
fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER);
@@ -1108,15 +1093,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 5: verify wallet database integrity
#ifdef ENABLE_WALLET
- if (!fDisableWallet) {
- if (!CWallet::Verify())
- return false;
- } // (!fDisableWallet)
-#endif // ENABLE_WALLET
+ if (!CWallet::Verify())
+ return false;
+#endif
// ********************************************************* Step 6: network initialization
assert(!g_connman);
- g_connman = std::unique_ptr<CConnman>(new CConnman());
+ g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())));
CConnman& connman = *g_connman;
RegisterNodeSignals(GetNodeSignals());
@@ -1249,8 +1232,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterValidationInterface(pzmqNotificationInterface);
}
#endif
+ uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set
+ uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME;
+
if (mapArgs.count("-maxuploadtarget")) {
- connman.SetMaxOutboundTarget(GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024);
+ nMaxOutboundLimit = GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024;
}
// ********************************************************* Step 7: load block chain
@@ -1437,17 +1423,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET
- if (fDisableWallet) {
- pwalletMain = NULL;
- LogPrintf("Wallet disabled!\n");
- } else {
- CWallet::InitLoadWallet();
- if (!pwalletMain)
- return false;
- }
-#else // ENABLE_WALLET
+ if (!CWallet::InitLoadWallet())
+ return false;
+#else
LogPrintf("No wallet support compiled in!\n");
-#endif // !ENABLE_WALLET
+#endif
// ********************************************************* Step 9: data directory maintenance
@@ -1533,6 +1513,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
connOptions.nSendBufferMaxSize = 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
connOptions.nReceiveFloodSize = 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
+ connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe;
+ connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
+
if(!connman.Start(threadGroup, scheduler, strNodeError, connOptions))
return InitError(strNodeError);
diff --git a/src/main.cpp b/src/main.cpp
index 593897f516..60bda426a6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -113,6 +113,8 @@ CScript COINBASE_FLAGS;
const string strMessageMagic = "Bitcoin Signed Message:\n";
+static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; // SHA256("main address relay")[0:8]
+
// Internal stuff
namespace {
@@ -2062,7 +2064,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
// Open history file to read
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("%s: OpenBlockFile failed", __func__);
+ return error("%s: OpenUndoFile failed", __func__);
// Read block
uint256 hashChecksum;
@@ -2386,6 +2388,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Start enforcing WITNESS rules using versionbits logic.
if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) {
flags |= SCRIPT_VERIFY_WITNESS;
+ flags |= SCRIPT_VERIFY_NULLDUMMY;
}
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
@@ -4739,11 +4742,9 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma
// Relay to a limited number of other nodes
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the addrKnowns of the chosen nodes prevent repeats
- static const uint64_t salt0 = GetRand(std::numeric_limits<uint64_t>::max());
- static const uint64_t salt1 = GetRand(std::numeric_limits<uint64_t>::max());
uint64_t hashAddr = addr.GetHash();
std::multimap<uint64_t, CNode*> mapMix;
- const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
+ const CSipHasher hasher = connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
auto sortfunc = [&mapMix, &hasher](CNode* pnode) {
if (pnode->nVersion >= CADDR_TIME_VERSION) {
diff --git a/src/net.cpp b/src/net.cpp
index cc9728b853..cce06f2d64 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -63,6 +63,7 @@
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
+static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
//
// Global state variables
//
@@ -387,7 +388,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
addrman.Attempt(addrConnect, fCountFailure);
// Add node
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, pszDest ? pszDest : "", false);
+ CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
@@ -448,7 +449,7 @@ void CNode::PushVersion()
{
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
- CAddress addrMe = GetLocalAddress(&addr, nLocalServices);
+ CAddress addrMe = CAddress(CService(), nLocalServices);
if (fLogIPs)
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nMyStartingHeight, addrMe.ToString(), addrYou.ToString(), id);
else
@@ -1022,7 +1023,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
}
}
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, "", true);
+ CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
pnode->fWhitelisted = whitelisted;
@@ -2023,7 +2024,7 @@ void Discover(boost::thread_group& threadGroup)
#endif
}
-CConnman::CConnman()
+CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
{
setBannedIsDirty = false;
fAddressesInitialized = false;
@@ -2046,9 +2047,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
{
nTotalBytesRecv = 0;
nTotalBytesSent = 0;
- nMaxOutboundLimit = 0;
nMaxOutboundTotalBytesSentInCycle = 0;
- nMaxOutboundTimeframe = 60*60*24; //1 day
nMaxOutboundCycleStartTime = 0;
nRelevantServices = connOptions.nRelevantServices;
@@ -2060,6 +2059,9 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
nSendBufferMaxSize = connOptions.nSendBufferMaxSize;
nReceiveFloodSize = connOptions.nSendBufferMaxSize;
+ nMaxOutboundLimit = connOptions.nMaxOutboundLimit;
+ nMaxOutboundTimeframe = connOptions.nMaxOutboundTimeframe;
+
SetBestHeight(connOptions.nBestHeight);
clientInterface = connOptions.uiInterface;
@@ -2108,7 +2110,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
if (pnodeLocalHost == NULL) {
CNetAddr local;
LookupHost("127.0.0.1", local, false);
- pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
+ pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0);
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
}
@@ -2498,10 +2500,10 @@ void CNode::Fuzz(int nChance)
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
-CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
+CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addr(addrIn),
- nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
+ nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001),
filterInventoryKnown(50000, 0.000001)
{
@@ -2694,12 +2696,14 @@ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
}
-/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad)
+CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id)
{
- static const uint64_t k0 = GetRand(std::numeric_limits<uint64_t>::max());
- static const uint64_t k1 = GetRand(std::numeric_limits<uint64_t>::max());
+ return CSipHasher(nSeed0, nSeed1).Write(id);
+}
+uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad)
+{
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
- return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
+ return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
}
diff --git a/src/net.h b/src/net.h
index a48ee02c44..d0b2773623 100644
--- a/src/net.h
+++ b/src/net.h
@@ -11,6 +11,7 @@
#include "amount.h"
#include "bloom.h"
#include "compat.h"
+#include "hash.h"
#include "limitedmap.h"
#include "netaddress.h"
#include "protocol.h"
@@ -72,6 +73,8 @@ static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The default for -maxuploadtarget. 0 = Unlimited */
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
+/** The default timeframe for -maxuploadtarget. 1 day. */
+static const uint64_t MAX_UPLOAD_TIMEFRAME = 60 * 60 * 24;
/** Default for blocks only*/
static const bool DEFAULT_BLOCKSONLY = false;
@@ -120,8 +123,10 @@ public:
CClientUIInterface* uiInterface = nullptr;
unsigned int nSendBufferMaxSize = 0;
unsigned int nReceiveFloodSize = 0;
+ uint64_t nMaxOutboundTimeframe = 0;
+ uint64_t nMaxOutboundLimit = 0;
};
- CConnman();
+ CConnman(uint64_t seed0, uint64_t seed1);
~CConnman();
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options options);
void Stop();
@@ -294,6 +299,8 @@ public:
void SetBestHeight(int height);
int GetBestHeight() const;
+ /** Get a unique deterministic randomizer. */
+ CSipHasher GetDeterministicRandomizer(uint64_t id);
private:
struct ListenSocket {
@@ -311,6 +318,8 @@ private:
void ThreadSocketHandler();
void ThreadDNSAddressSeed();
+ uint64_t CalculateKeyedNetGroup(const CAddress& ad);
+
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CSubNet& subNet);
CNode* FindNode(const std::string& addrName);
@@ -388,6 +397,9 @@ private:
int nMaxFeeler;
std::atomic<int> nBestHeight;
CClientUIInterface* clientInterface;
+
+ /** SipHasher seeds for deterministic randomness */
+ const uint64_t nSeed0, nSeed1;
};
extern std::unique_ptr<CConnman> g_connman;
void Discover(boost::thread_group& threadGroup);
@@ -656,16 +668,16 @@ public:
CAmount lastSentFeeFilter;
int64_t nextSendTimeFeeFilter;
- CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
+ CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false);
~CNode();
private:
CNode(const CNode&);
void operator=(const CNode&);
- static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
uint64_t nLocalHostNonce;
+ // Services offered to this peer
ServiceFlags nLocalServices;
int nMyStartingHeight;
public:
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index 2fdc59ea07..4afbe99fd3 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -131,6 +131,11 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
return nTxSize;
}
+unsigned int CTransaction::GetTotalSize() const
+{
+ return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
+}
+
std::string CTransaction::ToString() const
{
std::string str;
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 5689d15bf7..16c2e5c454 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -415,6 +415,13 @@ public:
// Compute modified tx size for priority calculation (optionally given tx size)
unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
+
+ /**
+ * Get the total transaction size in bytes, including witness data.
+ * "Total Size" defined in BIP141 and BIP144.
+ * @return Total transaction size in bytes
+ */
+ unsigned int GetTotalSize() const;
bool IsCoinBase() const
{
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 135f15ffa8..58cf4dede0 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -21,12 +21,12 @@
#include <QMessageBox>
#include <QSortFilterProxyModel>
-AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) :
+AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
model(0),
- mode(mode),
- tab(tab)
+ mode(_mode),
+ tab(_tab)
{
ui->setupUi(this);
@@ -107,14 +107,14 @@ AddressBookPage::~AddressBookPage()
delete ui;
}
-void AddressBookPage::setModel(AddressTableModel *model)
+void AddressBookPage::setModel(AddressTableModel *_model)
{
- this->model = model;
- if(!model)
+ this->model = _model;
+ if(!_model)
return;
proxyModel = new QSortFilterProxyModel(this);
- proxyModel->setSourceModel(model);
+ proxyModel->setSourceModel(_model);
proxyModel->setDynamicSortFilter(true);
proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
@@ -147,7 +147,7 @@ void AddressBookPage::setModel(AddressTableModel *model)
this, SLOT(selectionChanged()));
// Select row for newly created address
- connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int)));
+ connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int)));
selectionChanged();
}
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index 71ed3618e4..830c9cdf19 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -31,8 +31,8 @@ struct AddressTableEntry
QString address;
AddressTableEntry() {}
- AddressTableEntry(Type type, const QString &label, const QString &address):
- type(type), label(label), address(address) {}
+ AddressTableEntry(Type _type, const QString &_label, const QString &_address):
+ type(_type), label(_label), address(_address) {}
};
struct AddressTableEntryLessThan
@@ -73,8 +73,8 @@ public:
QList<AddressTableEntry> cachedAddressTable;
AddressTableModel *parent;
- AddressTablePriv(CWallet *wallet, AddressTableModel *parent):
- wallet(wallet), parent(parent) {}
+ AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent):
+ wallet(_wallet), parent(_parent) {}
void refreshAddressTable()
{
@@ -164,8 +164,8 @@ public:
}
};
-AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) :
- QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0)
+AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent) :
+ QAbstractTableModel(parent),walletModel(parent),wallet(_wallet),priv(0)
{
columns << tr("Label") << tr("Address");
priv = new AddressTablePriv(wallet, this);
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index e8aa79679c..129ea1efa4 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -18,10 +18,10 @@
#include <QMessageBox>
#include <QPushButton>
-AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
+AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) :
QDialog(parent),
ui(new Ui::AskPassphraseDialog),
- mode(mode),
+ mode(_mode),
model(0),
fCapsLock(false)
{
@@ -81,9 +81,9 @@ AskPassphraseDialog::~AskPassphraseDialog()
delete ui;
}
-void AskPassphraseDialog::setModel(WalletModel *model)
+void AskPassphraseDialog::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
}
void AskPassphraseDialog::accept()
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 272df3fdae..dd022ee762 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -12,6 +12,7 @@
#include "clientmodel.h"
#include "guiconstants.h"
#include "guiutil.h"
+#include "modaloverlay.h"
#include "networkstyle.h"
#include "notificator.h"
#include "openuridialog.h"
@@ -75,8 +76,9 @@ const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
-BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
+BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
QMainWindow(parent),
+ enableWallet(false),
clientModel(0),
walletFrame(0),
unitDisplayControl(0),
@@ -114,18 +116,16 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n
notificator(0),
rpcConsole(0),
helpMessageDialog(0),
+ modalOverlay(0),
prevBlocks(0),
spinnerFrame(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
QString windowTitle = tr(PACKAGE_NAME) + " - ";
#ifdef ENABLE_WALLET
- /* if compiled with wallet support, -disablewallet can still disable the wallet */
- enableWallet = !GetBoolArg("-disablewallet", false);
-#else
- enableWallet = false;
+ enableWallet = WalletModel::isWalletEnabled();
#endif // ENABLE_WALLET
if(enableWallet)
{
@@ -148,13 +148,13 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n
setUnifiedTitleAndToolBarOnMac(true);
#endif
- rpcConsole = new RPCConsole(platformStyle, 0);
+ rpcConsole = new RPCConsole(_platformStyle, 0);
helpMessageDialog = new HelpMessageDialog(this, false);
#ifdef ENABLE_WALLET
if(enableWallet)
{
/** Create wallet frame and make it the central widget */
- walletFrame = new WalletFrame(platformStyle, this);
+ walletFrame = new WalletFrame(_platformStyle, this);
setCentralWidget(walletFrame);
} else
#endif // ENABLE_WALLET
@@ -241,6 +241,12 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n
// Subscribe to notifications from core
subscribeToCoreSignals();
+
+ modalOverlay = new ModalOverlay(this->centralWidget());
+#ifdef ENABLE_WALLET
+ if(enableWallet)
+ connect(walletFrame, SIGNAL(requestedSyncWarningInfo()), this, SLOT(showModalOverlay()));
+#endif
}
BitcoinGUI::~BitcoinGUI()
@@ -451,38 +457,38 @@ void BitcoinGUI::createToolBars()
}
}
-void BitcoinGUI::setClientModel(ClientModel *clientModel)
+void BitcoinGUI::setClientModel(ClientModel *_clientModel)
{
- this->clientModel = clientModel;
- if(clientModel)
+ this->clientModel = _clientModel;
+ if(_clientModel)
{
// Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
// while the client has not yet fully loaded
createTrayIconMenu();
// Keep up to date with client
- setNumConnections(clientModel->getNumConnections());
- connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+ setNumConnections(_clientModel->getNumConnections());
+ connect(_clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL), false);
- connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
+ setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false);
+ connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
// Receive and report messages from client model
- connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
+ connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
// Show progress dialog
- connect(clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
+ connect(_clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
- rpcConsole->setClientModel(clientModel);
+ rpcConsole->setClientModel(_clientModel);
#ifdef ENABLE_WALLET
if(walletFrame)
{
- walletFrame->setClientModel(clientModel);
+ walletFrame->setClientModel(_clientModel);
}
#endif // ENABLE_WALLET
- unitDisplayControl->setOptionsModel(clientModel->getOptionsModel());
+ unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
- OptionsModel* optionsModel = clientModel->getOptionsModel();
+ OptionsModel* optionsModel = _clientModel->getOptionsModel();
if(optionsModel)
{
// be aware of the tray icon disable state change reported by the OptionsModel object.
@@ -491,6 +497,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// initialize the disable state of the tray icon with the current value in the model.
setTrayIconVisible(optionsModel->getHideTrayIcon());
}
+
+ modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime()));
} else {
// Disable possibility to show main window via action
toggleHideAction->setEnabled(false);
@@ -705,7 +713,17 @@ void BitcoinGUI::setNumConnections(int count)
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
{
- if(!clientModel)
+ if (modalOverlay)
+ {
+ if (header) {
+ /* use clientmodels getHeaderTipHeight and getHeaderTipTime because the NotifyHeaderTip signal does not fire when updating the best header */
+ modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime()));
+ }
+ else {
+ modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
+ }
+ }
+ if (!clientModel)
return;
// Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text)
@@ -754,7 +772,10 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
#ifdef ENABLE_WALLET
if(walletFrame)
+ {
walletFrame->showOutOfSyncWarning(false);
+ modalOverlay->showHide(true, true);
+ }
#endif // ENABLE_WALLET
progressBarLabel->setVisible(false);
@@ -762,30 +783,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
}
else
{
- // Represent time from last generated block in human readable text
- QString timeBehindText;
- const int HOUR_IN_SECONDS = 60*60;
- const int DAY_IN_SECONDS = 24*60*60;
- const int WEEK_IN_SECONDS = 7*24*60*60;
- const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
- if(secs < 2*DAY_IN_SECONDS)
- {
- timeBehindText = tr("%n hour(s)","",secs/HOUR_IN_SECONDS);
- }
- else if(secs < 2*WEEK_IN_SECONDS)
- {
- timeBehindText = tr("%n day(s)","",secs/DAY_IN_SECONDS);
- }
- else if(secs < YEAR_IN_SECONDS)
- {
- timeBehindText = tr("%n week(s)","",secs/WEEK_IN_SECONDS);
- }
- else
- {
- qint64 years = secs / YEAR_IN_SECONDS;
- qint64 remainder = secs % YEAR_IN_SECONDS;
- timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
- }
+ QString timeBehindText = GUIUtil::formateNiceTimeOffset(secs);
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
@@ -805,7 +803,10 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
#ifdef ENABLE_WALLET
if(walletFrame)
+ {
walletFrame->showOutOfSyncWarning(true);
+ modalOverlay->showHide();
+ }
#endif // ENABLE_WALLET
tooltip += QString("<br>");
@@ -1101,6 +1102,12 @@ void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
}
}
+void BitcoinGUI::showModalOverlay()
+{
+ if (modalOverlay)
+ modalOverlay->showHide(false, true);
+}
+
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
{
bool modal = (style & CClientUIInterface::MODAL);
@@ -1170,17 +1177,17 @@ void UnitDisplayStatusBarControl::createContextMenu()
}
/** Lets the control know about the Options Model (and its signals) */
-void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel)
+void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
{
- if (optionsModel)
+ if (_optionsModel)
{
- this->optionsModel = optionsModel;
+ this->optionsModel = _optionsModel;
// be aware of a display unit change reported by the OptionsModel object.
- connect(optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
+ connect(_optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
// initialize the display units label with the current value in the model.
- updateDisplayUnit(optionsModel->getDisplayUnit());
+ updateDisplayUnit(_optionsModel->getDisplayUnit());
}
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 41770929b4..0eaa44b263 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -29,6 +29,7 @@ class UnitDisplayStatusBarControl;
class WalletFrame;
class WalletModel;
class HelpMessageDialog;
+class ModalOverlay;
class CWallet;
@@ -118,6 +119,7 @@ private:
Notificator *notificator;
RPCConsole *rpcConsole;
HelpMessageDialog *helpMessageDialog;
+ ModalOverlay *modalOverlay;
/** Keep track of previous number of blocks, to detect progress */
int prevBlocks;
@@ -229,6 +231,8 @@ private Q_SLOTS:
/** When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly. */
void setTrayIconVisible(bool);
+
+ void showModalOverlay();
};
class UnitDisplayStatusBarControl : public QLabel
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 83c78850e2..6d19b3d122 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -27,9 +27,9 @@ static const int64_t nClientStartupTime = GetTime();
static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;
-ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
+ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
QObject(parent),
- optionsModel(optionsModel),
+ optionsModel(_optionsModel),
peerTableModel(0),
banTableModel(0),
pollTimer(0)
@@ -70,6 +70,22 @@ int ClientModel::getNumBlocks() const
return chainActive.Height();
}
+int ClientModel::getHeaderTipHeight() const
+{
+ LOCK(cs_main);
+ if (!pindexBestHeader)
+ return 0;
+ return pindexBestHeader->nHeight;
+}
+
+int64_t ClientModel::getHeaderTipTime() const
+{
+ LOCK(cs_main);
+ if (!pindexBestHeader)
+ return 0;
+ return pindexBestHeader->GetBlockTime();
+}
+
quint64 ClientModel::getTotalBytesRecv() const
{
if(!g_connman)
@@ -240,7 +256,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
// if we are in-sync, update the UI regardless of last update time
- if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
+ if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
//pass a async signal to the UI thread
QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
Q_ARG(int, pIndex->nHeight),
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 99fd574b9e..3fd8404cbb 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -51,7 +51,8 @@ public:
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const;
-
+ int getHeaderTipHeight() const;
+ int64_t getHeaderTipTime() const;
//! Return number of transactions in the mempool
long getMempoolSize() const;
//! Return the dynamic memory usage of the mempool
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index f53242100c..86fd4ebd65 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -35,11 +35,11 @@ QList<CAmount> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
bool CoinControlDialog::fSubtractFeeFromAmount = false;
-CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) :
+CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::CoinControlDialog),
model(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
ui->setupUi(this);
@@ -152,15 +152,15 @@ CoinControlDialog::~CoinControlDialog()
delete ui;
}
-void CoinControlDialog::setModel(WalletModel *model)
+void CoinControlDialog::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
- if(model && model->getOptionsModel() && model->getAddressTableModel())
+ if(_model && _model->getOptionsModel() && _model->getAddressTableModel())
{
updateView();
updateLabelLocked();
- CoinControlDialog::updateLabels(model, this);
+ CoinControlDialog::updateLabels(_model, this);
}
}
diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp
index 8a1a49bb06..f424e6cd98 100644
--- a/src/qt/csvmodelwriter.cpp
+++ b/src/qt/csvmodelwriter.cpp
@@ -8,15 +8,15 @@
#include <QFile>
#include <QTextStream>
-CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) :
+CSVModelWriter::CSVModelWriter(const QString &_filename, QObject *parent) :
QObject(parent),
- filename(filename), model(0)
+ filename(_filename), model(0)
{
}
-void CSVModelWriter::setModel(const QAbstractItemModel *model)
+void CSVModelWriter::setModel(const QAbstractItemModel *_model)
{
- this->model = model;
+ this->model = _model;
}
void CSVModelWriter::addColumn(const QString &title, int column, int role)
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
index 5f45031e9e..a9ffe016fd 100644
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -11,11 +11,11 @@
#include <QDataWidgetMapper>
#include <QMessageBox>
-EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) :
+EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
QDialog(parent),
ui(new Ui::EditAddressDialog),
mapper(0),
- mode(mode),
+ mode(_mode),
model(0)
{
ui->setupUi(this);
@@ -49,13 +49,13 @@ EditAddressDialog::~EditAddressDialog()
delete ui;
}
-void EditAddressDialog::setModel(AddressTableModel *model)
+void EditAddressDialog::setModel(AddressTableModel *_model)
{
- this->model = model;
- if(!model)
+ this->model = _model;
+ if(!_model)
return;
- mapper->setModel(model);
+ mapper->setModel(_model);
mapper->addMapping(ui->labelEdit, AddressTableModel::Label);
mapper->addMapping(ui->addressEdit, AddressTableModel::Address);
}
@@ -137,8 +137,8 @@ QString EditAddressDialog::getAddress() const
return address;
}
-void EditAddressDialog::setAddress(const QString &address)
+void EditAddressDialog::setAddress(const QString &_address)
{
- this->address = address;
- ui->addressEdit->setText(address);
+ this->address = _address;
+ ui->addressEdit->setText(_address);
}
diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui
new file mode 100644
index 0000000000..ccec1b3e1e
--- /dev/null
+++ b/src/qt/forms/modaloverlay.ui
@@ -0,0 +1,373 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ModalOverlay</class>
+ <widget class="ModalOverlay" name="ModalOverlay">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="bgWidget" native="true">
+ <property name="styleSheet">
+ <string notr="true">#bgWidget { background: rgba(0,0,0,220); }</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayoutMain" stretch="1">
+ <property name="leftMargin">
+ <number>60</number>
+ </property>
+ <property name="topMargin">
+ <number>60</number>
+ </property>
+ <property name="rightMargin">
+ <number>60</number>
+ </property>
+ <property name="bottomMargin">
+ <number>60</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="contentWidget" native="true">
+ <property name="styleSheet">
+ <string notr="true">#contentWidget { background: rgba(255,255,255,240); border-radius: 6px; }
+
+QLabel { color: rgb(40,40,40); }</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayoutSub" stretch="1,0,0,0">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutIconText" stretch="0,1">
+ <property name="topMargin">
+ <number>20</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutIcon">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="warningIcon">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/warning</normaloff>
+ <disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacerWarningIcon">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutInfoText">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="infoText">
+ <property name="text">
+ <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. This means that recent transactions will not be visible, and the balance will not be up-to-date until this process has completed.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="infoTextStrong">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Spending bitcoins may not be possible during that phase!</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacerInTextSpace">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacerAfterText">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::FieldsStayAtSizeHint</enum>
+ </property>
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelAmoutOfBlocksLeft">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Amount of blocks left</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="amountOfBlocksLeft">
+ <property name="text">
+ <string>unknown...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelLastBlockTime">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Last block time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="newestBlockDate">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>unknown...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelSyncDone">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Progress</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayoutSync" stretch="0,1">
+ <item>
+ <widget class="QLabel" name="percentageProgress">
+ <property name="text">
+ <string>~</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>24</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelProgressIncrease">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Progress increase per Hour</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="progressIncreasePerH">
+ <property name="text">
+ <string>calculating...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelEstimatedTimeLeft">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Estimated time left until synced</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="expectedTimeLeft">
+ <property name="text">
+ <string>calculating...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutButtons">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton">
+ <property name="text">
+ <string>Hide</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ModalOverlay</class>
+ <extends>QWidget</extends>
+ <header>modaloverlay.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index 6d792d1475..923ed68996 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -61,7 +61,7 @@
<item>
<widget class="QPushButton" name="labelWalletStatus">
<property name="enabled">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="maximumSize">
<size>
@@ -447,7 +447,7 @@
<item>
<widget class="QPushButton" name="labelTransactionsStatus">
<property name="enabled">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="maximumSize">
<size>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 444e35de8a..0beaddf997 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -462,9 +462,9 @@ void SubstituteFonts(const QString& language)
#endif
}
-ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
+ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold, QObject *parent) :
QObject(parent),
- size_threshold(size_threshold)
+ size_threshold(_size_threshold)
{
}
@@ -955,4 +955,40 @@ QString formatTimeOffset(int64_t nTimeOffset)
return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10));
}
+QString formateNiceTimeOffset(qint64 secs)
+{
+ // Represent time from last generated block in human readable text
+ QString timeBehindText;
+ const int HOUR_IN_SECONDS = 60*60;
+ const int DAY_IN_SECONDS = 24*60*60;
+ const int WEEK_IN_SECONDS = 7*24*60*60;
+ const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
+ if(secs < 60)
+ {
+ timeBehindText = QObject::tr("%n seconds(s)","",secs);
+ }
+ else if(secs < 2*HOUR_IN_SECONDS)
+ {
+ timeBehindText = QObject::tr("%n minutes(s)","",secs/60);
+ }
+ else if(secs < 2*DAY_IN_SECONDS)
+ {
+ timeBehindText = QObject::tr("%n hour(s)","",secs/HOUR_IN_SECONDS);
+ }
+ else if(secs < 2*WEEK_IN_SECONDS)
+ {
+ timeBehindText = QObject::tr("%n day(s)","",secs/DAY_IN_SECONDS);
+ }
+ else if(secs < YEAR_IN_SECONDS)
+ {
+ timeBehindText = QObject::tr("%n week(s)","",secs/WEEK_IN_SECONDS);
+ }
+ else
+ {
+ qint64 years = secs / YEAR_IN_SECONDS;
+ qint64 remainder = secs % YEAR_IN_SECONDS;
+ timeBehindText = QObject::tr("%1 and %2").arg(QObject::tr("%n year(s)", "", years)).arg(QObject::tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
+ }
+ return timeBehindText;
+}
} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index d5a658e7c0..e28f68930f 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -200,6 +200,8 @@ namespace GUIUtil
/* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
QString formatTimeOffset(int64_t nTimeOffset);
+ QString formateNiceTimeOffset(qint64 secs);
+
#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
// workaround for Qt OSX Bug:
// https://bugreports.qt-project.org/browse/QTBUG-15631
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 1a241ae0f0..5a336b105e 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -63,9 +63,9 @@ private:
#include "intro.moc"
-FreespaceChecker::FreespaceChecker(Intro *intro)
+FreespaceChecker::FreespaceChecker(Intro *_intro)
{
- this->intro = intro;
+ this->intro = _intro;
}
void FreespaceChecker::check()
diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp
new file mode 100644
index 0000000000..7951bd784e
--- /dev/null
+++ b/src/qt/modaloverlay.cpp
@@ -0,0 +1,158 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "modaloverlay.h"
+#include "ui_modaloverlay.h"
+
+#include "guiutil.h"
+
+#include <QResizeEvent>
+#include <QPropertyAnimation>
+
+ModalOverlay::ModalOverlay(QWidget *parent) :
+QWidget(parent),
+ui(new Ui::ModalOverlay),
+bestBlockHeight(0),
+layerIsVisible(false),
+userClosed(false)
+{
+ ui->setupUi(this);
+ connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(closeClicked()));
+ if (parent) {
+ parent->installEventFilter(this);
+ raise();
+ }
+
+ blockProcessTime.clear();
+ setVisible(false);
+}
+
+ModalOverlay::~ModalOverlay()
+{
+ delete ui;
+}
+
+bool ModalOverlay::eventFilter(QObject * obj, QEvent * ev) {
+ if (obj == parent()) {
+ if (ev->type() == QEvent::Resize) {
+ QResizeEvent * rev = static_cast<QResizeEvent*>(ev);
+ resize(rev->size());
+ if (!layerIsVisible)
+ setGeometry(0, height(), width(), height());
+
+ }
+ else if (ev->type() == QEvent::ChildAdded) {
+ raise();
+ }
+ }
+ return QWidget::eventFilter(obj, ev);
+}
+
+//! Tracks parent widget changes
+bool ModalOverlay::event(QEvent* ev) {
+ if (ev->type() == QEvent::ParentAboutToChange) {
+ if (parent()) parent()->removeEventFilter(this);
+ }
+ else if (ev->type() == QEvent::ParentChange) {
+ if (parent()) {
+ parent()->installEventFilter(this);
+ raise();
+ }
+ }
+ return QWidget::event(ev);
+}
+
+void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate)
+{
+
+ /* only update the blockheight if the headerschain-tip is not older then 30 days */
+ int64_t now = QDateTime::currentDateTime().toTime_t();
+ int64_t btime = blockDate.toTime_t();
+ if (btime+3600*24*30 > now)
+ {
+ if (count > bestBlockHeight)
+ bestBlockHeight = count;
+ }
+}
+
+void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress)
+{
+ QDateTime currentDate = QDateTime::currentDateTime();
+
+ // keep a vector of samples of verification progress at height
+ blockProcessTime.push_front(qMakePair(currentDate.currentMSecsSinceEpoch(), nVerificationProgress));
+
+ // show progress speed if we have more then one sample
+ if (blockProcessTime.size() >= 2)
+ {
+ double progressStart = blockProcessTime[0].second;
+ double progressDelta = 0;
+ double progressPerHour = 0;
+ qint64 timeDelta = 0;
+ qint64 remainingMSecs = 0;
+ double remainingProgress = 1.0 - nVerificationProgress;
+ for (int i = 1; i < blockProcessTime.size(); i++)
+ {
+ QPair<qint64, double> sample = blockProcessTime[i];
+
+ // take first sample after 500 seconds or last available one
+ if (sample.first < (currentDate.currentMSecsSinceEpoch() - 500*1000) || i == blockProcessTime.size()-1)
+ {
+ progressDelta = progressStart-sample.second;
+ timeDelta = blockProcessTime[0].first - sample.first;
+ progressPerHour = progressDelta/(double)timeDelta*1000*3600;
+ remainingMSecs = remainingProgress / progressDelta * timeDelta;
+ break;
+ }
+ }
+ // show progress increase per hour
+ ui->progressIncreasePerH->setText(QString::number(progressPerHour*100, 'f', 2)+"%");
+
+ // show expected remaining time
+ ui->expectedTimeLeft->setText(GUIUtil::formateNiceTimeOffset(remainingMSecs/1000.0));
+
+ // keep maximal 5000 samples
+ static const int MAX_SAMPLES = 5000;
+ if (blockProcessTime.count() > MAX_SAMPLES)
+ blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count()-MAX_SAMPLES);
+ }
+
+ // show the last block date
+ ui->newestBlockDate->setText(blockDate.toString());
+
+ // show the percentage done according to nVerificationProgress
+ ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%");
+ ui->progressBar->setValue(nVerificationProgress*100);
+
+ // show remaining amount of blocks
+ if (bestBlockHeight > 0)
+ ui->amountOfBlocksLeft->setText(QString::number(bestBlockHeight-count));
+ else
+ ui->expectedTimeLeft->setText(tr("Unknown. Syncing Headers..."));
+}
+
+void ModalOverlay::showHide(bool hide, bool userRequested)
+{
+ if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested))
+ return;
+
+ if (!isVisible() && !hide)
+ setVisible(true);
+
+ setGeometry(0, hide ? 0 : height(), width(), height());
+
+ QPropertyAnimation* animation = new QPropertyAnimation(this, "pos");
+ animation->setDuration(300);
+ animation->setStartValue(QPoint(0, hide ? 0 : this->height()));
+ animation->setEndValue(QPoint(0, hide ? this->height() : 0));
+ animation->setEasingCurve(QEasingCurve::OutQuad);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ layerIsVisible = !hide;
+}
+
+void ModalOverlay::closeClicked()
+{
+ showHide(true);
+ userClosed = true;
+}
diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h
new file mode 100644
index 0000000000..670c9e58ab
--- /dev/null
+++ b/src/qt/modaloverlay.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_MODALOVERLAY_H
+#define BITCOIN_QT_MODALOVERLAY_H
+
+#include <QDateTime>
+#include <QWidget>
+
+namespace Ui {
+ class ModalOverlay;
+}
+
+/** Modal overlay to display information about the chain-sync state */
+class ModalOverlay : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ModalOverlay(QWidget *parent);
+ ~ModalOverlay();
+
+public Q_SLOTS:
+ void tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress);
+ void setKnownBestHeight(int count, const QDateTime& blockDate);
+
+ // will show or hide the modal layer
+ void showHide(bool hide = false, bool userRequested = false);
+ void closeClicked();
+
+protected:
+ bool eventFilter(QObject * obj, QEvent * ev);
+ bool event(QEvent* ev);
+
+private:
+ Ui::ModalOverlay *ui;
+ int bestBlockHeight; //best known height (based on the headers)
+ QVector<QPair<qint64, double> > blockProcessTime;
+ bool layerIsVisible;
+ bool userClosed;
+};
+
+#endif // BITCOIN_QT_MODALOVERLAY_H
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
index 5f31f49372..acbfee0868 100644
--- a/src/qt/networkstyle.cpp
+++ b/src/qt/networkstyle.cpp
@@ -22,9 +22,9 @@ static const struct {
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
// titleAddText needs to be const char* for tr()
-NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText):
- appName(appName),
- titleAddText(qApp->translate("SplashScreen", titleAddText))
+NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText):
+ appName(_appName),
+ titleAddText(qApp->translate("SplashScreen", _titleAddText))
{
// load pixmap
QPixmap pixmap(":/icons/bitcoin");
diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp
index a45afde566..8277e20c90 100644
--- a/src/qt/notificator.cpp
+++ b/src/qt/notificator.cpp
@@ -33,17 +33,17 @@
const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128;
#endif
-Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent) :
- QObject(parent),
- parent(parent),
- programName(programName),
+Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon, QWidget *_parent) :
+ QObject(_parent),
+ parent(_parent),
+ programName(_programName),
mode(None),
- trayIcon(trayicon)
+ trayIcon(_trayIcon)
#ifdef USE_DBUS
,interface(0)
#endif
{
- if(trayicon && trayicon->supportsMessages())
+ if(_trayIcon && _trayIcon->supportsMessages())
{
mode = QSystemTray;
}
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index f73bb87064..588059d0c5 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -135,22 +135,22 @@ OptionsDialog::~OptionsDialog()
delete ui;
}
-void OptionsDialog::setModel(OptionsModel *model)
+void OptionsDialog::setModel(OptionsModel *_model)
{
- this->model = model;
+ this->model = _model;
- if(model)
+ if(_model)
{
/* check if client restart is needed and show persistent message */
- if (model->isRestartRequired())
+ if (_model->isRestartRequired())
showRestartWarning(true);
- QString strLabel = model->getOverriddenByCommandLine();
+ QString strLabel = _model->getOverriddenByCommandLine();
if (strLabel.isEmpty())
strLabel = tr("none");
ui->overriddenByCommandLineLabel->setText(strLabel);
- mapper->setModel(model);
+ mapper->setModel(_model);
setMapper();
mapper->toFirst();
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 6a0404cbf7..7ccdb89c0c 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -25,9 +25,9 @@ class TxViewDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- TxViewDelegate(const PlatformStyle *platformStyle):
+ TxViewDelegate(const PlatformStyle *_platformStyle):
QAbstractItemDelegate(), unit(BitcoinUnits::BTC),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
}
@@ -140,6 +140,8 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
// start with displaying the "out of sync" warnings
showOutOfSyncWarning(true);
+ connect(ui->labelWalletStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks()));
+ connect(ui->labelTransactionsStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks()));
}
void OverviewPage::handleTransactionClicked(const QModelIndex &index)
@@ -148,6 +150,11 @@ void OverviewPage::handleTransactionClicked(const QModelIndex &index)
Q_EMIT transactionClicked(filter->mapToSource(index));
}
+void OverviewPage::handleOutOfSyncWarningClicks()
+{
+ Q_EMIT outOfSyncWarningClicked();
+}
+
OverviewPage::~OverviewPage()
{
delete ui;
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index 911443c76a..65cd3341b6 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -42,6 +42,7 @@ public Q_SLOTS:
Q_SIGNALS:
void transactionClicked(const QModelIndex &index);
+ void outOfSyncWarningClicked();
private:
Ui::OverviewPage *ui;
@@ -62,6 +63,7 @@ private Q_SLOTS:
void handleTransactionClicked(const QModelIndex &index);
void updateAlerts(const QString &warnings);
void updateWatchOnlyLabels(bool showWatchOnly);
+ void handleOutOfSyncWarningClicks();
};
#endif // BITCOIN_QT_OVERVIEWPAGE_H
diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto
index b2281c4c7b..d2721a34bd 100644
--- a/src/qt/paymentrequest.proto
+++ b/src/qt/paymentrequest.proto
@@ -6,6 +6,8 @@
// https://en.bitcoin.it/wiki/Payment_Request
//
+syntax = "proto2";
+
package payments;
option java_package = "org.bitcoin.protocols.payments";
option java_outer_classname = "Protos";
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index c80aebb009..9f23e77a13 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -749,9 +749,9 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError>
Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
}
-void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
+void PaymentServer::setOptionsModel(OptionsModel *_optionsModel)
{
- this->optionsModel = optionsModel;
+ this->optionsModel = _optionsModel;
}
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp
index 11cbc7a47c..e4438cc43d 100644
--- a/src/qt/platformstyle.cpp
+++ b/src/qt/platformstyle.cpp
@@ -73,11 +73,11 @@ QIcon ColorizeIcon(const QString& filename, const QColor& colorbase)
}
-PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing):
- name(name),
- imagesOnButtons(imagesOnButtons),
- colorizeIcons(colorizeIcons),
- useExtraSpacing(useExtraSpacing),
+PlatformStyle::PlatformStyle(const QString &_name, bool _imagesOnButtons, bool _colorizeIcons, bool _useExtraSpacing):
+ name(_name),
+ imagesOnButtons(_imagesOnButtons),
+ colorizeIcons(_colorizeIcons),
+ useExtraSpacing(_useExtraSpacing),
singleColor(0,0,0),
textColor(0,0,0)
{
diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp
index baa2eb67f7..492b96ff09 100644
--- a/src/qt/qvalidatedlineedit.cpp
+++ b/src/qt/qvalidatedlineedit.cpp
@@ -15,14 +15,14 @@ QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
}
-void QValidatedLineEdit::setValid(bool valid)
+void QValidatedLineEdit::setValid(bool _valid)
{
- if(valid == this->valid)
+ if(_valid == this->valid)
{
return;
}
- if(valid)
+ if(_valid)
{
setStyleSheet("");
}
@@ -30,7 +30,7 @@ void QValidatedLineEdit::setValid(bool valid)
{
setStyleSheet(STYLE_INVALID);
}
- this->valid = valid;
+ this->valid = _valid;
}
void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp
index 146f3dd578..2f2478783c 100644
--- a/src/qt/qvaluecombobox.cpp
+++ b/src/qt/qvaluecombobox.cpp
@@ -20,9 +20,9 @@ void QValueComboBox::setValue(const QVariant &value)
setCurrentIndex(findData(value, role));
}
-void QValueComboBox::setRole(int role)
+void QValueComboBox::setRole(int _role)
{
- this->role = role;
+ this->role = _role;
}
void QValueComboBox::handleSelectionChanged(int idx)
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 0b355837ab..5c6dc97b20 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -22,24 +22,24 @@
#include <QScrollBar>
#include <QTextDocument>
-ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
+ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::ReceiveCoinsDialog),
model(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
ui->setupUi(this);
- if (!platformStyle->getImagesOnButtons()) {
+ if (!_platformStyle->getImagesOnButtons()) {
ui->clearButton->setIcon(QIcon());
ui->receiveButton->setIcon(QIcon());
ui->showRequestButton->setIcon(QIcon());
ui->removeRequestButton->setIcon(QIcon());
} else {
- ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
- ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
- ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
- ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->receiveButton->setIcon(_platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
+ ui->showRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/edit"));
+ ui->removeRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
}
// context menu actions
@@ -62,21 +62,21 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
}
-void ReceiveCoinsDialog::setModel(WalletModel *model)
+void ReceiveCoinsDialog::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
- if(model && model->getOptionsModel())
+ if(_model && _model->getOptionsModel())
{
- model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
- connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+ _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
+ connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
updateDisplayUnit();
QTableView* tableView = ui->recentRequestsView;
tableView->verticalHeader()->hide();
tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- tableView->setModel(model->getRecentRequestsTableModel());
+ tableView->setModel(_model->getRecentRequestsTableModel());
tableView->setAlternatingRowColors(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index b13ea3df70..998c9176d7 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -109,20 +109,20 @@ ReceiveRequestDialog::~ReceiveRequestDialog()
delete ui;
}
-void ReceiveRequestDialog::setModel(OptionsModel *model)
+void ReceiveRequestDialog::setModel(OptionsModel *_model)
{
- this->model = model;
+ this->model = _model;
- if (model)
- connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
+ if (_model)
+ connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
// update the display unit if necessary
update();
}
-void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &info)
+void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info)
{
- this->info = info;
+ this->info = _info;
update();
}
diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh
index a4c2fddbbf..d0deb1238c 100755
--- a/src/qt/res/movies/makespinner.sh
+++ b/src/qt/res/movies/makespinner.sh
@@ -1,3 +1,7 @@
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
FRAMEDIR=$(dirname $0)
for i in {0..35}
do
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index f35f401d06..ace9f1ceaa 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -83,8 +83,8 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase
{
Q_OBJECT
public:
- QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis):
- func(func)
+ QtRPCTimerBase(boost::function<void(void)>& _func, int64_t millis):
+ func(_func)
{
timer.setSingleShot(true);
connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
@@ -113,9 +113,11 @@ public:
#include "rpcconsole.moc"
/**
- * Split shell command line into a list of arguments. Aims to emulate \c bash and friends.
+ * Split shell command line into a list of arguments and execute the command(s).
+ * Aims to emulate \c bash and friends.
*
- * - Arguments are delimited with whitespace
+ * - Command nesting is possible with brackets [example: validateaddress(getnewaddress())]
+ * - Arguments are delimited with whitespace or comma
* - Extra whitespace at the beginning and end and between arguments will be ignored
* - Text can be "double" or 'single' quoted
* - The backslash \c \ is used as escape character
@@ -123,11 +125,15 @@ public:
* - Within double quotes, only escape \c " and backslashes before a \c " or another backslash
* - Within single quotes, no escaping is possible and no special interpretation takes place
*
- * @param[out] args Parsed arguments will be appended to this list
+ * @param[out] result stringified Result from the executed command(chain)
* @param[in] strCommand Command line to split
*/
-bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand)
+
+bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand)
{
+ std::vector< std::vector<std::string> > stack;
+ stack.push_back(std::vector<std::string>());
+
enum CmdParseState
{
STATE_EATING_SPACES,
@@ -135,95 +141,180 @@ bool parseCommandLine(std::vector<std::string> &args, const std::string &strComm
STATE_SINGLEQUOTED,
STATE_DOUBLEQUOTED,
STATE_ESCAPE_OUTER,
- STATE_ESCAPE_DOUBLEQUOTED
+ STATE_ESCAPE_DOUBLEQUOTED,
+ STATE_COMMAND_EXECUTED,
+ STATE_COMMAND_EXECUTED_INNER
} state = STATE_EATING_SPACES;
std::string curarg;
- Q_FOREACH(char ch, strCommand)
+ UniValue lastResult;
+
+ std::string strCommandTerminated = strCommand;
+ if (strCommandTerminated.back() != '\n')
+ strCommandTerminated += "\n";
+ for(char ch: strCommandTerminated)
{
switch(state)
{
- case STATE_ARGUMENT: // In or after argument
- case STATE_EATING_SPACES: // Handle runs of whitespace
- switch(ch)
+ case STATE_COMMAND_EXECUTED_INNER:
+ case STATE_COMMAND_EXECUTED:
{
- case '"': state = STATE_DOUBLEQUOTED; break;
- case '\'': state = STATE_SINGLEQUOTED; break;
- case '\\': state = STATE_ESCAPE_OUTER; break;
- case ' ': case '\n': case '\t':
- if(state == STATE_ARGUMENT) // Space ends argument
+ bool breakParsing = true;
+ switch(ch)
{
- args.push_back(curarg);
- curarg.clear();
+ case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER; break;
+ default:
+ if (state == STATE_COMMAND_EXECUTED_INNER)
+ {
+ if (ch != ']')
+ {
+ // append char to the current argument (which is also used for the query command)
+ curarg += ch;
+ break;
+ }
+ if (curarg.size())
+ {
+ // if we have a value query, query arrays with index and objects with a string key
+ UniValue subelement;
+ if (lastResult.isArray())
+ {
+ for(char argch: curarg)
+ if (!std::isdigit(argch))
+ throw std::runtime_error("Invalid result query");
+ subelement = lastResult[atoi(curarg.c_str())];
+ }
+ else if (lastResult.isObject())
+ subelement = find_value(lastResult, curarg);
+ else
+ throw std::runtime_error("Invalid result query"); //no array or object: abort
+ lastResult = subelement;
+ }
+
+ state = STATE_COMMAND_EXECUTED;
+ break;
+ }
+ // don't break parsing when the char is required for the next argument
+ breakParsing = false;
+
+ // pop the stack and return the result to the current command arguments
+ stack.pop_back();
+
+ // don't stringify the json in case of a string to avoid doublequotes
+ if (lastResult.isStr())
+ curarg = lastResult.get_str();
+ else
+ curarg = lastResult.write(2);
+
+ // if we have a non empty result, use it as stack argument otherwise as general result
+ if (curarg.size())
+ {
+ if (stack.size())
+ stack.back().push_back(curarg);
+ else
+ strResult = curarg;
+ }
+ curarg.clear();
+ // assume eating space state
+ state = STATE_EATING_SPACES;
}
- state = STATE_EATING_SPACES;
- break;
- default: curarg += ch; state = STATE_ARGUMENT;
+ if (breakParsing)
+ break;
}
- break;
- case STATE_SINGLEQUOTED: // Single-quoted string
- switch(ch)
+ case STATE_ARGUMENT: // In or after argument
+ case STATE_EATING_SPACES: // Handle runs of whitespace
+ switch(ch)
{
- case '\'': state = STATE_ARGUMENT; break;
- default: curarg += ch;
+ case '"': state = STATE_DOUBLEQUOTED; break;
+ case '\'': state = STATE_SINGLEQUOTED; break;
+ case '\\': state = STATE_ESCAPE_OUTER; break;
+ case '(': case ')': case '\n':
+ if (state == STATE_ARGUMENT)
+ {
+ if (ch == '(' && stack.size() && stack.back().size() > 0)
+ stack.push_back(std::vector<std::string>());
+ if (curarg.size())
+ {
+ // don't allow commands after executed commands on baselevel
+ if (!stack.size())
+ throw std::runtime_error("Invalid Syntax");
+ stack.back().push_back(curarg);
+ }
+ curarg.clear();
+ state = STATE_EATING_SPACES;
+ }
+ if ((ch == ')' || ch == '\n') && stack.size() > 0)
+ {
+ std::string strPrint;
+ // Convert argument list to JSON objects in method-dependent way,
+ // and pass it along with the method name to the dispatcher.
+ lastResult = tableRPC.execute(stack.back()[0], RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end())));
+
+ state = STATE_COMMAND_EXECUTED;
+ curarg.clear();
+ }
+ break;
+ case ' ': case ',': case '\t':
+ if(state == STATE_ARGUMENT) // Space ends argument
+ {
+ if (curarg.size())
+ stack.back().push_back(curarg);
+ curarg.clear();
+ }
+ state = STATE_EATING_SPACES;
+ break;
+ default: curarg += ch; state = STATE_ARGUMENT;
}
- break;
- case STATE_DOUBLEQUOTED: // Double-quoted string
- switch(ch)
+ break;
+ case STATE_SINGLEQUOTED: // Single-quoted string
+ switch(ch)
{
- case '"': state = STATE_ARGUMENT; break;
- case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
- default: curarg += ch;
+ case '\'': state = STATE_ARGUMENT; break;
+ default: curarg += ch;
}
- break;
- case STATE_ESCAPE_OUTER: // '\' outside quotes
- curarg += ch; state = STATE_ARGUMENT;
- break;
- case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
- if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
- curarg += ch; state = STATE_DOUBLEQUOTED;
- break;
+ break;
+ case STATE_DOUBLEQUOTED: // Double-quoted string
+ switch(ch)
+ {
+ case '"': state = STATE_ARGUMENT; break;
+ case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_ESCAPE_OUTER: // '\' outside quotes
+ curarg += ch; state = STATE_ARGUMENT;
+ break;
+ case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
+ if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
+ curarg += ch; state = STATE_DOUBLEQUOTED;
+ break;
}
}
switch(state) // final state
{
- case STATE_EATING_SPACES:
- return true;
- case STATE_ARGUMENT:
- args.push_back(curarg);
- return true;
- default: // ERROR to end in one of the other states
- return false;
+ case STATE_COMMAND_EXECUTED:
+ if (lastResult.isStr())
+ strResult = lastResult.get_str();
+ else
+ strResult = lastResult.write(2);
+ case STATE_ARGUMENT:
+ case STATE_EATING_SPACES:
+ return true;
+ default: // ERROR to end in one of the other states
+ return false;
}
}
void RPCExecutor::request(const QString &command)
{
- std::vector<std::string> args;
- if(!parseCommandLine(args, command.toStdString()))
- {
- Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
- return;
- }
- if(args.empty())
- return; // Nothing to do
try
{
- std::string strPrint;
- // Convert argument list to JSON objects in method-dependent way,
- // and pass it along with the method name to the dispatcher.
- UniValue result = tableRPC.execute(
- args[0],
- RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
-
- // Format result reply
- if (result.isNull())
- strPrint = "";
- else if (result.isStr())
- strPrint = result.get_str();
- else
- strPrint = result.write(2);
-
- Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
+ std::string result;
+ std::string executableCommand = command.toStdString() + "\n";
+ if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand))
+ {
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
+ return;
+ }
+ Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result));
}
catch (UniValue& objError)
{
@@ -244,13 +335,13 @@ void RPCExecutor::request(const QString &command)
}
}
-RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
+RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) :
QWidget(parent),
ui(new Ui::RPCConsole),
clientModel(0),
historyPtr(0),
cachedNodeid(-1),
- platformStyle(platformStyle),
+ platformStyle(_platformStyle),
peersTableContextMenu(0),
banTableContextMenu(0),
consoleFontSize(0)
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 28affa954d..50224a1cc0 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -35,6 +35,8 @@ public:
explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
+ static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand);
+
void setClientModel(ClientModel *model);
enum MessageClass {
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 8433818a64..4b2ba7d624 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -30,25 +30,25 @@
#define SEND_CONFIRM_DELAY 3
-SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
+SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SendCoinsDialog),
clientModel(0),
model(0),
fNewRecipientAllowed(true),
fFeeMinimized(true),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
ui->setupUi(this);
- if (!platformStyle->getImagesOnButtons()) {
+ if (!_platformStyle->getImagesOnButtons()) {
ui->addButton->setIcon(QIcon());
ui->clearButton->setIcon(QIcon());
ui->sendButton->setIcon(QIcon());
} else {
- ui->addButton->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
- ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
- ui->sendButton->setIcon(platformStyle->SingleColorIcon(":/icons/send"));
+ ui->addButton->setIcon(_platformStyle->SingleColorIcon(":/icons/add"));
+ ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->sendButton->setIcon(_platformStyle->SingleColorIcon(":/icons/send"));
}
GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
@@ -116,40 +116,40 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa
minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
}
-void SendCoinsDialog::setClientModel(ClientModel *clientModel)
+void SendCoinsDialog::setClientModel(ClientModel *_clientModel)
{
- this->clientModel = clientModel;
+ this->clientModel = _clientModel;
- if (clientModel) {
- connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel()));
+ if (_clientModel) {
+ connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel()));
}
}
-void SendCoinsDialog::setModel(WalletModel *model)
+void SendCoinsDialog::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
- if(model && model->getOptionsModel())
+ if(_model && _model->getOptionsModel())
{
for(int i = 0; i < ui->entries->count(); ++i)
{
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
if(entry)
{
- entry->setModel(model);
+ entry->setModel(_model);
}
}
- setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
- model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
- connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
- connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+ setBalance(_model->getBalance(), _model->getUnconfirmedBalance(), _model->getImmatureBalance(),
+ _model->getWatchBalance(), _model->getWatchUnconfirmedBalance(), _model->getWatchImmatureBalance());
+ connect(_model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
+ connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
updateDisplayUnit();
// Coin Control
- connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
- connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
- ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures());
+ connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(_model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
+ ui->frameCoinControl->setVisible(_model->getOptionsModel()->getCoinControlFeatures());
coinControlUpdateLabels();
// fee section
@@ -826,9 +826,9 @@ void SendCoinsDialog::coinControlUpdateLabels()
}
}
-SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int secDelay,
+SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int _secDelay,
QWidget *parent) :
- QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(secDelay)
+ QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(_secDelay)
{
setDefaultButton(QMessageBox::Cancel);
yesButton = button(QMessageBox::Yes);
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index d063f2c891..7eb1eb7e3a 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -15,11 +15,11 @@
#include <QApplication>
#include <QClipboard>
-SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) :
+SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) :
QStackedWidget(parent),
ui(new Ui::SendCoinsEntry),
model(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
ui->setupUi(this);
@@ -79,12 +79,12 @@ void SendCoinsEntry::on_payTo_textChanged(const QString &address)
updateLabel(address);
}
-void SendCoinsEntry::setModel(WalletModel *model)
+void SendCoinsEntry::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
- if (model && model->getOptionsModel())
- connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+ if (_model && _model->getOptionsModel())
+ connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
clear();
}
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 8e2e8a5098..4061909b71 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -20,11 +20,11 @@
#include <QClipboard>
-SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) :
+SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SignVerifyMessageDialog),
model(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
ui->setupUi(this);
@@ -60,9 +60,9 @@ SignVerifyMessageDialog::~SignVerifyMessageDialog()
delete ui;
}
-void SignVerifyMessageDialog::setModel(WalletModel *model)
+void SignVerifyMessageDialog::setModel(WalletModel *_model)
{
- this->model = model;
+ this->model = _model;
}
void SignVerifyMessageDialog::setAddress_SM(const QString &address)
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
new file mode 100644
index 0000000000..3dae33bafb
--- /dev/null
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -0,0 +1,93 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcnestedtests.h"
+
+#include "chainparams.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "rpc/register.h"
+#include "rpc/server.h"
+#include "rpcconsole.h"
+#include "test/testutil.h"
+#include "univalue.h"
+#include "util.h"
+
+#include <QDir>
+
+#include <boost/filesystem.hpp>
+
+void RPCNestedTests::rpcNestedTests()
+{
+ UniValue jsonRPCError;
+
+ // do some test setup
+ // could be moved to a more generic place when we add more tests on QT level
+ const CChainParams& chainparams = Params();
+ RegisterAllCoreRPCCommands(tableRPC);
+ ClearDatadirCache();
+ std::string path = QDir::tempPath().toStdString() + "/" + strprintf("test_bitcoin_qt_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
+ QDir dir(QString::fromStdString(path));
+ dir.mkpath(".");
+ mapArgs["-datadir"] = path;
+ //mempool.setSanityCheck(1.0);
+ pblocktree = new CBlockTreeDB(1 << 20, true);
+ pcoinsdbview = new CCoinsViewDB(1 << 23, true);
+ pcoinsTip = new CCoinsViewCache(pcoinsdbview);
+ InitBlockIndex(chainparams);
+ {
+ CValidationState state;
+ bool ok = ActivateBestChain(state, chainparams);
+ QVERIFY(ok);
+ }
+
+ SetRPCWarmupFinished();
+
+ std::string result;
+ std::string result2;
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[chain]"); //simple result filtering with path
+ QVERIFY(result=="main");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())"); //simple 2 level nesting
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getblock(getbestblockhash())[hash], true)");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo");
+ QVERIFY(result.substr(0,1) == "{");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()");
+ QVERIFY(result.substr(0,1) == "{");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo "); //whitespace at the end will be tolerated
+ QVERIFY(result.substr(0,1) == "{");
+
+#if QT_VERSION >= 0x050300
+ // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()()()")); //tolerate non command brackts
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(True)"), UniValue); //invalid argument
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "a(getblockchaininfo(True))"), UniValue); //method not found
+#endif
+
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child contaning the quotes in the key
+ QVERIFY(result == "null");
+
+ (RPCConsole::RPCExecuteCommandLine(result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
+ (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
+ QVERIFY(result == result2);
+ (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parametres is allowed
+ QVERIFY(result == result2);
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())[tx][0]");
+ QVERIFY(result == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
+
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+
+ boost::filesystem::remove_all(boost::filesystem::path(path));
+}
diff --git a/src/qt/test/rpcnestedtests.h b/src/qt/test/rpcnestedtests.h
new file mode 100644
index 0000000000..9ad409019f
--- /dev/null
+++ b/src/qt/test/rpcnestedtests.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
+#define BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
+
+#include <QObject>
+#include <QTest>
+
+#include "txdb.h"
+#include "txmempool.h"
+
+class RPCNestedTests : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void rpcNestedTests();
+
+private:
+ CCoinsViewDB *pcoinsdbview;
+};
+
+#endif // BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index db193420bf..dbaab54fb6 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -6,6 +6,9 @@
#include "config/bitcoin-config.h"
#endif
+#include "chainparams.h"
+#include "key.h"
+#include "rpcnestedtests.h"
#include "util.h"
#include "uritests.h"
@@ -27,10 +30,17 @@ Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
#endif
+extern void noui_connect();
+
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
+ ECC_Start();
SetupEnvironment();
+ SetupNetworking();
+ SelectParams(CBaseChainParams::MAIN);
+ noui_connect();
+
bool fInvalid = false;
// Don't remove this, it's needed to access
@@ -48,6 +58,10 @@ int main(int argc, char *argv[])
if (QTest::qExec(&test2) != 0)
fInvalid = true;
#endif
+ RPCNestedTests test3;
+ if (QTest::qExec(&test3) != 0)
+ fInvalid = true;
+ ECC_Stop();
return fInvalid;
}
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index bae0cbd1c8..65144e7865 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -241,6 +241,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
+ strHTML += "<b>" + tr("Transaction total size") + ":</b> " + QString::number(wtx.GetTotalSize()) + " bytes<br>";
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp
index 9dcb72f55e..e21b89b935 100644
--- a/src/qt/transactionfilterproxy.cpp
+++ b/src/qt/transactionfilterproxy.cpp
@@ -66,9 +66,9 @@ void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime
invalidateFilter();
}
-void TransactionFilterProxy::setAddressPrefix(const QString &addrPrefix)
+void TransactionFilterProxy::setAddressPrefix(const QString &_addrPrefix)
{
- this->addrPrefix = addrPrefix;
+ this->addrPrefix = _addrPrefix;
invalidateFilter();
}
@@ -95,9 +95,9 @@ void TransactionFilterProxy::setLimit(int limit)
this->limitRows = limit;
}
-void TransactionFilterProxy::setShowInactive(bool showInactive)
+void TransactionFilterProxy::setShowInactive(bool _showInactive)
{
- this->showInactive = showInactive;
+ this->showInactive = _showInactive;
invalidateFilter();
}
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index 8c754c3aad..8eff302aff 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -88,16 +88,16 @@ public:
{
}
- TransactionRecord(uint256 hash, qint64 time):
- hash(hash), time(time), type(Other), address(""), debit(0),
+ TransactionRecord(uint256 _hash, qint64 _time):
+ hash(_hash), time(_time), type(Other), address(""), debit(0),
credit(0), idx(0)
{
}
- TransactionRecord(uint256 hash, qint64 time,
- Type type, const std::string &address,
- const CAmount& debit, const CAmount& credit):
- hash(hash), time(time), type(type), address(address), debit(debit), credit(credit),
+ TransactionRecord(uint256 _hash, qint64 _time,
+ Type _type, const std::string &_address,
+ const CAmount& _debit, const CAmount& _credit):
+ hash(_hash), time(_time), type(_type), address(_address), debit(_debit), credit(_credit),
idx(0)
{
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index b29ecf8348..52261ff04b 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -59,9 +59,9 @@ struct TxLessThan
class TransactionTablePriv
{
public:
- TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent) :
- wallet(wallet),
- parent(parent)
+ TransactionTablePriv(CWallet *_wallet, TransactionTableModel *_parent) :
+ wallet(_wallet),
+ parent(_parent)
{
}
@@ -235,13 +235,13 @@ public:
}
};
-TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent):
+TransactionTableModel::TransactionTableModel(const PlatformStyle *_platformStyle, CWallet* _wallet, WalletModel *parent):
QAbstractTableModel(parent),
- wallet(wallet),
+ wallet(_wallet),
walletModel(parent),
- priv(new TransactionTablePriv(wallet, this)),
+ priv(new TransactionTablePriv(_wallet, this)),
fProcessingQueuedTransactions(false),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
priv->refreshWallet();
@@ -714,8 +714,8 @@ struct TransactionNotification
{
public:
TransactionNotification() {}
- TransactionNotification(uint256 hash, ChangeType status, bool showTransaction):
- hash(hash), status(status), showTransaction(showTransaction) {}
+ TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
+ hash(_hash), status(_status), showTransaction(_showTransaction) {}
void invoke(QObject *ttm)
{
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 48cf940502..856b16d2c4 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -184,13 +184,13 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails()));
}
-void TransactionView::setModel(WalletModel *model)
+void TransactionView::setModel(WalletModel *_model)
{
- this->model = model;
- if(model)
+ this->model = _model;
+ if(_model)
{
transactionProxyModel = new TransactionFilterProxy(this);
- transactionProxyModel->setSourceModel(model->getTransactionTableModel());
+ transactionProxyModel->setSourceModel(_model->getTransactionTableModel());
transactionProxyModel->setDynamicSortFilter(true);
transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
@@ -214,10 +214,10 @@ void TransactionView::setModel(WalletModel *model)
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH);
- if (model->getOptionsModel())
+ if (_model->getOptionsModel())
{
// Add third party transaction URLs to context menu
- QStringList listUrls = model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts);
+ QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts);
for (int i = 0; i < listUrls.size(); ++i)
{
QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host();
@@ -234,10 +234,10 @@ void TransactionView::setModel(WalletModel *model)
}
// show/hide column Watch-only
- updateWatchOnlyColumn(model->haveWatchOnly());
+ updateWatchOnlyColumn(_model->haveWatchOnly());
// Watch-only signal
- connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
+ connect(_model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
}
}
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index e4ca5e1831..69dcc9abb1 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -12,10 +12,10 @@
#include <QHBoxLayout>
#include <QLabel>
-WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) :
+WalletFrame::WalletFrame(const PlatformStyle *_platformStyle, BitcoinGUI *_gui) :
QFrame(_gui),
gui(_gui),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
// Leave HBox hook for adding a list view later
QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
@@ -33,9 +33,9 @@ WalletFrame::~WalletFrame()
{
}
-void WalletFrame::setClientModel(ClientModel *clientModel)
+void WalletFrame::setClientModel(ClientModel *_clientModel)
{
- this->clientModel = clientModel;
+ this->clientModel = _clientModel;
}
bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
@@ -57,6 +57,8 @@ bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
// Ensure a walletView is able to show the main window
connect(walletView, SIGNAL(showNormalIfMinimized()), gui, SLOT(showNormalIfMinimized()));
+ connect(walletView, SIGNAL(outOfSyncWarningClicked()), this, SLOT(outOfSyncWarningClicked()));
+
return true;
}
@@ -195,3 +197,7 @@ WalletView *WalletFrame::currentWalletView()
return qobject_cast<WalletView*>(walletStack->currentWidget());
}
+void WalletFrame::outOfSyncWarningClicked()
+{
+ Q_EMIT requestedSyncWarningInfo();
+}
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 9a5bc273c2..00c2f56363 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -38,6 +38,10 @@ public:
void showOutOfSyncWarning(bool fShow);
+Q_SIGNALS:
+ /** Notify that the user has requested more information about the out-of-sync warning */
+ void requestedSyncWarningInfo();
+
private:
QStackedWidget *walletStack;
BitcoinGUI *gui;
@@ -78,6 +82,8 @@ public Q_SLOTS:
void usedSendingAddresses();
/** Show used receiving addresses */
void usedReceivingAddresses();
+ /** Pass on signal over requested out-of-sync-warning information */
+ void outOfSyncWarningClicked();
};
#endif // BITCOIN_QT_WALLETFRAME_H
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 73851e97fc..c8a2cb37ec 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -27,8 +27,8 @@
#include <boost/foreach.hpp>
-WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
- QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
+WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) :
+ QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0),
transactionTableModel(0),
recentRequestsTableModel(0),
cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
@@ -531,10 +531,10 @@ WalletModel::UnlockContext WalletModel::requestUnlock()
return UnlockContext(this, valid, was_locked);
}
-WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock):
- wallet(wallet),
- valid(valid),
- relock(relock)
+WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid, bool _relock):
+ wallet(_wallet),
+ valid(_valid),
+ relock(_relock)
{
}
@@ -684,6 +684,11 @@ bool WalletModel::abandonTransaction(uint256 hash) const
return wallet->AbandonTransaction(hash);
}
+bool WalletModel::isWalletEnabled()
+{
+ return !GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
+}
+
bool WalletModel::hdEnabled() const
{
return wallet->IsHDEnabled();
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index a15ecf899b..e233fa690d 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -38,8 +38,8 @@ class SendCoinsRecipient
{
public:
explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
- explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
- address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
+ explicit SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message):
+ address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
// If from an unauthenticated payment request, this is used for storing
// the addresses, e.g. address-A<br />address-B<br />address-C.
@@ -145,8 +145,8 @@ public:
// Return status record for SendCoins, contains error id + information
struct SendCoinsReturn
{
- SendCoinsReturn(StatusCode status = OK):
- status(status) {}
+ SendCoinsReturn(StatusCode _status = OK):
+ status(_status) {}
StatusCode status;
};
@@ -203,6 +203,8 @@ public:
bool transactionCanBeAbandoned(uint256 hash) const;
bool abandonTransaction(uint256 hash) const;
+ static bool isWalletEnabled();
+
bool hdEnabled() const;
private:
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
index ffadf89cc8..fdec6a1c86 100644
--- a/src/qt/walletmodeltransaction.cpp
+++ b/src/qt/walletmodeltransaction.cpp
@@ -7,8 +7,8 @@
#include "policy/policy.h"
#include "wallet/wallet.h"
-WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
- recipients(recipients),
+WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &_recipients) :
+ recipients(_recipients),
walletTransaction(0),
keyChange(0),
fee(0)
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 495ebfd834..a9518413c2 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -29,11 +29,11 @@
#include <QPushButton>
#include <QVBoxLayout>
-WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
+WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent):
QStackedWidget(parent),
clientModel(0),
walletModel(0),
- platformStyle(platformStyle)
+ platformStyle(_platformStyle)
{
// Create tabs
overviewPage = new OverviewPage(platformStyle);
@@ -66,6 +66,7 @@ WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
// Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
+ connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
// Double-clicking on a transaction on the transaction history page shows details
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
@@ -104,47 +105,47 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui)
}
}
-void WalletView::setClientModel(ClientModel *clientModel)
+void WalletView::setClientModel(ClientModel *_clientModel)
{
- this->clientModel = clientModel;
+ this->clientModel = _clientModel;
- overviewPage->setClientModel(clientModel);
- sendCoinsPage->setClientModel(clientModel);
+ overviewPage->setClientModel(_clientModel);
+ sendCoinsPage->setClientModel(_clientModel);
}
-void WalletView::setWalletModel(WalletModel *walletModel)
+void WalletView::setWalletModel(WalletModel *_walletModel)
{
- this->walletModel = walletModel;
+ this->walletModel = _walletModel;
// Put transaction list in tabs
- transactionView->setModel(walletModel);
- overviewPage->setWalletModel(walletModel);
- receiveCoinsPage->setModel(walletModel);
- sendCoinsPage->setModel(walletModel);
- usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel());
- usedSendingAddressesPage->setModel(walletModel->getAddressTableModel());
-
- if (walletModel)
+ transactionView->setModel(_walletModel);
+ overviewPage->setWalletModel(_walletModel);
+ receiveCoinsPage->setModel(_walletModel);
+ sendCoinsPage->setModel(_walletModel);
+ usedReceivingAddressesPage->setModel(_walletModel->getAddressTableModel());
+ usedSendingAddressesPage->setModel(_walletModel->getAddressTableModel());
+
+ if (_walletModel)
{
// Receive and pass through messages from wallet model
- connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
+ connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
// Handle changes in encryption status
- connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
+ connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
updateEncryptionStatus();
// update HD status
- Q_EMIT hdEnabledStatusChanged(walletModel->hdEnabled());
+ Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled());
// Balloon pop-up for new transaction
- connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
+ connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(processNewTransaction(QModelIndex,int,int)));
// Ask for passphrase if needed
- connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
+ connect(_walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
// Show progress dialog
- connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
+ connect(_walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
}
}
@@ -322,3 +323,8 @@ void WalletView::showProgress(const QString &title, int nProgress)
else if (progressDialog)
progressDialog->setValue(nProgress);
}
+
+void WalletView::requestedSyncWarningInfo()
+{
+ Q_EMIT outOfSyncWarningClicked();
+}
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 2045605954..aaa6aacbf0 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -110,6 +110,9 @@ public Q_SLOTS:
/** Show progress dialog e.g. for rescan */
void showProgress(const QString &title, int nProgress);
+ /** User has requested more information about the out of sync state */
+ void requestedSyncWarningInfo();
+
Q_SIGNALS:
/** Signal that we want to show the main window */
void showNormalIfMinimized();
@@ -121,6 +124,8 @@ Q_SIGNALS:
void hdEnabledStatusChanged(int hdEnabled);
/** Notify that a new transaction appeared */
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
+ /** Notify that the out of sync warning icon has been pressed */
+ void outOfSyncWarningClicked();
};
#endif // BITCOIN_QT_WALLETVIEW_H
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 5afcf6353c..f0b7e0a07c 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -44,7 +44,7 @@ UniValue getinfo(const UniValue& params, bool fHelp)
if (fHelp || params.size() != 0)
throw runtime_error(
"getinfo\n"
- "Returns an object containing various state info.\n"
+ "\nDEPRECATED. Returns an object containing various state info.\n"
"\nResult:\n"
"{\n"
" \"version\": xxxxx, (numeric) the server version\n"
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 33f107d84b..97abeb7211 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
- CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, "", true);
+ CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
connman->ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, "", true);
+ CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1;
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index 5f150e4812..5ccaeb57bb 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -257,8 +257,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
addrman.Good(CAddress(addr, NODE_NONE));
//Test 15: No collision in tried table yet.
- BOOST_TEST_MESSAGE(addrman.size());
- BOOST_CHECK(addrman.size() == i);
+ BOOST_CHECK_EQUAL(addrman.size(), i);
}
//Test 16: tried table collision!
@@ -543,4 +542,4 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
// than 64 buckets.
BOOST_CHECK(buckets.size() > 64);
}
-BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index bc9a98ab04..680708533e 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -164,12 +164,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
bool fInboundIn = false;
// Test that fFeeler is false by default.
- CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
+ CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, pszDest, fInboundIn);
BOOST_CHECK(pnode1->fInbound == false);
BOOST_CHECK(pnode1->fFeeler == false);
fInboundIn = true;
- CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
+ CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, pszDest, fInboundIn);
BOOST_CHECK(pnode2->fInbound == true);
BOOST_CHECK(pnode2->fFeeler == false);
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index b1ceef4f64..02843d8525 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -72,7 +72,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
- g_connman = std::unique_ptr<CConnman>(new CConnman());
+ g_connman = std::unique_ptr<CConnman>(new CConnman(0x1337, 0x1337)); // Deterministic randomness for tests.
connman = g_connman.get();
RegisterNodeSignals(GetNodeSignals());
}
diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp
index c778e40a90..74a13e0e05 100644
--- a/src/ui_interface.cpp
+++ b/src/ui_interface.cpp
@@ -18,6 +18,11 @@ void InitWarning(const std::string& str)
uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
}
+std::string AmountHighWarn(const std::string& optname)
+{
+ return strprintf(_("%s is set very high!"), optname);
+}
+
std::string AmountErrMsg(const char* const optname, const std::string& strValue)
{
return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue);
diff --git a/src/ui_interface.h b/src/ui_interface.h
index 7e6557f8e2..177ff238db 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -112,6 +112,8 @@ void InitWarning(const std::string& str);
/** Show error message **/
bool InitError(const std::string& str);
+std::string AmountHighWarn(const std::string& optname);
+
std::string AmountErrMsg(const char* const optname, const std::string& strValue);
extern CClientUIInterface uiInterface;
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index 8428b1c683..e48b905bfb 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -56,7 +56,7 @@ public:
bool setNumStr(const std::string& val);
bool setInt(uint64_t val);
bool setInt(int64_t val);
- bool setInt(int val) { return setInt((int64_t)val); }
+ bool setInt(int val_) { return setInt((int64_t)val_); }
bool setFloat(double val);
bool setStr(const std::string& val);
bool setArray();
@@ -95,28 +95,28 @@ public:
bool push_backV(const std::vector<UniValue>& vec);
bool pushKV(const std::string& key, const UniValue& val);
- bool pushKV(const std::string& key, const std::string& val) {
- UniValue tmpVal(VSTR, val);
+ bool pushKV(const std::string& key, const std::string& val_) {
+ UniValue tmpVal(VSTR, val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, const char *val_) {
- std::string val(val_);
- return pushKV(key, val);
+ std::string _val(val_);
+ return pushKV(key, _val);
}
- bool pushKV(const std::string& key, int64_t val) {
- UniValue tmpVal(val);
+ bool pushKV(const std::string& key, int64_t val_) {
+ UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
- bool pushKV(const std::string& key, uint64_t val) {
- UniValue tmpVal(val);
+ bool pushKV(const std::string& key, uint64_t val_) {
+ UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
- bool pushKV(const std::string& key, int val) {
- UniValue tmpVal((int64_t)val);
+ bool pushKV(const std::string& key, int val_) {
+ UniValue tmpVal((int64_t)val_);
return pushKV(key, tmpVal);
}
- bool pushKV(const std::string& key, double val) {
- UniValue tmpVal(val);
+ bool pushKV(const std::string& key, double val_) {
+ UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKVs(const UniValue& obj);
diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp
index 0076d6678e..1f8cee6d29 100644
--- a/src/univalue/lib/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -119,32 +119,29 @@ bool UniValue::setNumStr(const string& val_)
return true;
}
-bool UniValue::setInt(uint64_t val)
+bool UniValue::setInt(uint64_t val_)
{
- string s;
ostringstream oss;
- oss << val;
+ oss << val_;
return setNumStr(oss.str());
}
-bool UniValue::setInt(int64_t val)
+bool UniValue::setInt(int64_t val_)
{
- string s;
ostringstream oss;
- oss << val;
+ oss << val_;
return setNumStr(oss.str());
}
-bool UniValue::setFloat(double val)
+bool UniValue::setFloat(double val_)
{
- string s;
ostringstream oss;
- oss << std::setprecision(16) << val;
+ oss << std::setprecision(16) << val_;
bool ret = setNumStr(oss.str());
typ = VNUM;
@@ -173,12 +170,12 @@ bool UniValue::setObject()
return true;
}
-bool UniValue::push_back(const UniValue& val)
+bool UniValue::push_back(const UniValue& val_)
{
if (typ != VARR)
return false;
- values.push_back(val);
+ values.push_back(val_);
return true;
}
@@ -192,13 +189,13 @@ bool UniValue::push_backV(const std::vector<UniValue>& vec)
return true;
}
-bool UniValue::pushKV(const std::string& key, const UniValue& val)
+bool UniValue::pushKV(const std::string& key, const UniValue& val_)
{
if (typ != VOBJ)
return false;
keys.push_back(key);
- values.push_back(val);
+ values.push_back(val_);
return true;
}
@@ -228,7 +225,7 @@ int UniValue::findKey(const std::string& key) const
bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
{
for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
- it != t.end(); it++) {
+ it != t.end(); ++it) {
int idx = findKey(it->first);
if (idx < 0)
return false;
diff --git a/src/util.cpp b/src/util.cpp
index c7d147a11e..93cc0412b5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -600,19 +600,19 @@ bool TryCreateDirectory(const boost::filesystem::path& p)
return false;
}
-void FileCommit(FILE *fileout)
+void FileCommit(FILE *file)
{
- fflush(fileout); // harmless if redundantly called
+ fflush(file); // harmless if redundantly called
#ifdef WIN32
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fileout));
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
FlushFileBuffers(hFile);
#else
#if defined(__linux__) || defined(__NetBSD__)
- fdatasync(fileno(fileout));
+ fdatasync(fileno(file));
#elif defined(__APPLE__) && defined(F_FULLFSYNC)
- fcntl(fileno(fileout), F_FULLFSYNC, 0);
+ fcntl(fileno(file), F_FULLFSYNC, 0);
#else
- fsync(fileno(fileout));
+ fsync(fileno(file));
#endif
#endif
}
diff --git a/src/util.h b/src/util.h
index 39328b51ef..45b3658557 100644
--- a/src/util.h
+++ b/src/util.h
@@ -93,7 +93,7 @@ bool error(const char* fmt, const Args&... args)
void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
void ParseParameters(int argc, const char*const argv[]);
-void FileCommit(FILE *fileout);
+void FileCommit(FILE *file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 42ebdb9b9b..e80fa7dff8 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -344,8 +344,6 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet.");
}
- ThreadFlushWalletDB(pwalletMain->strWalletFile);
-
return NullUniValue;
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 993caad400..3eb7e5d9ba 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2630,6 +2630,9 @@ static const CRPCCommand commands[] =
void RegisterWalletRPCCommands(CRPCTable &t)
{
+ if (GetBoolArg("-disablewallet", false))
+ return;
+
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
t.appendCommand(commands[vcidx].name, &commands[vcidx]);
}
diff --git a/src/wallet/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp
index a6cada46a2..a833be13d0 100644
--- a/src/wallet/test/accounting_tests.cpp
+++ b/src/wallet/test/accounting_tests.cpp
@@ -3,7 +3,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "wallet/wallet.h"
-#include "wallet/walletdb.h"
#include "wallet/test/wallet_test_fixture.h"
@@ -17,13 +16,13 @@ extern CWallet* pwalletMain;
BOOST_FIXTURE_TEST_SUITE(accounting_tests, WalletTestingSetup)
static void
-GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
+GetResults(std::map<CAmount, CAccountingEntry>& results)
{
std::list<CAccountingEntry> aes;
results.clear();
- BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK);
- walletdb.ListAccountCreditDebit("", aes);
+ BOOST_CHECK(pwalletMain->ReorderTransactions() == DB_LOAD_OK);
+ pwalletMain->ListAccountCreditDebit("", aes);
BOOST_FOREACH(CAccountingEntry& ae, aes)
{
results[ae.nOrderPos] = ae;
@@ -32,7 +31,6 @@ GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
BOOST_AUTO_TEST_CASE(acc_orderupgrade)
{
- CWalletDB walletdb(pwalletMain->strWalletFile);
std::vector<CWalletTx*> vpwtx;
CWalletTx wtx;
CAccountingEntry ae;
@@ -45,7 +43,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333333;
ae.strOtherAccount = "b";
ae.strComment = "";
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
wtx.mapValue["comment"] = "z";
pwalletMain->AddToWallet(wtx);
@@ -55,9 +53,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333336;
ae.strOtherAccount = "c";
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(pwalletMain->nOrderPosNext == 3);
BOOST_CHECK(2 == results.size());
@@ -71,9 +69,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333330;
ae.strOtherAccount = "d";
ae.nOrderPos = pwalletMain->IncOrderPosNext();
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 3);
BOOST_CHECK(pwalletMain->nOrderPosNext == 4);
@@ -105,7 +103,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
vpwtx[2]->nTimeReceived = (unsigned int)1333333329;
vpwtx[2]->nOrderPos = -1;
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 3);
BOOST_CHECK(pwalletMain->nOrderPosNext == 6);
@@ -121,9 +119,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333334;
ae.strOtherAccount = "e";
ae.nOrderPos = -1;
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 4);
BOOST_CHECK(pwalletMain->nOrderPosNext == 7);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 4c10ea0edb..50d63182ae 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -414,6 +414,9 @@ void CWallet::Flush(bool shutdown)
bool CWallet::Verify()
{
+ if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET))
+ return true;
+
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
@@ -649,6 +652,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true;
}
+DBErrors CWallet::ReorderTransactions()
+{
+ CWalletDB walletdb(strWalletFile);
+ return walletdb.ReorderTransactions(this);
+}
+
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
{
AssertLockHeld(cs_wallet); // nOrderPosNext
@@ -677,7 +686,7 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
debit.nTime = nNow;
debit.strOtherAccount = strTo;
debit.strComment = strComment;
- AddAccountingEntry(debit, walletdb);
+ AddAccountingEntry(debit, &walletdb);
// Credit
CAccountingEntry credit;
@@ -687,7 +696,7 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
credit.nTime = nNow;
credit.strOtherAccount = strFrom;
credit.strComment = strComment;
- AddAccountingEntry(credit, walletdb);
+ AddAccountingEntry(credit, &walletdb);
if (!walletdb.TxnCommit())
return false;
@@ -2501,9 +2510,21 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
return true;
}
-bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB & pwalletdb)
+void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
+ CWalletDB walletdb(strWalletFile);
+ return walletdb.ListAccountCreditDebit(strAccount, entries);
+}
+
+bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry)
{
- if (!pwalletdb.WriteAccountingEntry_Backend(acentry))
+ CWalletDB walletdb(strWalletFile);
+
+ return AddAccountingEntry(acentry, &walletdb);
+}
+
+bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwalletdb)
+{
+ if (!pwalletdb->WriteAccountingEntry_Backend(acentry))
return false;
laccentries.push_back(acentry);
@@ -3275,6 +3296,12 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
bool CWallet::InitLoadWallet()
{
+ if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
+ pwalletMain = NULL;
+ LogPrintf("Wallet disabled!\n");
+ return true;
+ }
+
std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
// needed to restore wallet transaction meta data after -zapwallettxes
@@ -3446,13 +3473,31 @@ bool CWallet::InitLoadWallet()
bool CWallet::ParameterInteraction()
{
+ if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET))
+ return true;
+
+ if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && SoftSetBoolArg("-walletbroadcast", false)) {
+ LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
+ }
+
+ if (GetBoolArg("-sysperms", false))
+ return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
+ if (GetArg("-prune", 0) && GetBoolArg("-rescan", false))
+ return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
+
+ if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB)
+ InitWarning(AmountHighWarn("-minrelaytxfee") + " " +
+ _("The wallet will avoid paying less than the minimum relay fee."));
+
if (mapArgs.count("-mintxfee"))
{
CAmount n = 0;
- if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
- CWallet::minTxFee = CFeeRate(n);
- else
+ if (!ParseMoney(mapArgs["-mintxfee"], n))
return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"]));
+ if (n > HIGH_TX_FEE_PER_KB)
+ InitWarning(AmountHighWarn("-mintxfee") + " " +
+ _("This is the minimum transaction fee you pay on every transaction."));
+ CWallet::minTxFee = CFeeRate(n);
}
if (mapArgs.count("-fallbackfee"))
{
@@ -3460,7 +3505,8 @@ bool CWallet::ParameterInteraction()
if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK))
return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"]));
if (nFeePerK > HIGH_TX_FEE_PER_KB)
- InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available."));
+ InitWarning(AmountHighWarn("-fallbackfee") + " " +
+ _("This is the transaction fee you may pay when fee estimates are not available."));
CWallet::fallbackFee = CFeeRate(nFeePerK);
}
if (mapArgs.count("-paytxfee"))
@@ -3469,7 +3515,9 @@ bool CWallet::ParameterInteraction()
if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"]));
if (nFeePerK > HIGH_TX_FEE_PER_KB)
- InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
+ InitWarning(AmountHighWarn("-paytxfee") + " " +
+ _("This is the transaction fee you will pay if you send a transaction."));
+
payTxFee = CFeeRate(nFeePerK, 1000);
if (payTxFee < ::minRelayTxFee)
{
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 61aff6e45a..f6c658928f 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -59,7 +59,7 @@ static const bool DEFAULT_WALLET_RBF = false;
//! Largest (in bytes) free transaction we're willing to create
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
static const bool DEFAULT_WALLETBROADCAST = true;
-
+static const bool DEFAULT_DISABLE_WALLET = false;
//! if set, all keys will be derived by using BIP32
static const bool DEFAULT_USE_HD_WALLET = true;
@@ -741,6 +741,7 @@ public:
* @return next transaction order id
*/
int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
+ DBErrors ReorderTransactions();
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false);
@@ -775,7 +776,9 @@ public:
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman);
- bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb);
+ void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
+ bool AddAccountingEntry(const CAccountingEntry&);
+ bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb);
static CFeeRate minTxFee;
static CFeeRate fallbackFee;