changeset 3377:8da60f83a63f draft

Change CWallet addressgrouping to use CTxDestination instead of strings. This is cleanup for the listaddressgroupings code. Also add some real help text.
author Gregory Maxwell <greg@xiph.org>
date Mon, 20 Aug 2012 13:43:33 -0400 (2012-08-20)
parents a15769159fbd
children 75fad4c8df94
files src/rpcrawtransaction.cpp src/rpcwallet.cpp src/wallet.cpp src/wallet.h
diffstat 4 files changed, 57 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -140,7 +140,7 @@
 {
     if (fHelp || params.size() > 3)
         throw runtime_error(
-            "listunspent [minconf=1] [maxconf=9999999] ['addr1','addr2',...]\n"
+            "listunspent [minconf=1] [maxconf=9999999]  [\"address\",...]\n"
             "Returns array of unspent transaction outputs\n"
             "with between minconf and maxconf (inclusive) confirmations.\n"
             "Optionally filtered to only include txouts paid to specified addresses.\n"
@@ -165,7 +165,7 @@
         {
             CBitcoinAddress address(input.get_str());
             if (!address.IsValid())
-                throw JSONRPCError(-5, string("Invalid Bitcoin address:")+input.get_str());
+                throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+input.get_str());
             if (setAddress.count(address))
                 throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+input.get_str());
            setAddress.insert(address);
@@ -180,8 +180,15 @@
         if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
             continue;
 
-        if (setAddress.size() && !setAddress.count(out.tx->GetAddressOfTxOut(out.i)))
-            continue;
+        if(setAddress.size())
+        {
+            CTxDestination address;
+            if(!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
+                continue;
+
+            if (!setAddress.count(address))
+                continue;
+        }
 
         int64 nValue = out.tx->vout[out.i].nValue;
         const CScript& pk = out.tx->vout[out.i].scriptPubKey;
@@ -243,7 +250,7 @@
     {
         CBitcoinAddress address(s.name_);
         if (!address.IsValid())
-            throw JSONRPCError(-5, string("Invalid Bitcoin address:")+s.name_);
+            throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+s.name_);
 
         if (setAddress.count(address))
             throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -277,17 +277,21 @@
 Value listaddressgroupings(const Array& params, bool fHelp)
 {
     if (fHelp)
-        throw runtime_error("listaddressgroupings");
+        throw runtime_error(
+            "listaddressgroupings\n"
+            "Lists groups of addresses which have had their common ownership\n"
+            "made public by common use as inputs or as the resulting change\n"
+            "in past transactions");
 
     Array jsonGroupings;
-    map<string, int64> balances = pwalletMain->GetAddressBalances();
-    BOOST_FOREACH(set<string> grouping, pwalletMain->GetAddressGroupings())
+    map<CTxDestination, int64> balances = pwalletMain->GetAddressBalances();
+    BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
     {
         Array jsonGrouping;
-        BOOST_FOREACH(string address, grouping)
+        BOOST_FOREACH(CTxDestination address, grouping)
         {
             Array addressInfo;
-            addressInfo.push_back(address);
+            addressInfo.push_back(CBitcoinAddress(address).ToString());
             addressInfo.push_back(ValueFromAmount(balances[address]));
             {
                 LOCK(pwalletMain->cs_wallet);
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -1620,9 +1620,9 @@
     return keypool.nTime;
 }
 
-std::map<std::string, int64> CWallet::GetAddressBalances()
+std::map<CTxDestination, int64> CWallet::GetAddressBalances()
 {
-    map<string, int64> balances;
+    map<CTxDestination, int64> balances;
 
     {
         LOCK(cs_wallet);
@@ -1640,14 +1640,16 @@
             if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
                 continue;
 
-            for (int i = 0; i < pcoin->vout.size(); i++)
+            for (unsigned int i = 0; i < pcoin->vout.size(); i++)
             {
+                CTxDestination addr;
                 if (!IsMine(pcoin->vout[i]))
                     continue;
+                if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
+                    continue;
 
                 int64 n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue;
 
-                string addr = pcoin->GetAddressOfTxOut(i);
                 if (!balances.count(addr))
                     balances[addr] = 0;
                 balances[addr] += n;
@@ -1658,69 +1660,67 @@
     return balances;
 }
 
-set< set<string> > CWallet::GetAddressGroupings()
+set< set<CTxDestination> > CWallet::GetAddressGroupings()
 {
-    set< set<string> > groupings;
-    set<string> grouping;
+    set< set<CTxDestination> > groupings;
+    set<CTxDestination> grouping;
 
     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
     {
         CWalletTx *pcoin = &walletEntry.second;
 
-        if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
-            continue;
-
-        if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
-            continue;
-
-        int nDepth = pcoin->GetDepthInMainChain();
-        if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
-            continue;
-
         if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0]))
         {
             // group all input addresses with each other
             BOOST_FOREACH(CTxIn txin, pcoin->vin)
-                grouping.insert(mapWallet[txin.prevout.hash].GetAddressOfTxOut(txin.prevout.n));
+            {
+                CTxDestination address;
+                if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
+                    continue;
+                grouping.insert(address);
+            }
 
             // group change with input addresses
             BOOST_FOREACH(CTxOut txout, pcoin->vout)
                 if (IsChange(txout))
                 {
                     CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash];
-                    string addr = tx.GetAddressOfTxOut(pcoin->vin[0].prevout.n);
                     CTxDestination txoutAddr;
-                    ExtractDestination(txout.scriptPubKey, txoutAddr);
-                    grouping.insert(CBitcoinAddress(txoutAddr).ToString());
+                    if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
+                        continue;
+                    grouping.insert(txoutAddr);
                 }
             groupings.insert(grouping);
             grouping.clear();
         }
 
         // group lone addrs by themselves
-        for (int i = 0; i < pcoin->vout.size(); i++)
+        for (unsigned int i = 0; i < pcoin->vout.size(); i++)
             if (IsMine(pcoin->vout[i]))
             {
-                grouping.insert(pcoin->GetAddressOfTxOut(i));
+                CTxDestination address;
+                if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
+                    continue;
+                grouping.insert(address);
                 groupings.insert(grouping);
                 grouping.clear();
             }
     }
 
-    set< set<string>* > uniqueGroupings; // a set of pointers to groups of addresses
-    map< string, set<string>* > setmap;  // map addresses to the unique group containing it
-    BOOST_FOREACH(set<string> grouping, groupings)
+    set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
+    map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
+    BOOST_FOREACH(set<CTxDestination> grouping, groupings)
     {
         // make a set of all the groups hit by this new group
-        set< set<string>* > hits;
-        map< string, set<string>* >::iterator it;
-        BOOST_FOREACH(string address, grouping)
+        set< set<CTxDestination>* > hits;
+        map< CTxDestination, set<CTxDestination>* >::iterator it;
+        BOOST_FOREACH(CTxDestination address, grouping)
             if ((it = setmap.find(address)) != setmap.end())
                 hits.insert((*it).second);
 
         // merge all hit groups into a new single group and delete old groups
-        set<string>* merged = new set<string>(grouping);
-        BOOST_FOREACH(set<string>* hit, hits)
+        set<CTxDestination>* merged = new set<CTxDestination>(grouping);
+        BOOST_FOREACH(set<CTxDestination>* hit, hits)
         {
             merged->insert(hit->begin(), hit->end());
             uniqueGroupings.erase(hit);
@@ -1729,12 +1729,12 @@
         uniqueGroupings.insert(merged);
 
         // update setmap
-        BOOST_FOREACH(string element, *merged)
+        BOOST_FOREACH(CTxDestination element, *merged)
             setmap[element] = merged;
     }
 
-    set< set<string> > ret;
-    BOOST_FOREACH(set<string>* uniqueGrouping, uniqueGroupings)
+    set< set<CTxDestination> > ret;
+    BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
     {
         ret.insert(*uniqueGrouping);
         delete uniqueGrouping;
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -10,7 +10,6 @@
 
 #include <stdlib.h>
 
-#include "base58.h"
 #include "main.h"
 #include "key.h"
 #include "keystore.h"
@@ -177,8 +176,8 @@
     int64 GetOldestKeyPoolTime();
     void GetAllReserveKeys(std::set<CKeyID>& setAddress);
 
-    std::set< std::set<std::string> > GetAddressGroupings();
-    std::map<std::string, int64> GetAddressBalances();
+    std::set< std::set<CTxDestination> > GetAddressGroupings();
+    std::map<CTxDestination, int64> GetAddressBalances();
 
     bool IsMine(const CTxIn& txin) const;
     int64 GetDebit(const CTxIn& txin) const;
@@ -647,13 +646,6 @@
         return true;
     }
 
-    std::string GetAddressOfTxOut(int n) const
-    {
-        CTxDestination addr;
-        ExtractDestination(vout[n].scriptPubKey, addr);
-        return CBitcoinAddress(addr).ToString();
-    }
-
     bool WriteToDisk();
 
     int64 GetTxTime() const;