Skip to content

test(ledger-suite-orchestrator): drop the StateMachine test fixture - #10956

Merged
gregorydemay merged 5 commits into
ic_DEFI-2262_3_cketh-pocket-icfrom
ic_DEFI-2262_4_lso-drop-state-machine
Aug 12, 2026
Merged

test(ledger-suite-orchestrator): drop the StateMachine test fixture#10956
gregorydemay merged 5 commits into
ic_DEFI-2262_3_cketh-pocket-icfrom
ic_DEFI-2262_4_lso-drop-state-machine

Conversation

@gregorydemay

@gregorydemay gregorydemay commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Completes the DEFI-2262 PocketIC migration for rs/ethereum: with the ckETH minter's integration tests now running on PocketIC, nothing in rs/ethereum still uses the ledger-suite-orchestrator's StateMachine-based test fixture. This PR deletes it, along with the now-unused ic-state-machine-tests, ic-types, ic-management-canister-types-private, and assert_matches dependencies, leaving PocketIC as the orchestrator's sole test harness.

  • Removed the StateMachine-based LedgerSuiteOrchestrator/flow/universal_canister fixture from ledger-suite-orchestrator/test_utils; the pocket_ic module (added in test(ledger-suite-orchestrator): migrate integration tests to PocketIC #10949) is now the crate's only fixture.
  • Kept the environment-agnostic helpers the pocket_ic module and cketh still import at their existing paths (wasm loaders, init-arg builders, usdc()/usdt(), constants).
  • Dropped the now-unused ic-state-machine-tests, ic-types, ic-management-canister-types-private, and assert_matches dependencies from Cargo.toml/BUILD.bazel.

📚 PR stack

  1. test(ledger-suite-orchestrator): migrate integration tests to PocketIC #10949 — test(ledger-suite-orchestrator): migrate integration tests to PocketIC
  2. test(cketh): deduplicate signed-transaction and transaction-hash literals in integration tests #10950 — test(cketh): deduplicate signed-transaction literals in integration tests
  3. test(cketh): migrate integration tests to PocketIC #10955 — test(cketh): migrate integration tests to PocketIC
  4. test(ledger-suite-orchestrator): drop the StateMachine test fixture #10956 — test(ledger-suite-orchestrator): drop the StateMachine test fixture 👈 you are here

🤖 Generated with Claude Code

Nothing in rs/ethereum consumes the old StateMachine-based fixture
(lib.rs's LedgerSuiteOrchestrator, flow.rs, universal_canister.rs) now
that both LSO and cketh integration tests run on PocketIC. Delete it
and the now-unused ic-state-machine-tests, ic-types, and
ic-management-canister-types-private dependencies, keeping only the
environment-agnostic helpers (wasm loaders, init-arg builders,
supported_erc20_tokens/usdc/usdt, constants) that the pocket_ic module
and cketh still import at their existing paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

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

Removes the legacy ic-state-machine-tests-based test fixture from rs/ethereum/ledger-suite-orchestrator/test_utils, leaving the existing PocketIC fixture as the only supported test harness and cleaning up now-unused dependencies.

Changes:

  • Deleted the StateMachine-based flow and universal_canister fixtures and removed the StateMachine LedgerSuiteOrchestrator helper implementation from test_utils/src/lib.rs.
  • Kept the environment-agnostic helpers (wasm loaders, init-arg builders, token helpers/constants) at their existing crate-root paths.
  • Dropped unused dependencies (ic-state-machine-tests, ic-types, ic-management-canister-types-private, assert_matches) from Cargo + Bazel, and updated Cargo.lock.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
rs/ethereum/ledger-suite-orchestrator/test_utils/src/universal_canister.rs Deleted the StateMachine-based universal canister helper (PocketIC version remains under pocket_ic/).
rs/ethereum/ledger-suite-orchestrator/test_utils/src/lib.rs Removed StateMachine fixture exports/impls; retained shared helper APIs/constants used by PocketIC + ckETH.
rs/ethereum/ledger-suite-orchestrator/test_utils/src/flow.rs Deleted the StateMachine-based flow/assertion helpers (PocketIC equivalents remain under pocket_ic/).
rs/ethereum/ledger-suite-orchestrator/test_utils/Cargo.toml Removed unused StateMachine-era dependencies.
rs/ethereum/ledger-suite-orchestrator/test_utils/BUILD.bazel Removed unused Bazel deps corresponding to the deleted fixture.
Cargo.lock Reflected the dependency removals for ic-ledger-suite-orchestrator-test-utils.

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

Comment thread rs/ethereum/ledger-suite-orchestrator/test_utils/Cargo.toml
Comment thread rs/ethereum/ledger-suite-orchestrator/test_utils/src/lib.rs
Comment thread rs/ethereum/ledger-suite-orchestrator/test_utils/src/lib.rs
@gregorydemay

Copy link
Copy Markdown
Contributor Author

🤖🧐 VERDICT: CHANGES_REQUESTED — 0 blockers, 0 mediums, 3 nits; CI pending (Bazel Test All, Bazel Test All on RBE, Cargo Build Linux, Cargo Lint Linux, Build IC, Bazel Run Fuzzers still running). The review substance is clean — the only thing standing between this and READY is green CI.

Review details

Verdict rationale

Nothing in the diff needs to change. CHANGES_REQUESTED is bookkeeping: my rules make a non-green CI a hard block on READY, and six jobs were still pending when I looked. Everything that has reported so far passes (Bazel Test arm64-linux, Bazel Test arm64-darwin, Autofix, Lock Generate, Candid compatibility checks, Check PULL_REQUEST_BAZEL_TARGETS, …). Re-review once the remaining jobs land.

The three questions a deletion PR has to answer

1. Was anything still needed deleted? No.
I enumerated every symbol surviving in test_utils/src/lib.rs and found a live consumer for each — the pocket_ic module (GIT_COMMIT_HASH, MAX_TICKS, the four wasm loaders, default_init_arg, MINTER_PRINCIPAL, the Ledger* re-exports), tests/tests.rs (GIT_COMMIT_HASH_UPGRADE, NNS_ROOT_PRINCIPAL, cketh_installed_canisters, tweak_ledger_suite_wasms, usdc/usdt/usdc_erc20_contract/usdt_erc20_contract), and cketh (supported_erc20_tokens, usdc, CKERC20_TRANSFER_FEE, pocket_ic::LedgerSuiteOrchestrator, pocket_ic::flow::call_ledger_icrc1_total_supply). The remaining private items (modify_wasm, is_gzipped_blob, ledger_init_arg, archive_wasm, ledger_get_blocks_disabled_wasm) are used inside the crate.

Conversely, every deleted symbol is gone repo-wide: new_state_machine, out_of_band_upgrade, stop_canister, assert_reply, AddErc20TokenFlow, ManagedCanistersAssert, UniversalCanister, CanisterHttpQuery have no reference outside the pocket_ic module's own (differently-typed) namesakes, and no file anywhere imports …test_utils::flow or …test_utils::universal_canister at the old root paths.

2. Was anything dead kept? Three pre-existing dead deps — see the inline nit on Cargo.toml. They predate the stack, so leaving them is legitimate surgical scope; I flagged them as a nit rather than a medium.

3. The sweep claims — one holds as stated, one needs restating.

Grep sweep: holds. grep -rn "state_machine_tests\|StateMachine\|state_machine" rs/ethereum returns 10 hits: 9 are historical git-log excerpts inside cketh/mainnet/*_upgrade_*.md proposal records (immutable by nature) and 1 is the explanatory comment at cketh/test_utils/src/lib.rs:941 — a cketh file, out of this PR's component scope. No Rust code in rs/ethereum mentions StateMachine.

Bazel sweep: the substantive criterion is met, but the plan's literal wording is unachievable. rdeps(//rs/ethereum/..., //rs/state_machine_tests) is not empty — it lists the four integration_tests targets. The reason is not a leftover: somepath(//rs/ethereum/ledger-suite-orchestrator:integration_tests, //rs/state_machine_tests) shows exactly one edge chain, integration_tests → //:pocket-ic-server (data) → //rs/pocket_ic_server:pocket-ic-server → //rs/state_machine_tests. The PocketIC server binary reuses the state-machine internals, so any target that runs PocketIC reaches //rs/state_machine_tests through its data attribute — the plan's → empty criterion could never hold for a PocketIC-based suite. The criterion that actually matters is compile-time linkage, and it is clean: attr(deps, "state_machine_tests", //rs/ethereum/...) returns nothing, and rdeps(//rs/ethereum/..., //rs/state_machine_tests) except rdeps(//rs/ethereum/..., //:pocket-ic-server) leaves no rs/ethereum target at all. No Rust library or test in rs/ethereum compiles against ic-state-machine-tests any more. I consider the acceptance criterion met in substance; the plan's wording should be read as "no compile dependency", not "no node in the transitive graph".

Maintainability rundown

  • Duplication: none found — and the PR removes the ~1000-line dual-fixture duplication the plan itself listed as a risk for the stack's lifetime.
  • Unused derives: none — no types are introduced.
  • Primitive-obsession parameters: none — no signatures are introduced.
  • Divergent invariant handling: none — no invariant checks are introduced or moved.
  • Silent fallbacks: none — no failure paths are introduced.
  • Dead code (G9): the three pre-existing dead deps above; nothing newly orphaned by this deletion.
  • Component boundary: clean. The delta touches only rs/ethereum/ledger-suite-orchestrator/test_utils/** plus Cargo.lock.
  • Cargo/Bazel mirroring: exact. All four removals are mirrored 1:1 — assert_matches@crate_index//:assert_matches, ic-state-machine-tests//rs/state_machine_tests, ic-types//rs/types/types, ic-management-canister-types-private//rs/types/management_canister_types — and Cargo.lock drops exactly those four entries. ic-types-cycles is correctly retained: pocket_ic/universal_canister.rs:7,43,62 uses Cycles.
  • Docs: the PR description and commit message list three dropped deps but four were dropped — assert_matches is missing from both. Trivial; mention it if you push another commit.

Testing

Pure deletion of unreferenced code, so no behaviour changes and no new tests are warranted; the guarantee needed is that the surviving suites are unaffected, which they are.

What I ran

  • cargo check --all-targets --all-features -p ic-ledger-suite-orchestrator-test-utils -p ic-ledger-suite-orchestrator -p ic-cketh-test-utils -p ic-cketh-minter → clean.
  • bazel test //rs/ethereum/ledger-suite-orchestrator:integration_tests //rs/ethereum/cketh/minter:integration_tests → 3/3 PASSED (integration_tests 15.8s, cketh_test 75.9s, ckerc20_test 147.7s).
  • bazel build //rs/ethereum/... → 48 targets, success (nothing else in the component referenced the deleted fixture).
  • The four Bazel queries quoted above.

@gregorydemay
gregorydemay marked this pull request as ready for review August 12, 2026 07:18
@gregorydemay
gregorydemay requested a review from a team as a code owner August 12, 2026 07:18
@zeropath-ai

zeropath-ai Bot commented Aug 12, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to b509d80.

Security Overview
Detected Code Changes
Change Type Relevant files
Refactor ► rs/ethereum/ledger-suite-orchestrator/test_utils/src/lib.rs
    Remove unused imports and simplify exports
► rs/ethereum/ledger-suite-orchestrator/test_utils/src/universal_canister.rs
    Delete universal_canister helper module
► rs/ethereum/ledger-suite-orchestrator/test_utils/BUILD.bazel
    Adjust Bazel BUILD to remove deleted test_utils dependencies
► rs/ethereum/ledger-suite-orchestrator/test_utils/Cargo.toml
    Remove unused dependencies
► rs/ethereum/ledger-suite-orchestrator/test_utils/src/flow.rs
    Delete large flow implementation file
Bug Fix ► rs/ethereum/ledger-suite-orchestrator/test_utils/BUILD.bazel
    Remove references to deleted sources and tests
► rs/ethereum/ledger-suite-orchestrator/test_utils/Cargo.toml
    Drop unused crate dependencies from workspace
► Cargo.lock (minor formatting/dependency listings adjustments)

@mbjorkqvist mbjorkqvist 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.

Thanks for the cleanup @gregorydemay!

Since you're removing dependencies anyway, I believe the following could also be removed (they were already unused before this PR though):

  • ic-http-types (in both Cargo.toml and BUILD.bazel)
  • proptest (also in both)
  • ic-test-utilities-load-wasm in Cargo.toml only

Rachit2323 pushed a commit to Rachit2323/ic that referenced this pull request Aug 12, 2026
dfinity#10949)

Migrates the ledger-suite-orchestrator (LSO) integration tests from the
internal `ic-state-machine-tests` harness to PocketIC, following the
pattern already used for the EVM-RPC canister
(dfinity/evm-rpc-canister#294). This is DEFI-2262: a pure refactor of
the test harness — same tests, same coverage, same semantics.

`CkErc20Setup` in `rs/ethereum/cketh` embeds LSO's fixture and shares a
`StateMachine` with it, so flipping LSO's fixture in place would break
cketh in the same commit. To keep this change single-component and the
tree green, this PR **adds** a PocketIC fixture in LSO's `test_utils`
alongside the existing StateMachine one (precedent:
`rs/ledger_suite/icp/test_utils`'s
`state_machine_helpers`/`pocket_ic_helpers` coexisting) and migrates
only `ledger-suite-orchestrator/tests/tests.rs` to it. The StateMachine
fixture stays untouched at its current paths and is still exercised by
`cketh`; it is deleted only in the last PR of this stack, once cketh no
longer needs it.

## Summary of changes
- New `pocket_ic` module in `ledger-suite-orchestrator/test_utils`
(`LedgerSuiteOrchestrator`, `AddErc20TokenFlow`,
`ManagedCanistersAssert`, `UniversalCanister`, `new_pocket_ic()`),
mirroring the existing StateMachine-based types and method names
one-for-one so later PRs in the stack only need to swap import paths.
- `new_pocket_ic()` builds a system subnet (LSO tests assert exact cycle
balances, which only hold on a non-charging subnet) with
canister-execution rate limiting disabled (LSO repeatedly
installs/upgrades ledger, index and archive canisters).
- Metrics assertions now go through `ic-metrics-assert`'s
`PocketIcHttpQuery` (feature `pocket_ic`) instead of a hand-rolled
`CanisterHttpQuery` impl.
- `tests/tests.rs` fully migrated to the new fixture.
- `Cargo.toml`/`BUILD.bazel` updated accordingly; `test_utils` keeps
`ic-state-machine-tests` for now (still needed by the old fixture).

## Coverage
- All spec requirements from the PR are covered: PocketIC fixture added
alongside the old one, `tests/tests.rs` fully migrated, old
fixture/paths untouched, `cketh` still builds against the untouched
fixture.

## 📚 PR stack

1. **dfinity#10949 — test(ledger-suite-orchestrator): migrate integration tests
to PocketIC** 👈 you are here
2. dfinity#10950 — test(cketh): deduplicate signed-transaction literals in
integration tests
3. dfinity#10955 — test(cketh): migrate integration tests to PocketIC
4. dfinity#10956 — test(ledger-suite-orchestrator): drop the StateMachine test
fixture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@gregorydemay
gregorydemay merged commit b509d80 into ic_DEFI-2262_3_cketh-pocket-ic Aug 12, 2026
31 checks passed
@gregorydemay
gregorydemay deleted the ic_DEFI-2262_4_lso-drop-state-machine branch August 12, 2026 16:37
pull Bot pushed a commit to mikeyhodl/ic that referenced this pull request Aug 12, 2026
…rals in integration tests (dfinity#10950)

## Summary
Small preparatory cleanup for the cketh integration tests ahead of the
PocketIC migration (DEFI-2262). No framework change here — tests still
run on `ic-state-machine-tests` and stay green.

- Deduplicated the inline raw-transaction and transaction-hash string
literals in `minter/tests/cketh.rs` that were byte-identical to the
`DEFAULT_WITHDRAWAL_TRANSACTION` / `DEFAULT_WITHDRAWAL_TRANSACTION_HASH`
constants already exported by `cketh/test_utils`.

Since PR 3 regenerates these signatures for the PocketIC fixture,
keeping every occurrence tied to the single constant means the
regeneration only needs to touch one place instead of risking a missed
or inconsistent literal.

## 📚 PR stack

1. dfinity#10949 — test(ledger-suite-orchestrator): migrate integration tests
to PocketIC
2. **dfinity#10950 — test(cketh): deduplicate signed-transaction literals in
integration tests** 👈 you are here
3. dfinity#10955 — test(cketh): migrate integration tests to PocketIC
4. dfinity#10956 — test(ledger-suite-orchestrator): drop the StateMachine test
fixture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@gregorydemay

gregorydemay commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

🤖 This PR was closed as merged by mistake — it was not reviewed or intentionally merged.

What happened: while fixing an unrelated review comment on #10955, I committed on this branch instead of #10955's and pushed the result to ic_DEFI-2262_3_cketh-pocket-ic. That made this branch's head reachable from its own base, so GitHub marked the PR merged and deleted the branch. GitHub does not allow reopening a merged PR, so this number cannot be recovered.

Where the content lives now: in #10955, unchanged. Since the merge cannot be undone, the ledger-suite-orchestrator fixture deletion stays where it landed rather than being moved. #10955's description has been updated to cover it, so the change is still described and reviewable — just under a different PR number than planned.

The replacement PR I had opened (#11122) is closed as unnecessary, and the unrelated PocketIC server lifetime fix that caused this has been moved out of #10955 into its own PR, #11123.

Apologies for the noise — the mistake was mine, not a change in plan.

pull Bot pushed a commit to bit-cook/ic that referenced this pull request Aug 13, 2026
## 📚 PR stack

1. ~~dfinity#10949~~ — test(ledger-suite-orchestrator): migrate integration
tests to PocketIC (merged)
2. ~~dfinity#10950~~ — test(cketh): deduplicate signed-transaction and
transaction-hash literals (merged)
3. **dfinity#10955 — test(cketh): migrate integration tests to PocketIC** 👈 you
are here
4. ~~dfinity#10956~~ — test(ledger-suite-orchestrator): drop the StateMachine
test fixture — **its content is part of this PR**, see below

Follow-up, based on this PR: dfinity#11123 (PocketIC server lifetime).

## Summary

Flips `rs/ethereum/cketh/test_utils` and the minter's
`cketh.rs`/`ckerc20.rs` integration tests from `ic-state-machine-tests`
onto the sync `pocket_ic` client, following the pattern established for
the ledger-suite-orchestrator in dfinity#10949.

The minter is now initialized against the fiduciary subnet's `"key_1"`
ECDSA key (StateMachine's `"master_ecdsa_public_key"` isn't available on
PocketIC's fiduciary subnet), which changes the minter's derived
Ethereum address. Every signature-derived constant is regenerated as a
consequence: `MINTER_ADDRESS`, `DEFAULT_WITHDRAWAL_TRANSACTION(_HASH)`,
`DEFAULT_CKERC20_WITHDRAWAL_TRANSACTION(_HASH)`, the r/s of the default
ERC20 signed transaction, the per-account deposit address in
`should_record_address_to_deposit`, and the resubmitted-transaction
literal in
`should_resubmit_new_transaction_with_same_max_fee_per_gas_when_price_increased`.

Canister-http mocking is rebuilt around PocketIC's `get_canister_http()`
/ `mock_canister_http_response()`, preserving the legacy `"Http body
exceeds size limit of {n} bytes."` reject that the minter's
response-size check matches on.

`tests/dump_stable_memory.rs` and `tests/deposit_from_cex_demo.rs` are
untouched.

## Also included: dropping the StateMachine fixture from the
orchestrator

This was meant to be a separate PR (dfinity#10956) reviewed on top of this one.
It was marked merged by mistake — see [the note
there](dfinity#10956 (comment))
— and since GitHub cannot reopen a merged PR, its content stays here
rather than being shuffled again.

With the ckETH minter's tests on PocketIC, nothing in `rs/ethereum` uses
the orchestrator's StateMachine-based fixture, so it is deleted along
with the now-unused `ic-state-machine-tests`, `ic-types`,
`ic-management-canister-types-private` and `assert_matches`
dependencies. The environment-agnostic helpers the `pocket_ic` module
and cketh still import (wasm loaders, init-arg builders,
`usdc()`/`usdt()`, constants) stay at their existing paths. After this
PR, no Rust target under `rs/ethereum` compiles against
`ic-state-machine-tests`.

## Behavioural differences PocketIC forces, and how they are handled

PocketIC differs from StateMachine in two ways the tests are sensitive
to. Both are handled in the fixture, in one place each, rather than
worked around per test.

**Time advances kill the outcalls in flight.** PocketIC fails
canister-http requests once they cross `CANISTER_HTTP_TIMEOUT_INTERVAL`;
StateMachine left them pending indefinitely. The requests also stay
listed until a round processes the failures, so a stub could bind to a
request that was already dead and see its response discarded. Worse, a
scraping cycle awaiting such a request keeps holding its `TimerGuard`,
so the firing due at the new time is dropped as `AlreadyProcessing` and
the query the test expects is never issued. `CkEthSetup::advance_time`
therefore fails those outcalls up front and deterministically, doing
what the advance would have done anyway. It is a no-op when nothing is
in flight, because a fixture that has executed no round is expected to
trigger the first scraping cycle itself.

**A stop request takes effect only in the following round.** The
outcalls the minter's timers issue in that last running round become
visible after it, so `stop_minter` ticks once before draining them.

The block number stubs also now match on `["finalized", false]`, which
is what the scraping cycle actually queries — unconstrained, they could
be consumed by the block height refresh timer's query for the latest
block.

## Runtime

Measured against master with identical in-test instrumentation on both
sides: **+5% (ckETH) and +11% (ckERC20)** of wall-clock at default
parallelism (+15%/+20% single-threaded). Fixture-light tests are
indistinguishable from master; the difference tracks the number of IC
rounds a test drives, since PocketIC runs out of process. The dominant
cost in both harnesses is tests that rebuild the whole fixture several
times within one `#[test]`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants