core: use proper DAO to get ExecFeeFactor

The usage of the Blockchain's one leads to the same ExecFeeFactor within
a single block. What we need is to update ExecFeeFactor after each
transaction invocation, thus, cached DAO should be used as it contains
all relevant changes.
This commit is contained in:
Anna Shaleva 2022-04-07 16:13:06 +03:00
parent 6ff11baa1b
commit 91a4bc5beb
5 changed files with 26 additions and 15 deletions

View file

@ -200,7 +200,7 @@ func TestAppCall(t *testing.T) {
}
fc := fakechain.NewFakeChain()
ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false, false), contractGetter, nil, nil, nil, zaptest.NewLogger(t))
ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false, false), interop.DefaultBaseExecFee, contractGetter, nil, nil, nil, zaptest.NewLogger(t))
t.Run("valid script", func(t *testing.T) {
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))

View file

@ -2304,7 +2304,14 @@ func (bc *Blockchain) ManagementContractHash() util.Uint160 {
}
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d *dao.Simple, 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)
baseExecFee := int64(interop.DefaultBaseExecFee)
if block == nil || block.Index != 0 {
// Use provided dao instead of Blockchain's one to fetch possible ExecFeeFactor
// changes that were not yet persisted to Blockchain's dao.
baseExecFee = bc.contracts.Policy.GetExecFeeFactorInternal(d)
}
ic := interop.NewContext(trigger, bc, d, baseExecFee, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log)
ic.Functions = systemInterops
switch {
case tx != nil:

View file

@ -67,15 +67,10 @@ type Context struct {
}
// NewContext returns new interop context.
func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple,
func NewContext(trigger trigger.Type, bc Ledger, d *dao.Simple, baseExecFee int64,
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error), natives []Contract,
block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
baseExecFee := int64(DefaultBaseExecFee)
dao := d.GetPrivate()
if bc != nil && (block == nil || block.Index != 0) {
baseExecFee = bc.GetBaseExecFee()
}
return &Context{
Chain: bc,
Network: uint32(bc.GetConfig().Magic),

View file

@ -72,7 +72,7 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM {
trigger.Verification,
fakechain.NewFakeChain(),
dao.NewSimple(storage.NewMemoryStore(), false, false),
nil, nil, nil,
interop.DefaultBaseExecFee, nil, nil, nil,
container,
nil)
ic.Container = container

View file

@ -55,16 +55,25 @@ func testGetSet(t *testing.T, c *neotest.ContractInvoker, name string, defaultVa
c.AddNewBlock(t, txSet, txGet)
c.CheckHalt(t, txSet.Hash(), stackitem.Null{})
if name != "GasPerBlock" { // GasPerBlock is set on the next block
c.CheckHalt(t, txGet.Hash(), stackitem.Make(defaultValue+1))
} else {
switch name {
case "GasPerBlock":
// GasPerBlock is set on the next block
c.CheckHalt(t, txGet.Hash(), stackitem.Make(defaultValue))
c.AddNewBlock(t)
randomInvoker.Invoke(t, defaultValue+1, getName)
case "ExecFeeFactor":
// ExecFeeFactor was risen, so the second transaction will fail because
// of gas limit exceeding (its fees are out-of-date).
c.CheckFault(t, txGet.Hash(), "gas limit exceeded")
// Set in a separate block.
committeeInvoker.Invoke(t, stackitem.Null{}, setName, defaultValue+1)
// Get in the next block.
randomInvoker.Invoke(t, defaultValue+1, getName)
default:
c.CheckHalt(t, txGet.Hash(), stackitem.Make(defaultValue+1))
// Get in the next block.
randomInvoker.Invoke(t, defaultValue+1, getName)
}
// Get in the next block.
randomInvoker.Invoke(t, defaultValue+1, getName)
})
}