Use ScriptVerifyMinimalData

Additionally, drop HasCanoncialPushes as ScriptVerifyMinimalData
offers more complete checks.
This commit is contained in:
David Hill 2015-02-24 20:11:57 -05:00
parent 3ed8f363e7
commit ff747f8eae
5 changed files with 41 additions and 38 deletions

View file

@ -274,16 +274,6 @@ func checkTransactionStandard(tx *btcutil.Tx, height int64) error {
"script is not push only", i) "script is not push only", i)
return txRuleError(wire.RejectNonstandard, str) return txRuleError(wire.RejectNonstandard, str)
} }
// Each transaction input signature script must only contain
// canonical data pushes. A canonical data push is one where
// the minimum possible number of bytes is used to represent
// the data push as possible.
if !txscript.HasCanonicalPushes(txIn.SignatureScript) {
str := fmt.Sprintf("transaction input %d: signature "+
"script has a non-canonical data push", i)
return txRuleError(wire.RejectNonstandard, str)
}
} }
// None of the output public key scripts can be a non-standard script or // None of the output public key scripts can be a non-standard script or

View file

@ -48,6 +48,7 @@ const (
// are more strict. // are more strict.
standardScriptVerifyFlags = txscript.ScriptBip16 | standardScriptVerifyFlags = txscript.ScriptBip16 |
txscript.ScriptVerifyDERSignatures | txscript.ScriptVerifyDERSignatures |
txscript.ScriptVerifyMinimalData |
txscript.ScriptStrictMultiSig | txscript.ScriptStrictMultiSig |
txscript.ScriptDiscourageUpgradableNops txscript.ScriptDiscourageUpgradableNops
) )

View file

@ -22,6 +22,14 @@ import (
// test package. // test package.
const TstMaxScriptSize = maxScriptSize const TstMaxScriptSize = maxScriptSize
// TstHasCanoncialPushes makes the internal isCanonicalPush function available
// to the test package.
var TstHasCanonicalPushes = canonicalPush
// TstParseScript makes the internal parseScript function available to the
// test package.
var TstParseScript = parseScript
// this file is present to export some internal interfaces so that we can // this file is present to export some internal interfaces so that we can
// test them reliably. // test them reliably.

View file

@ -484,26 +484,6 @@ func canonicalPush(pop parsedOpcode) bool {
return true return true
} }
// HasCanonicalPushes returns whether or not the passed script only contains
// canonical data pushes. A canonical data push one where the fewest number of
// bytes possible to encode the size of the data being pushed is used. This
// includes using the small integer opcodes for single byte data that can be
// represented directly.
func HasCanonicalPushes(script []byte) bool {
pops, err := parseScript(script)
if err != nil {
return false
}
for _, pop := range pops {
if !canonicalPush(pop) {
return false
}
}
return true
}
// GetScriptClass returns the class of the script passed. If the script does not // GetScriptClass returns the class of the script passed. If the script does not
// parse then NonStandardTy will be returned. // parse then NonStandardTy will be returned.
func GetScriptClass(script []byte) ScriptClass { func GetScriptClass(script []byte) ScriptClass {

View file

@ -106,10 +106,17 @@ func TestStandardPushes(t *testing.T) {
t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script) t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script)
continue continue
} }
if result := txscript.HasCanonicalPushes(script); !result { pops, err := txscript.TstParseScript(script)
t.Errorf("StandardPushesTests HasCanonicalPushes test #%d failed: %x\n", i, script) if err != nil {
t.Errorf("StandardPushesTests #%d failed to TstParseScript: %v", i, err)
continue continue
} }
for _, pop := range pops {
if result := txscript.TstHasCanonicalPushes(pop); !result {
t.Errorf("StandardPushesTests TstHasCanonicalPushes test #%d failed: %x\n", i, script)
break
}
}
} }
for i := 0; i <= txscript.MaxScriptElementSize; i++ { for i := 0; i <= txscript.MaxScriptElementSize; i++ {
builder := txscript.NewScriptBuilder() builder := txscript.NewScriptBuilder()
@ -123,10 +130,17 @@ func TestStandardPushes(t *testing.T) {
t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script) t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, script)
continue continue
} }
if result := txscript.HasCanonicalPushes(script); !result { pops, err := txscript.TstParseScript(script)
t.Errorf("StandardPushesTests HasCanonicalPushes test #%d failed: %x\n", i, script) if err != nil {
t.Errorf("StandardPushesTests #%d failed to TstParseScript: %v", i, err)
continue continue
} }
for _, pop := range pops {
if result := txscript.TstHasCanonicalPushes(pop); !result {
t.Errorf("StandardPushesTests TstHasCanonicalPushes test #%d failed: %x\n", i, script)
break
}
}
} }
} }
@ -4750,10 +4764,20 @@ func TestHasCanonicalPushes(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
if txscript.HasCanonicalPushes(test.script) != test.expected { pops, err := txscript.TstParseScript(test.script)
t.Errorf("HasCanonicalPushes #%d (%s) wrong result\n"+ if err != nil {
if test.expected {
t.Errorf("StandardPushesTests #%d failed to TstParseScript: %v", i, err)
}
continue
}
for _, pop := range pops {
if txscript.TstHasCanonicalPushes(pop) != test.expected {
t.Errorf("TstHasCanonicalPushes #%d (%s) wrong result\n"+
"got: %v\nwant: %v", i, test.name, true, "got: %v\nwant: %v", i, test.name, true,
test.expected) test.expected)
break
}
} }
} }
} }