From d4c3a17883ccba0518e66aab09042eeb071bebde Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 15 Jul 2020 22:43:30 +0300 Subject: [PATCH] interop/native: always use proper ScriptHashGetter, fix #924 All scripts are run in VM, so it's there to tell us about script hashes involved and it must be used instead of nep5ScriptHash kludge. --- pkg/core/interop/context.go | 1 + pkg/core/interop/runtime/witness.go | 12 ++++++------ pkg/core/interops.go | 1 + pkg/core/native/native_neo.go | 6 +----- pkg/core/native/native_nep5.go | 29 +---------------------------- pkg/core/native/policy.go | 6 +----- 6 files changed, 11 insertions(+), 44 deletions(-) diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index b92e39661..3b9d5edbd 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -31,6 +31,7 @@ type Context struct { Notifications []state.NotificationEvent Log *zap.Logger Invocations map[util.Uint160]int + ScriptGetter vm.ScriptHashGetter } // NewContext returns new interop context. diff --git a/pkg/core/interop/runtime/witness.go b/pkg/core/interop/runtime/witness.go index c152a8eff..48ede6d86 100644 --- a/pkg/core/interop/runtime/witness.go +++ b/pkg/core/interop/runtime/witness.go @@ -12,9 +12,9 @@ import ( // CheckHashedWitness checks given hash against current list of script hashes // for verifying in the interop context. -func CheckHashedWitness(ic *interop.Context, v vm.ScriptHashGetter, hash util.Uint160) (bool, error) { +func CheckHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) { if tx, ok := ic.Container.(*transaction.Transaction); ok { - return checkScope(ic.DAO, tx, v, hash) + return checkScope(ic.DAO, tx, ic.ScriptGetter, hash) } // only for non-Transaction types (Block, etc.) @@ -77,8 +77,8 @@ func checkScope(d dao.DAO, tx *transaction.Transaction, v vm.ScriptHashGetter, h // 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, v vm.ScriptHashGetter, key *keys.PublicKey) (bool, error) { - return CheckHashedWitness(ic, v, key.GetScriptHash()) +func CheckKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) { + return CheckHashedWitness(ic, key.GetScriptHash()) } // CheckWitness checks witnesses. @@ -94,9 +94,9 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error { if err != nil { return errors.New("parameter given is neither a key nor a hash") } - res, err = CheckKeyedWitness(ic, v, key) + res, err = CheckKeyedWitness(ic, key) } else { - res, err = CheckHashedWitness(ic, v, hash) + res, err = CheckHashedWitness(ic, hash) } if err != nil { return errors.Wrap(err, "failed to check") diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 35bb5e5ae..769b46645 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -32,6 +32,7 @@ func SpawnVM(ic *interop.Context) *vm.VM { if ic.Chain != nil { vm.RegisterInteropGetter(ic.Chain.(*Blockchain).contracts.GetNativeInterop(ic)) } + ic.ScriptGetter = vm return vm } diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 747025315..b9328bf67 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -253,11 +253,7 @@ func (n *NEO) vote(ic *interop.Context, args []stackitem.Item) stackitem.Item { // VoteInternal votes from account h for validarors specified in pubs. func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.PublicKeys) error { - ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{ - callingScriptHash: util.Uint160{}, - entryScriptHash: n.Hash, - currentScriptHash: n.Hash, - }, h) + ok, err := runtime.CheckHashedWitness(ic, h) if err != nil { return err } else if !ok { diff --git a/pkg/core/native/native_nep5.go b/pkg/core/native/native_nep5.go index 40ee7cbac..65b039e5c 100644 --- a/pkg/core/native/native_nep5.go +++ b/pkg/core/native/native_nep5.go @@ -175,11 +175,7 @@ func (c *nep5TokenNative) transfer(ic *interop.Context, from, to util.Uint160, a return errors.New("negative amount") } - ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{ - callingScriptHash: c.Hash, - entryScriptHash: c.Hash, - currentScriptHash: c.Hash, - }, from) + ok, err := runtime.CheckHashedWitness(ic, from) if err != nil { return err } else if !ok { @@ -301,29 +297,6 @@ func toUint160(s stackitem.Item) util.Uint160 { return u } -// scriptHash is an auxiliary structure which implements ScriptHashGetter -// interface over NEP5 native contract and is used for runtime.CheckHashedWitness -type nep5ScriptHash struct { - callingScriptHash util.Uint160 - entryScriptHash util.Uint160 - currentScriptHash util.Uint160 -} - -// GetCallingScriptHash implements ScriptHashGetter interface -func (s nep5ScriptHash) GetCallingScriptHash() util.Uint160 { - return s.callingScriptHash -} - -// GetEntryScriptHash implements ScriptHashGetter interface -func (s nep5ScriptHash) GetEntryScriptHash() util.Uint160 { - return s.entryScriptHash -} - -// GetCurrentScriptHash implements ScriptHashGetter interface -func (s nep5ScriptHash) GetCurrentScriptHash() util.Uint160 { - return s.currentScriptHash -} - func getOnPersistWrapper(f func(ic *interop.Context) error) interop.Method { return func(ic *interop.Context, _ []stackitem.Item) stackitem.Item { return stackitem.NewBool(f(ic) == nil) diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index ef74af543..add317852 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -423,11 +423,7 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) { if err != nil { return false, err } - return runtime.CheckHashedWitness(ic, nep5ScriptHash{ - callingScriptHash: p.Hash, - entryScriptHash: p.Hash, - currentScriptHash: p.Hash, - }, prevBlock.NextConsensus) + return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus) } // CheckPolicy checks whether transaction's script hashes for verifying are