diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/rpcdump.cpp | 2 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 5 | ||||
-rw-r--r-- | src/wallet/test/accounting_tests.cpp | 24 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 97 | ||||
-rw-r--r-- | src/wallet/wallet.h | 10 |
5 files changed, 101 insertions, 37 deletions
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 a399f8ad9f..3eb7e5d9ba 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1093,6 +1093,8 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet"); } + pwalletMain->SetAddressBook(w.result, "", "receive"); + return CBitcoinAddress(w.result).ToString(); } @@ -2628,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 a8ef6d9511..43e22383f4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -40,6 +40,7 @@ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; +bool fWalletRbf = DEFAULT_WALLET_RBF; const char * DEFAULT_WALLET_DAT = "wallet.dat"; const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; @@ -400,8 +401,8 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const if (mapTxSpends.count(txin.prevout) <= 1) continue; // No conflict if zero or one spends range = mapTxSpends.equal_range(txin.prevout); - for (TxSpends::const_iterator it = range.first; it != range.second; ++it) - result.insert(it->second); + for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it) + result.insert(_it->second); } return result; } @@ -413,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); @@ -648,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 @@ -676,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; @@ -686,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; @@ -1271,9 +1281,9 @@ int CWalletTx::GetRequestCount() const // How about the block it's in? if (nRequests == 0 && !hashUnset()) { - map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); - if (mi != pwallet->mapRequestCount.end()) - nRequests = (*mi).second; + map<uint256, int>::const_iterator _mi = pwallet->mapRequestCount.find(hashBlock); + if (_mi != pwallet->mapRequestCount.end()) + nRequests = (*_mi).second; else nRequests = 1; // If it's in someone else's block it must have got out } @@ -2362,11 +2372,17 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // Fill vin // - // Note how the sequence number is set to max()-1 so that the - // nLockTime set above actually works. + // Note how the sequence number is set to non-maxint so that + // the nLockTime set above actually works. + // + // BIP125 defines opt-in RBF as any nSequence < maxint-1, so + // we use the highest possible value in that range (maxint-2) + // to avoid conflicting with other possible uses of nSequence, + // and in the spirit of "smallest posible change from prior + // behavior." BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), - std::numeric_limits<unsigned int>::max()-1)); + std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1))); // Sign int nIn = 0; @@ -2494,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) +{ + CWalletDB walletdb(strWalletFile); + + return AddAccountingEntry(acentry, &walletdb); +} + +bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwalletdb) { - if (!pwalletdb.WriteAccountingEntry_Backend(acentry)) + if (!pwalletdb->WriteAccountingEntry_Backend(acentry)) return false; laccentries.push_back(acentry); @@ -2910,17 +2938,17 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings() set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it - BOOST_FOREACH(set<CTxDestination> grouping, groupings) + BOOST_FOREACH(set<CTxDestination> _grouping, groupings) { // make a set of all the groups hit by this new group set< set<CTxDestination>* > hits; map< CTxDestination, set<CTxDestination>* >::iterator it; - BOOST_FOREACH(CTxDestination address, grouping) + BOOST_FOREACH(CTxDestination address, _grouping) if ((it = setmap.find(address)) != setmap.end()) hits.insert((*it).second); // merge all hit groups into a new single group and delete old groups - set<CTxDestination>* merged = new set<CTxDestination>(grouping); + set<CTxDestination>* merged = new set<CTxDestination>(_grouping); BOOST_FOREACH(set<CTxDestination>* hit, hits) { merged->insert(hit->begin(), hit->end()); @@ -3246,6 +3274,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_WALLET_RBF)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); @@ -3267,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 @@ -3438,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) || 0 == 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")) { @@ -3452,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")) @@ -3461,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) { @@ -3486,6 +3542,7 @@ bool CWallet::ParameterInteraction() nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); + fWalletRbf = GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 016e4a3d74..c700e0ca7c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -37,6 +37,7 @@ extern CFeeRate payTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; +extern bool fWalletRbf; static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default @@ -53,10 +54,12 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; +//! -walletrbf default +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; @@ -737,6 +740,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); @@ -771,7 +775,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; |