Skip to content

Conversation

@SantiagoPittella
Copy link
Collaborator

I'm working on #1299 .

I noticed that we do not store the block in which an account is created, so the typical pagination that we are using in the other endpoint does not work here. We would need some kind of cursor to keep track the position of the overall query for the pagination. The problem is that we cannot count on any of the fields in the accounts schema to be ordered. A solution could be to add a created_at field storing the block number in which the account was deployed.

cc @Mirko-von-Leipzig @drahnr

@bobbinth
Copy link
Contributor

I noticed that we do not store the block in which an account is created, so the typical pagination that we are using in the other endpoint does not work here. We would need some kind of cursor to keep track the position of the overall query for the pagination. The problem is that we cannot count on any of the fields in the accounts schema to be ordered. A solution could be to add a created_at field storing the block number in which the account was deployed.

This is for the accounts table, right? And the proposal is to add created_at field to the accounts table so that we have a stable way to sort accounts (i.e., to avoid accounts getting re-sorted if a new account is added or an existing account is updated) - correct?

@Mirko-von-Leipzig
Copy link
Collaborator

I think we can technically rely on rowid here if we wanted since we never delete an account again (for now). That said, I think having the created_at height will be useful at some stage in any case. It can also be useful to short-circuit other queries perhaps e.g. if someone is querying the account state at some height this can be a quicker check than checking all account deltas.

Its a cheap column to add so imo we can do it.

@SantiagoPittella SantiagoPittella marked this pull request as ready for review December 16, 2025 19:51
@SantiagoPittella SantiagoPittella changed the title draft: add pagination to GetNetworkAccountIds feat: add pagination to GetNetworkAccountIds Dec 16, 2025
Ok(all_notes)
}

// TODO: add pagination.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed!

let response = self.inner.clone().get_network_account_ids(()).await?.into_inner();
pub async fn get_network_account_ids(
&self,
block_range: Option<RangeInclusive<BlockNumber>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid the Option? Nobody should request this without anyways, no?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think we need to retain the original behavior within this method. The ntx builder currently expects this to return all network account IDs.

To retain this behavior for now I would

  • revert function signature change
  • internally loop over and aggregate the returned pages

As currently used this will only return the first page in the main builder https://github.com/0xMiden/miden-node/pull/1452/changes#diff-630c8daca8771b806879dbee6a3059b92341ac7418c345180f537c911dd272a2R15

@SantiagoPittella ^^

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this changes

schema::accounts::account_id,
block_range: RangeInclusive<BlockNumber>,
) -> Result<(Vec<AccountId>, BlockNumber), DatabaseError> {
const ROW_OVERHEAD_BYTES: usize = AccountId::SERIALIZED_SIZE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

future work/probably too much: we might want to use build.rs that generates this const value

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I create an issue for this one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like @Mirko-von-Leipzig 's input on it first :)

Copy link
Collaborator

@Mirko-von-Leipzig Mirko-von-Leipzig Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an internal only endpoint, so I think we can get away with simplifying this as much as possible such that we don't need a derived MAX_ROWS at all, but can simply keep it at some arbitrary value.

With a small bit of refactoring in the ntx builder (briefly touched upon in #1478 (comment)), we can simplify this function signature to

pub(crate) fn select_all_network_account_ids(
    conn: &mut SqliteConnection,
    token: ContinuationToken,
) -> Result<(Vec<AccountId>, ContinuationToken), DatabaseError> 

This is because the ntx builder won't need to care about block-delimited pages, and instead only needs a mechanism to get all currently committed network account IDs.

So all we need is an iteration key that retains the order, which could be

ORDER BY rowid                  -- if we don't delete, or
ORDER BY created_at, account_id -- for an agnostic one

and then

struct ContinuationToken(rowid);
// or
struct ContinuationToken(BlockNumber, AccountId);

If we do decide to go the stream route, then ContinuationToken would remain internal only, otherwise it forms part of the protobuf.

Copy link
Collaborator

@Mirko-von-Leipzig Mirko-von-Leipzig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, but definitely requires the fix on the ntx client side.

I would also be interested in an experiment where we change the proto to return a stream of AccountId instead. Internally, the store would manage the stream by paginating internally (which no longer needs to be block bound, but can use rowid or any other internally consistent row token). e.g. request a page from db, stream the page, request next page, stream it etc.

Client can recover from a broken stream by initializing stream with Option<AccountI>, the last account ID received. Though we could also just restart from scratch since its an internal only API.

let response = self.inner.clone().get_network_account_ids(()).await?.into_inner();
pub async fn get_network_account_ids(
&self,
block_range: Option<RangeInclusive<BlockNumber>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think we need to retain the original behavior within this method. The ntx builder currently expects this to return all network account IDs.

To retain this behavior for now I would

  • revert function signature change
  • internally loop over and aggregate the returned pages

As currently used this will only return the first page in the main builder https://github.com/0xMiden/miden-node/pull/1452/changes#diff-630c8daca8771b806879dbee6a3059b92341ac7418c345180f537c911dd272a2R15

@SantiagoPittella ^^

@SantiagoPittella
Copy link
Collaborator Author

@Mirko-von-Leipzig I created #1478 to test the stream approach

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left a few comments inline - mostly related to making sure the comments/docs are up to date.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you!

@bobbinth bobbinth merged commit 77471e2 into next Jan 6, 2026
18 checks passed
@bobbinth bobbinth deleted the santiagopittella-get-network-accounts-pagination branch January 6, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants