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:
parent
aee200720d
commit
d4c3a17883
6 changed files with 11 additions and 44 deletions
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue