You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Operations that return iterators only return the first MaxIteratorResultItems items. Developers have NO mechanism to retrieve any values past the first MaxIteratorResultItems count.
This may be purely fixable in neo-modules repo, but I'm filing it in neo repo both for visibility and because at least one neo repo issue (#2683) and PR (#2686) are dealing with it. We can move to a modules repo if that's a better place for it.
I'd like to see Iterator operations work similarly to the StateService.FindStates RPC endpoint. FindStates takes an optional from parameter that indicates which records to skip. It also includes a truncated property that the caller can use to determine if there are more records to retrieve.
We can add logic to InvokeFunction and InvokeScript to retrieve an optional integer parameter. Those two methods already have duplicate logic for parsing signers and useDiagnostic. It would be fairly straightforward to DRY out that logic + add additional code to retrieve an optional skip parameter from the JSON array. This skip parameter value could then be passed to GetInvokeResult which would be used for converting an Iterator to JSON.
For reference, here's the RpcClient method declaration of FindStatesAsync:
Here's an example of how FindStates can be used in a loop to retrieve all the storage records:
ReadOnlyMemory<byte>from=default;varstates= Enumerable.Empty<(byte[] key,byte[] value)>();while(true){varresponse=await stateApi.FindStatesAsync(rootHash, contractHash, prefix,from);if(response.Results.Length ==0)break;// validate proof code omittedstates= states.Concat(response.Results);if(!response.Truncated)break;start= response.Results[^1].key;}// states now has all the found states.
The text was updated successfully, but these errors were encountered:
A stack returned from these RPCs is a set of items, so we can have multiple iterators there, what are we going to do with them?
I'm not that worried about multiple return values. Returning multiple items at all is atypical and I would expect returning more than one iterator is even less common.
Paging will require performing the same invocation again and again with this scheme (findstates is much easier wrt this).
I don't see any way to avoid multiple invocations if we're limited to using a stateless transport like HTTP. We could look at using a stateful protocol like WebSockets for pulling additional pages of data out of the iterator.
That's not to say that we don't have a problem, but I'm not sure what's the best solution.
I am very much open to suggestions. The design in #708 is an experiment to see what could be done w/ the least code churn. I'll think about the WebSocket approach and sketch that out as well in the next week or so
Background:
Operations that return iterators only return the first
MaxIteratorResultItems
items. Developers have NO mechanism to retrieve any values past the firstMaxIteratorResultItems
count.This may be purely fixable in neo-modules repo, but I'm filing it in neo repo both for visibility and because at least one neo repo issue (#2683) and PR (#2686) are dealing with it. We can move to a modules repo if that's a better place for it.
I'd like to see Iterator operations work similarly to the
StateService.FindStates
RPC endpoint.FindStates
takes an optionalfrom
parameter that indicates which records to skip. It also includes atruncated
property that the caller can use to determine if there are more records to retrieve.RpcServer
already returns atruncated
property for Iterator types, similar to the JSON returned byFindStates
.We can add logic to
InvokeFunction
andInvokeScript
to retrieve an optional integer parameter. Those two methods already have duplicate logic for parsingsigners
anduseDiagnostic
. It would be fairly straightforward to DRY out that logic + add additional code to retrieve an optionalskip
parameter from the JSON array. Thisskip
parameter value could then be passed toGetInvokeResult
which would be used for converting anIterator
to JSON.For reference, here's the
RpcClient
method declaration ofFindStatesAsync
:And the declaration of
RpcFoundStates
Here's an example of how FindStates can be used in a loop to retrieve all the storage records:
The text was updated successfully, but these errors were encountered: