Skip to content

Wallet: skip parent fetch in determine_coin_type for locally-known DL coins#20844

Draft
TheLastCicada wants to merge 2 commits into
mainfrom
wallet/skip-determine-coin-type-known
Draft

Wallet: skip parent fetch in determine_coin_type for locally-known DL coins#20844
TheLastCicada wants to merge 2 commits into
mainfrom
wallet/skip-determine-coin-type-known

Conversation

@TheLastCicada
Copy link
Copy Markdown
Contributor

Purpose:

Speed up wallet sync of DataLayer singletons (the CADT-style bulk-subscription case) by classifying tracked DL coins from local metadata before paying the parent get_coin_state + request_puzzle_solution round-trip in WalletStateManager.determine_coin_type.

Current Behavior:

For DataLayer mirror coins and previously-tracked singletons, WalletStateManager._add_coin_states falls through to determine_coin_type, which fetches the parent coin state and the puzzle solution and runs CLVM uncurry. None of the CAT/NFT/DID/Clawback/VC patterns match for these coins; the function returns and a subsequent block in _add_coin_states re-queries dl_store (or compares against MIRROR_PUZZLE_HASH) and re-classifies the coin to the DL wallet. The two RPCs and the CLVM uncurry are wasted work for every DL-classified coin, and the worst case (a heavily-used DL launcher being replayed against a freshly-tracking wallet) is ten of thousands of singleton coin states each paying that tax.

New Behavior:

A new WalletStateManager._data_layer_identifier_for_coin helper performs the same predicate (puzzle_hash == MIRROR_PUZZLE_HASH or dl_store.get_singleton_record(coin.name()) is not None) using only local data. determine_coin_type calls it after the existing pool / farmer reward early-return and returns the DL WalletIdentifier immediately when it matches, skipping the parent fetch and the CLVM uncurry. The post-call DL override block in _add_coin_states is removed because the helper covers the same predicate strictly earlier in the per-coin pipeline.

Invariants unchanged:

  • Set of coins classified as DL is identical (same predicate, evaluated in the same transaction).
  • coin_data for DL-classified coins is None on this path, matching what the old post-call override produced.
  • Pool / farmer reward early-return runs before the new short-circuit.
  • Coins not classified by local DL metadata still take the full parent-fetch path through determine_coin_type.
  • The request_puzzle_solution and parent get_coin_state round-trip are still performed for all other classifications (CAT, NFT, DID, Clawback, VC, notifications).

Testing Notes:

New unit tests in chia/_tests/wallet/test_wallet_state_manager.py pin each branch of the helper:

  • test_data_layer_identifier_for_coin_returns_none_without_dl_wallet
  • test_data_layer_identifier_for_coin_mirror_puzzle_hash
  • test_data_layer_identifier_for_coin_tracked_singleton
  • test_data_layer_identifier_for_coin_no_match_with_dl_wallet

New integration test test_add_coin_states_skips_parent_fetch_for_tracked_dl_singleton drives a tracked DL singleton through the production entry point (WalletStateManager.add_coin_states, the same one used by add_states_from_peer in trusted mode at wallet_node.py:999) with WalletNode.get_coin_state monkeypatched as a recorder. It asserts that parent_fetch_calls == [] and that the coin is owned by the DL wallet.

Mutation-verified locally: temporarily disabling the short-circuit makes the integration test fail with parent_fetch_calls != [], then re-enabling it restores the pass.

Local validation pipeline (skipping benchmarks, will run in CI):

  • Phase 1 (ruff check / ruff format --check / mypy on changed files): clean.
  • Phase 2 (targeted tests): chia/_tests/wallet/test_wallet_state_manager.py (39 selected), chia/_tests/wallet/db_wallet/test_dl_wallet.py (mirror, lifecycle, reorg, ownership-rollback), chia/_tests/wallet/test_wallet_node.py (41 selected), chia/_tests/wallet/sync/test_wallet_sync.py (sync, long_sync, reorgs, dusted wallet) — 120+ tests passing.
  • Phase 5 (pre-commit run --all-files): clean.

… coins

Moves the post-determine_coin_type DataLayer override from _add_coin_states
into determine_coin_type itself so DL mirror coins and previously-tracked
singletons are classified without the request_puzzle_solution + parent
get_coin_state round-trip. Helps the bulk-subscription case (e.g. CADT
replaying tens of thousands of DL singleton coin states for a tracked
launcher) on trusted-peer wallet sync.

Removes the now-redundant post-call DL override block (same predicate,
strictly later in the per-coin pipeline).
@TheLastCicada TheLastCicada added Changed Required label for PR that categorizes merge commit message as "Changed" for changelog Wallet labels Apr 29, 2026
@coveralls-official
Copy link
Copy Markdown

coveralls-official Bot commented Apr 29, 2026

Coverage Report for CI Build 25130365079

Coverage increased (+0.03%) to 91.241%

Details

  • Coverage increased (+0.03%) from the base build.
  • Patch coverage: 95 of 95 lines across 2 files are fully covered (100%).
  • 13 coverage regressions across 7 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

13 previously-covered lines in 7 files lost coverage.

File Lines Losing Coverage Coverage
chia/full_node/full_node_api.py 3 86.47%
chia/timelord/timelord.py 3 72.76%
chia/full_node/full_node.py 2 87.64%
chia/timelord/timelord_launcher.py 2 70.0%
chia/data_layer/data_layer.py 1 85.68%
chia/_tests/core/util/test_file_keyring_synchronization.py 1 96.88%
chia/_tests/simulation/test_simulation.py 1 96.49%

Coverage Stats

Coverage Status
Relevant Lines: 118125
Covered Lines: 107945
Line Coverage: 91.38%
Relevant Branches: 11749
Covered Branches: 10553
Branch Coverage: 89.82%
Branches in Coverage %: Yes
Coverage Strength: 1.83 hits per line

💛 - Coveralls

Replace monkeypatched async helper functions with AsyncMock and exercise the timestamp mock explicitly so Coveralls diff coverage includes the new test-only paths deterministically.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changed Required label for PR that categorizes merge commit message as "Changed" for changelog Wallet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant