txscript: Optimize IsPayToPubKeyHash
This converts the IsPayToPubKeyHash function to analyze the raw script instead of using the far less efficient parseScript, thereby significantly optimization the function. In order to accomplish this, it introduces two new functions. The first one is named extractPubKeyHash and works with the raw script bytes to simultaneously determine if the script is a pay-to-pubkey-hash script, and in the case it is, extract and return the hash. The second new function is named isPubKeyHashScript and is defined in terms of the former. The extract function approach was chosen 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. The following is a before and after comparison of analyzing a large script: benchmark old ns/op new ns/op delta BenchmarkIsPubKeyHashScript-8 62228 0.45 -100.00% benchmark old allocs new allocs delta BenchmarkIsPubKeyHashScript-8 1 0 -100.00% benchmark old bytes new bytes delta BenchmarkIsPubKeyHashScript-8 311299 0 -100.00%
This commit is contained in:
parent
c4da180d4f
commit
eb03d84098
2 changed files with 25 additions and 5 deletions
|
@ -72,11 +72,7 @@ func IsPayToPubKey(script []byte) bool {
|
|||
// IsPayToPubKeyHash returns true if the script is in the standard
|
||||
// pay-to-pubkey-hash (P2PKH) format, false otherwise.
|
||||
func IsPayToPubKeyHash(script []byte) bool {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isPubkeyHash(pops)
|
||||
return isPubKeyHashScript(script)
|
||||
}
|
||||
|
||||
// IsPayToScriptHash returns true if the script is in the standard
|
||||
|
|
|
@ -143,6 +143,30 @@ func isPubKeyScript(script []byte) bool {
|
|||
return extractPubKey(script) != nil
|
||||
}
|
||||
|
||||
// extractPubKeyHash extracts the public key hash from the passed script if it
|
||||
// is a standard pay-to-pubkey-hash script. It will return nil otherwise.
|
||||
func extractPubKeyHash(script []byte) []byte {
|
||||
// A pay-to-pubkey-hash script is of the form:
|
||||
// OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
if len(script) == 25 &&
|
||||
script[0] == OP_DUP &&
|
||||
script[1] == OP_HASH160 &&
|
||||
script[2] == OP_DATA_20 &&
|
||||
script[23] == OP_EQUALVERIFY &&
|
||||
script[24] == OP_CHECKSIG {
|
||||
|
||||
return script[3:23]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isPubKeyHashScript returns whether or not the passed script is a standard
|
||||
// pay-to-pubkey-hash script.
|
||||
func isPubKeyHashScript(script []byte) bool {
|
||||
return extractPubKeyHash(script) != nil
|
||||
}
|
||||
|
||||
// isPubkey returns true if the script passed is a pay-to-pubkey transaction,
|
||||
// false otherwise.
|
||||
func isPubkey(pops []parsedOpcode) bool {
|
||||
|
|
Loading…
Reference in a new issue