txscript: Optimize IsPayToWitnessScriptHash
This converts the IsPayToWitnessScriptHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimizing the function. In order to accomplish this, it introduces two new functions. The first one is named extractWitnessScriptHash and works with the raw script byte to simultaneously deteremine if the script is a p2wsh script, and in the case that is is, extract and return the hash. The second new function is named isWitnessScriptHashScript and is defined in terms of the former. The extract function approach was chosed because it is common for callers to want to only extract relevant details from a script if the script is of the specific type. Extracting those details requires performing the exact same checks to ensure the script is of the correct type, so it is more efficient to combine the two into one and define the type determination in terms of the result, so long as the extraction does not require allocations. Finally, this also deprecates the isWitnessScriptHash function that requires opcodes in favor of the new functions and modifies the comment on IsPayToWitnessScriptHash to call out the script version semantics. The following is a before and after comparison of executing IsPayToWitnessScriptHash on a large script: benchmark old ns/op new ns/op delta BenchmarkIsWitnessScriptHash-8 62774 0.63 -100.00% benchmark old allocs new allocs delta BenchmarkIsWitnessScriptHash-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsWitnessScriptHash-8 311299 0 -100.00%
This commit is contained in:
parent
b3dd941a77
commit
44c6be3d4e
2 changed files with 23 additions and 5 deletions
|
@ -100,11 +100,7 @@ func isWitnessScriptHash(pops []parsedOpcode) bool {
|
|||
// IsPayToWitnessScriptHash returns true if the is in the standard
|
||||
// pay-to-witness-script-hash (P2WSH) format, false otherwise.
|
||||
func IsPayToWitnessScriptHash(script []byte) bool {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isWitnessScriptHash(pops)
|
||||
return isWitnessScriptHashScript(script)
|
||||
}
|
||||
|
||||
// IsPayToWitnessPubKeyHash returns true if the is in the standard
|
||||
|
|
|
@ -421,6 +421,28 @@ func isWitnessPubKeyHashScript(script []byte) bool {
|
|||
return extractWitnessPubKeyHash(script) != nil
|
||||
}
|
||||
|
||||
// extractWitnessScriptHash extracts the witness script hash from the passed
|
||||
// script if it is standard pay-to-witness-script-hash script. It will return
|
||||
// nil otherwise.
|
||||
func extractWitnessScriptHash(script []byte) []byte {
|
||||
// A pay-to-witness-script-hash script is of the form:
|
||||
// OP_0 OP_DATA_32 <32-byte-hash>
|
||||
if len(script) == 34 &&
|
||||
script[0] == OP_0 &&
|
||||
script[1] == OP_DATA_32 {
|
||||
|
||||
return script[2:34]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isWitnessScriptHashScript returns whether or not the passed script is a
|
||||
// standard pay-to-witness-script-hash script.
|
||||
func isWitnessScriptHashScript(script []byte) bool {
|
||||
return extractWitnessScriptHash(script) != nil
|
||||
}
|
||||
|
||||
// isNullData returns true if the passed script is a null data transaction,
|
||||
// false otherwise.
|
||||
func isNullData(pops []parsedOpcode) bool {
|
||||
|
|
Loading…
Reference in a new issue