diff --git a/commonclient/invoker.go b/commonclient/invoker.go index ff2dad0..5b3d392 100644 --- a/commonclient/invoker.go +++ b/commonclient/invoker.go @@ -11,6 +11,7 @@ import ( // Invoker is a subset of methods provided by struct invoker.Invoker. The subset contains only those // methods that are used by ActorWrapper and clients of the contracts. type Invoker interface { + Run([]byte) (*result.Invoke, error) Call(contract util.Uint160, method string, params ...any) (*result.Invoke, error) TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error) TerminateSession(sessionID uuid.UUID) error diff --git a/commonclient/iterator.go b/commonclient/iterator.go index 2ff962c..0bdd68c 100644 --- a/commonclient/iterator.go +++ b/commonclient/iterator.go @@ -3,7 +3,9 @@ package commonclient import ( "fmt" + "github.com/google/uuid" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" + "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -14,13 +16,21 @@ func ReadIteratorItems(inv Invoker, batchSize int, contract util.Uint160, method panic("batch size must be positive") } - sessionID, iter, err := unwrap.SessionIterator(inv.Call(contract, method, params...)) + script, err := smartcontract.CreateCallAndPrefetchIteratorScript(contract, method, batchSize, params...) + if err != nil { + return nil, fmt.Errorf("couldn't create unwrap script: %w", err) + } + + arr, sessionID, iter, err := unwrap.ArrayAndSessionIterator(inv.Run(script)) if err != nil { return nil, fmt.Errorf("unwrap session iterator: %w", err) } + if (sessionID == uuid.UUID{}) { + return arr, nil + } var shouldStop bool - res := make([]stackitem.Item, 0, len(iter.Values)) + res := arr for !shouldStop { items, err := inv.TraverseIterator(sessionID, &iter, batchSize) if err != nil {