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.
This commit is contained in:
parent
cf27a26fc9
commit
b97bdbb690
|
@ -293,6 +293,34 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||||
assert_equal(mempool3[1]["prevtxid"], memtxid2)
|
assert_equal(mempool3[1]["prevtxid"], memtxid2)
|
||||||
assert_equal(mempool3[1]["prevout"], 1)
|
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"
|
print "Passed\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,9 @@ struct CMempoolAddressDeltaKey
|
||||||
uint160 addressBytes;
|
uint160 addressBytes;
|
||||||
uint256 txhash;
|
uint256 txhash;
|
||||||
unsigned int index;
|
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;
|
type = addressType;
|
||||||
addressBytes = addressHash;
|
addressBytes = addressHash;
|
||||||
txhash = hash;
|
txhash = hash;
|
||||||
|
@ -52,6 +52,7 @@ struct CMempoolAddressDeltaKey
|
||||||
addressBytes = addressHash;
|
addressBytes = addressHash;
|
||||||
txhash.SetNull();
|
txhash.SetNull();
|
||||||
index = 0;
|
index = 0;
|
||||||
|
spending = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +62,11 @@ struct CMempoolAddressDeltaKeyCompare
|
||||||
if (a.type == b.type) {
|
if (a.type == b.type) {
|
||||||
if (a.addressBytes == b.addressBytes) {
|
if (a.addressBytes == b.addressBytes) {
|
||||||
if (a.txhash == b.txhash) {
|
if (a.txhash == b.txhash) {
|
||||||
|
if (a.index == b.index) {
|
||||||
|
return a.spending < b.spending;
|
||||||
|
} else {
|
||||||
return a.index < b.index;
|
return a.index < b.index;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return a.txhash < b.txhash;
|
return a.txhash < b.txhash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,13 +133,13 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
|
||||||
const CTxOut &prevout = view.GetOutputFor(input);
|
const CTxOut &prevout = view.GetOutputFor(input);
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
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);
|
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
||||||
mapAddress.insert(make_pair(key, delta));
|
mapAddress.insert(make_pair(key, delta));
|
||||||
inserted.push_back(key);
|
inserted.push_back(key);
|
||||||
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
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);
|
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
||||||
mapAddress.insert(make_pair(key, delta));
|
mapAddress.insert(make_pair(key, delta));
|
||||||
inserted.push_back(key);
|
inserted.push_back(key);
|
||||||
|
@ -150,13 +150,13 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
|
||||||
const CTxOut &out = tx.vout[k];
|
const CTxOut &out = tx.vout[k];
|
||||||
if (out.scriptPubKey.IsPayToScriptHash()) {
|
if (out.scriptPubKey.IsPayToScriptHash()) {
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
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)));
|
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
||||||
inserted.push_back(key);
|
inserted.push_back(key);
|
||||||
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
||||||
std::pair<addressDeltaMap::iterator,bool> ret;
|
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)));
|
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
||||||
inserted.push_back(key);
|
inserted.push_back(key);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue