mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-01-03 09:22:49 +00:00
Merge pull request #3627 from nspcc-dev/fix-ntf
core: prove contract notifications count is not restricted
This commit is contained in:
commit
29bb3ff1cf
1 changed files with 73 additions and 8 deletions
|
@ -43,6 +43,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -2628,15 +2629,18 @@ func TestBlockchain_StoreAsTransaction_ExecutableConflict(t *testing.T) {
|
|||
// sure that NeoGo node is not affected by https://github.com/neo-project/neo/issues/3300 and does not need
|
||||
// the https://github.com/neo-project/neo/pull/3301.
|
||||
func TestEngineLimits(t *testing.T) {
|
||||
const eArgsCount = 500
|
||||
|
||||
bc, acc := chain.NewSingle(t)
|
||||
e := neotest.NewExecutor(t, bc, acc, acc)
|
||||
|
||||
src := `package test
|
||||
args, _ := strings.CutSuffix(strings.Repeat(`"", `, eArgsCount), `, `)
|
||||
src := fmt.Sprintf(`package test
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||
)
|
||||
// args is an array of LargeEvent parameters containing 500 empty strings.
|
||||
var args = []any{"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" };
|
||||
var args = []any{%s};
|
||||
func ProduceNumerousNotifications(count int) [][]any {
|
||||
for i := 0; i < count; i++ {
|
||||
runtime.Notify("LargeEvent", args...)
|
||||
|
@ -2656,8 +2660,7 @@ func TestEngineLimits(t *testing.T) {
|
|||
res = append(res, smallObject...)
|
||||
}
|
||||
return len(res)
|
||||
}`
|
||||
const eArgsCount = 500
|
||||
}`, args)
|
||||
eParams := make([]compiler.HybridParameter, eArgsCount)
|
||||
for i := range eParams {
|
||||
eParams[i].Name = fmt.Sprintf("str%d", i)
|
||||
|
@ -2675,16 +2678,16 @@ func TestEngineLimits(t *testing.T) {
|
|||
e.DeployContract(t, c, nil)
|
||||
|
||||
// ProduceNumerousNotifications: 1 iteration, no limits are hit.
|
||||
var args = make([]stackitem.Item, eArgsCount)
|
||||
for i := range args {
|
||||
args[i] = stackitem.Make("")
|
||||
var params = make([]stackitem.Item, eArgsCount)
|
||||
for i := range params {
|
||||
params[i] = stackitem.Make("")
|
||||
}
|
||||
cInv := e.NewInvoker(c.Hash, acc)
|
||||
cInv.Invoke(t, stackitem.Make([]stackitem.Item{
|
||||
stackitem.Make([]stackitem.Item{
|
||||
stackitem.Make(c.Hash),
|
||||
stackitem.Make("LargeEvent"),
|
||||
stackitem.Make(args),
|
||||
stackitem.Make(params),
|
||||
}),
|
||||
}), "produceNumerousNotifications", 1)
|
||||
|
||||
|
@ -2697,3 +2700,65 @@ func TestEngineLimits(t *testing.T) {
|
|||
// ProduceLargeObject: hit the limit.
|
||||
cInv.InvokeFail(t, "stack is too big", "produceLargeObject", 500)
|
||||
}
|
||||
|
||||
// TestRuntimeNotifyRefcounting tries to emit more than MaxStackSize notifications.
|
||||
func TestRuntimeNotifyRefcounting(t *testing.T) {
|
||||
const eArgsCount = 500
|
||||
|
||||
bc, acc := chain.NewSingle(t)
|
||||
e := neotest.NewExecutor(t, bc, acc, acc)
|
||||
|
||||
args, _ := strings.CutSuffix(strings.Repeat(`"", `, eArgsCount), `, `)
|
||||
src := fmt.Sprintf(`package test
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||
)
|
||||
// args is an array of LargeEvent parameters containing 500 empty strings.
|
||||
var args = []any{%s};
|
||||
func ProduceNumerousNotifications(count int) {
|
||||
for i := 0; i < count; i++ {
|
||||
runtime.Notify("LargeEvent", args...)
|
||||
}
|
||||
}`, args)
|
||||
|
||||
eParams := make([]compiler.HybridParameter, eArgsCount)
|
||||
for i := range eParams {
|
||||
eParams[i].Name = fmt.Sprintf("str%d", i)
|
||||
eParams[i].Type = smartcontract.ByteArrayType
|
||||
}
|
||||
c := neotest.CompileSource(t, acc.ScriptHash(), strings.NewReader(src), &compiler.Options{
|
||||
Name: "test_contract",
|
||||
ContractEvents: []compiler.HybridEvent{
|
||||
{
|
||||
Name: "LargeEvent",
|
||||
Parameters: eParams,
|
||||
},
|
||||
},
|
||||
})
|
||||
e.DeployContract(t, c, nil)
|
||||
|
||||
var params = make([]stackitem.Item, eArgsCount)
|
||||
for i := range params {
|
||||
params[i] = stackitem.Make("")
|
||||
}
|
||||
cInv := e.NewInvoker(c.Hash, acc)
|
||||
expected := state.NotificationEvent{
|
||||
ScriptHash: c.Hash,
|
||||
Name: "LargeEvent",
|
||||
Item: stackitem.NewArray(params),
|
||||
}
|
||||
|
||||
// ProduceNumerousNotifications: 1 iteration, no limits are hit.
|
||||
h := cInv.Invoke(t, stackitem.Null{}, "produceNumerousNotifications", 1)
|
||||
cInv.CheckTxNotificationEvent(t, h, 0, expected)
|
||||
|
||||
// ProduceNumerousNotifications: vm.MaxStackSize + 1 iterations.
|
||||
count := vm.MaxStackSize + 1
|
||||
h = cInv.Invoke(t, stackitem.Null{}, "produceNumerousNotifications", count)
|
||||
aer, err := e.Chain.GetAppExecResults(h, trigger.Application)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, count, len(aer[0].Events))
|
||||
for i := range count {
|
||||
require.Equal(t, expected, aer[0].Events[i])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue