Automatically add any matching outputs to a filter during matching.
This commit is contained in:
parent
269d9c6492
commit
d3b26f7077
3 changed files with 19 additions and 6 deletions
|
@ -88,16 +88,21 @@ bool CBloomFilter::IsWithinSizeConstraints() const
|
||||||
return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
|
return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBloomFilter::IsTransactionRelevantToFilter(const CTransaction& tx, const uint256& hash) const
|
bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& hash)
|
||||||
{
|
{
|
||||||
|
bool fFound = false;
|
||||||
// Match if the filter contains the hash of tx
|
// Match if the filter contains the hash of tx
|
||||||
// for finding tx when they appear in a block
|
// for finding tx when they appear in a block
|
||||||
if (contains(hash))
|
if (contains(hash))
|
||||||
return true;
|
fFound = true;
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, tx.vout)
|
for (unsigned int i = 0; i < tx.vout.size(); i++)
|
||||||
{
|
{
|
||||||
|
const CTxOut& txout = tx.vout[i];
|
||||||
// Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
|
// Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
|
||||||
|
// If this matches, also add the specific output that was matched.
|
||||||
|
// This means clients don't have to update the filter themselves when a new relevant tx
|
||||||
|
// is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
|
||||||
CScript::const_iterator pc = txout.scriptPubKey.begin();
|
CScript::const_iterator pc = txout.scriptPubKey.begin();
|
||||||
vector<unsigned char> data;
|
vector<unsigned char> data;
|
||||||
while (pc < txout.scriptPubKey.end())
|
while (pc < txout.scriptPubKey.end())
|
||||||
|
@ -106,10 +111,17 @@ bool CBloomFilter::IsTransactionRelevantToFilter(const CTransaction& tx, const u
|
||||||
if (!txout.scriptPubKey.GetOp(pc, opcode, data))
|
if (!txout.scriptPubKey.GetOp(pc, opcode, data))
|
||||||
break;
|
break;
|
||||||
if (data.size() != 0 && contains(data))
|
if (data.size() != 0 && contains(data))
|
||||||
return true;
|
{
|
||||||
|
fFound = true;
|
||||||
|
insert(COutPoint(hash, i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fFound)
|
||||||
|
return true;
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
{
|
{
|
||||||
// Match if the filter contains an outpoint tx spends
|
// Match if the filter contains an outpoint tx spends
|
||||||
|
|
|
@ -64,7 +64,8 @@ public:
|
||||||
// (catch a filter which was just deserialized which was too big)
|
// (catch a filter which was just deserialized which was too big)
|
||||||
bool IsWithinSizeConstraints() const;
|
bool IsWithinSizeConstraints() const;
|
||||||
|
|
||||||
bool IsTransactionRelevantToFilter(const CTransaction& tx, const uint256& hash) const;
|
// Also adds any outputs which match the filter to the filter (to match their spending txes)
|
||||||
|
bool IsRelevantAndUpdate(const CTransaction& tx, const uint256& hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BITCOIN_BLOOM_H */
|
#endif /* BITCOIN_BLOOM_H */
|
||||||
|
|
|
@ -2034,7 +2034,7 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
|
||||||
LOCK(pnode->cs_filter);
|
LOCK(pnode->cs_filter);
|
||||||
if (pnode->pfilter)
|
if (pnode->pfilter)
|
||||||
{
|
{
|
||||||
if (pnode->pfilter->IsTransactionRelevantToFilter(tx, hash))
|
if (pnode->pfilter->IsRelevantAndUpdate(tx, hash))
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
} else
|
} else
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
|
|
Loading…
Add table
Reference in a new issue