All pastes #1910623 Raw Edit

bitcoin listtransactions v4

public diff v1 · immutable
#1910623 ·published 2010-07-29 02:53 UTC
rendered paste body
Index: rpc.cpp===================================================================--- rpc.cpp	(revision 117)+++ rpc.cpp	(working copy)@@ -342,7 +342,170 @@     return "sent"; } +struct txnitem+{+    uint160 hash160;+    int64 nAmount;+    int nConf;+    bool gen;+    bool credit;+    bool debit;+    txnitem()+    {+	hash160 = 0;+        nAmount = 0;+        nConf = INT_MAX;+    }+}; +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.gen = true;+			item.credit = false;+			item.debit = false;+		    } else {+		    	item.gen = false;+			item.credit = true;+			item.debit = false;+		    }++		    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.gen = false;+			item.credit = false;+			item.debit = true;++		        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)+	{+	    string strAddress = Hash160ToAddress(txn.hash160);+	    string strLabel;+            int64 nAmount = txn.nAmount;+            int nConf = txn.nConf;++	    map<string, string>::iterator mi = mapAddressBook.find(strAddress);+	    if (mi != mapAddressBook.end())+		strLabel = (*mi).second;++	    if (returned >= nCount)+	    	return ret;++            Object obj;+            obj.push_back(Pair("address",       strAddress));+            obj.push_back(Pair("label",         strLabel));+	    if (txn.gen)+            	obj.push_back(Pair("class",     "generated"));+	    else if (txn.credit)+            	obj.push_back(Pair("class",     "credit"));+	    else if (txn.debit)+            	obj.push_back(Pair("class",     "debit"));+	    else+            	obj.push_back(Pair("class",     "special"));+            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 +520,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 +798,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]));