|
|
@ -113,6 +113,144 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) |
|
|
|
{ |
|
|
|
LOCK(cs); |
|
|
|
const CTransaction& tx = entry.GetTx(); |
|
|
|
std::vector<CMempoolAddressDeltaKey> inserted; |
|
|
|
|
|
|
|
uint256 txhash = tx.GetTxid(); |
|
|
|
for (unsigned int j = 0; j < tx.vin.size(); j++) { |
|
|
|
const CTxIn input = tx.vin[j]; |
|
|
|
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, 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, 1); |
|
|
|
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); |
|
|
|
mapAddress.insert(make_pair(key, delta)); |
|
|
|
inserted.push_back(key); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (unsigned int k = 0; k < tx.vout.size(); k++) { |
|
|
|
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, 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, 0); |
|
|
|
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); |
|
|
|
inserted.push_back(key); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
mapAddressInserted.insert(make_pair(txhash, inserted)); |
|
|
|
} |
|
|
|
|
|
|
|
bool CTxMemPool::getAddressIndex(std::vector<std::pair<uint160, int> > &addresses, |
|
|
|
std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > &results) |
|
|
|
{ |
|
|
|
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 && (*ait).first.type == (*it).second) { |
|
|
|
results.push_back(*ait); |
|
|
|
ait++; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool CTxMemPool::removeAddressIndex(const uint256 txhash) |
|
|
|
{ |
|
|
|
LOCK(cs); |
|
|
|
addressDeltaMapInserted::iterator it = mapAddressInserted.find(txhash); |
|
|
|
|
|
|
|
if (it != mapAddressInserted.end()) { |
|
|
|
std::vector<CMempoolAddressDeltaKey> keys = (*it).second; |
|
|
|
for (std::vector<CMempoolAddressDeltaKey>::iterator mit = keys.begin(); mit != keys.end(); mit++) { |
|
|
|
mapAddress.erase(*mit); |
|
|
|
} |
|
|
|
mapAddressInserted.erase(it); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) |
|
|
|
{ |
|
|
|
LOCK(cs); |
|
|
|
|
|
|
|
const CTransaction& tx = entry.GetTx(); |
|
|
|
std::vector<CSpentIndexKey> inserted; |
|
|
|
|
|
|
|
uint256 txhash = tx.GetTxid(); |
|
|
|
for (unsigned int j = 0; j < tx.vin.size(); j++) { |
|
|
|
const CTxIn input = tx.vin[j]; |
|
|
|
const CTxOut &prevout = view.GetOutputFor(input); |
|
|
|
uint160 addressHash; |
|
|
|
int addressType; |
|
|
|
|
|
|
|
if (prevout.scriptPubKey.IsPayToScriptHash()) { |
|
|
|
addressHash = uint160(vector<unsigned char> (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); |
|
|
|
addressType = 2; |
|
|
|
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { |
|
|
|
addressHash = uint160(vector<unsigned char> (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); |
|
|
|
addressType = 1; |
|
|
|
} else { |
|
|
|
addressHash.SetNull(); |
|
|
|
addressType = 0; |
|
|
|
} |
|
|
|
|
|
|
|
CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n); |
|
|
|
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, addressType, addressHash); |
|
|
|
|
|
|
|
mapSpent.insert(make_pair(key, value)); |
|
|
|
inserted.push_back(key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
mapSpentInserted.insert(make_pair(txhash, inserted)); |
|
|
|
} |
|
|
|
|
|
|
|
bool CTxMemPool::getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) |
|
|
|
{ |
|
|
|
LOCK(cs); |
|
|
|
mapSpentIndex::iterator it; |
|
|
|
|
|
|
|
it = mapSpent.find(key); |
|
|
|
if (it != mapSpent.end()) { |
|
|
|
value = it->second; |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
bool CTxMemPool::removeSpentIndex(const uint256 txhash) |
|
|
|
{ |
|
|
|
LOCK(cs); |
|
|
|
mapSpentIndexInserted::iterator it = mapSpentInserted.find(txhash); |
|
|
|
|
|
|
|
if (it != mapSpentInserted.end()) { |
|
|
|
std::vector<CSpentIndexKey> keys = (*it).second; |
|
|
|
for (std::vector<CSpentIndexKey>::iterator mit = keys.begin(); mit != keys.end(); mit++) { |
|
|
|
mapSpent.erase(*mit); |
|
|
|
} |
|
|
|
mapSpentInserted.erase(it); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive) |
|
|
|
{ |
|
|
@ -162,6 +300,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem |
|
|
|
mapTx.erase(hash); |
|
|
|
nTransactionsUpdated++; |
|
|
|
minerPolicyEstimator->removeTx(hash); |
|
|
|
removeAddressIndex(hash); |
|
|
|
removeSpentIndex(hash); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|