Merge pull request #18 from braydonf/0.12.1-bitcore-rebased-mempool-tests

mempool address index bug fixes
This commit is contained in:
Chris Kleeschulte
2016-06-15 12:45:09 -04:00
committed by GitHub
3 changed files with 63 additions and 14 deletions

View File

@@ -232,6 +232,8 @@ class AddressIndexTest(BitcoinTestFramework):
address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB"
addressHash3 = "aa9872b5bbcdb511d89e0e11aa27da73fd2c3f50".decode("hex")
scriptPubKey3 = CScript([OP_DUP, OP_HASH160, addressHash3, OP_EQUALVERIFY, OP_CHECKSIG])
address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ"
scriptPubKey4 = CScript([OP_HASH160, addressHash3, OP_EQUAL])
unspent = self.nodes[2].listunspent()
tx = CTransaction()
@@ -246,17 +248,26 @@ class AddressIndexTest(BitcoinTestFramework):
tx2 = CTransaction()
tx2.vin = [CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))]
amount = unspent[1]["amount"] * 100000000
tx2.vout = [CTxOut(amount, scriptPubKey3)]
tx2.vout = [
CTxOut(amount / 4, scriptPubKey3),
CTxOut(amount / 4, scriptPubKey3),
CTxOut(amount / 4, scriptPubKey4),
CTxOut(amount / 4, scriptPubKey4)
]
tx2.rehash()
signed_tx2 = self.nodes[2].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8"))
memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
time.sleep(2)
mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
assert_equal(len(mempool), 2)
assert_equal(len(mempool), 3)
assert_equal(mempool[0]["txid"], memtxid1)
assert_equal(mempool[1]["txid"], memtxid2)
assert_equal(mempool[0]["address"], address3)
assert_equal(mempool[0]["index"], 0)
assert_equal(mempool[1]["txid"], memtxid2)
assert_equal(mempool[1]["index"], 0)
assert_equal(mempool[2]["txid"], memtxid2)
assert_equal(mempool[2]["index"], 1)
self.nodes[2].generate(1);
self.sync_all();
@@ -264,8 +275,11 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(len(mempool2), 0)
tx = CTransaction()
tx.vin = [CTxIn(COutPoint(int(memtxid2, 16), 0))]
tx.vout = [CTxOut(amount - 10000, scriptPubKey2)]
tx.vin = [
CTxIn(COutPoint(int(memtxid2, 16), 0)),
CTxIn(COutPoint(int(memtxid2, 16), 1))
]
tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)]
tx.rehash()
self.nodes[2].importprivkey(privKey3)
signed_tx3 = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
@@ -273,9 +287,39 @@ class AddressIndexTest(BitcoinTestFramework):
time.sleep(2)
mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
assert_equal(len(mempool3), 1)
assert_equal(len(mempool3), 2)
assert_equal(mempool3[0]["prevtxid"], memtxid2)
assert_equal(mempool3[0]["prevout"], 0)
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"

View File

@@ -37,9 +37,9 @@ struct CMempoolAddressDeltaKey
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 @@ struct CMempoolAddressDeltaKey
addressBytes = addressHash;
txhash.SetNull();
index = 0;
spending = 0;
}
};
@@ -61,7 +62,11 @@ struct CMempoolAddressDeltaKeyCompare
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;
}

View File

@@ -434,13 +434,13 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
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 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
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);
}
@@ -472,7 +472,7 @@ bool CTxMemPool::getAddressIndex(std::vector<std::pair<uint160, int> > &addresse
LOCK(cs);
for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
addressDeltaMap::iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey((*it).second, (*it).first));
while (ait != mapAddress.end() && (*ait).first.addressBytes == (*it).first) {
while (ait != mapAddress.end() && (*ait).first.addressBytes == (*it).first && (*ait).first.type == (*it).second) {
results.push_back(*ait);
ait++;
}