Summary
RpcTest::basic (in src/tool/subcommands/api_cmd/api_compare_tests.rs) is too permissive and does not actually compare Forest's response against Lotus's response. This allowed a field-casing bug in Filecoin.NodeStatus (missing #[serde(rename_all = "PascalCase")] on NodeSyncStatus, NodePeerStatus, NodeChainStatus, NodeStatusResult) to go undetected until manual review.
Root cause
RpcTest::basic_raw sets check_syntax to deserialize the Forest JSON response into T via crate::rpc::json_validator::from_value_rejecting_unknown_fields::<T>.
- However, it sets
check_semantics: Box::new(|_, _| true), meaning it never inspects or compares the Lotus response at all.
- Since Forest's own response is generated from
T, deserializing it back into T is nearly always trivially true, regardless of field-name casing, ordering, or other schema differences relative to Lotus.
- Only
RpcTest::validate / RpcTest::validate_raw / RpcTest::identity perform real cross-comparison (deserializing and comparing/validating both Forest's and Lotus's JSON).
Impact
Any RPC method that only uses RpcTest::basic (rather than identity/validate) can silently drift from Lotus's actual JSON schema (casing, field names, structure) without the test suite catching it, as happened with Filecoin.NodeStatus.
Proposed change
- Make
RpcTest::basic/basic_raw also deserialize the Lotus response into T (at minimum), so casing/schema mismatches surface as syntax check failures rather than being silently ignored.
- Optionally, perform a lightweight structural comparison (e.g., same top-level field names/keys) between Forest and Lotus JSON, even without full semantic equality, since some methods (e.g., session/time-based ones) cannot use full
identity checks.
- Audit
common_tests(), chain_tests(), and other test groups in src/tool/subcommands/api_cmd/api_compare_tests.rs to see which methods could be upgraded from basic to identity/validate for stronger coverage.
Affected area
src/tool/subcommands/api_cmd/api_compare_tests.rs (RpcTest::basic, RpcTest::basic_raw, RpcTest::validate_raw)
Acceptance criteria
RpcTest::basic catches at least field-name/casing mismatches between Forest and Lotus responses (i.e., would have failed for the pre-fix NodeStatus result types).
- Existing test suite continues to pass for methods correctly matching Lotus's schema.
References
Summary
RpcTest::basic(insrc/tool/subcommands/api_cmd/api_compare_tests.rs) is too permissive and does not actually compare Forest's response against Lotus's response. This allowed a field-casing bug inFilecoin.NodeStatus(missing#[serde(rename_all = "PascalCase")]onNodeSyncStatus,NodePeerStatus,NodeChainStatus,NodeStatusResult) to go undetected until manual review.Root cause
RpcTest::basic_rawsetscheck_syntaxto deserialize the Forest JSON response intoTviacrate::rpc::json_validator::from_value_rejecting_unknown_fields::<T>.check_semantics: Box::new(|_, _| true), meaning it never inspects or compares the Lotus response at all.T, deserializing it back intoTis nearly always trivially true, regardless of field-name casing, ordering, or other schema differences relative to Lotus.RpcTest::validate/RpcTest::validate_raw/RpcTest::identityperform real cross-comparison (deserializing and comparing/validating both Forest's and Lotus's JSON).Impact
Any RPC method that only uses
RpcTest::basic(rather thanidentity/validate) can silently drift from Lotus's actual JSON schema (casing, field names, structure) without the test suite catching it, as happened withFilecoin.NodeStatus.Proposed change
RpcTest::basic/basic_rawalso deserialize the Lotus response intoT(at minimum), so casing/schema mismatches surface as syntax check failures rather than being silently ignored.identitychecks.common_tests(),chain_tests(), and other test groups insrc/tool/subcommands/api_cmd/api_compare_tests.rsto see which methods could be upgraded frombasictoidentity/validatefor stronger coverage.Affected area
src/tool/subcommands/api_cmd/api_compare_tests.rs(RpcTest::basic,RpcTest::basic_raw,RpcTest::validate_raw)Acceptance criteria
RpcTest::basiccatches at least field-name/casing mismatches between Forest and Lotus responses (i.e., would have failed for the pre-fixNodeStatusresult types).References
Filecoin.NodeStatusinput and field #7331Filecoin.NodeStatusinput and field #7331 (comment)