11package iscmoveclient
22
33import (
4+ "bytes"
45 "context"
56 "fmt"
7+ "sort"
68 "time"
79
810 "github.com/samber/lo"
11+ "golang.org/x/exp/maps"
912
1013 "github.com/iotaledger/wasp/clients/iota-go/iotaclient"
1114 "github.com/iotaledger/wasp/clients/iota-go/iotago"
@@ -212,10 +215,17 @@ func (c *Client) parseRequestAndFetchAssetsBag(obj *iotajsonrpc.IotaObjectData)
212215 }, nil
213216}
214217
215- func (c * Client ) GetRequestsWithCB (ctx context.Context , packageID iotago.PackageID , anchorAddress * iotago.ObjectID , cb func (error , * iscmove.RefWithObject [iscmove.Request ])) error {
218+ func (c * Client ) GetRequestsSorted (ctx context.Context , packageID iotago.PackageID , anchorAddress * iotago.ObjectID , maxAmountOfRequests int , cb func (error , * iscmove.RefWithObject [iscmove.Request ])) {
216219 var lastSeen * iotago.ObjectID
220+
221+ pulledRequests := map [iotago.ObjectID ]* iotajsonrpc.IotaObjectData {}
222+ sortedRequestIDs := make ([]iotago.ObjectID , 0 )
223+
224+ _ = (pulledRequests )
225+ _ = sortedRequestIDs
226+
217227 for {
218- res , err := c .GetOwnedObjects (ctx , iotaclient.GetOwnedObjectsRequest {
228+ objs , err := c .GetOwnedObjects (ctx , iotaclient.GetOwnedObjectsRequest {
219229 Address : anchorAddress ,
220230 Query : & iotajsonrpc.IotaObjectResponseQuery {
221231 Filter : & iotajsonrpc.IotaObjectDataFilter {
@@ -229,29 +239,44 @@ func (c *Client) GetRequestsWithCB(ctx context.Context, packageID iotago.Package
229239 },
230240 Cursor : lastSeen ,
231241 })
242+
232243 if ctx .Err () != nil {
233244 cb (fmt .Errorf ("failed to fetch requests: %w" , err ), nil )
234245 continue
235246 }
236- if len (res .Data ) == 0 {
237- return nil
247+
248+ if objs == nil || len (objs .Data ) == 0 {
249+ break
238250 }
239251
240- lastSeen = res .NextCursor
241- for _ , reqData := range res .Data {
242- if ctx .Err () != nil {
243- return ctx .Err ()
244- }
252+ lastSeen = objs .NextCursor
245253
246- fmt .Printf ("Polling request id:%s, digest: %s, now:%s\n " , reqData .Data .ObjectID , reqData .Data .Digest , time .Now ().String ())
247- req , err := c .parseRequestAndFetchAssetsBag (reqData .Data )
248- if err != nil {
249- cb (fmt .Errorf ("failed to decode requests: %w" , err ), nil )
250- } else {
251- cb (nil , req )
252- }
254+ for _ , req := range objs .Data {
255+ pulledRequests [* req .Data .ObjectID ] = req .Data
253256 }
254257 }
258+
259+ // Sort object IDs
260+ objectKeys := maps .Keys (pulledRequests )
261+ sort .Slice (objectKeys , func (i , j int ) bool {
262+ return bytes .Compare (objectKeys [i ][:], objectKeys [j ][:]) < 0
263+ })
264+
265+ if len (objectKeys ) >= maxAmountOfRequests {
266+ sortedRequestIDs = objectKeys [:maxAmountOfRequests ]
267+ } else {
268+ sortedRequestIDs = objectKeys
269+ }
270+
271+ // We only pass the maxRequests amount of requests into the result, to not overload the mempool.
272+ // Periodically, this function will be called by the Chain Manager to pick up the next amount of transactions.
273+ // This ensures that we don't suddenly load 20k of Requests into the mempool which fills up at a lower limit.
274+ // It improves the startup time of the node and makes sure that the Consensus gets the same IDs across all nodes in a sorted manner.
275+
276+ for _ , reqID := range sortedRequestIDs {
277+ ref , err := c .parseRequestAndFetchAssetsBag (pulledRequests [reqID ])
278+ cb (err , ref )
279+ }
255280}
256281
257282func (c * Client ) GetRequests (
0 commit comments