From 1a5fb01e61ee85cecf81ea172fb974b75f2b3260 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 16 Jul 2020 09:56:57 +0300 Subject: [PATCH] core: adjust System.Contract.IsStandard interop Part of #1055. It should check not only stored contracts, but also interop context script container in case if it's a transaction. --- pkg/core/interop_system.go | 13 +++++++++++-- pkg/core/interop_system_test.go | 34 +++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 06632c813..de84623aa 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -486,8 +486,17 @@ func contractIsStandard(ic *interop.Context, v *vm.VM) error { } var result bool cs, _ := ic.DAO.GetContractState(u) - if cs == nil || vm.IsStandardContract(cs.Script) { - result = true + if cs != nil { + result = vm.IsStandardContract(cs.Script) + } else { + if tx, ok := ic.Container.(*transaction.Transaction); ok { + for _, witness := range tx.Scripts { + if witness.ScriptHash() == u { + result = vm.IsStandardContract(witness.VerificationScript) + break + } + } + } } v.Estack().PushVal(result) return nil diff --git a/pkg/core/interop_system_test.go b/pkg/core/interop_system_test.go index a47894946..e17b3ffe2 100644 --- a/pkg/core/interop_system_test.go +++ b/pkg/core/interop_system_test.go @@ -5,8 +5,10 @@ import ( "testing" "github.com/nspcc-dev/dbft/crypto" + "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/core/state" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" @@ -157,7 +159,35 @@ func TestContractIsStandard(t *testing.T) { v, ic, chain := createVM(t) defer chain.Close() - t.Run("True", func(t *testing.T) { + t.Run("contract not stored", func(t *testing.T) { + priv, err := keys.NewPrivateKey() + require.NoError(t, err) + + pub := priv.PublicKey() + tx := transaction.New(netmode.TestNet, []byte{1, 2, 3}, 1) + tx.Scripts = []transaction.Witness{ + { + InvocationScript: []byte{1, 2, 3}, + VerificationScript: pub.GetVerificationScript(), + }, + } + ic.Container = tx + + t.Run("true", func(t *testing.T) { + v.Estack().PushVal(pub.GetScriptHash().BytesBE()) + require.NoError(t, contractIsStandard(ic, v)) + require.True(t, v.Estack().Pop().Bool()) + }) + + t.Run("false", func(t *testing.T) { + tx.Scripts[0].VerificationScript = []byte{9, 8, 7} + v.Estack().PushVal(pub.GetScriptHash().BytesBE()) + require.NoError(t, contractIsStandard(ic, v)) + require.False(t, v.Estack().Pop().Bool()) + }) + }) + + t.Run("contract stored, true", func(t *testing.T) { priv, err := keys.NewPrivateKey() require.NoError(t, err) @@ -169,7 +199,7 @@ func TestContractIsStandard(t *testing.T) { require.NoError(t, contractIsStandard(ic, v)) require.True(t, v.Estack().Pop().Bool()) }) - t.Run("False", func(t *testing.T) { + t.Run("contract stored, false", func(t *testing.T) { script := []byte{byte(opcode.PUSHT)} require.NoError(t, ic.DAO.PutContractState(&state.Contract{ID: 24, Script: script}))