interop: fetch baseExecFee once and keep it in the Context

It never changes during single execution, so we can cache it and avoid going
to Policer via Chain for every instruction.
This commit is contained in:
Roman Khimov 2021-08-11 15:42:23 +03:00
parent bdb2d24a5a
commit 13da1b62fb
3 changed files with 19 additions and 11 deletions

View file

@ -48,14 +48,20 @@ type Context struct {
VM *vm.VM
Functions []Function
getContract func(dao.DAO, util.Uint160) (*state.Contract, error)
baseExecFee int64
}
// NewContext returns new interop context.
func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO,
getContract func(dao.DAO, util.Uint160) (*state.Contract, error), natives []Contract,
block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
baseExecFee := int64(DefaultBaseExecFee)
dao := d.GetWrapped()
nes := make([]state.NotificationEvent, 0)
if bc != nil && (block == nil || block.Index != 0) {
baseExecFee = bc.GetPolicer().GetBaseExecFee()
}
return &Context{
Chain: bc,
Network: uint32(bc.GetConfig().Magic),
@ -69,6 +75,7 @@ func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO,
// Functions is a slice of interops sorted by ID.
Functions: []Function{},
getContract: getContract,
baseExecFee: baseExecFee,
}
}
@ -254,10 +261,7 @@ func (ic *Context) GetFunction(id uint32) *Function {
// BaseExecFee represents factor to multiply syscall prices with.
func (ic *Context) BaseExecFee() int64 {
if ic.Chain == nil || (ic.Block != nil && ic.Block.Index == 0) {
return DefaultBaseExecFee
}
return ic.Chain.GetPolicer().GetBaseExecFee()
return ic.baseExecFee
}
// SyscallHandler handles syscall with id.

View file

@ -5,6 +5,7 @@ import (
"fmt"
"testing"
"github.com/nspcc-dev/neo-go/internal/fakechain"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/fee"
@ -67,12 +68,15 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM {
buf[0] = byte(opcode.SYSCALL)
binary.LittleEndian.PutUint32(buf[1:], neoCryptoCheckMultisigID)
ic := &interop.Context{
Network: uint32(netmode.UnitTestNet),
Trigger: trigger.Verification,
Container: container,
Functions: Interops,
}
ic := interop.NewContext(
trigger.Verification,
fakechain.NewFakeChain(),
dao.NewSimple(storage.NewMemoryStore(), false),
nil, nil, nil,
container,
nil)
ic.Container = container
ic.Functions = Interops
v := ic.SpawnVM()
v.LoadScript(buf)
return v

View file

@ -7,5 +7,5 @@ import (
// GetPrice returns a price for executing op with the provided parameter.
func (ic *Context) GetPrice(op opcode.Opcode, parameter []byte) int64 {
return fee.Opcode(ic.BaseExecFee(), op)
return fee.Opcode(ic.baseExecFee, op)
}