|
|
@ -408,103 +408,6 @@ bool IsStandardTx(const CTransaction& tx, string& reason) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Check transaction inputs, and make sure any
|
|
|
|
|
|
|
|
// pay-to-script-hash transactions are evaluating IsStandard scripts
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Why bother? To avoid denial-of-service attacks; an attacker
|
|
|
|
|
|
|
|
// can submit a standard HASH... OP_EQUAL transaction,
|
|
|
|
|
|
|
|
// which will get accepted into blocks. The redemption
|
|
|
|
|
|
|
|
// script can be anything; an attacker could use a very
|
|
|
|
|
|
|
|
// expensive-to-check-upon-redemption script like:
|
|
|
|
|
|
|
|
// DUP CHECKSIG DROP ... repeated 100 times... OP_1
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (tx.IsSpamMessage()) |
|
|
|
|
|
|
|
return true; // Coinbases don't use vin normally
|
|
|
|
|
|
|
|
/* [MF]
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<vector<unsigned char> > vSolutions; |
|
|
|
|
|
|
|
txnouttype whichType; |
|
|
|
|
|
|
|
// get the scriptPubKey corresponding to this input:
|
|
|
|
|
|
|
|
const CScript& prevScript = prev.scriptPubKey; |
|
|
|
|
|
|
|
if (!Solver(prevScript, whichType, vSolutions)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); |
|
|
|
|
|
|
|
if (nArgsExpected < 0) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Transactions with extra stuff in their scriptSigs are
|
|
|
|
|
|
|
|
// non-standard. Note that this EvalScript() call will
|
|
|
|
|
|
|
|
// be quick, because if there are any operations
|
|
|
|
|
|
|
|
// beside "push data" in the scriptSig the
|
|
|
|
|
|
|
|
// IsStandard() call returns false
|
|
|
|
|
|
|
|
vector<vector<unsigned char> > stack; |
|
|
|
|
|
|
|
if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false, 0)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (whichType == TX_SCRIPTHASH) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (stack.empty()) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
CScript subscript(stack.back().begin(), stack.back().end()); |
|
|
|
|
|
|
|
vector<vector<unsigned char> > vSolutions2; |
|
|
|
|
|
|
|
txnouttype whichType2; |
|
|
|
|
|
|
|
if (!Solver(subscript, whichType2, vSolutions2)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
if (whichType2 == TX_SCRIPTHASH) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int tmpExpected; |
|
|
|
|
|
|
|
tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); |
|
|
|
|
|
|
|
if (tmpExpected < 0) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
nArgsExpected += tmpExpected; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (stack.size() != (unsigned int)nArgsExpected) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int GetLegacySigOpCount(const CTransaction& tx) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
unsigned int nSigOps = 0; |
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
nSigOps += txin.scriptSig.GetSigOpCount(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
BOOST_FOREACH(const CTxOut& txout, tx.vout) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
nSigOps += txout.scriptPubKey.GetSigOpCount(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
return nSigOps; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (tx.IsSpamMessage()) |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int nSigOps = 0; |
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]); |
|
|
|
|
|
|
|
if (prevout.scriptPubKey.IsPayToScriptHash()) |
|
|
|
|
|
|
|
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
return nSigOps; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CMerkleTx::SetMerkleBranch(const CBlock* pblock) |
|
|
|
int CMerkleTx::SetMerkleBranch(const CBlock* pblock) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1385,13 +1288,6 @@ void static FlushBlockFile(bool fFinalize = false) |
|
|
|
|
|
|
|
|
|
|
|
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize); |
|
|
|
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize); |
|
|
|
|
|
|
|
|
|
|
|
static CCheckQueue<CScriptCheck> scriptcheckqueue(128); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ThreadScriptCheck() { |
|
|
|
|
|
|
|
RenameThread("bitcoin-scriptch"); |
|
|
|
|
|
|
|
scriptcheckqueue.Thread(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) |
|
|
|
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Check it again in case a previous version let a bad block in
|
|
|
|
// Check it again in case a previous version let a bad block in
|
|
|
|