Browse Source

Add HasCanonicalPushes(), and use it in IsStandardTx

Conflicts:
	src/script.cpp
	src/script.h

Rebased-from: b8ee034b9f47b562932ba21cd0334d803f77ec98 0.8.x
0.8
Pieter Wuille 11 years ago committed by Warren Togami
parent
commit
fc1426bc0a
  1. 4
      src/main.cpp
  2. 27
      src/script.cpp
  3. 4
      src/script.h
  4. 18
      src/test/script_tests.cpp

4
src/main.cpp

@ -399,6 +399,10 @@ bool CTransaction::IsStandard(string& strReason) const @@ -399,6 +399,10 @@ bool CTransaction::IsStandard(string& strReason) const
strReason = "scriptsig-not-pushonly";
return false;
}
if (!txin.scriptSig.HasCanonicalPushes()) {
strReason = "non-canonical-push";
return false;
}
}
BOOST_FOREACH(const CTxOut& txout, vout) {
if (!::IsStandard(txout.scriptPubKey)) {

27
src/script.cpp

@ -1740,6 +1740,33 @@ bool CScript::IsPayToScriptHash() const @@ -1740,6 +1740,33 @@ bool CScript::IsPayToScriptHash() const
this->at(22) == OP_EQUAL);
}
bool CScript::HasCanonicalPushes() const
{
const_iterator pc = begin();
while (pc < end())
{
opcodetype opcode;
std::vector<unsigned char> data;
if (!GetOp(pc, opcode, data))
return false;
if (opcode > OP_16)
continue;
if (opcode < OP_PUSHDATA1 && opcode > OP_0 && (data.size() == 1 && data[0] <= 16))
// Could have used an OP_n code, rather than a 1-byte push.
return false;
if (opcode == OP_PUSHDATA1 && data.size() < OP_PUSHDATA1)
// Could have used a normal n-byte push, rather than OP_PUSHDATA1.
return false;
if (opcode == OP_PUSHDATA2 && data.size() <= 0xFF)
// Could have used an OP_PUSHDATA1.
return false;
if (opcode == OP_PUSHDATA4 && data.size() <= 0xFFFF)
// Could have used an OP_PUSHDATA2.
return false;
}
return true;
}
class CScriptVisitor : public boost::static_visitor<bool>
{
private:

4
src/script.h

@ -533,7 +533,7 @@ public: @@ -533,7 +533,7 @@ public:
bool IsPayToScriptHash() const;
// Called by CTransaction::IsStandard
// Called by CTransaction::IsStandard and P2SH VerifyScript (which makes it consensus-critical).
bool IsPushOnly() const
{
const_iterator pc = begin();
@ -548,6 +548,8 @@ public: @@ -548,6 +548,8 @@ public:
return true;
}
// Called by IsStandardTx.
bool HasCanonicalPushes() const;
void SetDestination(const CTxDestination& address);
void SetMultisig(int nRequired, const std::vector<CPubKey>& keys);

18
src/test/script_tests.cpp

@ -444,4 +444,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) @@ -444,4 +444,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
BOOST_CHECK(combined == partial3c);
}
BOOST_AUTO_TEST_CASE(script_standard_push)
{
for (int i=0; i<1000; i++) {
CScript script;
script << i;
BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push.");
BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Number " << i << " push is not canonical.");
}
for (int i=0; i<1000; i++) {
std::vector<unsigned char> data(i, '\111');
CScript script;
script << data;
BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push.");
BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Length " << i << " push is not canonical.");
}
}
BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save