changeset 29678:128e85c789df

mempool: same address and index for an input and output bug fixes a bug that would happen when an output would match an input with the same address and index, and would lead to the outputs not appearing in results.
author Braydon Fuller <braydon@bitpay.com>
date Fri, 10 Jun 2016 14:41:51 -0400
parents 1b94659c13a8
children 7c51ac1e241b
files qa/rpc-tests/addressindex.py src/addressindex.h src/txmempool.cpp
diffstat 3 files changed, 40 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/qa/rpc-tests/addressindex.py	Fri Jun 10 14:02:51 2016 -0400
+++ b/qa/rpc-tests/addressindex.py	Fri Jun 10 14:41:51 2016 -0400
@@ -293,6 +293,34 @@
         assert_equal(mempool3[1]["prevtxid"], memtxid2)
         assert_equal(mempool3[1]["prevout"], 1)
 
+        # sending and receiving to the same address
+        privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8"
+        address1 = "myAUWSHnwsQrhuMWv4Br6QsCnpB41vFwHn"
+        address1hash = "c192bff751af8efec15135d42bfeedf91a6f3e34".decode("hex")
+        address1script = CScript([OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG])
+
+        self.nodes[0].sendtoaddress(address1, 10)
+        self.nodes[0].generate(1)
+        self.sync_all()
+
+        utxos = self.nodes[1].getaddressutxos({"addresses": [address1]})
+        assert_equal(len(utxos), 1)
+
+        tx = CTransaction()
+        tx.vin = [
+            CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["outputIndex"]))
+        ]
+        amount = utxos[0]["satoshis"] - 1000
+        tx.vout = [CTxOut(amount, address1script)]
+        tx.rehash()
+        self.nodes[0].importprivkey(privkey1)
+        signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
+        mem_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
+
+        self.sync_all()
+        mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
+        assert_equal(len(mempool_deltas), 2)
+
         print "Passed\n"
 
 
--- a/src/addressindex.h	Fri Jun 10 14:02:51 2016 -0400
+++ b/src/addressindex.h	Fri Jun 10 14:41:51 2016 -0400
@@ -37,9 +37,9 @@
     uint160 addressBytes;
     uint256 txhash;
     unsigned int index;
-    bool spending;
+    int spending;
 
-    CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, bool s) {
+    CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) {
         type = addressType;
         addressBytes = addressHash;
         txhash = hash;
@@ -52,6 +52,7 @@
         addressBytes = addressHash;
         txhash.SetNull();
         index = 0;
+        spending = 0;
     }
 };
 
@@ -61,7 +62,11 @@
         if (a.type == b.type) {
             if (a.addressBytes == b.addressBytes) {
                 if (a.txhash == b.txhash) {
-                    return a.index < b.index;
+                    if (a.index == b.index) {
+                        return a.spending < b.spending;
+                    } else {
+                        return a.index < b.index;
+                    }
                 } else {
                     return a.txhash < b.txhash;
                 }
--- a/src/txmempool.cpp	Fri Jun 10 14:02:51 2016 -0400
+++ b/src/txmempool.cpp	Fri Jun 10 14:41:51 2016 -0400
@@ -434,13 +434,13 @@
         const CTxOut &prevout = view.GetOutputFor(input);
         if (prevout.scriptPubKey.IsPayToScriptHash()) {
             vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
-            CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, true);
+            CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, 1);
             CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
             mapAddress.insert(make_pair(key, delta));
             inserted.push_back(key);
         } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
             vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
-            CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, true);
+            CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, 1);
             CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
             mapAddress.insert(make_pair(key, delta));
             inserted.push_back(key);
@@ -451,13 +451,13 @@
         const CTxOut &out = tx.vout[k];
         if (out.scriptPubKey.IsPayToScriptHash()) {
             vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
-            CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, false);
+            CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, 0);
             mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
             inserted.push_back(key);
         } else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
             vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
             std::pair<addressDeltaMap::iterator,bool> ret;
-            CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, false);
+            CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, 0);
             mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
             inserted.push_back(key);
         }