Major updates integration from all upstreams
This commit is contained in:
@@ -110,9 +110,12 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
|
||||
}
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
|
||||
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
|
||||
mapNullifiers[nf] = &tx;
|
||||
mapSproutNullifiers[nf] = &tx;
|
||||
}
|
||||
}
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
mapSaplingNullifiers[spendDescription.nullifier] = &tx;
|
||||
}
|
||||
nTransactionsUpdated++;
|
||||
totalTxSize += entry.GetTxSize();
|
||||
cachedInnerUsage += entry.DynamicMemoryUsage();
|
||||
@@ -337,10 +340,12 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
|
||||
mapNextTx.erase(txin.prevout);
|
||||
BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) {
|
||||
BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers) {
|
||||
mapNullifiers.erase(nf);
|
||||
mapSproutNullifiers.erase(nf);
|
||||
}
|
||||
}
|
||||
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
mapSaplingNullifiers.erase(spendDescription.nullifier);
|
||||
}
|
||||
removed.push_back(tx);
|
||||
totalTxSize -= mapTx.find(hash)->GetTxSize();
|
||||
cachedInnerUsage -= mapTx.find(hash)->DynamicMemoryUsage();
|
||||
@@ -392,7 +397,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
|
||||
}
|
||||
|
||||
|
||||
void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot)
|
||||
void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot, ShieldedType type)
|
||||
{
|
||||
// If a block is disconnected from the tip, and the root changed,
|
||||
// we must invalidate transactions from the mempool which spend
|
||||
@@ -403,11 +408,26 @@ void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot)
|
||||
|
||||
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
|
||||
const CTransaction& tx = it->GetTx();
|
||||
BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) {
|
||||
if (joinsplit.anchor == invalidRoot) {
|
||||
transactionsToRemove.push_back(tx);
|
||||
break;
|
||||
}
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) {
|
||||
if (joinsplit.anchor == invalidRoot) {
|
||||
transactionsToRemove.push_back(tx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SAPLING:
|
||||
BOOST_FOREACH(const SpendDescription& spendDescription, tx.vShieldedSpend) {
|
||||
if (spendDescription.anchor == invalidRoot) {
|
||||
transactionsToRemove.push_back(tx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("Unknown shielded type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,16 +455,24 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>
|
||||
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
|
||||
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
|
||||
std::map<uint256, const CTransaction*>::iterator it = mapNullifiers.find(nf);
|
||||
if (it != mapNullifiers.end()) {
|
||||
std::map<uint256, const CTransaction*>::iterator it = mapSproutNullifiers.find(nf);
|
||||
if (it != mapSproutNullifiers.end()) {
|
||||
const CTransaction &txConflict = *it->second;
|
||||
if (txConflict != tx)
|
||||
{
|
||||
if (txConflict != tx) {
|
||||
remove(txConflict, removed, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
std::map<uint256, const CTransaction*>::iterator it = mapSaplingNullifiers.find(spendDescription.nullifier);
|
||||
if (it != mapSaplingNullifiers.end()) {
|
||||
const CTransaction &txConflict = *it->second;
|
||||
if (txConflict != tx) {
|
||||
remove(txConflict, removed, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
|
||||
@@ -574,19 +602,19 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||
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 uint256 &nf, joinsplit.nullifiers) {
|
||||
assert(!pcoins->GetNullifier(nf));
|
||||
assert(!pcoins->GetNullifier(nf, SPROUT));
|
||||
}
|
||||
|
||||
ZCIncrementalMerkleTree tree;
|
||||
SproutMerkleTree tree;
|
||||
auto it = intermediates.find(joinsplit.anchor);
|
||||
if (it != intermediates.end()) {
|
||||
tree = it->second;
|
||||
} else {
|
||||
assert(pcoins->GetAnchorAt(joinsplit.anchor, tree));
|
||||
assert(pcoins->GetSproutAnchorAt(joinsplit.anchor, tree));
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const uint256& commitment, joinsplit.commitments)
|
||||
@@ -596,6 +624,12 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||
|
||||
intermediates.insert(std::make_pair(tree.root(), tree));
|
||||
}
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
SaplingMerkleTree tree;
|
||||
|
||||
assert(pcoins->GetSaplingAnchorAt(spendDescription.anchor, tree));
|
||||
assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING));
|
||||
}
|
||||
if (fDependsWait)
|
||||
waitingOnDependants.push_back(&(*it));
|
||||
else {
|
||||
@@ -633,18 +667,35 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||
assert(it->first == it->second.ptx->vin[it->second.n].prevout);
|
||||
}
|
||||
|
||||
for (std::map<uint256, const CTransaction*>::const_iterator it = mapNullifiers.begin(); it != mapNullifiers.end(); it++) {
|
||||
uint256 hash = it->second->GetHash();
|
||||
indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
|
||||
const CTransaction& tx = it2->GetTx();
|
||||
assert(it2 != mapTx.end());
|
||||
assert(&tx == it->second);
|
||||
}
|
||||
checkNullifiers(SPROUT);
|
||||
checkNullifiers(SAPLING);
|
||||
|
||||
assert(totalTxSize == checkTotal);
|
||||
assert(innerUsage == cachedInnerUsage);
|
||||
}
|
||||
|
||||
void CTxMemPool::checkNullifiers(ShieldedType type) const
|
||||
{
|
||||
const std::map<uint256, const CTransaction*>* mapToUse;
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
mapToUse = &mapSproutNullifiers;
|
||||
break;
|
||||
case SAPLING:
|
||||
mapToUse = &mapSaplingNullifiers;
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("Unknown nullifier type");
|
||||
}
|
||||
for (const auto& entry : *mapToUse) {
|
||||
uint256 hash = entry.second->GetHash();
|
||||
CTxMemPool::indexed_transaction_set::const_iterator findTx = mapTx.find(hash);
|
||||
const CTransaction& tx = findTx->GetTx();
|
||||
assert(findTx != mapTx.end());
|
||||
assert(&tx == entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::queryHashes(vector<uint256>& vtxid)
|
||||
{
|
||||
vtxid.clear();
|
||||
@@ -746,13 +797,23 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
return mapSproutNullifiers.count(nullifier);
|
||||
case SAPLING:
|
||||
return mapSaplingNullifiers.count(nullifier);
|
||||
default:
|
||||
throw runtime_error("Unknown nullifier type");
|
||||
}
|
||||
}
|
||||
|
||||
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
||||
|
||||
bool CCoinsViewMemPool::GetNullifier(const uint256 &nf) const {
|
||||
if (mempool.mapNullifiers.count(nf))
|
||||
return true;
|
||||
|
||||
return base->GetNullifier(nf);
|
||||
bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, ShieldedType type) const
|
||||
{
|
||||
return mempool.nullifierExists(nf, type) || base->GetNullifier(nf, type);
|
||||
}
|
||||
|
||||
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
|
||||
Reference in New Issue
Block a user