-
Notifications
You must be signed in to change notification settings - Fork 73
fix: serialize sources in build info ordered by source unit ID #354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Fixes #178 The `sources` key in build info was ordered alphabetically by path instead of by source unit ID, which broke compatibility with solc's JSON output and Hardhat's build format. This PR: 1. Adds a custom serde serializer for `CompilerOutput.sources` that orders entries by their source unit ID instead of path 2. Enables `preserve_order` feature for `serde_json` to maintain insertion order when converting to `serde_json::Value` 3. Adds a regression test to verify sources are ordered by ID Amp-Thread-ID: https://ampcode.com/threads/T-019be4d8-6ecf-72ef-94ba-ce4726744e00 Co-authored-by: Amp <[email protected]>
41a977e to
e8887b5
Compare
- Empty sources - Single source file - Non-sequential IDs with gaps (5, 50, 100) - Roundtrip serialization/deserialization - Many sources (50 files)
e8887b5 to
dfc5e7b
Compare
Adds an integration test that: 1. Creates a project with 3 Solidity files (Z_Last, A_First, M_Middle) 2. Compiles the project with build_info enabled 3. Reads the generated build info JSON 4. Verifies sources appear in order of source unit ID in the output
The fix was only applied to foundry_compilers::compilers::CompilerOutput, but not to foundry_compilers_artifacts::CompilerOutput. Both structs need the custom serializer to ensure sources are ordered by ID. Also improved the E2E test to correctly search for source entry patterns in the JSON output (avoiding false matches in AST content).
Move the sources_by_id serialization module to a single location in foundry_compilers_artifacts::serde_helpers and use it from both: - foundry_compilers_artifacts::CompilerOutput - foundry_compilers::compilers::CompilerOutput This removes ~110 lines of duplicated code.
| semver = { version = "1.0", features = ["serde"] } | ||
| serde = { version = "1", features = ["derive", "rc"] } | ||
| serde_json = "1.0" | ||
| serde_json = { version = "1.0", features = ["preserve_order"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces some level of overhead but should be relatively small. I am unsure however if this causes any unexpected side effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without preserve_order, serde_json::to_value() captures into a BTreeMap-backed Map that re-sorts alphabetically, losing the ordering from the custom serializer
Fixes #178
Summary
The
sourceskey in build info was ordered alphabetically by path instead of by source unit ID, which broke compatibility with solc's JSON output and Hardhat's build format. Tools that rely on the index of a source path insourcesmatching its source unit ID (e.g., for source map resolution) would fail.Changes
CompilerOutput.sources- Added asources_by_idserde module that serializes the sources map ordered by source unit ID rather than by pathpreserve_orderforserde_json- This ensures that when the output is converted toserde_json::Value(inRawBuildInfo::new), the insertion order is preservedBefore
{"output": {"sources": {"a_first.sol": {"id": 2}, "m_middle.sol": {"id": 1}, "z_last.sol": {"id": 0}}}}After
{"output": {"sources": {"z_last.sol": {"id": 0}, "m_middle.sol": {"id": 1}, "a_first.sol": {"id": 2}}}}Note: The input sources remain alphabetically ordered as that's the input to the compiler. The output sources are now ordered by ID to match solc's output.