0xMiden / 0xMiden/node

store: sync_account_vault and sync_account_storage_maps silently drop all updates when single block exceeds MAX_ROWS

オープン
#2,461 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Rust
スター
104
フォーク
138
平均マージ
1日 13時間
マージ済み PR(30日)
56

説明

### Version

main branch, commit 597e354c (2026-08-09)

### Other packages versions

N/A store crate internal bug

### What happened?

sync_account_vault and sync_account_storage_maps silently lose data when a single block contains more vault/storage_map updates for an account than MAX_ROWS.

Vault: crates/store/src/db/models/queries/accounts.rs:556-573
Storage maps: crates/store/src/db/models/queries/accounts.rs:778-797

Current logic (vault example):

let (last_block_included, values) = if let Some(&(last_block_num, ..)) = raw.last()
&& raw.len() > MAX_ROWS
{
let values = raw
.into_iter()
.take_while(|(bn, ..)| *bn != last_block_num)
.map(AccountVaultValue::from_raw_row)
.collect::, DatabaseError>>()?;

let last_block_included = values.last().map_or(*block_range.start(), |v| v.block_num);
(last_block_included, values)
}

If ALL rows come from block_range.start() = N and the block is saturated:
- take_while(|bn| *bn != N) → empty values
- last_block_included = block_range.start() = N
- Client interprets: "Synced to N, no updates." → sets next_start = N + 1
- All vault/storage_map updates in block N are permanently lost to the client.

### What should have happened?

The function should never tell the client "you are fully synced to block N" when block N actually contains updates that were dropped due to pagination limits.

Either:
1. Return a non empty response guaranteeing progress, OR
2. Return an explicit error (e.g. BlockTooLargeToPage) so the client knows intra-block pagination is needed.

The client should never skip a block thinking it has no data.

### How can this be reproduced?

Trigger condition: >61,681 vault asset updates in a single block for a single account.

Achievable with high-throughput DeFi / NFT smart accounts if protocol batch/block limits increase.

Test that should fail on current code:

#[test]
fn supersaturated_single_block_vault_does_not_lose_data() {
// Insert MAX_ROWS + 100 vault updates for account A in block N
// Query sync_account_vault for A in range [N..]
// Must return updates AND not skip block N
}

No such test exists in tests.rs today for the all-from-same-block saturation case.

### Relevant log output

```shell
// No runtime log this is a silent data loss bug.
// The buggy path returns Ok((N, [])) which looks like a valid "no updates" response.
```

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。