Add ABI/annotation drift check; fix one dropped stakingV2 face - #3003
Draft
taopunks wants to merge 2 commits into
Draft
Add ABI/annotation drift check; fix one dropped stakingV2 face#3003taopunks wants to merge 2 commits into
taopunks wants to merge 2 commits into
Conversation
… source precompiles/src/solidity/*.abi is what EVM integrators consume as the interface of record. It is maintained alongside precompiles/src/*.rs rather than generated from it, so a face can be added to the Rust and missed in the ABI. The omission is silent: the precompile dispatches correctly on chain, but tooling that enumerates from the vendored ABI cannot see the face at all. This test diffs the two sets in both directions and fails naming the signature. Two details worth noting: The Rust scanner is newline-agnostic. rustfmt wraps long attributes, so a line-oriented scan silently misses exactly the faces with the most parameters — today that is serveAxonTls and both long registerNetwork variants, three of the most privileged faces in the tree. A strict single-line regex finds 165 of 168. The ABI side is module-agnostic, unioning every .abi rather than pairing each to a Rust module. Modules are snake_case and artifacts are camelCase, and staking.rs alone declares both staking and stakingV2 — a per-module mapping is a second thing that can be wrong, and it fails in the direction that manufactures findings. ed25519/sr25519 verify() is allowlisted: those precompiles consume raw calldata and dispatch no selector, so the artifacts describe a calling convention with no annotated face behind it. This commit fails: it finds one drifted face. The fix follows.
…V2 artifacts getTotalColdkeyStakeOnSubnet(bytes32,uint256) is declared at precompiles/src/ staking.rs with #[precompile::public] and #[precompile::view], inside impl StakingPrecompileV2, and dispatches on chain today. It is absent from precompiles/src/solidity/stakingV2.abi and stakingV2.sol. Present in the Rust and missing from the vendored artifacts at both v438 (c1463f2) and v440 (e4ffa2e) — two releases. stakingV2.abi grew 101 -> 139 entries across v439, so the artifacts are actively maintained and this is a drop rather than staleness. An integrator enumerating callable faces from the vendored ABI — which is the natural thing to do, since it is the machine-readable artifact — cannot see this face at all. Added to both the .abi and the .sol, matching the shape and placement of its sibling getTotalColdkeyStake(bytes32). With this commit the test added in the previous commit passes.
|
@taopunks is attempting to deploy a commit to the RaoFoundation Team on Vercel. A member of the Team first needs to authorize it. |
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.
getTotalColdkeyStakeOnSubnet(bytes32,uint256)is declared inprecompiles/src/staking.rswith#[precompile::public]and#[precompile::view]insideimpl StakingPrecompileV2, and dispatches on chain today. It is absent fromprecompiles/src/solidity/stakingV2.abiandstakingV2.sol.Present in the Rust and missing from the vendored artifacts at both v438 (
c1463f2c) and v440 (e4ffa2e1) — two releases.stakingV2.abigrew from 24 to 33 function entries across v439, so the artifacts are actively maintained and this looks like a drop rather than staleness.An integrator enumerating callable faces from the vendored ABI — the natural thing to do, since it is the machine-readable artifact — cannot see this face at all.
Reproduce
Extract every
#[precompile::public("…")]fromprecompiles/src/*.rs; extract everytype: "function"signature fromprecompiles/src/solidity/*.abi; diff both directions. Ate4ffa2e1: 168 rust faces, 168 abi functions, one present only in the Rust.The reverse direction returns only
verify(bytes32,bytes32,bytes32,bytes32)oned25519Verify/sr25519Verify— those precompiles consume raw calldata and dispatch no selector, so the artifacts describe a calling convention with no annotated face behind them. Allowlisted in the check with that reasoning inline.Two implementation notes
The Rust scanner is newline-agnostic on purpose.
rustfmtwraps long attributes, so a line-oriented scan silently misses exactly the faces with the most parameters — todayserveAxonTlsand both longregisterNetworkvariants. A strict single-line regex finds 165 of 168.The ABI side is module-agnostic, unioning every
.abirather than pairing each to a Rust module. Modules aresnake_case, artifacts arecamelCase, andstaking.rsalone declares bothstakingandstakingV2— a per-module mapping is a second thing that can be wrong, and it fails in the direction that manufactures findings. (My first attempt did exactly that and reported 9 false drops.)Commits
maintoday, naming the drifted faceVerification
Run against
1.89.0(matchingrust-toolchain.toml), with the workspace'sexpect-used/unwrap-used/indexing-slicing/arithmetic-side-effectsdeny lints replicated:cargo test --test abi_drifton pristinemain→ fails, naminggetTotalColdkeyStakeOnSubnet(bytes32,uint256)cargo clippy --all-targets -- -D warnings→ cleanThe test module carries
#![allow(clippy::expect_used, clippy::arithmetic_side_effects, clippy::indexing_slicing)], matching the pattern already used inaddress_mapping.rs,alpha.rs,crowdloan.rs,leasing.rsand others. It uses no.unwrap().No runtime logic is touched — requesting the
no-spec-version-bumplabel.Related
#2455 (precompile versioning and deprecation lifecycle) describes the general fragility this sits inside. #2998's
coverage-and-testing.mdspecifies finding drift in both directions between the Rust signatures and the vendored ABIs — this adds a mechanical check for that specific direction, and the one face it currently finds is the motivation.Disclosure
I hit this from the integrator side: I gate precompile calls from a contract and enumerate the callable surface to build that gate. The missing face is why I noticed.