aboutsummaryrefslogtreecommitdiff
path: root/src/rpcwallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpcwallet.cpp')
-rw-r--r--src/rpcwallet.cpp187
1 files changed, 132 insertions, 55 deletions
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index a5a7df0867..1e46129065 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -8,6 +8,7 @@
#include "init.h"
#include "net.h"
#include "netbase.h"
+#include "timedata.h"
#include "util.h"
#include "wallet.h"
#include "walletdb.h"
@@ -49,7 +50,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
{
entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
entry.push_back(Pair("blockindex", wtx.nIndex));
- entry.push_back(Pair("blocktime", (boost::int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
+ entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
}
uint256 hash = wtx.GetHash();
entry.push_back(Pair("txid", hash.GetHex()));
@@ -57,8 +58,12 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
conflicts.push_back(conflict.GetHex());
entry.push_back(Pair("walletconflicts", conflicts));
- entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
- entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived));
+ Array respends;
+ BOOST_FOREACH(const uint256& respend, wtx.GetConflicts(false))
+ respends.push_back(respend.GetHex());
+ entry.push_back(Pair("respendsobserved", respends));
+ entry.push_back(Pair("time", wtx.GetTxTime()));
+ entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
entry.push_back(Pair(item.first, item.second));
}
@@ -318,7 +323,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
" to which you're sending the transaction. This is not part of the \n"
" transaction, just kept in your wallet.\n"
"\nResult:\n"
- "\"transactionid\" (string) The transaction id. (view at https://blockchain.info/tx/[transactionid])\n"
+ "\"transactionid\" (string) The transaction id.\n"
"\nExamples:\n"
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
@@ -341,7 +346,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
EnsureWalletIsUnlocked();
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
@@ -552,7 +557,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
}
-int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
+int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter)
{
int64_t nBalance = 0;
@@ -564,7 +569,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
continue;
int64_t nReceived, nSent, nFee;
- wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
+ wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
nBalance += nReceived;
@@ -577,18 +582,18 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
return nBalance;
}
-int64_t GetAccountBalance(const string& strAccount, int nMinDepth)
+int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter)
{
CWalletDB walletdb(pwalletMain->strWalletFile);
- return GetAccountBalance(walletdb, strAccount, nMinDepth);
+ return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
}
Value getbalance(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 2)
+ if (fHelp || params.size() > 3)
throw runtime_error(
- "getbalance ( \"account\" minconf )\n"
+ "getbalance ( \"account\" minconf includeWatchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n"
"If account is specified, returns the balance in the account.\n"
"Note that the account \"\" is not the same as leaving the parameter out.\n"
@@ -596,6 +601,7 @@ Value getbalance(const Array& params, bool fHelp)
"\nArguments:\n"
"1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
+ "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"amount (numeric) The total amount in btc received for this account.\n"
"\nExamples:\n"
@@ -617,6 +623,10 @@ Value getbalance(const Array& params, bool fHelp)
int nMinDepth = 1;
if (params.size() > 1)
nMinDepth = params[1].get_int();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
if (params[0].get_str() == "*") {
// Calculate total balance a different way from GetBalance()
@@ -633,7 +643,7 @@ Value getbalance(const Array& params, bool fHelp)
string strSentAccount;
list<pair<CTxDestination, int64_t> > listReceived;
list<pair<CTxDestination, int64_t> > listSent;
- wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
+ wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
@@ -648,7 +658,7 @@ Value getbalance(const Array& params, bool fHelp)
string strAccount = AccountFromValue(params[0]);
- int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
return ValueFromAmount(nBalance);
}
@@ -747,7 +757,7 @@ Value sendfrom(const Array& params, bool fHelp)
" to which you're sending the transaction. This is not part of the transaction, \n"
" it is just kept in your wallet.\n"
"\nResult:\n"
- "\"transactionid\" (string) The transaction id. (view at https://blockchain.info/tx/[transactionid])\n"
+ "\"transactionid\" (string) The transaction id.\n"
"\nExamples:\n"
"\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n"
+ HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
@@ -776,12 +786,12 @@ Value sendfrom(const Array& params, bool fHelp)
EnsureWalletIsUnlocked();
// Check funds
- int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
// Send
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
@@ -807,7 +817,7 @@ Value sendmany(const Array& params, bool fHelp)
"4. \"comment\" (string, optional) A comment\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
- " the number of addresses. See https://blockchain.info/tx/[transactionid]\n"
+ " the number of addresses.\n"
"\nExamples:\n"
"\nSend two amounts to two different addresses:\n"
+ HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
@@ -853,7 +863,7 @@ Value sendmany(const Array& params, bool fHelp)
EnsureWalletIsUnlocked();
// Check funds
- int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
if (totalAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
@@ -871,7 +881,7 @@ Value sendmany(const Array& params, bool fHelp)
}
// Defined in rpcmisc.cpp
-extern CScript _createmultisig(const Array& params);
+extern CScript _createmultisig_redeemScript(const Array& params);
Value addmultisigaddress(const Array& params, bool fHelp)
{
@@ -908,7 +918,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
strAccount = AccountFromValue(params[2]);
// Construct using pay-to-script-hash:
- CScript inner = _createmultisig(params);
+ CScript inner = _createmultisig_redeemScript(params);
CScriptID innerID = inner.GetID();
pwalletMain->AddCScript(inner);
@@ -922,10 +932,12 @@ struct tallyitem
int64_t nAmount;
int nConf;
vector<uint256> txids;
+ bool fIsWatchonly;
tallyitem()
{
nAmount = 0;
nConf = std::numeric_limits<int>::max();
+ fIsWatchonly = false;
}
};
@@ -941,6 +953,11 @@ Value ListReceived(const Array& params, bool fByAccounts)
if (params.size() > 1)
fIncludeEmpty = params[1].get_bool();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
// Tally
map<CBitcoinAddress, tallyitem> mapTally;
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
@@ -957,13 +974,19 @@ Value ListReceived(const Array& params, bool fByAccounts)
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
CTxDestination address;
- if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
+ if (!ExtractDestination(txout.scriptPubKey, address))
+ continue;
+
+ isminefilter mine = IsMine(*pwalletMain, address);
+ if(!(mine & filter))
continue;
tallyitem& item = mapTally[address];
item.nAmount += txout.nValue;
item.nConf = min(item.nConf, nDepth);
item.txids.push_back(wtx.GetHash());
+ if (mine & ISMINE_WATCH_ONLY)
+ item.fIsWatchonly = true;
}
}
@@ -980,10 +1003,12 @@ Value ListReceived(const Array& params, bool fByAccounts)
int64_t nAmount = 0;
int nConf = std::numeric_limits<int>::max();
+ bool fIsWatchonly = false;
if (it != mapTally.end())
{
nAmount = (*it).second.nAmount;
nConf = (*it).second.nConf;
+ fIsWatchonly = (*it).second.fIsWatchonly;
}
if (fByAccounts)
@@ -991,10 +1016,13 @@ Value ListReceived(const Array& params, bool fByAccounts)
tallyitem& item = mapAccountTally[strAccount];
item.nAmount += nAmount;
item.nConf = min(item.nConf, nConf);
+ item.fIsWatchonly = fIsWatchonly;
}
else
{
Object obj;
+ if(fIsWatchonly)
+ obj.push_back(Pair("involvesWatchonly", true));
obj.push_back(Pair("address", address.ToString()));
obj.push_back(Pair("account", strAccount));
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
@@ -1019,6 +1047,8 @@ Value ListReceived(const Array& params, bool fByAccounts)
int64_t nAmount = (*it).second.nAmount;
int nConf = (*it).second.nConf;
Object obj;
+ if((*it).second.fIsWatchonly)
+ obj.push_back(Pair("involvesWatchonly", true));
obj.push_back(Pair("account", (*it).first));
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
@@ -1031,17 +1061,19 @@ Value ListReceived(const Array& params, bool fByAccounts)
Value listreceivedbyaddress(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 2)
+ if (fHelp || params.size() > 3)
throw runtime_error(
- "listreceivedbyaddress ( minconf includeempty )\n"
+ "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n"
"\nList balances by receiving address.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (numeric, optional, dafault=false) Whether to include addresses that haven't received any payments.\n"
+ "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n"
"[\n"
" {\n"
+ " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
" \"address\" : \"receivingaddress\", (string) The receiving address\n"
" \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n"
" \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
@@ -1053,7 +1085,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
"\nExamples:\n"
+ HelpExampleCli("listreceivedbyaddress", "")
+ HelpExampleCli("listreceivedbyaddress", "6 true")
- + HelpExampleRpc("listreceivedbyaddress", "6, true")
+ + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
);
return ListReceived(params, false);
@@ -1061,17 +1093,19 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
Value listreceivedbyaccount(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 2)
+ if (fHelp || params.size() > 3)
throw runtime_error(
- "listreceivedbyaccount ( minconf includeempty )\n"
+ "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n"
"\nList balances by account.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
+ "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n"
"[\n"
" {\n"
+ " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
" \"account\" : \"accountname\", (string) The account name of the receiving account\n"
" \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
@@ -1082,7 +1116,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
"\nExamples:\n"
+ HelpExampleCli("listreceivedbyaccount", "")
+ HelpExampleCli("listreceivedbyaccount", "6 true")
- + HelpExampleRpc("listreceivedbyaccount", "6, true")
+ + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
);
return ListReceived(params, true);
@@ -1095,16 +1129,17 @@ static void MaybePushAddress(Object & entry, const CTxDestination &dest)
entry.push_back(Pair("address", addr.ToString()));
}
-void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
+void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter)
{
int64_t nFee;
string strSentAccount;
list<pair<CTxDestination, int64_t> > listReceived;
list<pair<CTxDestination, int64_t> > listSent;
- wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
+ wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
bool fAllAccounts = (strAccount == string("*"));
+ bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
// Sent
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
@@ -1112,6 +1147,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
{
Object entry;
+ if(involvesWatchonly || (::IsMine(*pwalletMain, s.first) & ISMINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
entry.push_back(Pair("account", strSentAccount));
MaybePushAddress(entry, s.first);
entry.push_back(Pair("category", "send"));
@@ -1134,6 +1171,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
if (fAllAccounts || (account == strAccount))
{
Object entry;
+ if(involvesWatchonly || (::IsMine(*pwalletMain, r.first) & ISMINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
entry.push_back(Pair("account", account));
MaybePushAddress(entry, r.first);
if (wtx.IsCoinBase())
@@ -1167,7 +1206,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
Object entry;
entry.push_back(Pair("account", acentry.strAccount));
entry.push_back(Pair("category", "move"));
- entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
+ entry.push_back(Pair("time", acentry.nTime));
entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
entry.push_back(Pair("comment", acentry.strComment));
@@ -1177,16 +1216,16 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
Value listtransactions(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 3)
+ if (fHelp || params.size() > 4)
throw runtime_error(
- "listtransactions ( \"account\" count from )\n"
+ "listtransactions ( \"account\" count from includeWatchonly)\n"
"\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
"\nArguments:\n"
"1. \"account\" (string, optional) The account name. If not included, it will list all transactions for all accounts.\n"
" If \"\" is set, it will list transactions for the default account.\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. from (numeric, optional, default=0) The number of transactions to skip\n"
-
+ "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"[\n"
" {\n"
@@ -1209,8 +1248,13 @@ Value listtransactions(const Array& params, bool fHelp)
" category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
" category of transactions.\n"
- " \"txid\": \"transactionid\", (string) The transaction id (see https://blockchain.info/tx/[transactionid]. Available \n"
- " for 'send' and 'receive' category of transactions.\n"
+ " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
+ " \"walletconflicts\" : [\n"
+ " \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
+ " ],\n"
+ " \"respendsobserved\" : [\n"
+ " \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
+ " ],\n"
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
" \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
" for 'send' and 'receive' category of transactions.\n"
@@ -1241,6 +1285,10 @@ Value listtransactions(const Array& params, bool fHelp)
int nFrom = 0;
if (params.size() > 2)
nFrom = params[2].get_int();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 3)
+ if(params[3].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
if (nCount < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
@@ -1257,7 +1305,7 @@ Value listtransactions(const Array& params, bool fHelp)
{
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0)
- ListTransactions(*pwtx, strAccount, 0, true, ret);
+ ListTransactions(*pwtx, strAccount, 0, true, ret, filter);
CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0)
AcentryToJSON(*pacentry, strAccount, ret);
@@ -1285,12 +1333,13 @@ Value listtransactions(const Array& params, bool fHelp)
Value listaccounts(const Array& params, bool fHelp)
{
- if (fHelp || params.size() > 1)
+ if (fHelp || params.size() > 2)
throw runtime_error(
- "listaccounts ( minconf )\n"
+ "listaccounts ( minconf includeWatchonly)\n"
"\nReturns Object that has account names as keys, account balances as values.\n"
"\nArguments:\n"
- "1. minconf (numeric, optional, default=1) Only onclude transactions with at least this many confirmations\n"
+ "1. minconf (numeric, optional, default=1) Only onclude transactions with at least this many confirmations\n"
+ "2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"{ (json object where keys are account names, and values are numeric balances\n"
" \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
@@ -1310,10 +1359,14 @@ Value listaccounts(const Array& params, bool fHelp)
int nMinDepth = 1;
if (params.size() > 0)
nMinDepth = params[0].get_int();
+ isminefilter includeWatchonly = ISMINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
map<string, int64_t> mapAccountBalances;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) {
- if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
+ if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me
mapAccountBalances[entry.second.name] = 0;
}
@@ -1327,7 +1380,7 @@ Value listaccounts(const Array& params, bool fHelp)
int nDepth = wtx.GetDepthInMainChain();
if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
continue;
- wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
+ wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
mapAccountBalances[strSentAccount] -= nFee;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
mapAccountBalances[strSentAccount] -= s.second;
@@ -1357,11 +1410,12 @@ Value listsinceblock(const Array& params, bool fHelp)
{
if (fHelp)
throw runtime_error(
- "listsinceblock ( \"blockhash\" target-confirmations )\n"
+ "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n"
"\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
"\nArguments:\n"
"1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
"2. target-confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
+ "3. includeWatchonly: (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')"
"\nResult:\n"
"{\n"
" \"transactions\": [\n"
@@ -1375,7 +1429,13 @@ Value listsinceblock(const Array& params, bool fHelp)
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
- " \"txid\": \"transactionid\", (string) The transaction id (see https://blockchain.info/tx/[transactionid]. Available for 'send' and 'receive' category of transactions.\n"
+ " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
+ " \"walletconflicts\" : [\n"
+ " \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
+ " ],\n"
+ " \"respendsobserved\" : [\n"
+ " \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
+ " ],\n"
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
" \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
" \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
@@ -1391,6 +1451,7 @@ Value listsinceblock(const Array& params, bool fHelp)
CBlockIndex *pindex = NULL;
int target_confirms = 1;
+ isminefilter filter = ISMINE_SPENDABLE;
if (params.size() > 0)
{
@@ -1410,6 +1471,10 @@ Value listsinceblock(const Array& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
}
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
Array transactions;
@@ -1419,7 +1484,7 @@ Value listsinceblock(const Array& params, bool fHelp)
CWalletTx tx = (*it).second;
if (depth == -1 || tx.GetDepthInMainChain() < depth)
- ListTransactions(tx, "*", 0, true, transactions);
+ ListTransactions(tx, "*", 0, true, transactions, filter);
}
CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
@@ -1434,12 +1499,13 @@ Value listsinceblock(const Array& params, bool fHelp)
Value gettransaction(const Array& params, bool fHelp)
{
- if (fHelp || params.size() != 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"gettransaction \"txid\"\n"
"\nGet detailed information about in-wallet transaction <txid>\n"
"\nArguments:\n"
"1. \"txid\" (string, required) The transaction id\n"
+ "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
"\nResult:\n"
"{\n"
" \"amount\" : x.xxx, (numeric) The transaction amount in btc\n"
@@ -1447,7 +1513,13 @@ Value gettransaction(const Array& params, bool fHelp)
" \"blockhash\" : \"hash\", (string) The block hash\n"
" \"blockindex\" : xx, (numeric) The block index\n"
" \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
- " \"txid\" : \"transactionid\", (string) The transaction id, see also https://blockchain.info/tx/[transactionid]\n"
+ " \"txid\" : \"transactionid\", (string) The transaction id.\n"
+ " \"walletconflicts\" : [\n"
+ " \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
+ " ],\n"
+ " \"respendsobserved\" : [\n"
+ " \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
+ " ],\n"
" \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
" \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
" \"details\" : [\n"
@@ -1470,24 +1542,29 @@ Value gettransaction(const Array& params, bool fHelp)
uint256 hash;
hash.SetHex(params[0].get_str());
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
Object entry;
if (!pwalletMain->mapWallet.count(hash))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
- int64_t nCredit = wtx.GetCredit();
- int64_t nDebit = wtx.GetDebit();
+ int64_t nCredit = wtx.GetCredit(filter);
+ int64_t nDebit = wtx.GetDebit(filter);
int64_t nNet = nCredit - nDebit;
- int64_t nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+ int64_t nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
- if (wtx.IsFromMe())
+ if (wtx.IsFromMe(filter))
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
WalletTxToJSON(wtx, entry);
Array details;
- ListTransactions(wtx, "*", 0, false, details);
+ ListTransactions(wtx, "*", 0, false, details, filter);
entry.push_back(Pair("details", details));
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
@@ -1747,7 +1824,7 @@ Value lockunspent(const Array& params, bool fHelp)
throw runtime_error(
"lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n"
"\nUpdates list of temporarily unspendable outputs.\n"
- "Temporarily lock (lock=true) or unlock (lock=false) specified transaction outputs.\n"
+ "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
"A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
"Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
"is always cleared (by virtue of process exit) when a node stops or fails.\n"
@@ -1884,7 +1961,7 @@ Value settxfee(const Array& params, bool fHelp)
if (params[0].get_real() != 0.0)
nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
- nTransactionFee = nAmount;
+ payTxFee = CFeeRate(nAmount, 1000);
return true;
}
@@ -1912,9 +1989,9 @@ Value getwalletinfo(const Array& params, bool fHelp)
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
- obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
if (pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
+ obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
return obj;
}