All pastes #1911295 Raw Edit

bitcoin listtransactions v5

public diff v1 · immutable
#1911295 ·published 2010-07-29 21:18 UTC
rendered paste body
Index: rpc.cpp===================================================================--- rpc.cpp	(revision 117)+++ rpc.cpp	(working copy)@@ -342,7 +342,172 @@     return "sent"; } +enum txn_classification+{+	txn_unknown,+	txn_generated,+	txn_credit,+	txn_debit,+}; +static const char *txn_class_str[] = {+	"unknown",+	"generated",+	"credit",+	"debit",+};++struct txnitem+{+    uint160 hash160;+    int64 nAmount;+    int nConf;+    enum txn_classification txnClass;+    txnitem()+    {+	hash160 = 0;+        nAmount = 0;+        nConf = INT_MAX;+	txnClass = txn_unknown;+    }+};++bool txnitem_cmp(const txnitem& a, const txnitem &b)+{+	return a.nConf < b.nConf;+}++Value ListTransactions(int64 nCount, bool fGenerated)+{+    vector<txnitem> tv;+    CRITICAL_BLOCK(cs_mapWallet)+    {+        for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)+        {+            const CWalletTx& wtx = (*it).second;+	    int64 nCredit = wtx.GetCredit(true);+	    int64 nDebit = wtx.GetDebit();+	    int64 nNet = nCredit - nDebit;++	    bool gen = wtx.IsCoinBase();+            if (gen) {+		if (!fGenerated)+			continue;+	    	if (!wtx.IsInMainChain())+			continue;+	    }++            int nDepth = wtx.GetDepthInMainChain();++	    if (nNet > 0)+	    {+                foreach(const CTxOut& txout, wtx.vout)+                {+                    uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();++		    if (!txout.IsMine())+			    continue;++                    txnitem item;+		    item.hash160 = hash160;+                    item.nAmount = txout.nValue;+                    item.nConf = min(item.nConf, nDepth);+		    if (gen)+		        item.txnClass = txn_generated;+		    else+		        item.txnClass = txn_credit;++		    tv.push_back(item);+                }+            }+	    else+	    {+	    	bool fAllFromMe = true;+		foreach(const CTxIn& txin, wtx.vin)+		    fAllFromMe = fAllFromMe && txin.IsMine();++		bool fAllToMe = true;+		foreach(const CTxOut& txout, wtx.vout)+		    fAllToMe = fAllToMe && txout.IsMine();++		if (fAllFromMe && fAllToMe)	// payment to self+		{+			// FIXME+		}+		else if (fAllFromMe)		// debit+		{+		    int64 nTxFee = nDebit - wtx.GetValueOut();+		    for (int nOut = 0; nOut < wtx.vout.size(); nOut++)+		    {+		    	const CTxOut& txout = wtx.vout[nOut];+			if (txout.IsMine())+			    continue;++                        uint160 hash160;+			ExtractHash160(txout.scriptPubKey, hash160);++			int64 nValue = txout.nValue;+			if (nTxFee > 0)+			{+				nValue += nTxFee;+				nTxFee = 0;+			}++                        txnitem item;+		        item.hash160 = hash160;+                        item.nAmount = nValue;+                        item.nConf = min(item.nConf, nDepth);+			item.txnClass = txn_debit;++		        tv.push_back(item);+		    }+		}+		else				// mixed debit txn+		{+			// FIXME+		}+	    }+        }+    }++    std::sort(tv.begin(), tv.end(), txnitem_cmp);++    // Reply+    Array ret;+    int64 returned = 0;+    CRITICAL_BLOCK(cs_mapAddressBook)+    {+        foreach(const txnitem& txn, tv)+	{+	    if (returned >= nCount)+	    	break;++	    string strAddress = Hash160ToAddress(txn.hash160);+	    string strLabel, strClass;+            int64 nAmount = txn.nAmount;+            int nConf = txn.nConf;++	    map<string, string>::iterator mi = mapAddressBook.find(strAddress);+	    if (mi != mapAddressBook.end())+		strLabel = (*mi).second;++	    strClass = txn_class_str[txn.txnClass];++            Object obj;+            obj.push_back(Pair("address",       strAddress));+            obj.push_back(Pair("label",         strLabel));+            obj.push_back(Pair("class",         strClass));+            obj.push_back(Pair("amount",        (double)nAmount /(double)COIN));+            obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 :nConf)));+            ret.push_back(obj);++	    returned++;+        }+    }++    return ret;+}+ Value listtransactions(const Array& params, bool fHelp) {     if (fHelp || params.size() > 2)@@ -357,10 +522,7 @@     if (params.size() > 1)         fGenerated = params[1].get_bool(); -    Array ret;-    //// not finished-    ret.push_back("not implemented yet");-    return ret;+    return ListTransactions(nCount, fGenerated); }  @@ -638,6 +800,7 @@     make_pair("getreceivedbylabel",    &getreceivedbylabel),     make_pair("listreceivedbyaddress", &listreceivedbyaddress),     make_pair("listreceivedbylabel",   &listreceivedbylabel),+    make_pair("listtransactions",      &listtransactions), }; map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));