Remove async trait#1314
Merged
Merged
Conversation
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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
(i) better compile time correctness guarantees
(ii) better runtime performance characteristics
(i) when upstream also drops the dep the dependency graph will pare
Intended to be behavior preserving and local tests all pass.