forked from TrueCloudLab/neoneo-go
interop: wrap contract.LoadToken in context.LoadToken
Creating a closure in runtime is a relatively costly thing, but it can easily be avoided.
This commit is contained in:
parent
799394192b
commit
638b04b29a
5 changed files with 30 additions and 26 deletions
|
@ -202,7 +202,7 @@ func TestAppCall(t *testing.T) {
|
||||||
|
|
||||||
fc := fakechain.NewFakeChain()
|
fc := fakechain.NewFakeChain()
|
||||||
ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false, false),
|
ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false, false),
|
||||||
interop.DefaultBaseExecFee, native.DefaultStoragePrice, contractGetter, nil, nil, nil, zaptest.NewLogger(t))
|
interop.DefaultBaseExecFee, native.DefaultStoragePrice, contractGetter, nil, nil, nil, nil, zaptest.NewLogger(t))
|
||||||
|
|
||||||
t.Run("valid script", func(t *testing.T) {
|
t.Run("valid script", func(t *testing.T) {
|
||||||
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
||||||
|
|
|
@ -1110,7 +1110,6 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
||||||
v := systemInterop.SpawnVM()
|
v := systemInterop.SpawnVM()
|
||||||
v.LoadScriptWithFlags(tx.Script, callflag.All)
|
v.LoadScriptWithFlags(tx.Script, callflag.All)
|
||||||
v.SetPriceGetter(systemInterop.GetPrice)
|
v.SetPriceGetter(systemInterop.GetPrice)
|
||||||
v.LoadToken = contract.LoadToken(systemInterop)
|
|
||||||
v.GasLimit = tx.SystemFee
|
v.GasLimit = tx.SystemFee
|
||||||
|
|
||||||
err := systemInterop.Exec()
|
err := systemInterop.Exec()
|
||||||
|
@ -2169,7 +2168,6 @@ func (bc *Blockchain) GetTestVM(t trigger.Type, tx *transaction.Transaction, b *
|
||||||
systemInterop := bc.newInteropContext(t, bc.dao, b, tx)
|
systemInterop := bc.newInteropContext(t, bc.dao, b, tx)
|
||||||
vm := systemInterop.SpawnVM()
|
vm := systemInterop.SpawnVM()
|
||||||
vm.SetPriceGetter(systemInterop.GetPrice)
|
vm.SetPriceGetter(systemInterop.GetPrice)
|
||||||
vm.LoadToken = contract.LoadToken(systemInterop)
|
|
||||||
return systemInterop
|
return systemInterop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2204,7 +2202,6 @@ func (bc *Blockchain) GetTestHistoricVM(t trigger.Type, tx *transaction.Transact
|
||||||
systemInterop := bc.newInteropContext(t, dTrie, b, tx)
|
systemInterop := bc.newInteropContext(t, dTrie, b, tx)
|
||||||
vm := systemInterop.SpawnVM()
|
vm := systemInterop.SpawnVM()
|
||||||
vm.SetPriceGetter(systemInterop.GetPrice)
|
vm.SetPriceGetter(systemInterop.GetPrice)
|
||||||
vm.LoadToken = contract.LoadToken(systemInterop)
|
|
||||||
return systemInterop, nil
|
return systemInterop, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2280,7 +2277,6 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
|
|
||||||
vm := interopCtx.SpawnVM()
|
vm := interopCtx.SpawnVM()
|
||||||
vm.SetPriceGetter(interopCtx.GetPrice)
|
vm.SetPriceGetter(interopCtx.GetPrice)
|
||||||
vm.LoadToken = contract.LoadToken(interopCtx)
|
|
||||||
vm.GasLimit = gas
|
vm.GasLimit = gas
|
||||||
if err := bc.InitVerificationContext(interopCtx, hash, witness); err != nil {
|
if err := bc.InitVerificationContext(interopCtx, hash, witness); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -2376,7 +2372,7 @@ func (bc *Blockchain) newInteropContext(trigger trigger.Type, d *dao.Simple, blo
|
||||||
// changes that were not yet persisted to Blockchain's dao.
|
// changes that were not yet persisted to Blockchain's dao.
|
||||||
baseStorageFee = bc.contracts.Policy.GetStoragePriceInternal(d)
|
baseStorageFee = bc.contracts.Policy.GetStoragePriceInternal(d)
|
||||||
}
|
}
|
||||||
ic := interop.NewContext(trigger, bc, d, baseExecFee, baseStorageFee, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log)
|
ic := interop.NewContext(trigger, bc, d, baseExecFee, baseStorageFee, bc.contracts.Management.GetContract, bc.contracts.Contracts, contract.LoadToken, block, tx, bc.log)
|
||||||
ic.Functions = systemInterops
|
ic.Functions = systemInterops
|
||||||
switch {
|
switch {
|
||||||
case tx != nil:
|
case tx != nil:
|
||||||
|
|
|
@ -64,6 +64,7 @@ type Context struct {
|
||||||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
||||||
baseExecFee int64
|
baseExecFee int64
|
||||||
baseStorageFee int64
|
baseStorageFee int64
|
||||||
|
loadToken func(ic *Context, id int32) error
|
||||||
GetRandomCounter uint32
|
GetRandomCounter uint32
|
||||||
signers []transaction.Signer
|
signers []transaction.Signer
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,7 @@ type Context struct {
|
||||||
// NewContext returns new interop context.
|
// NewContext returns new interop context.
|
||||||
func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple, baseExecFee, baseStorageFee int64,
|
func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple, baseExecFee, baseStorageFee int64,
|
||||||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error), natives []Contract,
|
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error), natives []Contract,
|
||||||
|
loadTokenFunc func(ic *Context, id int32) error,
|
||||||
block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
|
block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
|
||||||
dao := d.GetPrivate()
|
dao := d.GetPrivate()
|
||||||
cfg := bc.GetConfig()
|
cfg := bc.GetConfig()
|
||||||
|
@ -88,6 +90,7 @@ func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple, baseExecFee, bas
|
||||||
getContract: getContract,
|
getContract: getContract,
|
||||||
baseExecFee: baseExecFee,
|
baseExecFee: baseExecFee,
|
||||||
baseStorageFee: baseStorageFee,
|
baseStorageFee: baseStorageFee,
|
||||||
|
loadToken: loadTokenFunc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +301,12 @@ func (ic *Context) BaseStorageFee() int64 {
|
||||||
return ic.baseStorageFee
|
return ic.baseStorageFee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadToken wraps externally provided load-token loading function providing it with context,
|
||||||
|
// this function can then be easily used by VM.
|
||||||
|
func (ic *Context) LoadToken(id int32) error {
|
||||||
|
return ic.loadToken(ic, id)
|
||||||
|
}
|
||||||
|
|
||||||
// SyscallHandler handles syscall with id.
|
// SyscallHandler handles syscall with id.
|
||||||
func (ic *Context) SyscallHandler(_ *vm.VM, id uint32) error {
|
func (ic *Context) SyscallHandler(_ *vm.VM, id uint32) error {
|
||||||
f := ic.GetFunction(id)
|
f := ic.GetFunction(id)
|
||||||
|
@ -317,6 +326,7 @@ func (ic *Context) SyscallHandler(_ *vm.VM, id uint32) error {
|
||||||
// SpawnVM spawns a new VM with the specified gas limit and set context.VM field.
|
// SpawnVM spawns a new VM with the specified gas limit and set context.VM field.
|
||||||
func (ic *Context) SpawnVM() *vm.VM {
|
func (ic *Context) SpawnVM() *vm.VM {
|
||||||
v := vm.NewWithTrigger(ic.Trigger)
|
v := vm.NewWithTrigger(ic.Trigger)
|
||||||
|
v.LoadToken = ic.LoadToken
|
||||||
v.GasLimit = -1
|
v.GasLimit = -1
|
||||||
v.SyscallHandler = ic.SyscallHandler
|
v.SyscallHandler = ic.SyscallHandler
|
||||||
ic.VM = v
|
ic.VM = v
|
||||||
|
|
|
@ -22,8 +22,7 @@ type policyChecker interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadToken calls method specified by the token id.
|
// LoadToken calls method specified by the token id.
|
||||||
func LoadToken(ic *interop.Context) func(id int32) error {
|
func LoadToken(ic *interop.Context, id int32) error {
|
||||||
return func(id int32) error {
|
|
||||||
ctx := ic.VM.Context()
|
ctx := ic.VM.Context()
|
||||||
if !ctx.GetCallFlags().Has(callflag.ReadStates | callflag.AllowCall) {
|
if !ctx.GetCallFlags().Has(callflag.ReadStates | callflag.AllowCall) {
|
||||||
return errors.New("invalid call flags")
|
return errors.New("invalid call flags")
|
||||||
|
@ -42,7 +41,6 @@ func LoadToken(ic *interop.Context) func(id int32) error {
|
||||||
}
|
}
|
||||||
return callInternal(ic, cs, tok.Method, tok.CallFlag, tok.HasReturn, args, false)
|
return callInternal(ic, cs, tok.Method, tok.CallFlag, tok.HasReturn, args, false)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Call calls a contract with flags.
|
// Call calls a contract with flags.
|
||||||
func Call(ic *interop.Context) error {
|
func Call(ic *interop.Context) error {
|
||||||
|
|
|
@ -73,7 +73,7 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM {
|
||||||
trigger.Verification,
|
trigger.Verification,
|
||||||
fakechain.NewFakeChain(),
|
fakechain.NewFakeChain(),
|
||||||
dao.NewSimple(storage.NewMemoryStore(), false, false),
|
dao.NewSimple(storage.NewMemoryStore(), false, false),
|
||||||
interop.DefaultBaseExecFee, native.DefaultStoragePrice, nil, nil, nil,
|
interop.DefaultBaseExecFee, native.DefaultStoragePrice, nil, nil, nil, nil,
|
||||||
container,
|
container,
|
||||||
nil)
|
nil)
|
||||||
ic.Container = container
|
ic.Container = container
|
||||||
|
|
Loading…
Reference in a new issue