Skip to content

[Storehouse] 011 - Add checkpoint iterate nodes function and util - #8587

Open
zhangchiqing wants to merge 4 commits into
leo/payloadless-util-convert-checkpointfrom
leo/payloadless-checkpoint-iteration
Open

[Storehouse] 011 - Add checkpoint iterate nodes function and util#8587
zhangchiqing wants to merge 4 commits into
leo/payloadless-util-convert-checkpointfrom
leo/payloadless-checkpoint-iteration

Conversation

@zhangchiqing

@zhangchiqing zhangchiqing commented Jun 25, 2026

Copy link
Copy Markdown
Member

This PR introduces a utility that streams a v6 or v7 checkpoint file and reports the total number of leaf and interim nodes. To minimize memory usage, it processes the checkpoint incrementally instead of loading the entire checkpoint into memory and reconstructing the trie.

While the initial use case is fairly specific, the implementation provides a generic checkpoint trie node iterator (ledger/complete/wal/checkpoint_node_iterator.go#IterateCheckpointNodes) that can be reused for other purposes. For example, it can be used to collect payload size statistics, group nodes by owner key, or support other checkpoint analysis tasks.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e95b5d59-3a05-49d0-8fcc-65decf7a2776

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch leo/payloadless-checkpoint-iteration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zhangchiqing
zhangchiqing marked this pull request as ready for review June 25, 2026 23:51
@zhangchiqing
zhangchiqing requested a review from a team as a code owner June 25, 2026 23:51
@zhangchiqing zhangchiqing changed the title [Storehouse] Add checkpoint iterate nodes function and util [Storehouse] 010 - Add checkpoint iterate nodes function and util Jun 26, 2026
@zhangchiqing zhangchiqing changed the title [Storehouse] 010 - Add checkpoint iterate nodes function and util [Storehouse] 011 - Add checkpoint iterate nodes function and util Jun 26, 2026
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 534061d to b826c88 Compare July 2, 2026 19:12
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from b826c88 to 39f9dcb Compare July 13, 2026 17:26
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 39f9dcb to 61ed3ef Compare July 14, 2026 20:01
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 61ed3ef to a4335f8 Compare July 31, 2026 04:33
if isV7 {
subtrieChecksums, _, err = readCheckpointHeaderV7(headerPath, logger)
} else {
subtrieChecksums, _, err = readCheckpointHeader(headerPath, logger)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The header's top-trie checksum is discarded here, so the top-trie part file never gets the header-vs-footer cross-check that subtries get via processCheckpointSubTrie. The godoc claim "matching the regular checkpoint readers" is inaccurate for the top-trie file.

}
}

isDef := meta.hash == ledger.GetDefaultHashForHeight(int(meta.height))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

meta.height is an unvalidated uint16 from disk, and GetDefaultHashForHeight is defaultHashes[height] with 257 entries and no bounds check (ledger/trie.go:63). A corrupt checkpoint with height > 256 panics instead of returning an error.

Comment on lines +199 to +203
if !it.referenced.get(idx) {
return fmt.Errorf("%w: node at global index %d is not referenced by any parent or trie root (orphan node)",
ErrCheckpointIntegrity, idx)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This orphan-node pass, the documented "callback error aborts iteration" contract, and the trie-root rootIndex > total rejection in iterateTopTrie have no test coverage.

//
// No error returns are expected during normal operation.
func readCheckpointHeaderVersion(headerPath string) (uint16, error) {
f, err := os.Open(headerPath)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: two pattern divergences in this version read: the header file ends up opened and parsed twice (here, then readCheckpointHeader/readCheckpointHeaderV7 re-opens it), and this uses plain os.Open + defer Close without the evictFileFromLinuxPageCache + closeAndMergeError pattern (or withFile) used by every other checkpoint file read.

res.interimNodes++

// An interim node with exactly one nil child is legitimate in a compactified
// trie (the present child is itself an interim node). Both-nil cannot occur,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: "Both-nil cannot occur" is true for writer-produced compactified tries, but emit does not reject a both-nil interim node in a corrupt checkpoint. Reword (e.g. "does not occur in a valid checkpoint").


it := &checkpointIterator{
fn: fn,
isDefault: newBitset(total + 1),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: the bitsets are sized by footer node counts, which decodeNodeCount accepts without any bound. A corrupt footer declaring e.g. 2^40 nodes makes this allocation panic (OOM) instead of returning an error. We could add a cheap bounds check.

@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from a4335f8 to de8435f Compare August 18, 2026 01:55
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@codecov-commenter

codecov-commenter commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from de8435f to 14fedc3 Compare August 18, 2026 15:43
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 14fedc3 to af08206 Compare August 18, 2026 17:25
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from af08206 to 758bce9 Compare August 18, 2026 18:18
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 758bce9 to 09cf0c9 Compare August 18, 2026 20:29
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 09cf0c9 to b4dd69a Compare August 19, 2026 19:09
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from f6ca6ac to 2810330 Compare August 24, 2026 14:01
@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from 2810330 to a5c5025 Compare August 25, 2026 02:47
@blacksmith-sh

This comment has been minimized.

@zhangchiqing
zhangchiqing force-pushed the leo/payloadless-checkpoint-iteration branch from a5c5025 to f0aa72c Compare August 25, 2026 23:00
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.

4 participants