vm: optimize IsSignatureContract

We use it a lot in (*Blockchain).IsTxStillRelevant().

name                   old time/op    new time/op    delta
IsSignatureContract-8    19.1ns ± 5%     1.2ns ± 4%  -93.81%  (p=0.000 n=10+10)

name                   old alloc/op   new alloc/op   delta
IsSignatureContract-8     0.00B          0.00B          ~     (all equal)

name                   old allocs/op  new allocs/op  delta
IsSignatureContract-8      0.00           0.00          ~     (all equal)
This commit is contained in:
Roman Khimov 2022-06-07 10:29:13 +03:00
parent 92c94f265c
commit 19ad31dc52
2 changed files with 16 additions and 10 deletions

View file

@ -48,3 +48,12 @@ func BenchmarkScriptPushPop(t *testing.B) {
})
}
}
func BenchmarkIsSignatureContract(t *testing.B) {
b64script := "DCED2eixa9myLTNF1tTN4xvhw+HRYVMuPQzOy5Xs4utYM25BVuezJw=="
script, err := base64.StdEncoding.DecodeString(b64script)
require.NoError(t, err)
for n := 0; n < t.N; n++ {
_ = IsSignatureContract(script)
}
}

View file

@ -118,17 +118,14 @@ func ParseSignatureContract(script []byte) ([]byte, bool) {
return nil, false
}
ctx := NewContext(script)
instr, param, err := ctx.Next()
if err != nil || instr != opcode.PUSHDATA1 || len(param) != 33 {
return nil, false
// We don't use Context for this simple case, it's more efficient this way.
if script[0] == byte(opcode.PUSHDATA1) && // PUSHDATA1
script[1] == 33 && // with a public key parameter
script[35] == byte(opcode.SYSCALL) && // and a CheckSig SYSCALL.
binary.LittleEndian.Uint32(script[36:]) == verifyInteropID {
return script[2:35], true
}
pub := param
instr, param, err = ctx.Next()
if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != verifyInteropID {
return nil, false
}
return pub, true
return nil, false
}
// IsStandardContract checks whether the passed script is a signature or