aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/rpcwallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r--src/wallet/rpcwallet.cpp160
1 files changed, 41 insertions, 119 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 27596929f1..5e6afcd7cb 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -146,38 +146,12 @@ UniValue getnewaddress(const UniValue& params, bool fHelp)
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
{
- CWalletDB walletdb(pwalletMain->strWalletFile);
-
- CAccount account;
- walletdb.ReadAccount(strAccount, account);
-
- if (!bForceNew) {
- if (!account.vchPubKey.IsValid())
- bForceNew = true;
- else {
- // Check if the current key has been used
- CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
- it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
- ++it)
- BOOST_FOREACH(const CTxOut& txout, (*it).second.vout)
- if (txout.scriptPubKey == scriptPubKey) {
- bForceNew = true;
- break;
- }
- }
- }
-
- // Generate a new key
- if (bForceNew) {
- if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
- throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
-
- pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
- walletdb.WriteAccount(strAccount, account);
+ CPubKey pubKey;
+ if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
}
- return CBitcoinAddress(account.vchPubKey.GetID());
+ return CBitcoinAddress(pubKey.GetID());
}
UniValue getaccountaddress(const UniValue& params, bool fHelp)
@@ -673,38 +647,6 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp)
}
-CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter)
-{
- CAmount nBalance = 0;
-
- // Tally wallet transactions
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
- {
- const CWalletTx& wtx = (*it).second;
- if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
- continue;
-
- CAmount nReceived, nSent, nFee;
- wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
-
- if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
- nBalance += nReceived;
- nBalance -= nSent + nFee;
- }
-
- // Tally internal accounting entries
- nBalance += walletdb.GetAccountCreditDebit(strAccount);
-
- return nBalance;
-}
-
-CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter)
-{
- CWalletDB walletdb(pwalletMain->strWalletFile);
- return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
-}
-
-
UniValue getbalance(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
@@ -775,7 +717,7 @@ UniValue getbalance(const UniValue& params, bool fHelp)
string strAccount = AccountFromValue(params[0]);
- CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
+ CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter);
return ValueFromAmount(nBalance);
}
@@ -836,33 +778,7 @@ UniValue movecmd(const UniValue& params, bool fHelp)
if (params.size() > 4)
strComment = params[4].get_str();
- CWalletDB walletdb(pwalletMain->strWalletFile);
- if (!walletdb.TxnBegin())
- throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
-
- int64_t nNow = GetAdjustedTime();
-
- // Debit
- CAccountingEntry debit;
- debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
- debit.strAccount = strFrom;
- debit.nCreditDebit = -nAmount;
- debit.nTime = nNow;
- debit.strOtherAccount = strTo;
- debit.strComment = strComment;
- pwalletMain->AddAccountingEntry(debit, walletdb);
-
- // Credit
- CAccountingEntry credit;
- credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
- credit.strAccount = strTo;
- credit.nCreditDebit = nAmount;
- credit.nTime = nNow;
- credit.strOtherAccount = strFrom;
- credit.strComment = strComment;
- pwalletMain->AddAccountingEntry(credit, walletdb);
-
- if (!walletdb.TxnCommit())
+ if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment))
throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
return true;
@@ -923,7 +839,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
EnsureWalletIsUnlocked();
// Check funds
- CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
@@ -1026,7 +942,7 @@ UniValue sendmany(const UniValue& params, bool fHelp)
EnsureWalletIsUnlocked();
// Check funds
- CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
if (totalAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
@@ -1836,7 +1752,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
string strDest = params[0].get_str();
- if (!BackupWallet(*pwalletMain, strDest))
+ if (!pwalletMain->BackupWallet(strDest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
return NullUniValue;
@@ -2339,13 +2255,14 @@ UniValue listunspent(const UniValue& params, bool fHelp)
"\nResult\n"
"[ (array of json object)\n"
" {\n"
- " \"txid\" : \"txid\", (string) the transaction id \n"
+ " \"txid\" : \"txid\", (string) the transaction id \n"
" \"vout\" : n, (numeric) the vout value\n"
- " \"address\" : \"address\", (string) the bitcoin address\n"
- " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
- " \"scriptPubKey\" : \"key\", (string) the script key\n"
+ " \"address\" : \"address\", (string) the bitcoin address\n"
+ " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
+ " \"scriptPubKey\" : \"key\", (string) the script key\n"
" \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
+ " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
" \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
" \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
" }\n"
@@ -2391,38 +2308,34 @@ UniValue listunspent(const UniValue& params, bool fHelp)
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
continue;
- if (setAddress.size()) {
- CTxDestination address;
- if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
- continue;
+ CTxDestination address;
+ const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey;
+ bool fValidAddress = ExtractDestination(scriptPubKey, address);
- if (!setAddress.count(address))
- continue;
- }
+ if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
+ continue;
- CAmount nValue = out.tx->vout[out.i].nValue;
- const CScript& pk = out.tx->vout[out.i].scriptPubKey;
UniValue entry(UniValue::VOBJ);
entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
entry.push_back(Pair("vout", out.i));
- CTxDestination address;
- if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
+
+ if (fValidAddress) {
entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
+
if (pwalletMain->mapAddressBook.count(address))
entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
- }
- entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end())));
- if (pk.IsPayToScriptHash()) {
- CTxDestination address;
- if (ExtractDestination(pk, address)) {
+
+ if (scriptPubKey.IsPayToScriptHash()) {
const CScriptID& hash = boost::get<CScriptID>(address);
CScript redeemScript;
if (pwalletMain->GetCScript(hash, redeemScript))
entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
}
}
- entry.push_back(Pair("amount",ValueFromAmount(nValue)));
- entry.push_back(Pair("confirmations",out.nDepth));
+
+ entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+ entry.push_back(Pair("amount", ValueFromAmount(out.tx->vout[out.i].nValue)));
+ entry.push_back(Pair("confirmations", out.nDepth));
entry.push_back(Pair("spendable", out.fSpendable));
entry.push_back(Pair("solvable", out.fSolvable));
results.push_back(entry);
@@ -2456,6 +2369,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
+ " \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n"
" }\n"
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
"\nResult:\n"
@@ -2482,6 +2396,8 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
int changePosition = -1;
bool includeWatching = false;
bool lockUnspents = false;
+ CFeeRate feeRate = CFeeRate(0);
+ bool overrideEstimatedFeerate = false;
if (params.size() > 1) {
if (params[1].type() == UniValue::VBOOL) {
@@ -2493,7 +2409,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
UniValue options = params[1];
- RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true);
+ RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true);
if (options.exists("changeAddress")) {
CBitcoinAddress address(options["changeAddress"].get_str());
@@ -2512,6 +2428,12 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
if (options.exists("lockUnspents"))
lockUnspents = options["lockUnspents"].get_bool();
+
+ if (options.exists("feeRate"))
+ {
+ feeRate = CFeeRate(options["feeRate"].get_real());
+ overrideEstimatedFeerate = true;
+ }
}
}
@@ -2527,16 +2449,16 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
CMutableTransaction tx(origTx);
- CAmount nFee;
+ CAmount nFeeOut;
string strFailReason;
- if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
+ if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("hex", EncodeHexTx(tx)));
result.push_back(Pair("changepos", changePosition));
- result.push_back(Pair("fee", ValueFromAmount(nFee)));
+ result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
return result;
}