From 19ad31dc527f1c8fbd152a68f8f2b0cf4ccd7fbc Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 7 Jun 2022 10:29:13 +0300 Subject: [PATCH] vm: optimize IsSignatureContract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- pkg/vm/bench_test.go | 9 +++++++++ pkg/vm/contract_checks.go | 17 +++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/pkg/vm/bench_test.go b/pkg/vm/bench_test.go index c0403ea8b..d1ad21f24 100644 --- a/pkg/vm/bench_test.go +++ b/pkg/vm/bench_test.go @@ -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) + } +} diff --git a/pkg/vm/contract_checks.go b/pkg/vm/contract_checks.go index 1336765f4..51bb68040 100644 --- a/pkg/vm/contract_checks.go +++ b/pkg/vm/contract_checks.go @@ -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