From 9586af32f2da5cfa3153eac5342035f97f74ea43 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 13 Apr 2020 15:56:41 +0300 Subject: [PATCH] core: move runtime.CheckWitness interop to a separate package --- pkg/core/interop/runtime/witness.go | 54 +++++++++++++++++++++++++++++ pkg/core/interop_neo.go | 3 +- pkg/core/interop_system.go | 46 ------------------------ pkg/core/interops.go | 7 ++-- 4 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 pkg/core/interop/runtime/witness.go diff --git a/pkg/core/interop/runtime/witness.go b/pkg/core/interop/runtime/witness.go new file mode 100644 index 000000000..1f1dd58f6 --- /dev/null +++ b/pkg/core/interop/runtime/witness.go @@ -0,0 +1,54 @@ +package runtime + +import ( + "github.com/nspcc-dev/neo-go/pkg/core/interop" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm" + "github.com/pkg/errors" +) + +// CheckHashedWitness checks given hash against current list of script hashes +// for verifying in the interop context. +func CheckHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) { + hashes, err := ic.Chain.GetScriptHashesForVerifying(ic.Tx) + if err != nil { + return false, errors.Wrap(err, "failed to get script hashes") + } + for _, v := range hashes { + if hash.Equals(v) { + return true, nil + } + } + return false, nil +} + +// CheckKeyedWitness checks hash of signature check contract with a given public +// key against current list of script hashes for verifying in the interop context. +func CheckKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) { + return CheckHashedWitness(ic, key.GetScriptHash()) +} + +// CheckWitness checks witnesses. +func CheckWitness(ic *interop.Context, v *vm.VM) error { + var res bool + var err error + + hashOrKey := v.Estack().Pop().Bytes() + hash, err := util.Uint160DecodeBytesBE(hashOrKey) + if err != nil { + var key *keys.PublicKey + key, err = keys.NewPublicKeyFromBytes(hashOrKey) + if err != nil { + return errors.New("parameter given is neither a key nor a hash") + } + res, err = CheckKeyedWitness(ic, key) + } else { + res, err = CheckHashedWitness(ic, hash) + } + if err != nil { + return errors.Wrap(err, "failed to check") + } + v.Estack().PushVal(res) + return nil +} diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index 31fb8ac28..c43b85ccb 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/nspcc-dev/neo-go/pkg/core/interop" + "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/keys" @@ -635,7 +636,7 @@ func assetCreate(ic *interop.Context, v *vm.VM) error { if owner.IsInfinity() { return errors.New("can't have infinity as an owner key") } - witnessOk, err := checkKeyedWitness(ic, owner) + witnessOk, err := runtime.CheckKeyedWitness(ic, owner) if err != nil { return err } diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 0809e8b6a..116a65b54 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -11,11 +11,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop" "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/keys" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" - gherr "github.com/pkg/errors" "go.uber.org/zap" ) @@ -279,50 +277,6 @@ func runtimeGetTrigger(ic *interop.Context, v *vm.VM) error { return nil } -// checkHashedWitness checks given hash against current list of script hashes -// for verifying in the interop context. -func checkHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) { - hashes, err := ic.Chain.GetScriptHashesForVerifying(ic.Tx) - if err != nil { - return false, gherr.Wrap(err, "failed to get script hashes") - } - for _, v := range hashes { - if hash.Equals(v) { - return true, nil - } - } - return false, nil -} - -// checkKeyedWitness checks hash of signature check contract with a given public -// key against current list of script hashes for verifying in the interop context. -func checkKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) { - return checkHashedWitness(ic, key.GetScriptHash()) -} - -// runtimeCheckWitness checks witnesses. -func runtimeCheckWitness(ic *interop.Context, v *vm.VM) error { - var res bool - var err error - - hashOrKey := v.Estack().Pop().Bytes() - hash, err := util.Uint160DecodeBytesBE(hashOrKey) - if err != nil { - key, err := keys.NewPublicKeyFromBytes(hashOrKey) - if err != nil { - return errors.New("parameter given is neither a key nor a hash") - } - res, err = checkKeyedWitness(ic, key) - } else { - res, err = checkHashedWitness(ic, hash) - } - if err != nil { - return gherr.Wrap(err, "failed to check") - } - v.Estack().PushVal(res) - return nil -} - // runtimeNotify should pass stack item to the notify plugin to handle it, but // in neo-go the only meaningful thing to do here is to log. func runtimeNotify(ic *interop.Context, v *vm.VM) error { diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 5b337957c..3d4d8355c 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -14,6 +14,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator" "github.com/nspcc-dev/neo-go/pkg/core/interop/iterator" + "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" @@ -85,7 +86,7 @@ var systemInterops = []interop.Function{ {Name: "System.Header.GetIndex", Func: headerGetIndex, Price: 1}, {Name: "System.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1}, {Name: "System.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1}, - {Name: "System.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200}, + {Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200}, {Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1}, {Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1}, {Name: "System.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1}, @@ -163,7 +164,7 @@ var neoInterops = []interop.Function{ {Name: "Neo.Output.GetAssetId", Func: outputGetAssetID, Price: 1}, {Name: "Neo.Output.GetScriptHash", Func: outputGetScriptHash, Price: 1}, {Name: "Neo.Output.GetValue", Func: outputGetValue, Price: 1}, - {Name: "Neo.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200}, + {Name: "Neo.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200}, {Name: "Neo.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1}, {Name: "Neo.Runtime.GetTime", Func: runtimeGetTime, Price: 1}, {Name: "Neo.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1}, @@ -235,7 +236,7 @@ var neoInterops = []interop.Function{ {Name: "AntShares.Output.GetAssetId", Func: outputGetAssetID, Price: 1}, {Name: "AntShares.Output.GetScriptHash", Func: outputGetScriptHash, Price: 1}, {Name: "AntShares.Output.GetValue", Func: outputGetValue, Price: 1}, - {Name: "AntShares.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200}, + {Name: "AntShares.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200}, {Name: "AntShares.Runtime.Log", Func: runtimeLog, Price: 1}, {Name: "AntShares.Runtime.Notify", Func: runtimeNotify, Price: 1}, {Name: "AntShares.Storage.Delete", Func: storageDelete, Price: 100},