Skip to content

Commit 956b424

Browse files
authored
Merge pull request #18 from braydonf/0.12.1-bitcore-rebased-mempool-tests
mempool address index bug fixes
2 parents bd8328c + c01f783 commit 956b424

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

qa/rpc-tests/addressindex.py

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ def run_test(self):
232232
address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB"
233233
addressHash3 = "aa9872b5bbcdb511d89e0e11aa27da73fd2c3f50".decode("hex")
234234
scriptPubKey3 = CScript([OP_DUP, OP_HASH160, addressHash3, OP_EQUALVERIFY, OP_CHECKSIG])
235+
address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ"
236+
scriptPubKey4 = CScript([OP_HASH160, addressHash3, OP_EQUAL])
235237
unspent = self.nodes[2].listunspent()
236238

237239
tx = CTransaction()
@@ -246,36 +248,78 @@ def run_test(self):
246248
tx2 = CTransaction()
247249
tx2.vin = [CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))]
248250
amount = unspent[1]["amount"] * 100000000
249-
tx2.vout = [CTxOut(amount, scriptPubKey3)]
251+
tx2.vout = [
252+
CTxOut(amount / 4, scriptPubKey3),
253+
CTxOut(amount / 4, scriptPubKey3),
254+
CTxOut(amount / 4, scriptPubKey4),
255+
CTxOut(amount / 4, scriptPubKey4)
256+
]
250257
tx2.rehash()
251258
signed_tx2 = self.nodes[2].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8"))
252259
memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
253260
time.sleep(2)
254261

255262
mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
256-
assert_equal(len(mempool), 2)
263+
assert_equal(len(mempool), 3)
257264
assert_equal(mempool[0]["txid"], memtxid1)
258-
assert_equal(mempool[1]["txid"], memtxid2)
259265
assert_equal(mempool[0]["address"], address3)
266+
assert_equal(mempool[0]["index"], 0)
267+
assert_equal(mempool[1]["txid"], memtxid2)
268+
assert_equal(mempool[1]["index"], 0)
269+
assert_equal(mempool[2]["txid"], memtxid2)
270+
assert_equal(mempool[2]["index"], 1)
260271

261272
self.nodes[2].generate(1);
262273
self.sync_all();
263274
mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]})
264275
assert_equal(len(mempool2), 0)
265276

266277
tx = CTransaction()
267-
tx.vin = [CTxIn(COutPoint(int(memtxid2, 16), 0))]
268-
tx.vout = [CTxOut(amount - 10000, scriptPubKey2)]
278+
tx.vin = [
279+
CTxIn(COutPoint(int(memtxid2, 16), 0)),
280+
CTxIn(COutPoint(int(memtxid2, 16), 1))
281+
]
282+
tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)]
269283
tx.rehash()
270284
self.nodes[2].importprivkey(privKey3)
271285
signed_tx3 = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
272286
memtxid3 = self.nodes[2].sendrawtransaction(signed_tx3["hex"], True)
273287
time.sleep(2)
274288

275289
mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
276-
assert_equal(len(mempool3), 1)
290+
assert_equal(len(mempool3), 2)
277291
assert_equal(mempool3[0]["prevtxid"], memtxid2)
278292
assert_equal(mempool3[0]["prevout"], 0)
293+
assert_equal(mempool3[1]["prevtxid"], memtxid2)
294+
assert_equal(mempool3[1]["prevout"], 1)
295+
296+
# sending and receiving to the same address
297+
privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8"
298+
address1 = "myAUWSHnwsQrhuMWv4Br6QsCnpB41vFwHn"
299+
address1hash = "c192bff751af8efec15135d42bfeedf91a6f3e34".decode("hex")
300+
address1script = CScript([OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG])
301+
302+
self.nodes[0].sendtoaddress(address1, 10)
303+
self.nodes[0].generate(1)
304+
self.sync_all()
305+
306+
utxos = self.nodes[1].getaddressutxos({"addresses": [address1]})
307+
assert_equal(len(utxos), 1)
308+
309+
tx = CTransaction()
310+
tx.vin = [
311+
CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["outputIndex"]))
312+
]
313+
amount = utxos[0]["satoshis"] - 1000
314+
tx.vout = [CTxOut(amount, address1script)]
315+
tx.rehash()
316+
self.nodes[0].importprivkey(privkey1)
317+
signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
318+
mem_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
319+
320+
self.sync_all()
321+
mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
322+
assert_equal(len(mempool_deltas), 2)
279323

280324
print "Passed\n"
281325

src/addressindex.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ struct CMempoolAddressDeltaKey
3737
uint160 addressBytes;
3838
uint256 txhash;
3939
unsigned int index;
40-
bool spending;
40+
int spending;
4141

42-
CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, bool s) {
42+
CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) {
4343
type = addressType;
4444
addressBytes = addressHash;
4545
txhash = hash;
@@ -52,6 +52,7 @@ struct CMempoolAddressDeltaKey
5252
addressBytes = addressHash;
5353
txhash.SetNull();
5454
index = 0;
55+
spending = 0;
5556
}
5657
};
5758

@@ -61,7 +62,11 @@ struct CMempoolAddressDeltaKeyCompare
6162
if (a.type == b.type) {
6263
if (a.addressBytes == b.addressBytes) {
6364
if (a.txhash == b.txhash) {
64-
return a.index < b.index;
65+
if (a.index == b.index) {
66+
return a.spending < b.spending;
67+
} else {
68+
return a.index < b.index;
69+
}
6570
} else {
6671
return a.txhash < b.txhash;
6772
}

src/txmempool.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,13 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
434434
const CTxOut &prevout = view.GetOutputFor(input);
435435
if (prevout.scriptPubKey.IsPayToScriptHash()) {
436436
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
437-
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, true);
437+
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, 1);
438438
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
439439
mapAddress.insert(make_pair(key, delta));
440440
inserted.push_back(key);
441441
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
442442
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
443-
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, true);
443+
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, 1);
444444
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
445445
mapAddress.insert(make_pair(key, delta));
446446
inserted.push_back(key);
@@ -451,13 +451,13 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
451451
const CTxOut &out = tx.vout[k];
452452
if (out.scriptPubKey.IsPayToScriptHash()) {
453453
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
454-
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, false);
454+
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, 0);
455455
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
456456
inserted.push_back(key);
457457
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
458458
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
459459
std::pair<addressDeltaMap::iterator,bool> ret;
460-
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, false);
460+
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, 0);
461461
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
462462
inserted.push_back(key);
463463
}
@@ -472,7 +472,7 @@ bool CTxMemPool::getAddressIndex(std::vector<std::pair<uint160, int> > &addresse
472472
LOCK(cs);
473473
for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
474474
addressDeltaMap::iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey((*it).second, (*it).first));
475-
while (ait != mapAddress.end() && (*ait).first.addressBytes == (*it).first) {
475+
while (ait != mapAddress.end() && (*ait).first.addressBytes == (*it).first && (*ait).first.type == (*it).second) {
476476
results.push_back(*ait);
477477
ait++;
478478
}

0 commit comments

Comments
 (0)