Skip to content

test(foreign-tx): sui inspector tests + localnet docs - #3791

Merged
frolvanya merged 21 commits into
mainfrom
feat/sui-inspector-tests
Jul 14, 2026
Merged

test(foreign-tx): sui inspector tests + localnet docs#3791
frolvanya merged 21 commits into
mainfrom
feat/sui-inspector-tests

Conversation

@frolvanya

Copy link
Copy Markdown
Collaborator

No description provided.

@frolvanya
frolvanya marked this pull request as ready for review July 13, 2026 14:26
@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR changes both test files and documentation/configuration files, so the type prefix should probably be chore: instead of test: to capture all the changes.

Suggested title: chore(foreign-tx): add sui inspector tests + localnet docs

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

Pull request overview

Adds test coverage for the Sui foreign-chain inspector (unit-style integration tests + an ignored manual live-RPC test) and completes localnet plumbing so verify_foreign_transaction can be exercised against Sui.

Changes:

  • crates/foreign-chain-inspector/tests/sui_inspector.rs (new): 17 tests covering happy paths (checkpointed event extraction, index selection, address normalization symmetry), finality (NotFinalized), execution status (TransactionFailed, malformed status/effects), digest consistency, RPC classifiation (TransactionNotFound, transient RpcRequestFailed), and event-content invariants.
  • crates/foreign-chain-inspector/tests/sui_rpc_manual.rs (new): #[ignore]d live-mainnet smoke test against archive.mainnet.sui.io for a known epoch-change tx.
  • crates/node/src/tests/foreign_chain_configuration.rs: adds sui: None to keep the exhaustive ForeignChainsConfig literal compiling.
  • docs/localnet/*: adds the Sui foreign-chain section to mpc-config.template.toml, config.yaml.template, localnet.md, and a verify_foreign_tx_sui.json args file; wires the corresponding call into scripts/launch-localnet.sh.

Reviewed changes

Per-file summary
File Description
crates/foreign-chain-inspector/tests/sui_inspector.rs New mock-client-based tests for SuiInspector::extract.
crates/foreign-chain-inspector/tests/sui_rpc_manual.rs New ignored manual test against public mainnet archive RPC.
crates/node/src/tests/foreign_chain_configuration.rs Adds sui: None to exhaustive ForeignChainsConfig.
docs/localnet/args/verify_foreign_tx_sui.json New sample args file for a Sui verify request.
docs/localnet/localnet.md Adds Sui verify_foreign_transaction example block.
docs/localnet/mpc-config.template.toml Adds Sui provider block.
docs/localnet/mpc-configs/config.yaml.template Adds Sui provider block.
scripts/launch-localnet.sh Runs the new Sui verify_foreign_transaction call.

Findings

Non-blocking (nits, follow-ups, suggestions):

  • crates/foreign-chain-inspector/tests/sui_rpc_manual.rs:23 — the ignored manual test uses lowercase given/when/then and a non-__should_ function name (inspector_extracts_event_against_live_rpc_provider). This matches the existing aptos_rpc_manual.rs convention, so it is consistent, but if the <sut>__should_<assertion> form from engineering-standards.md is meant to apply here too, all *_rpc_manual.rs files could be aligned in a follow-up.
  • crates/foreign-chain-inspector/tests/sui_inspector.rs:34-46MockSuiClient::get_service_info / get_checkpoint panic via unimplemented!(). That is fine as long as no code path in SuiInspector::extract ever grows a call into those (e.g. if SuiFinality later gains a variant that consults get_checkpoint, these tests would panic instead of failing cleanly). Not an issue today; worth remembering when new finality/extractor variants land.
  • crates/foreign-chain-inspector/tests/sui_inspector.rs:97extract__should_return_normalized_event_for_checkpointed_transaction and several sibling tests re-build the same expected SuiEvent via expected_event(). That's fine, but the second test (extract__should_return_correct_event_for_specific_index) only asserts on type_tag; consider asserting the full SuiEvent to guarantee index selection didn't accidentally cross-contaminate other fields.
  • docs/localnet/args/verify_foreign_tx_sui.json:5tx_id is hex-encoded (SuiTxId uses #[serde_as(as = \"Hex\")]), while the manual RPC test uses base58 (8eBMXpC8Np7RNDwwiGwSmeev1cSoc7w3fPXdikhH7RZo). Both are correct given where they are used, but a one-line comment in localnet.md noting the hex convention on the contract side would help operators who copy digests from suiscan (which is base58).
  • docs/localnet/mpc-config.template.toml:97 and docs/localnet/mpc-configs/config.yaml.template:64 — the archive RPC (https://archive.mainnet.sui.io) is set as the only provider. Regular fullnodes prune the gRPC read path (per the comment in sui_rpc_manual.rs), so this default is right, but consider dropping a one-liner in localnet.md explaining why the archive endpoint is used (matches the value the code assumes for the sample digest to still resolve).

No blocking issues — this is pure test/docs coverage, follows the project's Given/When/Then conventions and comment guidance, and the mock design lines up with how the sibling aptos_inspector.rs tests are written.

✅ Approved

@frolvanya
frolvanya force-pushed the feat/sui-inspector-tests branch from 21e4b7e to 5665050 Compare July 13, 2026 14:43
@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: Since this PR adds source code to crates/foreign-chain-config-tester/src/ (checks.rs, golden.rs, main.rs), the type prefix should be feat: rather than test:. The test: type is for test files only.

Suggested title: feat(foreign-tx): sui inspector tests + localnet docs

@anodar anodar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, dropped some optional nits.

.context("provider returned no checkpoint height")?;
// Load-balanced providers may answer consecutive calls from different backends; probing
// slightly behind the reported tip keeps the check off the backend-sync race.
let probe_height = height.saturating_sub(CHECKPOINT_PROBE_OFFSET);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: let's do checked_sub here, current height is at 9 digits, if subtraction of small offset saturates it there's something wrong.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Refactored in 065ac5f

};
use foreign_chain_rpc_interfaces::sui::{Status, SuiRpcClient};

const CHECKPOINT_HEIGHT: u64 = 296_112_296;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: let's make this value very obvious that it has no special meaning (even though it's close to mainnet checkpoint number). Either add comment or/and change value to 123456 (or something like that).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added comment in 065ac5f


// Then
let error = result.unwrap_err().to_string();
assert!(error.contains("chain id mismatch"), "{error}");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I know this is an existing patter in this file, but string comparison in errors is brittle. Consider returning custom error type and checking that instead.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Refactored in 065ac5f

/// from the provider's latest checkpoint.
#[derive(Clone, Copy)]
pub struct SuiVector {
pub chain_id: &'static str,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a comment that this is expected to be base58 encoding (and maybe drop from above the struct itself).

Or preferably accept it without encoding (mainnet: 35834a8a, testnet: 4c78adac) and do encoding in the code instead. That way it's easier to search for chan id to verify it's correct.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added comment in 065ac5f

out: &mut Vec<ProviderResult>,
) {
let Some(vector) = vector else {
mark_skipped("sui", cfg, &no_reference_reason(network), out);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: not introduced in your PR, but I've realized we only will mark chain as skipped if there exists chain field with empty config. If it's not present at all it won't appear in output as skipped.

We should instead at the call site do something like:

if let Some(cfg) = &fc.sui  && vector = Some(vector) {
...
} else {
    mark_skipped
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Refactored in 065ac5f

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR includes source code changes in crates/foreign-chain-config-tester/src/, so the type prefix should be feat: instead of test: (which is for test files only).
Suggested title: feat(foreign-tx): sui inspector tests + localnet docs

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR modifies source code files in crates/foreign-chain-config-tester/src/ alongside test and documentation additions. Since source code is being changed, a type like feat: would be more appropriate than test:.
Suggested title: feat(foreign-tx): sui inspector tests + localnet docs

@frolvanya

Copy link
Copy Markdown
Collaborator Author

@claude review

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

Pull request overview

Follow-up to feat/sui-inspector that lands (1) 17 mock-client-backed unit tests for SuiInspector::extract, (2) an ignored manual live-RPC smoke test against archive.mainnet.sui.io, (3) a Sui probe in the foreign-chain config tester (chain-identity + latest-checkpoint round-trip, since fullnodes prune history), (4) localnet plumbing (config.yaml.template, mpc-config.template.toml, verify_foreign_tx_sui.json, launch-localnet.sh), and (5) a typed Mismatch error so tests no longer match error-message substrings. All substantive review nits from @anodar were addressed in 065ac5f8.

Changes:

  • Sui unit tests over a MockSuiClient covering happy paths, finality, execution status, digest consistency, RPC classification, event-content invariants.
  • Ignored manual test against the live archive endpoint, pinned to Sui's first epoch-change tx.
  • New check_sui in the config tester: verifies chain id via get_service_info, then runs the real inspector against the first tx of tip - 10.
  • Mismatch typed error in checks.rs; check_aptos/verify_block_hash migrated over.
  • mark_not_configured so every supported chain always shows up in the report (removes the "no chains configured" fallback in report::render).
  • Sui provider block wired into the localnet templates + a Sui verify_foreign_transaction call in launch-localnet.sh.

Reviewed changes

Per-file summary
File Description
crates/foreign-chain-config-tester/Cargo.toml Adds bs58 workspace dependency.
crates/foreign-chain-config-tester/README.md Documents Sui's chain-identity-plus-tip-probe approach and updated sample output.
crates/foreign-chain-config-tester/src/checks.rs Adds check_sui, Mismatch enum; migrates aptos/block-hash checks to typed errors.
crates/foreign-chain-config-tester/src/golden.rs Adds SuiVector + mainnet/testnet chain-id golden values and base58_32 helper.
crates/foreign-chain-config-tester/src/main.rs Wires run_sui/prepare_sui; adds mark_not_configured for absent chains.
crates/foreign-chain-config-tester/src/report.rs Drops the "no chains configured" fallback (now every chain always emits a row).
crates/foreign-chain-inspector/tests/sui_inspector.rs New: 17 mock-client tests for SuiInspector::extract.
crates/foreign-chain-inspector/tests/sui_rpc_manual.rs New: #[ignore]d live-RPC smoke test.
docs/localnet/* Adds Sui provider block to templates + verify_foreign_tx_sui.json; documents the call in localnet.md.
scripts/launch-localnet.sh Adds the Sui verify_foreign_transaction call to the localnet flow.

Findings

Non-blocking (nits, follow-ups, suggestions):

  • crates/foreign-chain-inspector/tests/sui_rpc_manual.rs:66-73parse_tx_digest is a panicking test-plumbing helper over hard-coded input. Per docs/engineering-standards.md §"must_ prefix for panicking test helpers", it should be must_parse_tx_digest. The sibling aptos_rpc_manual.rs::parse_tx_hash has the same gap (pre-existing); worth aligning the whole *_rpc_manual.rs family in a follow-up.
  • crates/foreign-chain-config-tester/src/checks.rs (check_sui) — treating TransactionFailed and LogIndexOutOfBounds as Ok(()) means the successful decode path may never actually run on providers whose recent checkpoints happen to lead with failed or event-less txs. Fine as a floor guarantee; a lightweight improvement would be to re-probe an older checkpoint (or scan a few txs in the same checkpoint) once a "structurally-not-decoded" verdict is seen, so the check still exercises event extraction when possible. Not a blocker — the chain-id check already rejects the wrong network, and provider bugs in the decode path will still surface on real signing.
  • crates/foreign-chain-config-tester/src/checks.rs (CHECKPOINT_PROBE_OFFSET = 10) — this magic number leans on the assumption that load-balanced backends won't lag more than ~10 checkpoints. If that assumption ever breaks (e.g. during a rebalance) the tester will report intermittent NotFinalized / TransactionNotFound failures. Consider surfacing the offset in the failure message so operators can distinguish "backend lag" from "real drift" without reading the source.
  • crates/foreign-chain-inspector/tests/sui_inspector.rs:113, 148, 431let SuiExtractedValue::Event(event) = &extracted_values[0]; compiles today because SuiExtractedValue has a single variant, but silently breaks (compile error) the moment another variant lands. assert_matches!(&extracted_values[0], SuiExtractedValue::Event(event) => { ... }) or a let-else would degrade more gracefully — trivial.
  • crates/foreign-chain-config-tester/src/golden.rs (SuiVector::chain_id) — the follow-up commit added the "0x35834a8a mainnet / 0x4c78adac testnet" pointer in the doc comment, which is the grep-friendly identifier. @anodar's alternate suggestion (store the 4-byte prefix directly and encode in code) is still cleaner, but keeping base58 matches what get_service_info returns verbatim so this trade-off is defensible.

No blocking issues. Substantive nits from the initial review round are addressed in 065ac5f8.

✅ Approved

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR modifies source code files in crates/foreign-chain-config-tester/src/ alongside test files and documentation. When source code files change, the type should typically be feat: (if adding new functionality) rather than test:.

Suggested title: feat(foreign-tx): sui inspector tests + localnet docs or test(foreign-tx): sui inspector tests + localnet docs if the source code changes are minimal supporting code.

@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR modifies source code files under crates/foreign-chain-config-tester/src/ in addition to tests and docs. The test prefix is typically used when only test files are modified. Consider using feat (if adding new functionality), refactor (if restructuring), or chore (if maintenance work) depending on the nature of those source code changes.

anodar
anodar previously approved these changes Jul 14, 2026

@anodar anodar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you!

Comment on lines +175 to +176
// (not saturating): real checkpoint heights are 9 digits, so a height below the small
// offset means the provider returned something wrong — surface it instead of probing 0.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: this type of comments aren't very useful for future reader of the code. This was discussion in the PR but doesn't have to go in the comments.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed comment in 4f33c66

Base automatically changed from feat/sui-inspector to main July 14, 2026 13:11
@anodar
anodar dismissed their stale review July 14, 2026 13:11

The base branch was changed.

@claude

claude Bot commented Jul 14, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR includes significant source code changes across multiple crates (foreign-chain-inspector, foreign-chain-rpc-interfaces, node-config, etc.) alongside tests and documentation. The type should be feat: instead of test:.

Suggested title: feat(foreign-tx): sui inspector implementation with tests and localnet docs

@claude

claude Bot commented Jul 14, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR spans multiple areas (tests, docs, source code, config templates), so the type prefix should probably be chore: instead of test:.

Suggested title: chore(foreign-tx): sui inspector tests + localnet docs

Copilot AI review requested due to automatic review settings July 14, 2026 13:13
@claude

claude Bot commented Jul 14, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR changes source code files (in foreign-chain-config-tester/src/) in addition to tests and docs. The test type should be used only when test files are changed. Consider using chore: instead for infrastructure/maintenance work.

Suggested title: chore(foreign-tx): sui inspector tests + localnet docs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds Sui support to the foreign-chain tooling and localnet workflow, so operators/devs can verify Sui foreign transactions via the same inspector path used by the node and can validate RPC configuration with foreign-chain-config-tester.

Changes:

  • Extend localnet docs/templates and the launch-localnet.sh flow to include a Sui verify_foreign_transaction example.
  • Add Sui inspector tests (mocked unit-style tests plus an ignored live-RPC manual test) to foreign-chain-inspector.
  • Extend foreign-chain-config-tester with Sui support (golden vectors + Sui check implementation) and adjust reporting behavior to always include supported chains (including “not configured” rows).

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/launch-localnet.sh Adds a Sui verify_foreign_transaction call in the localnet smoke flow.
docs/localnet/mpc-configs/config.yaml.template Adds Sui RPC provider config to the YAML template.
docs/localnet/mpc-config.template.toml Adds Sui RPC provider config to the TOML template used by localnet.
docs/localnet/localnet.md Documents the Sui verify_foreign_transaction invocation.
docs/localnet/args/verify_foreign_tx_sui.json Adds Sui request args payload for localnet testing.
crates/foreign-chain-inspector/tests/sui_rpc_manual.rs Adds an ignored live-RPC manual test for Sui event extraction.
crates/foreign-chain-inspector/tests/sui_inspector.rs Adds comprehensive mocked tests for Sui inspector extraction and error handling.
crates/foreign-chain-config-tester/src/report.rs Adjusts report rendering behavior (removes special-case empty-results message).
crates/foreign-chain-config-tester/src/main.rs Adds Sui provider checking and “not configured” placeholder rows for absent chains.
crates/foreign-chain-config-tester/src/golden.rs Adds Sui golden vectors and base58→[u8;32] decoding helper.
crates/foreign-chain-config-tester/src/checks.rs Adds Sui provider check logic and introduces typed mismatch errors for assertions.
crates/foreign-chain-config-tester/README.md Updates tool documentation/output examples to include Sui (and Aptos) behavior.
crates/foreign-chain-config-tester/Cargo.toml Adds bs58 dependency for Sui digest handling.
Cargo.lock Records the new dependency resolution for bs58.

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

Comment thread crates/foreign-chain-config-tester/src/checks.rs
Comment thread crates/foreign-chain-config-tester/src/checks.rs
Comment thread crates/foreign-chain-config-tester/src/golden.rs
@claude

claude Bot commented Jul 14, 2026

Copy link
Copy Markdown

PR title type suggestion: This PR includes documentation and source code changes beyond just test files. Since it adds new testing capability along with documentation and implementation, feat: might be more appropriate.

Suggested title: feat(foreign-tx): add sui inspector tests and localnet documentation

@netrome netrome left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The changes since @anodar approved seems trivial, so I'll approve to unblock merging this PR.

@frolvanya
frolvanya added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit bb72d9c Jul 14, 2026
15 checks passed
@frolvanya
frolvanya deleted the feat/sui-inspector-tests branch July 14, 2026 15:01
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.

5 participants