Get rid of inaccurate ScriptSigArgsExpected
This commit is contained in:
parent
da83ecd454
commit
52b29dca76
@ -135,45 +135,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||||||
const CScript& prevScript = prev.scriptPubKey;
|
const CScript& prevScript = prev.scriptPubKey;
|
||||||
if (!Solver(prevScript, whichType, vSolutions))
|
if (!Solver(prevScript, whichType, vSolutions))
|
||||||
return false;
|
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)
|
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())
|
if (stack.empty())
|
||||||
return false;
|
return false;
|
||||||
CScript subscript(stack.back().begin(), stack.back().end());
|
CScript subscript(stack.back().begin(), stack.back().end());
|
||||||
std::vector<std::vector<unsigned char> > vSolutions2;
|
if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
|
||||||
txnouttype whichType2;
|
|
||||||
if (Solver(subscript, whichType2, vSolutions2))
|
|
||||||
{
|
|
||||||
int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
|
|
||||||
if (tmpExpected < 0)
|
|
||||||
return false;
|
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 (stack.size() != (unsigned int)nArgsExpected)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -161,27 +161,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
|||||||
return false;
|
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)
|
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||||
{
|
{
|
||||||
vector<valtype> vSolutions;
|
vector<valtype> vSolutions;
|
||||||
|
@ -71,7 +71,6 @@ typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
|||||||
const char* GetTxnOutputType(txnouttype t);
|
const char* GetTxnOutputType(txnouttype t);
|
||||||
|
|
||||||
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
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 ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
|
||||||
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
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]
|
// 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);
|
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;
|
CMutableTransaction txToNonStd1;
|
||||||
txToNonStd1.vout.resize(1);
|
txToNonStd1.vout.resize(1);
|
||||||
txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
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(AreInputsStandard(t1, coins));
|
||||||
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
|
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)
|
BOOST_AUTO_TEST_CASE(test_IsStandard)
|
||||||
|
Loading…
Reference in New Issue
Block a user