From d2e961bd946468a4aa289595514a612b7bf7b3bd Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 17 Mar 2016 16:06:08 -0400 Subject: [PATCH] rpc: added getaddressbalance method using addressindex --- qa/rpc-tests/addressindex.py | 12 ++++++ src/rpc/misc.cpp | 84 ++++++++++++++++++++++++++++-------- src/rpcserver.h | 1 + 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/qa/rpc-tests/addressindex.py b/qa/rpc-tests/addressindex.py index 2e15348d6..8f123eaa0 100755 --- a/qa/rpc-tests/addressindex.py +++ b/qa/rpc-tests/addressindex.py @@ -44,6 +44,10 @@ class AddressIndexTest(BitcoinTestFramework): assert_equal(self.nodes[1].getbalance(), 0) assert_equal(self.nodes[2].getbalance(), 0) + # Check that balances are correct + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0['balance'], 0); + # Check p2pkh and p2sh address indexes print "Testing p2pkh and p2sh address index..." @@ -89,6 +93,10 @@ class AddressIndexTest(BitcoinTestFramework): assert_equal(multitxids[4], txid2); assert_equal(multitxids[5], txidb2); + # Check that balances are correct + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0['balance'], 45 * 100000000); + # Check that outputs with the same address will only return one txid print "Testing for txid uniqueness..." addressHash = "6349a418fc4578d10a372b54b45c280cc8c4382f".decode("hex") @@ -109,6 +117,10 @@ class AddressIndexTest(BitcoinTestFramework): assert_equal(len(txidsmany), 4); assert_equal(txidsmany[3], sent_txid); + # Check that balances are correct + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0['balance'], 45 * 100000000 + 21); + print "Passed\n" diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 9ee2e945b..165591b25 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -494,6 +494,7 @@ static const CRPCCommand commands[] = /* Address index */ { "addressindex", "getaddresstxids", &getaddresstxids, false }, /* insight explorer */ + { "addressindex", "getaddressbalance", &getaddressbalance, false }, /* insight explorer */ /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, @@ -505,23 +506,9 @@ void RegisterMiscRPCCommands(CRPCTable &tableRPC) tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); } -UniValue getaddresstxids(const UniValue& params, bool fHelp) +bool getAddressesFromParams(const UniValue& params, std::vector > &addresses) { - if (fHelp || params.size() != 1) - throw runtime_error( - "getaddresstxids\n" - "\nReturns the txids for an address (requires addressindex to be enabled).\n" - "\nResult\n" - "[\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - "]\n" - ); - - std::vector > addresses; - if (params[0].isStr()) { - CBitcoinAddress address(params[0].get_str()); uint160 hashBytes; int type = 0; @@ -529,7 +516,6 @@ UniValue getaddresstxids(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } addresses.push_back(std::make_pair(hashBytes, type)); - } else if (params[0].isObject()) { UniValue addressValues = find_value(params[0].get_obj(), "addresses"); @@ -553,9 +539,73 @@ UniValue getaddresstxids(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } + return true; + + +} + +UniValue getaddressbalance(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressbalance\n" + "\nReturns the balance for an address (requires addressindex to be enabled).\n" + "\nResult\n" + "{\n" + " \"balance\" (string) The current balance\n" + " ,...\n" + "}\n" + ); + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + std::vector > addressIndex; - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); ++it) { + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + + CAmount balance = 0; + + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + balance += it->second; + } + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("balance", balance)); + + return result; + +} + +UniValue getaddresstxids(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddresstxids\n" + "\nReturns the txids for an address (requires addressindex to be enabled).\n" + "\nResult\n" + "[\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + ); + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + std::vector > addressIndex; + + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); } diff --git a/src/rpcserver.h b/src/rpcserver.h index 6263a1f98..56c344a39 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -174,6 +174,7 @@ extern void EnsureWalletIsUnlocked(); extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp extern UniValue getaddresstxids(const UniValue& params, bool fHelp); +extern UniValue getaddressbalance(const UniValue& params, bool fHelp); extern UniValue getpeerinfo(const UniValue& params, bool fHelp); extern UniValue ping(const UniValue& params, bool fHelp);