Auto merge of #1490 - str4d:1454-deprecate-accounts, r=bitcartel

Throw an RPC error for all accounts except the default

Closes #1454
This commit is contained in:
zkbot 2016-10-10 23:55:02 -04:00
commit 7dc49cbc6a
7 changed files with 66 additions and 70 deletions

View File

@ -64,8 +64,8 @@ class ListTransactionsTest(BitcoinTestFramework):
# sendmany from node1: twice to self, twice to node2:
send_to = { self.nodes[0].getnewaddress() : 0.11,
self.nodes[1].getnewaddress() : 0.22,
self.nodes[0].getaccountaddress("from1") : 0.33,
self.nodes[1].getaccountaddress("toself") : 0.44 }
self.nodes[0].getaccountaddress("") : 0.33,
self.nodes[1].getaccountaddress("") : 0.44 }
txid = self.nodes[1].sendmany("", send_to)
self.sync_all()
check_array_result(self.nodes[1].listtransactions(),
@ -85,13 +85,13 @@ class ListTransactionsTest(BitcoinTestFramework):
{"txid":txid} )
check_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.33")},
{"txid":txid, "account" : "from1"} )
{"txid":txid, "account" : ""} )
check_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.44")},
{"txid":txid, "account" : ""} )
check_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.44")},
{"txid":txid, "account" : "toself"} )
{"txid":txid, "account" : ""} )
if __name__ == '__main__':
ListTransactionsTest().main()

View File

@ -30,19 +30,14 @@ class TxnMallTest(BitcoinTestFramework):
for i in range(4):
assert_equal(self.nodes[i].getbalance(), starting_balance)
self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
# Assign coins to foo and bar accounts:
self.nodes[0].move("", "foo", (starting_balance - (mining_reward - 5)))
self.nodes[0].move("", "bar", (mining_reward - 5))
assert_equal(self.nodes[0].getbalance(""), 0)
# Coins are sent to node1_address
node1_address = self.nodes[1].getnewaddress("from0")
node1_address = self.nodes[1].getnewaddress("")
# First: use raw transaction API to send (starting_balance - (mining_reward - 2)) BTC to node1_address,
# but don't broadcast:
(total_in, inputs) = gather_inputs(self.nodes[0], (starting_balance - (mining_reward - 2)))
change_address = self.nodes[0].getnewaddress("foo")
change_address = self.nodes[0].getnewaddress("")
outputs = {}
outputs[change_address] = (mining_reward - 2)
outputs[node1_address] = (starting_balance - (mining_reward - 2))
@ -53,9 +48,9 @@ class TxnMallTest(BitcoinTestFramework):
# Create two transaction from node[0] to node[1]; the
# second must spend change from the first because the first
# spends all mature inputs:
txid1 = self.nodes[0].sendfrom("foo", node1_address, (starting_balance - (mining_reward - 2)), 0)
txid2 = self.nodes[0].sendfrom("bar", node1_address, 5, 0)
txid1 = self.nodes[0].sendfrom("", node1_address, (starting_balance - (mining_reward - 2)), 0)
txid2 = self.nodes[0].sendfrom("", node1_address, 5, 0)
# Have node0 mine a block:
if (self.options.mine_block):
self.nodes[0].generate(1)
@ -72,19 +67,15 @@ class TxnMallTest(BitcoinTestFramework):
expected += tx2["amount"] + tx2["fee"]
assert_equal(self.nodes[0].getbalance(), expected)
# foo and bar accounts should be debited:
assert_equal(self.nodes[0].getbalance("foo"), (starting_balance - (mining_reward - 5))+tx1["amount"]+tx1["fee"])
assert_equal(self.nodes[0].getbalance("bar"), (mining_reward - 5)+tx2["amount"]+tx2["fee"])
if self.options.mine_block:
assert_equal(tx1["confirmations"], 1)
assert_equal(tx2["confirmations"], 1)
# Node1's "from0" balance should be both transaction amounts:
assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"]))
# Node1's total balance should be its starting balance plus both transaction amounts:
assert_equal(self.nodes[1].getbalance(""), starting_balance - (tx1["amount"]+tx2["amount"]))
else:
assert_equal(tx1["confirmations"], 0)
assert_equal(tx2["confirmations"], 0)
# Now give doublespend to miner:
mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"])
# ... mine a block...
@ -98,23 +89,19 @@ class TxnMallTest(BitcoinTestFramework):
# Re-fetch transaction info:
tx1 = self.nodes[0].gettransaction(txid1)
tx2 = self.nodes[0].gettransaction(txid2)
# Both transactions should be conflicted
assert_equal(tx1["confirmations"], -1)
assert_equal(tx2["confirmations"], -1)
# Node0's total balance should be starting balance, plus 100BTC for
# Node0's total balance should be starting balance, plus (mining_reward * 2) for
# two more matured blocks, minus (starting_balance - (mining_reward - 2)) for the double-spend:
expected = starting_balance + (mining_reward * 2) - (starting_balance - (mining_reward - 2))
assert_equal(self.nodes[0].getbalance(), expected)
assert_equal(self.nodes[0].getbalance("*"), expected)
# foo account should be debited, but bar account should not:
assert_equal(self.nodes[0].getbalance("foo"), (starting_balance - (mining_reward - 5))-(starting_balance - (mining_reward - 2)))
assert_equal(self.nodes[0].getbalance("bar"), (mining_reward - 5))
# Node1's "from" account balance should be just the mutated send:
assert_equal(self.nodes[1].getbalance("from0"), (starting_balance - (mining_reward - 2)))
# Node1's total balance should be its starting balance plus the amount of the mutated send:
assert_equal(self.nodes[1].getbalance(""), starting_balance + (starting_balance - (mining_reward - 2)))
if __name__ == '__main__':
TxnMallTest().main()

