// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "txmempool.h"
const CTransaction& tx = mapTx.find(hash)->GetTx();
for (unsigned int i = 0; i < tx.vin.size(); i++)
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
- BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
+ BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
mapSproutNullifiers[nf] = &tx;
}
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.GetHash();
+ for (unsigned int j = 0; j < tx.vin.size(); j++) {
+ const CTxIn input = tx.vin[j];
+ const CTxOut &prevout = view.GetOutputFor(input);
+ CScript::ScriptType type = prevout.scriptPubKey.GetType();
+ if (type == CScript::UNKNOWN)
+ continue;
+ CMempoolAddressDeltaKey key(type, prevout.scriptPubKey.AddressHash(), 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 j = 0; j < tx.vout.size(); j++) {
+ const CTxOut &out = tx.vout[j];
+ CScript::ScriptType type = out.scriptPubKey.GetType();
+ if (type == CScript::UNKNOWN)
+ continue;
+ CMempoolAddressDeltaKey key(type, out.scriptPubKey.AddressHash(), txhash, j, 0);
+ mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
+ inserted.push_back(key);
+ }
+
+ mapAddressInserted.insert(make_pair(txhash, inserted));
+}
+
+// START insightexplorer
+void CTxMemPool::getAddressIndex(
+ const std::vector<std::pair<uint160, int>>& addresses,
+ std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta>>& results)
+{
+ LOCK(cs);
+ for (const auto& it : addresses) {
+ auto 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++;
+ }
+ }
+}
+
+void CTxMemPool::removeAddressIndex(const uint256& txhash)
+{
+ LOCK(cs);
+ auto it = mapAddressInserted.find(txhash);
+
+ if (it != mapAddressInserted.end()) {
+ std::vector<CMempoolAddressDeltaKey> keys = it->second;
+ for (const auto& mit : keys) {
+ mapAddress.erase(mit);
+ }
+ mapAddressInserted.erase(it);
+ }
+}
+
+void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
+{
+ LOCK(cs);
+ const CTransaction& tx = entry.GetTx();
+ uint256 txhash = tx.GetHash();
+ std::vector<CSpentIndexKey> inserted;
+
+ for (unsigned int j = 0; j < tx.vin.size(); j++) {
+ const CTxIn input = tx.vin[j];
+ const CTxOut &prevout = view.GetOutputFor(input);
+ CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
+ CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue,
+ prevout.scriptPubKey.GetType(),
+ prevout.scriptPubKey.AddressHash());
+ mapSpent.insert(make_pair(key, value));
+ inserted.push_back(key);
+ }
+ mapSpentInserted.insert(make_pair(txhash, inserted));
+}
+
+bool CTxMemPool::getSpentIndex(const CSpentIndexKey &key, CSpentIndexValue &value)
+{
+ LOCK(cs);
+ std::map<CSpentIndexKey, CSpentIndexValue, CSpentIndexKeyCompare>::iterator it = mapSpent.find(key);
+ if (it != mapSpent.end()) {
+ value = it->second;
+ return true;
+ }
+ return false;
+}
+
+void CTxMemPool::removeSpentIndex(const uint256 txhash)
+{
+ LOCK(cs);
+ auto 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);
+ }
+}
+// END insightexplorer
void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
{
}
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapNextTx.erase(txin.prevout);
- BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) {
+ BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) {
BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers) {
mapSproutNullifiers.erase(nf);
}
mapTx.erase(hash);
nTransactionsUpdated++;
minerPolicyEstimator->removeTx(hash);
+
+ // insightexplorer
+ if (fAddressIndex)
+ removeAddressIndex(hash);
+ if (fSpentIndex)
+ removeSpentIndex(hash);
}
}
}
const CTransaction& tx = it->GetTx();
switch (type) {
case SPROUT:
- BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) {
+ BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) {
if (joinsplit.anchor == invalidRoot) {
transactionsToRemove.push_back(tx);
break;
}
}
- BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
+ BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
std::map<uint256, const CTransaction*>::iterator it = mapSproutNullifiers.find(nf);
if (it != mapSproutNullifiers.end()) {
i++;
}
- boost::unordered_map<uint256, ZCIncrementalMerkleTree, CCoinsKeyHasher> intermediates;
+ boost::unordered_map<uint256, SproutMerkleTree, CCoinsKeyHasher> intermediates;
- BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
+ BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
assert(!pcoins->GetNullifier(nf, SPROUT));
}
- ZCIncrementalMerkleTree tree;
+ SproutMerkleTree tree;
auto it = intermediates.find(joinsplit.anchor);
if (it != intermediates.end()) {
tree = it->second;
intermediates.insert(std::make_pair(tree.root(), tree));
}
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
- ZCSaplingIncrementalMerkleTree tree;
+ SaplingMerkleTree tree;
assert(pcoins->GetSaplingAnchorAt(spendDescription.anchor, tree));
assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING));