aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.qt.include2
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/chainparams.cpp17
-rw-r--r--src/consensus/params.h1
-rw-r--r--src/init.cpp92
-rw-r--r--src/init.h2
-rw-r--r--src/main.cpp30
-rw-r--r--src/policy/policy.cpp2
-rw-r--r--src/primitives/block.cpp2
-rw-r--r--src/primitives/transaction.h7
-rw-r--r--src/qt/rpcconsole.cpp2
-rw-r--r--src/qt/transactiondesc.cpp3
-rw-r--r--src/qt/transactionrecord.cpp7
-rw-r--r--src/qt/transactionrecord.h4
-rw-r--r--src/rest.cpp3
-rw-r--r--src/rpc/blockchain.cpp29
-rw-r--r--src/rpc/client.cpp1
-rw-r--r--src/rpc/mining.cpp24
-rw-r--r--src/rpc/misc.cpp18
-rw-r--r--src/rpc/net.cpp22
-rw-r--r--src/rpc/rawtransaction.cpp20
-rw-r--r--src/rpc/register.h32
-rw-r--r--src/rpc/server.cpp64
-rw-r--r--src/rpc/server.h59
-rw-r--r--src/test/bctest.py2
-rwxr-xr-xsrc/test/bitcoin-util-test.py2
-rw-r--r--src/test/rpc_tests.cpp26
-rw-r--r--src/test/test_bitcoin.cpp8
-rw-r--r--src/timedata.cpp2
-rw-r--r--src/timedata.h2
-rw-r--r--src/versionbits.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp14
-rw-r--r--src/wallet/rpcwallet.h4
-rw-r--r--src/wallet/wallet.cpp143
-rw-r--r--src/wallet/wallet.h11
36 files changed, 374 insertions, 288 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6ad7aabae0..1e54512cbd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,6 +130,7 @@ BITCOIN_CORE_H = \
rpc/client.h \
rpc/protocol.h \
rpc/server.h \
+ rpc/register.h \
scheduler.h \
script/sigcache.h \
script/sign.h \
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 247ca3f1d4..8443fe697b 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -392,7 +392,7 @@ SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
- $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" ../share/qt/extract_strings_qt.py $^
+ $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^
translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 4481349e50..d806fb219e 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -130,7 +130,7 @@ bitcoin_test_clean : FORCE
check-local:
@echo "Running test/bitcoin-util-test.py..."
- $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
+ $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
if EMBEDDED_UNIVALUE
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 508c4de167..965d131695 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -86,7 +86,13 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
- /**
+
+ // Deployment of BIP68, BIP112, and BIP113.
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017
+
+ /**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
* a large 32-bit integer with any alignment.
@@ -171,6 +177,12 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
+
+ // Deployment of BIP68, BIP112, and BIP113.
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017
+
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
pchMessageStart[2] = 0x09;
@@ -238,6 +250,9 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL;
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
+ consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 7c3a8e84c3..4f3480b89b 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -15,6 +15,7 @@ namespace Consensus {
enum DeploymentPos
{
DEPLOYMENT_TESTDUMMY,
+ DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
MAX_VERSION_BITS_DEPLOYMENTS
};
diff --git a/src/init.cpp b/src/init.cpp
index 38ac91b2af..3667820a21 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -24,9 +24,11 @@
#include "net.h"
#include "policy/policy.h"
#include "rpc/server.h"
+#include "rpc/register.h"
#include "script/standard.h"
#include "script/sigcache.h"
#include "scheduler.h"
+#include "timedata.h"
#include "txdb.h"
#include "txmempool.h"
#include "torcontrol.h"
@@ -63,9 +65,6 @@
using namespace std;
-#ifdef ENABLE_WALLET
-CWallet* pwalletMain = NULL;
-#endif
bool fFeeEstimatesInitialized = false;
static const bool DEFAULT_PROXYRANDOMIZE = true;
static const bool DEFAULT_REST_ENABLE = false;
@@ -365,6 +364,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS));
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER));
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER));
+ strUsage += HelpMessageOpt("-maxtimeadjustment", strprintf(_("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)"), DEFAULT_MAX_TIME_ADJUSTMENT));
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG));
@@ -913,10 +913,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fPruneMode = true;
}
+ RegisterAllCoreRPCCommands(tableRPC);
#ifdef ENABLE_WALLET
bool fDisableWallet = GetBoolArg("-disablewallet", false);
if (!fDisableWallet)
- walletRegisterRPCCommands();
+ RegisterWalletRPCCommands(tableRPC);
#endif
nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
@@ -944,56 +945,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp);
#ifdef ENABLE_WALLET
- if (mapArgs.count("-mintxfee"))
- {
- CAmount n = 0;
- if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
- CWallet::minTxFee = CFeeRate(n);
- else
- return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"]));
- }
- if (mapArgs.count("-fallbackfee"))
- {
- CAmount nFeePerK = 0;
- 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."));
- CWallet::fallbackFee = CFeeRate(nFeePerK);
- }
- if (mapArgs.count("-paytxfee"))
- {
- CAmount nFeePerK = 0;
- 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."));
- payTxFee = CFeeRate(nFeePerK, 1000);
- if (payTxFee < ::minRelayTxFee)
- {
- return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
- mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
- }
- }
- if (mapArgs.count("-maxtxfee"))
- {
- CAmount nMaxFee = 0;
- if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
- return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"]));
- if (nMaxFee > HIGH_MAX_TX_FEE)
- InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
- maxTxFee = nMaxFee;
- if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
- {
- return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
- mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
- }
- }
- nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
- bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
- fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS);
-
- std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
+ if (!CWallet::ParameterInteraction())
+ return false;
#endif // ENABLE_WALLET
fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
@@ -1028,11 +981,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), _(PACKAGE_NAME)));
std::string strDataDir = GetDataDir().string();
-#ifdef ENABLE_WALLET
- // Wallet file must be a plain filename without a directory
- if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
- return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
-#endif
+
// Make sure only a single Bitcoin process is using the data directory.
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
@@ -1093,20 +1042,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 5: verify wallet database integrity
#ifdef ENABLE_WALLET
if (!fDisableWallet) {
- LogPrintf("Using wallet %s\n", strWalletFile);
- uiInterface.InitMessage(_("Verifying wallet..."));
-
- std::string warningString;
- std::string errorString;
-
- if (!CWallet::Verify(strWalletFile, warningString, errorString))
+ if (!CWallet::Verify())
return false;
-
- if (!warningString.empty())
- InitWarning(warningString);
- if (!errorString.empty())
- return InitError(errorString);
-
} // (!fDisableWallet)
#endif // ENABLE_WALLET
// ********************************************************* Step 6: network initialization
@@ -1417,16 +1354,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
pwalletMain = NULL;
LogPrintf("Wallet disabled!\n");
} else {
- std::string warningString;
- std::string errorString;
- pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString);
- if (!warningString.empty())
- InitWarning(warningString);
- if (!errorString.empty())
- {
- LogPrintf("%s", errorString);
- return InitError(errorString);
- }
+ CWallet::InitLoadWallet();
if (!pwalletMain)
return false;
}
diff --git a/src/init.h b/src/init.h
index af1b94b72a..63e07ccb3c 100644
--- a/src/init.h
+++ b/src/init.h
@@ -16,8 +16,6 @@ namespace boost
class thread_group;
} // namespace boost
-extern CWallet* pwalletMain;
-
void StartShutdown();
bool ShutdownRequested();
/** Interrupt threads */
diff --git a/src/main.cpp b/src/main.cpp
index 36189f4ffc..2c0b3bfee7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2286,6 +2286,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
}
+ // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
+ int nLockTimeFlags = 0;
+ if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) {
+ flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
+ nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
+ }
+
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
@@ -2294,7 +2301,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
std::vector<int> prevheights;
- int nLockTimeFlags = 0;
CAmount nFees = 0;
int nInputs = 0;
unsigned int nSigOps = 0;
@@ -2549,8 +2555,8 @@ void static UpdateTip(CBlockIndex *pindexNew) {
nTimeBestReceived = GetTime();
mempool.AddTransactionsUpdated(1);
- LogPrintf("%s: new best=%s height=%d bits=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
- chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nBits,
+ LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utx)\n", __func__,
+ chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), chainActive.Tip()->nVersion,
log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
@@ -3284,8 +3290,8 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
// Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades
if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
- return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(v%d)", version - 1),
- strprintf("rejected nVersion=%d block", version - 1));
+ return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", version - 1),
+ strprintf("rejected nVersion=0x%08x block", version - 1));
return true;
}
@@ -3295,12 +3301,18 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
const Consensus::Params& consensusParams = Params().GetConsensus();
+ // Start enforcing BIP113 (Median Time Past) using versionbits logic.
+ int nLockTimeFlags = 0;
+ if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) {
+ nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
+ }
+
+ int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
+ ? pindexPrev->GetMedianTimePast()
+ : block.GetBlockTime();
+
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
- int nLockTimeFlags = 0;
- int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
- ? pindexPrev->GetMedianTimePast()
- : block.GetBlockTime();
if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction");
}
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 332abc430e..e3ed7be000 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -55,7 +55,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
bool IsStandardTx(const CTransaction& tx, std::string& reason)
{
- if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
+ if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
index 59e949d71a..6fb33230a5 100644
--- a/src/primitives/block.cpp
+++ b/src/primitives/block.cpp
@@ -18,7 +18,7 @@ uint256 CBlockHeader::GetHash() const
std::string CBlock::ToString() const
{
std::stringstream s;
- s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
+ s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
GetHash().ToString(),
nVersion,
hashPrevBlock.ToString(),
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index e124dca365..149816406a 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -207,8 +207,15 @@ private:
void UpdateHash() const;
public:
+ // Default transaction version.
static const int32_t CURRENT_VERSION=1;
+ // Changing the default transaction version requires a two step process: first
+ // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date
+ // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and
+ // MAX_STANDARD_VERSION will be equal.
+ static const int32_t MAX_STANDARD_VERSION=2;
+
// The local variables are made const to prevent unintended modification
// without updating the cached hash value. However, CTransaction is not
// actually immutable; deserialization and assignment are implemented,
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 42112c42f1..d8647d902a 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -459,6 +459,8 @@ void RPCConsole::setClientModel(ClientModel *model)
autoCompleter = new QCompleter(wordList, this);
ui->lineEdit->setCompleter(autoCompleter);
+ // clear the lineEdit after activating from QCompleter
+ connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection);
}
}
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 1b8bf978ad..bae0cbd1c8 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -240,7 +240,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
- strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>";
+ strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
+ strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm)
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 1efeda93ec..4fe47181f6 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -262,11 +262,10 @@ bool TransactionRecord::statusUpdateNeeded()
QString TransactionRecord::getTxID() const
{
- return formatSubTxId(hash, idx);
+ return QString::fromStdString(hash.ToString());
}
-QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
+int TransactionRecord::getOutputIndex() const
{
- return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
+ return idx;
}
-
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index 330cd48cfa..8c754c3aad 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -129,8 +129,8 @@ public:
/** Return the unique identifier for this transaction (part) */
QString getTxID() const;
- /** Format subtransaction id */
- static QString formatSubTxId(const uint256 &hash, int vout);
+ /** Return the output index of the subtransaction */
+ int getOutputIndex() const;
/** Update status from core wallet tx.
*/
diff --git a/src/rest.cpp b/src/rest.cpp
index ebdccc9402..2dff8d7dad 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -273,6 +273,9 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa
return rest_block(req, strURIPart, false);
}
+// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp
+UniValue getblockchaininfo(const UniValue& params, bool fHelp);
+
static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
{
if (!CheckWarmup(req))
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index a110dff0d1..f1c9d9f7ab 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -681,6 +681,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
+ bip9_softforks.push_back(BIP9SoftForkDesc("csv", consensusParams, Consensus::DEPLOYMENT_CSV));
obj.push_back(Pair("softforks", softforks));
obj.push_back(Pair("bip9_softforks", bip9_softforks));
@@ -911,3 +912,31 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp)
return NullUniValue;
}
+
+static const CRPCCommand commands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
+ { "blockchain", "getbestblockhash", &getbestblockhash, true },
+ { "blockchain", "getblockcount", &getblockcount, true },
+ { "blockchain", "getblock", &getblock, true },
+ { "blockchain", "getblockhash", &getblockhash, true },
+ { "blockchain", "getblockheader", &getblockheader, true },
+ { "blockchain", "getchaintips", &getchaintips, true },
+ { "blockchain", "getdifficulty", &getdifficulty, true },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
+ { "blockchain", "getrawmempool", &getrawmempool, true },
+ { "blockchain", "gettxout", &gettxout, true },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
+ { "blockchain", "verifychain", &verifychain, true },
+
+ /* Not shown in help */
+ { "hidden", "invalidateblock", &invalidateblock, true },
+ { "hidden", "reconsiderblock", &reconsiderblock, true },
+};
+
+void RegisterBlockchainRPCCommands(CRPCTable &tableRPC)
+{
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+}
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 89420b93d7..b040d2bc80 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -30,7 +30,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "generate", 0 },
{ "generate", 1 },
{ "generatetoaddress", 0 },
- { "generatetoaddress", 1 },
{ "generatetoaddress", 2 },
{ "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 },
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index a2abbb323d..b63ee22889 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -781,3 +781,27 @@ UniValue estimatesmartpriority(const UniValue& params, bool fHelp)
result.push_back(Pair("blocks", answerFound));
return result;
}
+
+static const CRPCCommand commands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ { "mining", "getnetworkhashps", &getnetworkhashps, true },
+ { "mining", "getmininginfo", &getmininginfo, true },
+ { "mining", "prioritisetransaction", &prioritisetransaction, true },
+ { "mining", "getblocktemplate", &getblocktemplate, true },
+ { "mining", "submitblock", &submitblock, true },
+
+ { "generating", "generate", &generate, true },
+ { "generating", "generatetoaddress", &generatetoaddress, true },
+
+ { "util", "estimatefee", &estimatefee, true },
+ { "util", "estimatepriority", &estimatepriority, true },
+ { "util", "estimatesmartfee", &estimatesmartfee, true },
+ { "util", "estimatesmartpriority", &estimatesmartpriority, true },
+};
+
+void RegisterMiningRPCCommands(CRPCTable &tableRPC)
+{
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+}
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 0aab9c3043..e8a099b445 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -396,3 +396,21 @@ UniValue setmocktime(const UniValue& params, bool fHelp)
return NullUniValue;
}
+
+static const CRPCCommand commands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */
+ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
+ { "util", "createmultisig", &createmultisig, true },
+ { "util", "verifymessage", &verifymessage, true },
+
+ /* Not shown in help */
+ { "hidden", "setmocktime", &setmocktime, true },
+};
+
+void RegisterMiscRPCCommands(CRPCTable &tableRPC)
+{
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+}
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 065214a98a..017cd6ca32 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -626,3 +626,25 @@ UniValue clearbanned(const UniValue& params, bool fHelp)
return NullUniValue;
}
+
+static const CRPCCommand commands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ { "network", "getconnectioncount", &getconnectioncount, true },
+ { "network", "ping", &ping, true },
+ { "network", "getpeerinfo", &getpeerinfo, true },
+ { "network", "addnode", &addnode, true },
+ { "network", "disconnectnode", &disconnectnode, true },
+ { "network", "getaddednodeinfo", &getaddednodeinfo, true },
+ { "network", "getnettotals", &getnettotals, true },
+ { "network", "getnetworkinfo", &getnetworkinfo, true },
+ { "network", "setban", &setban, true },
+ { "network", "listbanned", &listbanned, true },
+ { "network", "clearbanned", &clearbanned, true },
+};
+
+void RegisterNetRPCCommands(CRPCTable &tableRPC)
+{
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+}
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 34dd3b30f5..de8cd68f66 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -841,3 +841,23 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
return hashTx.GetHex();
}
+
+static const CRPCCommand commands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
+ { "rawtransactions", "decodescript", &decodescript, true },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
+
+ { "blockchain", "gettxoutproof", &gettxoutproof, true },
+ { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
+};
+
+void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
+{
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+}
diff --git a/src/rpc/register.h b/src/rpc/register.h
new file mode 100644
index 0000000000..01aa58a25d
--- /dev/null
+++ b/src/rpc/register.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef BITCOIN_RPCREGISTER_H
+#define BITCOIN_RPCREGISTER_H
+
+/** These are in one header file to avoid creating tons of single-function
+ * headers for everything under src/rpc/ */
+class CRPCTable;
+
+/** Register block chain RPC commands */
+void RegisterBlockchainRPCCommands(CRPCTable &tableRPC);
+/** Register P2P networking RPC commands */
+void RegisterNetRPCCommands(CRPCTable &tableRPC);
+/** Register miscellaneous RPC commands */
+void RegisterMiscRPCCommands(CRPCTable &tableRPC);
+/** Register mining RPC commands */
+void RegisterMiningRPCCommands(CRPCTable &tableRPC);
+/** Register raw transaction RPC commands */
+void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
+
+static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC)
+{
+ RegisterBlockchainRPCCommands(tableRPC);
+ RegisterNetRPCCommands(tableRPC);
+ RegisterMiscRPCCommands(tableRPC);
+ RegisterMiningRPCCommands(tableRPC);
+ RegisterRawTransactionRPCCommands(tableRPC);
+}
+
+#endif
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 1303a3bb13..8326fe14d2 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -256,72 +256,8 @@ static const CRPCCommand vRPCCommands[] =
{ // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ----------
/* Overall control/query calls */
- { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */
{ "control", "help", &help, true },
{ "control", "stop", &stop, true },
-
- /* P2P networking */
- { "network", "getnetworkinfo", &getnetworkinfo, true },
- { "network", "addnode", &addnode, true },
- { "network", "disconnectnode", &disconnectnode, true },
- { "network", "getaddednodeinfo", &getaddednodeinfo, true },
- { "network", "getconnectioncount", &getconnectioncount, true },
- { "network", "getnettotals", &getnettotals, true },
- { "network", "getpeerinfo", &getpeerinfo, true },
- { "network", "ping", &ping, true },
- { "network", "setban", &setban, true },
- { "network", "listbanned", &listbanned, true },
- { "network", "clearbanned", &clearbanned, true },
-
- /* Block chain and UTXO */
- { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
- { "blockchain", "getbestblockhash", &getbestblockhash, true },
- { "blockchain", "getblockcount", &getblockcount, true },
- { "blockchain", "getblock", &getblock, true },
- { "blockchain", "getblockhash", &getblockhash, true },
- { "blockchain", "getblockheader", &getblockheader, true },
- { "blockchain", "getchaintips", &getchaintips, true },
- { "blockchain", "getdifficulty", &getdifficulty, true },
- { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
- { "blockchain", "getrawmempool", &getrawmempool, true },
- { "blockchain", "gettxout", &gettxout, true },
- { "blockchain", "gettxoutproof", &gettxoutproof, true },
- { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
- { "blockchain", "verifychain", &verifychain, true },
-
- /* Mining */
- { "mining", "getblocktemplate", &getblocktemplate, true },
- { "mining", "getmininginfo", &getmininginfo, true },
- { "mining", "getnetworkhashps", &getnetworkhashps, true },
- { "mining", "prioritisetransaction", &prioritisetransaction, true },
- { "mining", "submitblock", &submitblock, true },
-
- /* Coin generation */
- { "generating", "generate", &generate, true },
- { "generating", "generatetoaddress", &generatetoaddress, true },
-
- /* Raw transactions */
- { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
- { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
- { "rawtransactions", "decodescript", &decodescript, true },
- { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
- { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
- { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
-
- /* Utility functions */
- { "util", "createmultisig", &createmultisig, true },
- { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
- { "util", "verifymessage", &verifymessage, true },
- { "util", "estimatefee", &estimatefee, true },
- { "util", "estimatepriority", &estimatepriority, true },
- { "util", "estimatesmartfee", &estimatesmartfee, true },
- { "util", "estimatesmartpriority", &estimatesmartpriority, true },
-
- /* Not shown in help */
- { "hidden", "invalidateblock", &invalidateblock, true },
- { "hidden", "reconsiderblock", &reconsiderblock, true },
- { "hidden", "setmocktime", &setmocktime, true },
};
CRPCTable::CRPCTable()
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 35e114feef..a7ed710ce6 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -181,65 +181,6 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri
extern void EnsureWalletIsUnlocked();
-extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpc/net.cpp
-extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
-extern UniValue ping(const UniValue& params, bool fHelp);
-extern UniValue addnode(const UniValue& params, bool fHelp);
-extern UniValue disconnectnode(const UniValue& params, bool fHelp);
-extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp);
-extern UniValue getnettotals(const UniValue& params, bool fHelp);
-extern UniValue setban(const UniValue& params, bool fHelp);
-extern UniValue listbanned(const UniValue& params, bool fHelp);
-extern UniValue clearbanned(const UniValue& params, bool fHelp);
-
-extern UniValue generate(const UniValue& params, bool fHelp);
-extern UniValue generatetoaddress(const UniValue& params, bool fHelp);
-extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
-extern UniValue getmininginfo(const UniValue& params, bool fHelp);
-extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);
-extern UniValue getblocktemplate(const UniValue& params, bool fHelp);
-extern UniValue submitblock(const UniValue& params, bool fHelp);
-extern UniValue estimatefee(const UniValue& params, bool fHelp);
-extern UniValue estimatepriority(const UniValue& params, bool fHelp);
-extern UniValue estimatesmartfee(const UniValue& params, bool fHelp);
-extern UniValue estimatesmartpriority(const UniValue& params, bool fHelp);
-
-extern UniValue verifymessage(const UniValue& params, bool fHelp);
-extern UniValue createmultisig(const UniValue& params, bool fHelp);
-extern UniValue validateaddress(const UniValue& params, bool fHelp);
-extern UniValue getinfo(const UniValue& params, bool fHelp);
-extern UniValue getblockchaininfo(const UniValue& params, bool fHelp);
-extern UniValue getnetworkinfo(const UniValue& params, bool fHelp);
-extern UniValue setmocktime(const UniValue& params, bool fHelp);
-
-extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rpc/rawtransaction.cpp
-extern UniValue listunspent(const UniValue& params, bool fHelp);
-extern UniValue lockunspent(const UniValue& params, bool fHelp);
-extern UniValue listlockunspent(const UniValue& params, bool fHelp);
-extern UniValue createrawtransaction(const UniValue& params, bool fHelp);
-extern UniValue decoderawtransaction(const UniValue& params, bool fHelp);
-extern UniValue decodescript(const UniValue& params, bool fHelp);
-extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
-extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
-extern UniValue gettxoutproof(const UniValue& params, bool fHelp);
-extern UniValue verifytxoutproof(const UniValue& params, bool fHelp);
-
-extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpc/blockchain.cpp
-extern UniValue getbestblockhash(const UniValue& params, bool fHelp);
-extern UniValue getdifficulty(const UniValue& params, bool fHelp);
-extern UniValue settxfee(const UniValue& params, bool fHelp);
-extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
-extern UniValue getrawmempool(const UniValue& params, bool fHelp);
-extern UniValue getblockhash(const UniValue& params, bool fHelp);
-extern UniValue getblockheader(const UniValue& params, bool fHelp);
-extern UniValue getblock(const UniValue& params, bool fHelp);
-extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
-extern UniValue gettxout(const UniValue& params, bool fHelp);
-extern UniValue verifychain(const UniValue& params, bool fHelp);
-extern UniValue getchaintips(const UniValue& params, bool fHelp);
-extern UniValue invalidateblock(const UniValue& params, bool fHelp);
-extern UniValue reconsiderblock(const UniValue& params, bool fHelp);
-
bool StartRPC();
void InterruptRPC();
void StopRPC();
diff --git a/src/test/bctest.py b/src/test/bctest.py
index 3a8d0ea51b..8105b87ffa 100644
--- a/src/test/bctest.py
+++ b/src/test/bctest.py
@@ -1,7 +1,7 @@
# Copyright 2014 BitPay, Inc.
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
+from __future__ import division,print_function,unicode_literals
import subprocess
import os
import json
diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py
index 20afb16a9e..95dd3e81b4 100755
--- a/src/test/bitcoin-util-test.py
+++ b/src/test/bitcoin-util-test.py
@@ -2,7 +2,7 @@
# Copyright 2014 BitPay, Inc.
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
+from __future__ import division,print_function,unicode_literals
import os
import bctest
import buildenv
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index d6309ca384..bbda6a48f4 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -11,6 +11,7 @@
#include "test/test_bitcoin.h"
#include <boost/algorithm/string.hpp>
+#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
#include <univalue.h>
@@ -36,7 +37,7 @@ UniValue CallRPC(string args)
string strMethod = vArgs[0];
vArgs.erase(vArgs.begin());
UniValue params = RPCConvertValues(strMethod, vArgs);
-
+ BOOST_CHECK(tableRPC[strMethod]);
rpcfn_type method = tableRPC[strMethod]->actor;
try {
UniValue result = (*method)(params, false);
@@ -308,4 +309,27 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128");
}
+BOOST_AUTO_TEST_CASE(rpc_convert_values_generatetoaddress)
+{
+ UniValue result;
+
+ BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a")));
+ BOOST_CHECK_EQUAL(result[0].get_int(), 101);
+ BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a");
+
+ BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU")));
+ BOOST_CHECK_EQUAL(result[0].get_int(), 101);
+ BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU");
+
+ BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a")("9")));
+ BOOST_CHECK_EQUAL(result[0].get_int(), 1);
+ BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a");
+ BOOST_CHECK_EQUAL(result[2].get_int(), 9);
+
+ BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU")("9")));
+ BOOST_CHECK_EQUAL(result[0].get_int(), 1);
+ BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU");
+ BOOST_CHECK_EQUAL(result[2].get_int(), 9);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index dadc8b948f..97b9996252 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -17,6 +17,8 @@
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
+#include "rpc/server.h"
+#include "rpc/register.h"
#ifdef ENABLE_WALLET
#include "wallet/db.h"
#include "wallet/wallet.h"
@@ -29,7 +31,6 @@
#include <boost/thread.hpp>
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
-CWallet* pwalletMain;
extern bool fPrintToConsole;
extern void noui_connect();
@@ -53,9 +54,12 @@ BasicTestingSetup::~BasicTestingSetup()
TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
const CChainParams& chainparams = Params();
+ // Ideally we'd move all the RPC tests to the functional testing framework
+ // instead of unit tests, but for now we need these here.
+ RegisterAllCoreRPCCommands(tableRPC);
#ifdef ENABLE_WALLET
bitdb.MakeMock();
- walletRegisterRPCCommands();
+ RegisterWalletRPCCommands(tableRPC);
#endif
ClearDatadirCache();
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
diff --git a/src/timedata.cpp b/src/timedata.cpp
index 4d2f8d1e3b..b6bcf86fbf 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -83,7 +83,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
int64_t nMedian = vTimeOffsets.median();
std::vector<int64_t> vSorted = vTimeOffsets.sorted();
// Only let other nodes change our time by so much
- if (abs64(nMedian) < 70 * 60)
+ if (abs64(nMedian) <= std::max<int64_t>(0, GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT)))
{
nTimeOffset = nMedian;
}
diff --git a/src/timedata.h b/src/timedata.h
index 2296baf11b..9f2499c85c 100644
--- a/src/timedata.h
+++ b/src/timedata.h
@@ -10,6 +10,8 @@
#include <stdint.h>
#include <vector>
+static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 70 * 60;
+
class CNetAddr;
/**
diff --git a/src/versionbits.cpp b/src/versionbits.cpp
index fbb60c0fc5..78feb8ab0c 100644
--- a/src/versionbits.cpp
+++ b/src/versionbits.cpp
@@ -25,7 +25,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
break;
}
if (pindexPrev->GetMedianTimePast() < nTimeStart) {
- // Optimizaton: don't recompute down further, as we know every earlier block will be before the start time
+ // Optimization: don't recompute down further, as we know every earlier block will be before the start time
cache[pindexPrev] = THRESHOLD_DEFINED;
break;
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index a1733bae77..61c9846e11 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2509,7 +2509,7 @@ extern UniValue importwallet(const UniValue& params, bool fHelp);
extern UniValue importprunedfunds(const UniValue& params, bool fHelp);
extern UniValue removeprunedfunds(const UniValue& params, bool fHelp);
-const CRPCCommand vWalletRPCCommands[] =
+static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ----------
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false },
@@ -2559,14 +2559,8 @@ const CRPCCommand vWalletRPCCommands[] =
{ "wallet", "removeprunedfunds", &removeprunedfunds, true },
};
-void walletRegisterRPCCommands()
+void RegisterWalletRPCCommands(CRPCTable &tableRPC)
{
- unsigned int vcidx;
- for (vcidx = 0; vcidx < ARRAYLEN(vWalletRPCCommands); vcidx++)
- {
- const CRPCCommand *pcmd;
-
- pcmd = &vWalletRPCCommands[vcidx];
- tableRPC.appendCommand(pcmd->name, pcmd);
- }
+ for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+ tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
}
diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h
index 42e8021afa..a5de7e2de1 100644
--- a/src/wallet/rpcwallet.h
+++ b/src/wallet/rpcwallet.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_WALLET_RPCWALLET_H
#define BITCOIN_WALLET_RPCWALLET_H
-void walletRegisterRPCCommands();
+class CRPCTable;
+
+void RegisterWalletRPCCommands(CRPCTable &tableRPC);
#endif //BITCOIN_WALLET_RPCWALLET_H
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 1ea8d2ffe7..e8c9466710 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -33,6 +33,7 @@
using namespace std;
+CWallet* pwalletMain = NULL;
/** Transaction fee set by the user */
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
@@ -364,8 +365,33 @@ void CWallet::Flush(bool shutdown)
bitdb.Flush(shutdown);
}
-bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
+bool static UIError(const std::string &str)
{
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
+ return false;
+}
+
+void static UIWarning(const std::string &str)
+{
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
+}
+
+static std::string AmountErrMsg(const char * const optname, const std::string& strValue)
+{
+ return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue);
+}
+
+bool CWallet::Verify()
+{
+ std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
+
+ LogPrintf("Using wallet %s\n", walletFile);
+ uiInterface.InitMessage(_("Verifying wallet..."));
+
+ // Wallet file must be a plain filename without a directory
+ if (walletFile != boost::filesystem::basename(walletFile) + boost::filesystem::extension(walletFile))
+ return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string()));
+
if (!bitdb.Open(GetDataDir()))
{
// try moving the database env out of the way
@@ -381,9 +407,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
// try again
if (!bitdb.Open(GetDataDir())) {
// if it still fails, it probably means we can't even create the database env
- string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
- errorString += msg;
- return true;
+ return UIError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()));
}
}
@@ -399,14 +423,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
if (r == CDBEnv::RECOVER_OK)
{
- warningString += strprintf(_("Warning: Wallet file corrupt, data salvaged!"
+ UIWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if"
" your balance or transactions are incorrect you should"
" restore from a backup."),
- walletFile, "wallet.{timestamp}.bak", GetDataDir());
+ walletFile, "wallet.{timestamp}.bak", GetDataDir()));
}
if (r == CDBEnv::RECOVER_FAIL)
- errorString += strprintf(_("%s corrupt, salvage failed"), walletFile);
+ return UIError(strprintf(_("%s corrupt, salvage failed"), walletFile));
}
return true;
@@ -3018,20 +3042,20 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
return strUsage;
}
-CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString)
+bool CWallet::InitLoadWallet()
{
+ std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT);
+
// needed to restore wallet transaction meta data after -zapwallettxes
std::vector<CWalletTx> vWtx;
if (GetBoolArg("-zapwallettxes", false)) {
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
- CWallet *tempWallet = new CWallet(strWalletFile);
+ CWallet *tempWallet = new CWallet(walletFile);
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
if (nZapWalletRet != DB_LOAD_OK) {
- errorString = strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile);
- uiInterface.InitMessage(strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile));
- return NULL;
+ return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
}
delete tempWallet;
@@ -3042,32 +3066,27 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
int64_t nStart = GetTimeMillis();
bool fFirstRun = true;
- CWallet *walletInstance = new CWallet(strWalletFile);
+ CWallet *walletInstance = new CWallet(walletFile);
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK)
{
if (nLoadWalletRet == DB_CORRUPT)
- errorString += strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile) + "\n";
+ return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
{
- warningString += strprintf(_("Error reading %s! All keys read correctly, but transaction data"
+ UIWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect."),
- strWalletFile);
+ walletFile));
}
else if (nLoadWalletRet == DB_TOO_NEW)
- errorString += strprintf(_("Error loading %s: Wallet requires newer version of %s"),
- strWalletFile, _(PACKAGE_NAME)) +
- "\n";
+ return UIError(strprintf(_("Error loading %s: Wallet requires newer version of %s"),
+ walletFile, _(PACKAGE_NAME)));
else if (nLoadWalletRet == DB_NEED_REWRITE)
{
- errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n";
- LogPrintf("%s", errorString);
+ return UIError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
}
else
- errorString += strprintf(_("Error loading %s"), strWalletFile) + "\n";
-
- if (!errorString.empty())
- return NULL;
+ return UIError(strprintf(_("Error loading %s"), walletFile));
}
if (GetBoolArg("-upgradewallet", fFirstRun))
@@ -3083,8 +3102,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
if (nMaxVersion < walletInstance->GetVersion())
{
- errorString += _("Cannot downgrade wallet") + "\n";
- return NULL;
+ return UIError(_("Cannot downgrade wallet"));
}
walletInstance->SetMaxVersion(nMaxVersion);
}
@@ -3098,10 +3116,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
if (walletInstance->GetKeyFromPool(newDefaultKey)) {
walletInstance->SetDefaultKey(newDefaultKey);
if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive"))
- {
- errorString += _("Cannot write default address") += "\n";
- return NULL;
- }
+ return UIError(_("Cannot write default address") += "\n");
}
walletInstance->SetBestChain(chainActive.GetLocator());
@@ -3116,7 +3131,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
pindexRescan = chainActive.Genesis();
else
{
- CWalletDB walletdb(strWalletFile);
+ CWalletDB walletdb(walletFile);
CBlockLocator locator;
if (walletdb.ReadBestBlock(locator))
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
@@ -3135,10 +3150,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
block = block->pprev;
if (pindexRescan != block)
- {
- errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
- return NULL;
- }
+ return UIError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
}
uiInterface.InitMessage(_("Rescanning..."));
@@ -3152,7 +3164,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
// Restore wallet transaction metadata after -zapwallettxes=1
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
{
- CWalletDB walletdb(strWalletFile);
+ CWalletDB walletdb(walletFile);
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
{
@@ -3176,7 +3188,62 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
}
walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
- return walletInstance;
+ pwalletMain = walletInstance;
+ return true;
+}
+
+bool CWallet::ParameterInteraction()
+{
+ if (mapArgs.count("-mintxfee"))
+ {
+ CAmount n = 0;
+ if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
+ CWallet::minTxFee = CFeeRate(n);
+ else
+ return UIError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"]));
+ }
+ if (mapArgs.count("-fallbackfee"))
+ {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK))
+ return UIError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"]));
+ if (nFeePerK > HIGH_TX_FEE_PER_KB)
+ UIWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available."));
+ CWallet::fallbackFee = CFeeRate(nFeePerK);
+ }
+ if (mapArgs.count("-paytxfee"))
+ {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
+ return UIError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"]));
+ if (nFeePerK > HIGH_TX_FEE_PER_KB)
+ UIWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
+ payTxFee = CFeeRate(nFeePerK, 1000);
+ if (payTxFee < ::minRelayTxFee)
+ {
+ return UIError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
+ mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
+ }
+ }
+ if (mapArgs.count("-maxtxfee"))
+ {
+ CAmount nMaxFee = 0;
+ if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
+ return UIError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"]));
+ if (nMaxFee > HIGH_MAX_TX_FEE)
+ UIWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
+ maxTxFee = nMaxFee;
+ if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
+ {
+ return UIError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
+ mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
+ }
+ }
+ nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
+ bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
+ fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS);
+
+ return true;
}
CKeyPool::CKeyPool()
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 5db36f52d1..867f33a7b5 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -28,6 +28,8 @@
#include <boost/shared_ptr.hpp>
+extern CWallet* pwalletMain;
+
/**
* Settings
*/
@@ -841,7 +843,7 @@ public:
void Flush(bool shutdown=false);
//! Verify the wallet database and perform salvage if required
- static bool Verify(const std::string& walletFile, std::string& warningString, std::string& errorString);
+ static bool Verify();
/**
* Address book entry changed.
@@ -876,8 +878,11 @@ public:
/* Returns the wallets help message */
static std::string GetWalletHelpString(bool showDebug);
- /* initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
- static CWallet* InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString);
+ /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
+ static bool InitLoadWallet();
+
+ /* Wallets parameter interaction */
+ static bool ParameterInteraction();
};
/** A key allocated from the key pool. */