core: simplify interop functions

We now have the only interop table (system interops).
This commit is contained in:
Anna Shaleva 2021-05-11 17:40:03 +03:00
parent 6d59689d9c
commit 4b933f88a7
7 changed files with 23 additions and 42 deletions

View file

@ -94,10 +94,8 @@ func TestSyscallExecution(t *testing.T) {
ic := &interop.Context{} ic := &interop.Context{}
core.SpawnVM(ic) // set Functions field core.SpawnVM(ic) // set Functions field
for _, fs := range ic.Functions { for _, fs := range ic.Functions {
for i := range fs { // It will be set in test and we want to fail if calling invalid syscall.
// It will be set in test and we want to fail if calling invalid syscall. fs.Func = nil
fs[i].Func = nil
}
} }
for goName, tc := range interops { for goName, tc := range interops {
t.Run(goName, func(t *testing.T) { t.Run(goName, func(t *testing.T) {

View file

@ -1860,7 +1860,7 @@ func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context { func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context {
ic := interop.NewContext(trigger, bc, d, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log) ic := interop.NewContext(trigger, bc, d, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log)
ic.Functions = [][]interop.Function{systemInterops, neoInterops} ic.Functions = systemInterops
switch { switch {
case tx != nil: case tx != nil:
ic.Container = tx ic.Container = tx

View file

@ -44,7 +44,7 @@ type Context struct {
Notifications []state.NotificationEvent Notifications []state.NotificationEvent
Log *zap.Logger Log *zap.Logger
VM *vm.VM VM *vm.VM
Functions [][]Function Functions []Function
getContract func(dao.DAO, util.Uint160) (*state.Contract, error) getContract func(dao.DAO, util.Uint160) (*state.Contract, error)
} }
@ -64,8 +64,8 @@ func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO,
DAO: dao, DAO: dao,
Notifications: nes, Notifications: nes,
Log: log, Log: log,
// Functions is a slice of slices of interops sorted by ID. // Functions is a slice of interops sorted by ID.
Functions: [][]Function{}, Functions: []Function{},
getContract: getContract, getContract: getContract,
} }
} }
@ -229,13 +229,11 @@ func (ic *Context) GetContract(hash util.Uint160) (*state.Contract, error) {
// GetFunction returns metadata for interop with the specified id. // GetFunction returns metadata for interop with the specified id.
func (ic *Context) GetFunction(id uint32) *Function { func (ic *Context) GetFunction(id uint32) *Function {
for _, slice := range ic.Functions { n := sort.Search(len(ic.Functions), func(i int) bool {
n := sort.Search(len(slice), func(i int) bool { return ic.Functions[i].ID >= id
return slice[i].ID >= id })
}) if n < len(ic.Functions) && ic.Functions[n].ID == id {
if n < len(slice) && slice[n].ID == id { return &ic.Functions[n]
return &slice[n]
}
} }
return nil return nil
} }

View file

@ -71,8 +71,8 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM {
Network: uint32(netmode.UnitTestNet), Network: uint32(netmode.UnitTestNet),
Trigger: trigger.Verification, Trigger: trigger.Verification,
Container: container, Container: container,
Functions: Interops,
} }
Register(ic)
v := ic.SpawnVM() v := ic.SpawnVM()
v.LoadScript(buf) v.LoadScript(buf)
return v return v

View file

@ -10,16 +10,12 @@ var (
neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckSig)) neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckSig))
) )
var cryptoInterops = []interop.Function{ // Interops represents sorted crypto-related interop functions.
var Interops = []interop.Function{
{ID: neoCryptoCheckMultisigID, Func: ECDSASecp256r1CheckMultisig}, {ID: neoCryptoCheckMultisigID, Func: ECDSASecp256r1CheckMultisig},
{ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig}, {ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig},
} }
func init() { func init() {
interop.Sort(cryptoInterops) interop.Sort(Interops)
}
// Register adds crypto interops to ic.
func Register(ic *interop.Context) {
ic.Functions = append(ic.Functions, cryptoInterops)
} }

View file

@ -24,7 +24,7 @@ import (
// up for current blockchain. // up for current blockchain.
func SpawnVM(ic *interop.Context) *vm.VM { func SpawnVM(ic *interop.Context) *vm.VM {
vm := ic.SpawnVM() vm := ic.SpawnVM()
ic.Functions = [][]interop.Function{systemInterops, neoInterops} ic.Functions = systemInterops
return vm return vm
} }
@ -38,6 +38,8 @@ var systemInterops = []interop.Function{
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10}, {Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10},
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.States}, {Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.States},
{Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.States}, {Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.States},
{Name: interopnames.SystemCryptoCheckMultisig, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 2},
{Name: interopnames.SystemCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
{Name: interopnames.SystemIteratorNext, Func: iterator.Next, Price: 1 << 15, ParamCount: 1}, {Name: interopnames.SystemIteratorNext, Func: iterator.Next, Price: 1 << 15, ParamCount: 1},
{Name: interopnames.SystemIteratorValue, Func: iterator.Value, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemIteratorValue, Func: iterator.Value, Price: 1 << 4, ParamCount: 1},
{Name: interopnames.SystemRuntimeBurnGas, Func: runtime.BurnGas, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemRuntimeBurnGas, Func: runtime.BurnGas, Price: 1 << 4, ParamCount: 1},
@ -73,22 +75,10 @@ var systemInterops = []interop.Function{
RequiredFlags: callflag.ReadStates, ParamCount: 1}, RequiredFlags: callflag.ReadStates, ParamCount: 1},
} }
var neoInterops = []interop.Function{
{Name: interopnames.SystemCryptoCheckMultisig, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 2},
{Name: interopnames.SystemCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
}
// initIDinInteropsSlice initializes IDs from names in one given
// Function slice and then sorts it.
func initIDinInteropsSlice(iops []interop.Function) {
for i := range iops {
iops[i].ID = interopnames.ToID([]byte(iops[i].Name))
}
interop.Sort(iops)
}
// init initializes IDs in the global interop slices. // init initializes IDs in the global interop slices.
func init() { func init() {
initIDinInteropsSlice(systemInterops) for i := range systemInterops {
initIDinInteropsSlice(neoInterops) systemInterops[i].ID = interopnames.ToID([]byte(systemInterops[i].Name))
}
interop.Sort(systemInterops)
} }

View file

@ -118,8 +118,7 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) {
} }
func newTestVM(w *transaction.Witness, tx *transaction.Transaction) *vm.VM { func newTestVM(w *transaction.Witness, tx *transaction.Transaction) *vm.VM {
ic := &interop.Context{Network: uint32(netmode.UnitTestNet), Container: tx} ic := &interop.Context{Network: uint32(netmode.UnitTestNet), Container: tx, Functions: crypto.Interops}
crypto.Register(ic)
v := ic.SpawnVM() v := ic.SpawnVM()
v.LoadScript(w.VerificationScript) v.LoadScript(w.VerificationScript)
v.LoadScript(w.InvocationScript) v.LoadScript(w.InvocationScript)