Skip to content

chore(ethereum): forbid HashMap/HashSet via clippy disallowed-types#298

Draft
pepe-anchor wants to merge 1 commit into
mainfrom
worktree-726e4220
Draft

chore(ethereum): forbid HashMap/HashSet via clippy disallowed-types#298
pepe-anchor wants to merge 1 commit into
mainfrom
worktree-726e4220

Conversation

@pepe-anchor
Copy link
Copy Markdown
Contributor

Why am I making this PR?

The visualsign-ethereum crate used HashMap/HashSet in production and test code. Iteration order over these maps is non-deterministic across runs, which is a silent correctness risk: the rendered SignablePayload JSON feeds downstream hashing and wallet display, so any map that leaks iteration order into output breaks determinism. This mirrors the same fix already applied to visualsign-solana in commit b723208.

What am I changing?

  • Added src/chain_parsers/visualsign-ethereum/clippy.toml with disallowed-types rules for std::collections::HashMap and std::collections::HashSet. The rule is crate-wide intentionally (see comment in the file).
  • Migrated all production files in visualsign-ethereum/src/ from HashMap/HashSet to BTreeMap/BTreeSet: abi_registry.rs, registry.rs, token_metadata.rs, visualizer.rs, networks.rs.
  • Added PartialOrd/Ord derives to WellKnownAddress (required by BTreeMap key constraint).
  • Migrated test code in abi_metadata.rs and tests/lib_test.rs. Boundary conversions at the proto FFI point (where generated code still uses HashMap) use .into_iter().collect() with the destination type inferred.

Also included in this branch (already merged as #294): ci(stagex) versioned TVC summary + surfpool gitignore.

What is the Linear ticket?

N/A (internal chore, mirrors b723208 on prasanna/clippy-disallow-hashmap-in-solana-presets)

What are the rollback steps?

Delete src/chain_parsers/visualsign-ethereum/clippy.toml and revert the BTreeMap/BTreeSet renames back to HashMap/HashSet in the 7 changed source files. No data migrations, no config changes, no deployed state to unwind.

Is this change backwards compatible?

Yes. BTreeMap and BTreeSet satisfy the same public interfaces as their Hash* counterparts at every call site. No exported types changed shape. The ChainMetadata.assets field type changed from HashMap to BTreeMap in the Rust struct, but that struct is internal to this crate and not part of any serialized wire format.

Does this require cross-team/service coordination?

No.

How do I know it works as designed? Which tests exercise this code?

203 tests pass (199 unit + 4 lib integration):

cargo test -p visualsign-ethereum
# all 203 tests pass

Clippy clean (no disallowed_types violations remain):

cargo clippy -p visualsign-ethereum --all-targets -- -D warnings
# no warnings or errors

Format clean:

cargo fmt --check -p visualsign-ethereum
# no diff

Co-authored with Claude.

Generated with Claude Code

Mirrors the in-flight Solana branch (b723208) for visualsign-ethereum.
Adds `src/chain_parsers/visualsign-ethereum/clippy.toml` enforcing
`disallowed-types` for `std::collections::HashMap` and `HashSet`, and
migrates all internal usage to BTreeMap/BTreeSet.

Rationale: iteration order over any map that ends up in rendered
SignablePayload output must be stable across runs. HashMap's randomized
hasher silently breaks this. Forbidding HashMap crate-wide prevents the
pattern from being reintroduced.

Boundary conversions (2 sites): abi_metadata.rs test helper and
lib_test.rs each return BTreeMap and collect into the proto field's
HashMap at the call site (`into_iter().collect()`), keeping BTreeMap
internally and only converting at the FFI boundary.

Verified: cargo clippy -p visualsign-ethereum --all-targets -D warnings
clean, cargo fmt clean, 203 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enforces deterministic collection iteration within the visualsign-ethereum crate by disallowing std::collections::HashMap/HashSet via Clippy and migrating internal usage to BTreeMap/BTreeSet, reducing the risk of non-deterministic rendered SignablePayload JSON.

Changes:

  • Add crate-local clippy.toml with disallowed-types rules banning HashMap/HashSet.
  • Migrate production code and tests from HashMap/HashSet to BTreeMap/BTreeSet, including adding Ord derives where required.
  • Update test fixtures to perform boundary conversions into generated-proto HashMap fields via .into_iter().collect().

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/chain_parsers/visualsign-ethereum/clippy.toml Adds Clippy disallowed-types rules to forbid HashMap/HashSet crate-wide for determinism.
src/chain_parsers/visualsign-ethereum/src/abi_registry.rs Migrates ABI registry storage to BTreeMap under Arc for deterministic ordering.
src/chain_parsers/visualsign-ethereum/src/abi_metadata.rs Updates test fixtures to build with BTreeMap and collect into proto HashMap at the boundary.
src/chain_parsers/visualsign-ethereum/src/visualizer.rs Migrates visualizer registries from HashMap to BTreeMap.
src/chain_parsers/visualsign-ethereum/src/token_metadata.rs Switches ChainMetadata.assets to BTreeMap and updates tests accordingly.
src/chain_parsers/visualsign-ethereum/src/registry.rs Migrates multiple registries to BTreeMap and derives Ord for WellKnownAddress; updates tests/sets.
src/chain_parsers/visualsign-ethereum/src/networks.rs Migrates uniqueness tests from HashSet to BTreeSet.
src/chain_parsers/visualsign-ethereum/tests/lib_test.rs Updates integration test metadata construction to use BTreeMap and collect into proto HashMap.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/chain_parsers/visualsign-ethereum/src/token_metadata.rs
@pepe-anchor pepe-anchor requested a review from Copilot May 13, 2026 20:52
@pepe-anchor pepe-anchor marked this pull request as ready for review May 13, 2026 20:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment on lines +22 to +25
disallowed-types = [
{ path = "std::collections::HashMap", reason = "use BTreeMap -- iteration order affects rendered SignablePayload output and breaks deterministic hashing. See clippy.toml comment." },
{ path = "std::collections::HashSet", reason = "use BTreeSet for the same reason as HashMap." },
]
@pepe-anchor pepe-anchor marked this pull request as draft May 14, 2026 10:02
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.

2 participants