fix(netconf-proto): make YANG library content-id calculation independent on the module order - #44
Open
rodonile wants to merge 1 commit into
Open
fix(netconf-proto): make YANG library content-id calculation independent on the module order#44rodonile wants to merge 1 commit into
rodonile wants to merge 1 commit into
Conversation
rodonile
force-pushed
the
fix-order-sha256
branch
from
August 25, 2026 12:24
7498d19 to
674edff
Compare
rodonile
enabled auto-merge (rebase)
August 25, 2026 12:25
There was a problem hiding this comment.
Pull request overview
This PR makes ModuleSetBuilder::build_yang_lib() compute a stable content-id (SHA-256) that depends only on the set content rather than the module discovery/insertion order, preventing duplicate on-disk cache directories for semantically identical schemas.
Changes:
- Sorts modules, features, submodules, and import-only modules deterministically before feeding them into the SHA-256 hasher.
- Adds a regression test asserting
content-idis independent of module insertion order.
Suppressed comments (1)
crates/netconf-proto/src/yanglib.rs:2100
- Doc comment says the hash inputs are sorted "by name/revision", but the implementation sorts modules/submodules by name only (modules are unique by name) and features lexically. Rewording avoids implying revision is part of the general sort key.
})
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The SHA-256 content-id fingerprint in build_yang_lib() hashed modules, features, and submodules in IndexMap insertion order, which depends on BFS dependency traversal order. Semantically identical module sets could therefore produce different content-ids, causing duplicate yang-push cache directories for the same subscription. Sort modules by name, features lexically, submodules by name, and import-only modules by name+revision before hashing, so the content-id is a canonical, order-independent fingerprint. Add a regression test asserting content-id is stable across insertion order.
rodonile
force-pushed
the
fix-order-sha256
branch
from
August 25, 2026 12:35
674edff to
7c79094
Compare
Comment on lines
+2874
to
+2878
| #[test] | ||
| fn test_build_yang_lib_content_id_is_insertion_order_independent() { | ||
| let module_a = Module::new( | ||
| "module-a".into(), | ||
| Some("2020-01-01".into()), |
Comment on lines
+2126
to
2130
| let mut features: Vec<&Box<str>> = module.features().iter().collect(); | ||
| features.sort_unstable(); | ||
| for feature in features { | ||
| content_id.update(feature.as_ref()); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ModuleSetBuilder::build_yang_lib()computes a SHA-256content-idby hashing modules, features, and submodules in the order they
happen to be stored in an
IndexMap(insertion order). That orderis driven by the BFS dependency traversal in
NetConfSshClient::load_from_modules(), seeded from thesubscription's xpath-filter namespace resolution.
Since
content-idis used verbatim as the on-disk cache directoryname (
kafka-yang-producer-cache/<content-id>/...), two fetchesthat resolve the same set of modules but in a different order
produce two different SHA-256 digests, and thus two separate cache
directories for what is really the same schema. This was observed
on a subscription where the order of modules in
yang-lib.xmlresulted being different, due to the root modules list also being
ordered differently when extracted from subscription-started
message wrt. from get-subscriptions rpc.
Fix
Sort everything that feeds the hash before updating it:
This makes
content-ida canonical fingerprint of the module setcontent, independent of discovery/insertion order.