txscript: Correct nulldata standardness check.
This corrects the isNullData standard transaction type test to work properly with canonically-encoded data pushes. In particular, single byte data pushes that are small integers (0-16) are converted to the equivalent numeric opcodes when canonically encoded and the code failed to detect them properly. It also adds several tests to ensure that both canonical and non-canonical nulldata scripts are recognized properly and modifies the test failure print to include the script that failed. This does not affect consensus since it is just a standardness check.
This commit is contained in:
parent
07e1e308f1
commit
b60e3547d2
2 changed files with 53 additions and 21 deletions
|
@ -138,7 +138,8 @@ func isNullData(pops []parsedOpcode) bool {
|
||||||
|
|
||||||
return l == 2 &&
|
return l == 2 &&
|
||||||
pops[0].opcode.value == OP_RETURN &&
|
pops[0].opcode.value == OP_RETURN &&
|
||||||
pops[1].opcode.value <= OP_PUSHDATA4 &&
|
(isSmallInt(pops[1].opcode) || pops[1].opcode.value <=
|
||||||
|
OP_PUSHDATA4) &&
|
||||||
len(pops[1].data) <= MaxDataCarrierSize
|
len(pops[1].data) <= MaxDataCarrierSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -804,19 +804,15 @@ func TestCalcMultiSigStats(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scriptClassTest houses a test used to ensure various scripts have the
|
|
||||||
// expected class.
|
|
||||||
type scriptClassTest struct {
|
|
||||||
name string
|
|
||||||
script string
|
|
||||||
class txscript.ScriptClass
|
|
||||||
}
|
|
||||||
|
|
||||||
// scriptClassTests houses several test scripts used to ensure various class
|
// scriptClassTests houses several test scripts used to ensure various class
|
||||||
// determination is working as expected. It's defined as a test global versus
|
// determination is working as expected. It's defined as a test global versus
|
||||||
// inside a function scope since this spans both the standard tests and the
|
// inside a function scope since this spans both the standard tests and the
|
||||||
// consensus tests (pay-to-script-hash is part of consensus).
|
// consensus tests (pay-to-script-hash is part of consensus).
|
||||||
var scriptClassTests = []scriptClassTest{
|
var scriptClassTests = []struct {
|
||||||
|
name string
|
||||||
|
script string
|
||||||
|
class txscript.ScriptClass
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
name: "Pay Pubkey",
|
name: "Pay Pubkey",
|
||||||
script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
|
script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
|
||||||
|
@ -847,21 +843,56 @@ var scriptClassTests = []scriptClassTest{
|
||||||
"9ae88 EQUAL",
|
"9ae88 EQUAL",
|
||||||
class: txscript.ScriptHashTy,
|
class: txscript.ScriptHashTy,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
// Nulldata with no data at all.
|
// Nulldata with no data at all.
|
||||||
name: "nulldata",
|
name: "nulldata no data",
|
||||||
script: "RETURN",
|
script: "RETURN",
|
||||||
class: txscript.NullDataTy,
|
class: txscript.NullDataTy,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Nulldata with small data.
|
// Nulldata with single zero push.
|
||||||
name: "nulldata2",
|
name: "nulldata zero",
|
||||||
|
script: "RETURN 0",
|
||||||
|
class: txscript.NullDataTy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Nulldata with small integer push.
|
||||||
|
name: "nulldata small int",
|
||||||
|
script: "RETURN 1",
|
||||||
|
class: txscript.NullDataTy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Nulldata with max small integer push.
|
||||||
|
name: "nulldata max small int",
|
||||||
|
script: "RETURN 16",
|
||||||
|
class: txscript.NullDataTy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Nulldata with small data push.
|
||||||
|
name: "nulldata small data",
|
||||||
script: "RETURN DATA_8 0x046708afdb0fe554",
|
script: "RETURN DATA_8 0x046708afdb0fe554",
|
||||||
class: txscript.NullDataTy,
|
class: txscript.NullDataTy,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Nulldata with max allowed data.
|
// Canonical nulldata with 60-byte data push.
|
||||||
name: "nulldata3",
|
name: "canonical nulldata 60-byte push",
|
||||||
|
script: "RETURN 0x3c 0x046708afdb0fe5548271967f1a67130b7105cd" +
|
||||||
|
"6a828e03909a67962e0ea1f61deb649f6bc3f4cef3046708afdb" +
|
||||||
|
"0fe5548271967f1a67130b7105cd6a",
|
||||||
|
class: txscript.NullDataTy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Non-canonical nulldata with 60-byte data push.
|
||||||
|
name: "non-canonical nulldata 60-byte push",
|
||||||
|
script: "RETURN PUSHDATA1 0x3c 0x046708afdb0fe5548271967f1a67" +
|
||||||
|
"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
|
||||||
|
"046708afdb0fe5548271967f1a67130b7105cd6a",
|
||||||
|
class: txscript.NullDataTy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Nulldata with max allowed data to be considered standard.
|
||||||
|
name: "nulldata max standard push",
|
||||||
script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
|
script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
|
||||||
"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
|
"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
|
||||||
"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
|
"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
|
||||||
|
@ -869,9 +900,9 @@ var scriptClassTests = []scriptClassTest{
|
||||||
class: txscript.NullDataTy,
|
class: txscript.NullDataTy,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Nulldata with more than max allowed data (so therefore
|
// Nulldata with more than max allowed data to be considered
|
||||||
// nonstandard)
|
// standard (so therefore nonstandard)
|
||||||
name: "nulldata4",
|
name: "nulldata exceed max standard push",
|
||||||
script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
|
script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
|
||||||
"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
|
"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
|
||||||
"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
|
"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
|
||||||
|
@ -881,7 +912,7 @@ var scriptClassTests = []scriptClassTest{
|
||||||
{
|
{
|
||||||
// Almost nulldata, but add an additional opcode after the data
|
// Almost nulldata, but add an additional opcode after the data
|
||||||
// to make it nonstandard.
|
// to make it nonstandard.
|
||||||
name: "nulldata5",
|
name: "almost nulldata",
|
||||||
script: "RETURN 4 TRUE",
|
script: "RETURN 4 TRUE",
|
||||||
class: txscript.NonStandardTy,
|
class: txscript.NonStandardTy,
|
||||||
},
|
},
|
||||||
|
@ -951,8 +982,8 @@ func TestScriptClass(t *testing.T) {
|
||||||
script := mustParseShortForm(test.script)
|
script := mustParseShortForm(test.script)
|
||||||
class := txscript.GetScriptClass(script)
|
class := txscript.GetScriptClass(script)
|
||||||
if class != test.class {
|
if class != test.class {
|
||||||
t.Errorf("%s: expected %s got %s", test.name,
|
t.Errorf("%s: expected %s got %s (script %x)", test.name,
|
||||||
test.class, class)
|
test.class, class, script)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue