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.
This commit is contained in:
Roman Khimov 2020-07-15 22:43:30 +03:00
parent aee200720d
commit d4c3a17883
6 changed files with 11 additions and 44 deletions

View file

@ -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.

View file

@ -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")

View file

@ -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
}

View file

@ -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 {

View file

@ -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)

View file

@ -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