changeset 29633:07de3eedb80a

rpc: added getaddressbalance method using addressindex
author Braydon Fuller <courier@braydon.com>
date Thu, 17 Mar 2016 16:06:08 -0400
parents bf5e7fb3a59e
children 388e58e8be25
files qa/rpc-tests/addressindex.py src/rpcmisc.cpp src/rpcserver.cpp src/rpcserver.h
diffstat 4 files changed, 80 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/qa/rpc-tests/addressindex.py	Wed Mar 16 14:50:19 2016 -0400
+++ b/qa/rpc-tests/addressindex.py	Thu Mar 17 16:06:08 2016 -0400
@@ -44,6 +44,10 @@
         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 @@
         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 @@
         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"
 
 
--- a/src/rpcmisc.cpp	Wed Mar 16 14:50:19 2016 -0400
+++ b/src/rpcmisc.cpp	Thu Mar 17 16:06:08 2016 -0400
@@ -397,23 +397,9 @@
     return NullUniValue;
 }
 
-UniValue getaddresstxids(const UniValue& params, bool fHelp)
+bool getAddressesFromParams(const UniValue& params, std::vector<std::pair<uint160, int> > &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<std::pair<uint160, int> > addresses;
-
     if (params[0].isStr()) {
-
         CBitcoinAddress address(params[0].get_str());
         uint160 hashBytes;
         int type = 0;
@@ -421,7 +407,6 @@
             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");
@@ -445,9 +430,73 @@
         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<std::pair<uint160, int> > addresses;
+
+    if (!getAddressesFromParams(params, addresses)) {
+        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
+    }
+
     std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
 
-    for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); ++it) {
+    for (std::vector<std::pair<uint160, int> >::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<std::pair<CAddressIndexKey, CAmount> >::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<std::pair<uint160, int> > addresses;
+
+    if (!getAddressesFromParams(params, addresses)) {
+        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
+    }
+
+    std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
+
+    for (std::vector<std::pair<uint160, int> >::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");
         }
--- a/src/rpcserver.cpp	Wed Mar 16 14:50:19 2016 -0400
+++ b/src/rpcserver.cpp	Thu Mar 17 16:06:08 2016 -0400
@@ -315,6 +315,7 @@
 
     /* Address index */
     { "addressindex",       "getaddresstxids",        &getaddresstxids,        false },
+    { "addressindex",       "getaddressbalance",      &getaddressbalance,      false },
 
     /* Utility functions */
     { "util",               "createmultisig",         &createmultisig,         true  },
--- a/src/rpcserver.h	Wed Mar 16 14:50:19 2016 -0400
+++ b/src/rpcserver.h	Thu Mar 17 16:06:08 2016 -0400
@@ -167,6 +167,7 @@
 
 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);