diff --git a/src/main.cpp b/src/main.cpp
index 847b1ea..1a424b8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -641,6 +641,16 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
if ((int64)tx.nLockTime > std::numeric_limits<int>::max())
return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet");
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ {
+ if (txout.scriptPubKey.IsBlacklisted())
+ {
+ tx.fBlacklisted = true;
+ printf("AcceptToMemoryPool() : flagging transaction with blacklisted output: %s\n", tx.GetHash().ToString().c_str());
+ break;
+ }
+ }
+
// Rather not work on nonstandard transactions (unless -testnet)
if (!fTestNet && !tx.IsStandard())
return error("CTxMemPool::accept() : nonstandard transaction type");
@@ -717,6 +727,15 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
view.SetBackend(dummy);
}
+ for (std::vector<CTxIn>::iterator it = tx.vin.begin(); it != tx.vin.end(); ++it)
+ {
+ COutPoint & outpoint = it->prevout;
+ const CCoins &coins = view.GetCoins(outpoint.hash);
+ assert(coins.IsAvailable(outpoint.n));
+ if (coins.vout[outpoint.n].scriptPubKey.IsBlacklisted())
+ return error("AcceptToMemoryPool() : ignoring transaction with blacklisted input: %s", tx.GetHash().ToString().c_str());
+ }
+
// Check for non-standard pay-to-script-hash in inputs
if (!tx.AreInputsStandard(view) && !fTestNet)
return error("CTxMemPool::accept() : nonstandard transaction input");
@@ -866,7 +885,11 @@ void CTxMemPool::queryHashes(std::vector<uint256>& vtxid)
LOCK(cs);
vtxid.reserve(mapTx.size());
for (map<uint256, CTransaction>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
+ {
+ if (mi->second.fBlacklisted)
+ continue;
vtxid.push_back((*mi).first);
+ }
}
@@ -3435,7 +3458,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CValidationState state;
if (tx.AcceptToMemoryPool(state, true, true, &fMissingInputs))
{
- RelayTransaction(tx, inv.hash, vMsg);
+ if (!tx.fBlacklisted)
+ RelayTransaction(tx, inv.hash, vMsg);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
@@ -4134,7 +4158,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
{
CTransaction& tx = (*mi).second;
- if (tx.IsCoinBase() || !tx.IsFinal())
+ if (tx.IsCoinBase() || tx.fBlacklisted || !tx.IsFinal())
continue;
COrphan* porphan = NULL;
diff --git a/src/main.h b/src/main.h
index 23a4d3b..ec77123 100644
--- a/src/main.h
+++ b/src/main.h
@@ -477,8 +477,12 @@ public:
std::vector<CTxOut> vout;
unsigned int nLockTime;
+ bool fBlacklisted;
+
+
CTransaction()
{
+ fBlacklisted = false;
SetNull();
}
diff --git a/src/script.cpp b/src/script.cpp
index 5e5cd09..a7dfe4a 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -1896,6 +1896,15 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const
return subscript.GetSigOpCount(true);
}
+bool CScript::IsBlacklisted() const
+{
+ return (this->size() > 6 &&
+ this->at(0) == OP_DUP &&
+ this->at(3) == 0x06 &&
+ this->at(4) == 0xf1 &&
+ this->at(5) == 0xb6);
+}
+
bool CScript::IsPayToScriptHash() const
{
// Extra-fast test for pay-to-script-hash CScripts:
diff --git a/src/script.h b/src/script.h
index 4b29f62..30d6020 100644
--- a/src/script.h
+++ b/src/script.h
@@ -529,6 +529,8 @@ public:
// pay-to-script-hash transactions:
unsigned int GetSigOpCount(const CScript& scriptSig) const;
+ bool IsBlacklisted() const;
+
bool IsPayToScriptHash() const;
// Called by CTransaction::IsStandard