Skip to content

Remove async trait#1314

Merged
nachog00 merged 7 commits into
devfrom
remove_async_trait
Jun 30, 2026
Merged

Remove async trait#1314
nachog00 merged 7 commits into
devfrom
remove_async_trait

Conversation

@zancas

@zancas zancas commented Jun 28, 2026

Copy link
Copy Markdown
Member

Async Functions In Traits landed in Rust 1.75 almost 3 years ago.

Removing the async_trait dependency incurs some ergonomics/readability costs.

Its benefits include:

  • delimiting which signatures actually needed to be constrained as Send
  • migrate to compiled types instead of dynamically dispatched trait object
    (i) better compile time correctness guarantees
    (ii) better runtime performance characteristics
  • removal of a direct dependency
    (i) when upstream also drops the dep the dependency graph will pare

Intended to be behavior preserving and local tests all pass.

zancas and others added 5 commits June 27, 2026 17:16
Record the decision to migrate zaino-state's trait definitions off the
`#[async_trait]` macro to native async fn in traits (AFIT), supplying the
`Send` bound by hand through a `SendFut` supertrait alias.

The decision is grounded in compiler-checked evidence: stripping the macro
crate-wide and compiling yields zero E0038 (no call site uses these traits as
trait objects) and 15 Send errors (Send, not object safety, is what the macro
carries here). Requires no MSRV change — the pattern is stable since 1.75.0,
below the 1.95.0 toolchain pin.

Justifications: makes the Send bound explicit, returns concrete future
implementors instead of boxed trait objects, surfaces which methods relied on
the previously-implicit Send, and removes async-trait from this crate's direct
dependencies (off the critical path for the eventual transitive removal, and
less version-skew exposure today).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the `#[async_trait]` macro on zaino-state's async trait definitions
with native async fn in traits (AFIT), supplying the `Send` bound the macro
added implicitly via a `SendFut` supertrait alias:
`pub trait SendFut<T>: Future<Output = T> + Send`.

- 108 method declarations become `fn ... -> impl SendFut<T>`; impl blocks keep
  their ergonomic `async fn` form.
- The 7 default-bodied trait methods retain their defaults, wrapped in
  `async move { ... }` to satisfy the explicit Send-future return.
- Three gnarly BlockchainSource return payloads get pub(crate) type aliases
  (TreestateBytes, ShieldedTreeRoots, NonfinalizedBlockReceiver) to keep the
  signatures readable and clear clippy::type_complexity.
- Drop the now-unused direct `async-trait` dependency. It remains in the
  graph transitively via tonic and jsonrpsee, so there is no build/binary
  change yet — this gets zaino-state off the critical path for the eventual
  removal and shrinks its declared dependency surface.

No call site needs dyn-compatibility (verified: zero E0038 when the macro is
stripped crate-wide), so native AFIT loses nothing here. The toolchain is
pinned at 1.95.0; AFIT is stable since 1.75.0, so there is no MSRV change.

See docs/adr/0002-native-afit-over-async-trait.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…erride

StateServiceSubscriber carried a byte-for-byte copy of ZcashIndexer's default
`get_taddress_txids_helper` body — same range-clamping, error strings, and
final `get_address_tx_ids` delegation. Delete the override so State inherits
the canonical default: its behavior becomes provably identical to the default
rather than a copy free to drift, and the default returns to two inheritors
(FetchServiceSubscriber + StateServiceSubscriber).

Pre-existing duplication surfaced while migrating to native AFIT; behavior is
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zancas
zancas requested a review from nachog00 June 29, 2026 15:17
@nachog00 nachog00 self-assigned this Jun 29, 2026
nachog00
nachog00 approved these changes Jun 30, 2026
@nachog00
nachog00 merged commit 1bca799 into dev Jun 30, 2026
33 checks passed
zancas added a commit that referenced this pull request Jun 30, 2026
The merged dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jun 30, 2026
The merged dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jul 1, 2026
The merged dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jul 1, 2026
Dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jul 1, 2026
Dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jul 2, 2026
Dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zancas added a commit that referenced this pull request Jul 3, 2026
Dev dropped async_trait (#1314, native AFIT) and reworked ChainWork into a NonZeroU128 primitive passed as Option<ChainWork> at call sites (#1313). Update the spend-index code to match: impl_state_source_forwarders! no longer emits #[async_trait] (its async fn forwarders satisfy BlockchainSource's native -> impl SendFut<_> methods), and SpendIndexSync::run passes None for build_indexed_block_from_source's now-Option<ChainWork> parent_chainwork (chainwork is irrelevant to spend extraction), dropping the unused ChainWork import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

3 participants