Skip to content

Vault lookup can omit live assets when tombstones consume the SQL row limit #2574

Description

@Kewe63

Version

next at 4c211fc (miden-node-store 0.16.0-rc.5)

Other packages versions

Not applicable.

What happened?

select_account_vault_at_block() applies LIMIT MAX_RETURN_ENTRIES + 1 before filtering deletion tombstones represented by NULL assets.

The query in crates/store/src/db/models/queries/accounts.rs is:

SELECT asset FROM account_vault_assets WHERE account_id = ?1 AND block_num <= ?2 AND valid_until > ?2 LIMIT ?3

The returned rows are then filtered in Rust with entries.into_iter().flatten().

If tombstone rows consume the SQL limit before a live asset is reached, the live asset is omitted. The post-query filtering removes the tombstones and can return an empty or incomplete vault without reporting LimitExceeded.

What should have happened?

Deletion tombstones should not consume the limit used for live vault assets. Every live asset valid at the requested block should be returned when the number of live assets is within AccountVaultDetails::MAX_RETURN_ENTRIES.

If the number of live assets exceeds the limit, the caller should receive the existing LimitExceeded result rather than a silently incomplete vault.

How can this be reproduced?

Create an in-memory SQLite database using the production account_vault_assets schema and insert:

  • 1,001 rows for the same account with asset = NULL and valid_until = i64::MAX;
  • one additional live row with asset = "LIVE" and a vault key ordered after the tombstone keys.

Run the production query with block number 2 and limit 1001:

SELECT asset FROM account_vault_assets WHERE account_id = ?1 AND block_num <= ?2 AND valid_until > ?2 LIMIT ?3

The query returns 1,001 rows, all containing NULL. After Rust applies .flatten(), the result is empty and the live asset is missing.

Running the equivalent query with AND asset IS NOT NULL before LIMIT returns the live asset.

Relevant log output

rows_returned: 1001
non_null_returned: 0
filtered_assets:
  - LIVE
query_plan:
  SEARCH account_vault_assets USING PRIMARY KEY (account_id=? AND block_num<?)
bug_reproduced: true

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    None yet

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions