Get rid of inaccurate ScriptSigArgsExpected
(cherry picked from commit 52b29dca7670c3f6d2ab918c0fff1d17c4e494ad)
This commit is contained in:
parent
196ad6913f
commit
5d743099b5
5 changed files with 6 additions and 70 deletions
|
@ -132,45 +132,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||
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
|
||||
// IsStandardTx() will have already returned false
|
||||
// and this method isn't called.
|
||||
std::vector<std::vector<unsigned char> > stack;
|
||||
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
|
||||
return false;
|
||||
|
||||
if (whichType == TX_SCRIPTHASH)
|
||||
{
|
||||
std::vector<std::vector<unsigned char> > stack;
|
||||
// convert the scriptSig into a stack, so we can inspect the redeemScript
|
||||
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0))
|
||||
return false;
|
||||
if (stack.empty())
|
||||
return false;
|
||||
CScript subscript(stack.back().begin(), stack.back().end());
|
||||
std::vector<std::vector<unsigned char> > vSolutions2;
|
||||
txnouttype whichType2;
|
||||
if (Solver(subscript, whichType2, vSolutions2))
|
||||
{
|
||||
int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
|
||||
if (tmpExpected < 0)
|
||||
return false;
|
||||
nArgsExpected += tmpExpected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any other Script with less than 15 sigops OK:
|
||||
unsigned int sigops = subscript.GetSigOpCount(true);
|
||||
// ... extra data left on the stack after execution is OK, too:
|
||||
return (sigops <= MAX_P2SH_SIGOPS);
|
||||
if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.size() != (unsigned int)nArgsExpected)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -161,27 +161,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
|||
return false;
|
||||
}
|
||||
|
||||
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TX_NULL_DATA:
|
||||
return -1;
|
||||
case TX_PUBKEY:
|
||||
return 1;
|
||||
case TX_PUBKEYHASH:
|
||||
return 2;
|
||||
case TX_MULTISIG:
|
||||
if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
|
||||
return -1;
|
||||
return vSolutions[0][0] + 1;
|
||||
case TX_SCRIPTHASH:
|
||||
return 1; // doesn't include args needed by the script
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
|
|
|
@ -71,7 +71,6 @@ typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
|||
const char* GetTxnOutputType(txnouttype t);
|
||||
|
||||
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
||||
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
||||
|
||||
|
|
|
@ -346,15 +346,6 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U);
|
||||
|
||||
// Make sure adding crap to the scriptSigs makes them non-standard:
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
CScript t = txTo.vin[i].scriptSig;
|
||||
txTo.vin[i].scriptSig = (CScript() << 11) + t;
|
||||
BOOST_CHECK(!::AreInputsStandard(txTo, coins));
|
||||
txTo.vin[i].scriptSig = t;
|
||||
}
|
||||
|
||||
CMutableTransaction txToNonStd1;
|
||||
txToNonStd1.vout.resize(1);
|
||||
txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||
|
|
|
@ -310,14 +310,6 @@ BOOST_AUTO_TEST_CASE(test_Get)
|
|||
|
||||
BOOST_CHECK(AreInputsStandard(t1, coins));
|
||||
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
|
||||
|
||||
// Adding extra junk to the scriptSig should make it non-standard:
|
||||
t1.vin[0].scriptSig << OP_11;
|
||||
BOOST_CHECK(!AreInputsStandard(t1, coins));
|
||||
|
||||
// ... as should not having enough:
|
||||
t1.vin[0].scriptSig = CScript();
|
||||
BOOST_CHECK(!AreInputsStandard(t1, coins));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_IsStandard)
|
||||
|
|
Loading…
Reference in a new issue