Make removeOpcodeByData only search canonical pushes.
Matches bitcoind behaviour. Pointed out by one of their tx_invalid tests.
This commit is contained in:
parent
76339baf6c
commit
1b1fef7369
2 changed files with 11044 additions and 29 deletions
45
script.go
45
script.go
|
@ -325,6 +325,32 @@ func IsPushOnlyScript(script []byte) bool {
|
||||||
return isPushOnly(pops)
|
return isPushOnly(pops)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// canonicalPush returns true if the object is either not a push instruction
|
||||||
|
// or the push instruction contained wherein is matches the canonical form
|
||||||
|
// or using the smallest instruction to do the job. False otherwise.
|
||||||
|
func canonicalPush(pop parsedOpcode) bool {
|
||||||
|
opcode := pop.opcode.value
|
||||||
|
data := pop.data
|
||||||
|
dataLen := len(pop.data)
|
||||||
|
if opcode > OP_16 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA2 && dataLen <= 0xff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA4 && dataLen <= 0xffff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// HasCanonicalPushes returns whether or not the passed script only contains
|
// HasCanonicalPushes returns whether or not the passed script only contains
|
||||||
// canonical data pushes. A canonical data push one where the fewest number of
|
// 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
|
// bytes possible to encode the size of the data being pushed is used. This
|
||||||
|
@ -337,22 +363,7 @@ func HasCanonicalPushes(script []byte) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pop := range pops {
|
for _, pop := range pops {
|
||||||
opcode := pop.opcode.value
|
if !canonicalPush(pop) {
|
||||||
data := pop.data
|
|
||||||
dataLen := len(pop.data)
|
|
||||||
if opcode > OP_16 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if opcode == OP_PUSHDATA2 && dataLen <= 0xff {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if opcode == OP_PUSHDATA4 && dataLen <= 0xffff {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,7 +765,7 @@ func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode {
|
||||||
func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
|
func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
|
||||||
retScript := make([]parsedOpcode, 0, len(pkscript))
|
retScript := make([]parsedOpcode, 0, len(pkscript))
|
||||||
for _, pop := range pkscript {
|
for _, pop := range pkscript {
|
||||||
if !bytes.Contains(pop.data, data) {
|
if !canonicalPush(pop) || !bytes.Contains(pop.data, data) {
|
||||||
retScript = append(retScript, pop)
|
retScript = append(retScript, pop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11018
script_test.go
11018
script_test.go
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue