forked from TrueCloudLab/neoneo-go
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
|
Notifications []state.NotificationEvent
|
||||||
Log *zap.Logger
|
Log *zap.Logger
|
||||||
Invocations map[util.Uint160]int
|
Invocations map[util.Uint160]int
|
||||||
|
ScriptGetter vm.ScriptHashGetter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext returns new interop context.
|
// NewContext returns new interop context.
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
|
|
||||||
// CheckHashedWitness checks given hash against current list of script hashes
|
// CheckHashedWitness checks given hash against current list of script hashes
|
||||||
// for verifying in the interop context.
|
// 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 {
|
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.)
|
// 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
|
// CheckKeyedWitness checks hash of signature check contract with a given public
|
||||||
// key against current list of script hashes for verifying in the interop context.
|
// 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) {
|
func CheckKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) {
|
||||||
return CheckHashedWitness(ic, v, key.GetScriptHash())
|
return CheckHashedWitness(ic, key.GetScriptHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckWitness checks witnesses.
|
// CheckWitness checks witnesses.
|
||||||
|
@ -94,9 +94,9 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("parameter given is neither a key nor a hash")
|
return errors.New("parameter given is neither a key nor a hash")
|
||||||
}
|
}
|
||||||
res, err = CheckKeyedWitness(ic, v, key)
|
res, err = CheckKeyedWitness(ic, key)
|
||||||
} else {
|
} else {
|
||||||
res, err = CheckHashedWitness(ic, v, hash)
|
res, err = CheckHashedWitness(ic, hash)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to check")
|
return errors.Wrap(err, "failed to check")
|
||||||
|
|
|
@ -32,6 +32,7 @@ func SpawnVM(ic *interop.Context) *vm.VM {
|
||||||
if ic.Chain != nil {
|
if ic.Chain != nil {
|
||||||
vm.RegisterInteropGetter(ic.Chain.(*Blockchain).contracts.GetNativeInterop(ic))
|
vm.RegisterInteropGetter(ic.Chain.(*Blockchain).contracts.GetNativeInterop(ic))
|
||||||
}
|
}
|
||||||
|
ic.ScriptGetter = vm
|
||||||
return 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.
|
// VoteInternal votes from account h for validarors specified in pubs.
|
||||||
func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.PublicKeys) error {
|
func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.PublicKeys) error {
|
||||||
ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
ok, err := runtime.CheckHashedWitness(ic, h)
|
||||||
callingScriptHash: util.Uint160{},
|
|
||||||
entryScriptHash: n.Hash,
|
|
||||||
currentScriptHash: n.Hash,
|
|
||||||
}, h)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
|
|
|
@ -175,11 +175,7 @@ func (c *nep5TokenNative) transfer(ic *interop.Context, from, to util.Uint160, a
|
||||||
return errors.New("negative amount")
|
return errors.New("negative amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
ok, err := runtime.CheckHashedWitness(ic, from)
|
||||||
callingScriptHash: c.Hash,
|
|
||||||
entryScriptHash: c.Hash,
|
|
||||||
currentScriptHash: c.Hash,
|
|
||||||
}, from)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
|
@ -301,29 +297,6 @@ func toUint160(s stackitem.Item) util.Uint160 {
|
||||||
return u
|
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 {
|
func getOnPersistWrapper(f func(ic *interop.Context) error) interop.Method {
|
||||||
return func(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
return func(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
||||||
return stackitem.NewBool(f(ic) == nil)
|
return stackitem.NewBool(f(ic) == nil)
|
||||||
|
|
|
@ -423,11 +423,7 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus)
|
||||||
callingScriptHash: p.Hash,
|
|
||||||
entryScriptHash: p.Hash,
|
|
||||||
currentScriptHash: p.Hash,
|
|
||||||
}, prevBlock.NextConsensus)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckPolicy checks whether transaction's script hashes for verifying are
|
// CheckPolicy checks whether transaction's script hashes for verifying are
|
||||||
|
|
Loading…
Reference in a new issue