View File

@ -77,7 +77,7 @@ class WalletTest (BitcoinTestFramework):
inputs = []
outputs = {}
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"]
outputs[self.nodes[2].getnewaddress("")] = utxo["amount"]
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx))
@ -92,12 +92,11 @@ class WalletTest (BitcoinTestFramework):
assert_equal(self.nodes[0].getbalance(), 0)
assert_equal(self.nodes[2].getbalance(), 50)
assert_equal(self.nodes[2].getbalance("from1"), 50-21)
assert_equal(self.nodes[0].getbalance("*"), 0)
assert_equal(self.nodes[2].getbalance("*"), 50)
# Send 10 BTC normal
address = self.nodes[0].getnewaddress("test")
address = self.nodes[0].getnewaddress("")
self.nodes[2].settxfee(Decimal('0.001'))
txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
self.nodes[2].generate(1)
@ -117,7 +116,7 @@ class WalletTest (BitcoinTestFramework):
assert_equal(self.nodes[0].getbalance("*"), Decimal('19.99900000'))
# Sendmany 10 BTC
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
txid = self.nodes[2].sendmany("", {address: 10}, 0, "", [])
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('19.99800000'))
@ -126,7 +125,7 @@ class WalletTest (BitcoinTestFramework):
assert_equal(self.nodes[0].getbalance("*"), Decimal('29.99900000'))
# Sendmany 10 BTC with subtract fee from amount
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
txid = self.nodes[2].sendmany("", {address: 10}, 0, "", [address])
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), Decimal('9.99800000'))
@ -151,7 +150,7 @@ class WalletTest (BitcoinTestFramework):
sync_mempools(self.nodes)
assert(txid1 in self.nodes[3].getrawmempool())
#check if we can list zero value tx as available coins
#1. create rawtx
#2. hex-changed one output to 0.0
@ -160,18 +159,18 @@ class WalletTest (BitcoinTestFramework):
usp = self.nodes[1].listunspent()
inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
outputs = {self.nodes[1].getnewaddress(): 9.998, self.nodes[0].getnewaddress(): 11.11}
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
decRawTx = self.nodes[1].decoderawtransaction(rawTx)
signedRawTx = self.nodes[1].signrawtransaction(rawTx)
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
zeroValueTxid= decRawTx['txid']
sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex'])
self.sync_all()
self.nodes[1].generate(1) #mine a block
self.sync_all()
unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
found = False
for uTx in unspentTxs:
@ -179,7 +178,7 @@ class WalletTest (BitcoinTestFramework):
found = True
assert_equal(uTx['amount'], Decimal('0.00000000'));
assert(found)
#do some -walletbroadcast tests
stop_nodes(self.nodes)
wait_bitcoinds()
@ -203,10 +202,10 @@ class WalletTest (BitcoinTestFramework):
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
assert_equal(self.nodes[2].getbalance(), Decimal('11.99800000')); #should not be
assert_equal(self.nodes[2].getbalance("*"), Decimal('11.99800000')); #should not be
#create another tx
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2);
#restart the nodes with -walletbroadcast=1
stop_nodes(self.nodes)
wait_bitcoinds()
@ -215,10 +214,10 @@ class WalletTest (BitcoinTestFramework):
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
sync_blocks(self.nodes)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
#tx should be added to balance because after restarting the nodes tx should be broadcastet
assert_equal(self.nodes[2].getbalance(), Decimal('13.99800000')); #should not be
assert_equal(self.nodes[2].getbalance("*"), Decimal('13.99800000')); #should not be

View File

@ -69,7 +69,7 @@ enum RPCErrorCode
//! Wallet errors
RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.)
RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account
RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name
RPC_WALLET_ACCOUNTS_UNSUPPORTED = -11, //! Accounts are unsupported
RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first
RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first
RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect

View File

@ -34,6 +34,12 @@ Value CallRPC(string args)
boost::split(vArgs, args, boost::is_any_of(" \t"));
string strMethod = vArgs[0];
vArgs.erase(vArgs.begin());
// Handle empty strings the same way as CLI
for (auto i = 0; i < vArgs.size(); i++) {
if (vArgs[i] == "\"\"") {
vArgs[i] = "";
}
}
Array params = RPCConvertValues(strMethod, vArgs);
rpcfn_type method = tableRPC[strMethod]->actor;

View File

@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
CPubKey demoPubkey = pwalletMain->GenerateNewKey();
CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
Value retValue;
string strAccount = "walletDemoAccount";
string strAccount = "";
string strPurpose = "receive";
BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
CWalletDB walletdb(pwalletMain->strWalletFile);
@ -109,7 +109,9 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
/*********************************
* setaccount
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"));
BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " \"\""));
/* Accounts are disabled */
BOOST_CHECK_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"), runtime_error);
/* t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1GpgV is not owned by the test wallet. */
BOOST_CHECK_THROW(CallRPC("setaccount t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1GpgV nullaccount"), runtime_error);
BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
@ -121,7 +123,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
* getbalance
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString()));
BOOST_CHECK_THROW(CallRPC("getbalance " + demoAddress.ToString()), runtime_error);
/*********************************
* listunspent
@ -192,13 +194,16 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
* getnewaddress
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("getnewaddress"));
BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount"));
BOOST_CHECK_NO_THROW(CallRPC("getnewaddress \"\""));
/* Accounts are deprecated */
BOOST_CHECK_THROW(CallRPC("getnewaddress getnewaddress_demoaccount"), runtime_error);
/*********************************
* getaccountaddress
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\""));
BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account
/* Accounts are deprecated */
BOOST_CHECK_THROW(CallRPC("getaccountaddress accountThatDoesntExists"), runtime_error);
BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount));
BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get());
@ -234,8 +239,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error);
BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount));
Array arr = retValue.get_array();
BOOST_CHECK(arr.size() > 0);
BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
BOOST_CHECK_EQUAL(4, arr.size());
bool notFound = true;
for (auto a : arr) {
notFound &= CBitcoinAddress(a.get_str()).Get() != demoAddress.Get();
}
BOOST_CHECK(!notFound);
/*
* getblocksubsidy

View File

@ -101,8 +101,8 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
string AccountFromValue(const Value& value)
{
string strAccount = value.get_str();
if (strAccount == "*")
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
if (strAccount != "")
throw JSONRPCError(RPC_WALLET_ACCOUNTS_UNSUPPORTED, "Accounts are unsupported");
return strAccount;
}
@ -115,10 +115,8 @@ Value getnewaddress(const Array& params, bool fHelp)
throw runtime_error(
"getnewaddress ( \"account\" )\n"
"\nReturns a new Bitcoin address for receiving payments.\n"
"If 'account' is specified (DEPRECATED), it is added to the address book \n"
"so payments received with the address will be credited to 'account'.\n"
"\nArguments:\n"
"1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
"1. \"account\" (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) The new bitcoin address\n"
"\nExamples:\n"
@ -195,7 +193,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
"getaccountaddress \"account\"\n"
"\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) The account bitcoin address\n"
"\nExamples:\n"
@ -263,7 +261,7 @@ Value setaccount(const Array& params, bool fHelp)
"\nDEPRECATED. Sets the account associated with the given address.\n"
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n"
"2. \"account\" (string, required) The account to assign the address to.\n"
"2. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nExamples:\n"
+ HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"")
+ HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
@ -340,7 +338,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
"getaddressesbyaccount \"account\"\n"
"\nDEPRECATED. Returns the list of addresses for the given account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name.\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"[ (json array of string)\n"
" \"bitcoinaddress\" (string) a bitcoin address associated with the given account\n"
@ -629,7 +627,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
"getreceivedbyaccount \"account\" ( minconf )\n"
"\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n"
"amount (numeric) The total amount in btc received for this account.\n"
@ -716,12 +714,9 @@ Value getbalance(const Array& params, bool fHelp)
if (fHelp || params.size() > 3)
throw runtime_error(
"getbalance ( \"account\" minconf includeWatchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n"
"If account is specified (DEPRECATED), returns the balance in the account.\n"
"Note that the account \"\" is not the same as leaving the parameter out.\n"
"The server total may be different to the balance in the default \"\" account.\n"
"\nReturns the server's total available balance.\n"
"\nArguments:\n"
"1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
"1. \"account\" (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" or to the string \"*\", either of which will give the total available balance. Passing any other string will result in an error.\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"
@ -809,8 +804,8 @@ Value movecmd(const Array& params, bool fHelp)
"move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
"\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
"2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"toaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
"\nResult:\n"
@ -881,7 +876,7 @@ Value sendfrom(const Array& params, bool fHelp)
"The amount is a real and is rounded to the nearest 0.00000001."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n"
"3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n"
"4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
@ -943,7 +938,7 @@ Value sendmany(const Array& params, bool fHelp)
"\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"amounts\" (string, required) A json object with addresses and amounts\n"
" {\n"
" \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n"
@ -1060,7 +1055,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
" \"address\" (string) bitcoin address or hex-encoded public key\n"
" ...,\n"
" ]\n"
"3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"3. \"account\" (string, optional) DEPRECATED. If provided, MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n"