feat(core): add non-consuming SyncRequest iterators#2236
feat(core): add non-consuming SyncRequest iterators#2236alok844937-design wants to merge 2 commits into
Conversation
|
@evanlinjin PTAL |
There was a problem hiding this comment.
Thanks for picking this up.
This PR silently changes iter_... methods from consuming methods to non-consuming. This will be a problem for downstream callers.
Additionally, into_... is the wrong naming convention. As per Rust API Guidelines, the into prefix should be reserved for methods that consume all of self.
To fix these naming problems, I propose the following:
- Rename consuming methods to use the
drain_prefix. - Reintroduce
iter_methods that call thedrain_methods, but mark them as deprecated. This way these changes are backwards compatible. - Use no prefix (
spks(),txids(), etc.) for read-only methods.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2236 +/- ##
==========================================
- Coverage 78.65% 78.46% -0.20%
==========================================
Files 30 30
Lines 5909 5924 +15
Branches 279 279
==========================================
Hits 4648 4648
- Misses 1185 1200 +15
Partials 76 76
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for the feedback! I've updated the PR based on your suggestions:
PTAL when you have a chance. Thanks! |
- Rename consuming iterators to drain_txids/drain_outpoints - Add read-only accessors: spks(), txids(), outpoints() - Deprecate iter_txids/iter_outpoints as compatibility wrappers delegating to drain_txids/drain_outpoints - Update call-sites in esplora and electrum backends - Update/rename tests accordingly Fixes bitcoindevkit#2220
67933be to
7ba14fe
Compare
| fn test_spks_does_not_consume() { | ||
| let spk1 = bitcoin::ScriptBuf::new(); | ||
| let spk2 = bitcoin::ScriptBuf::new(); | ||
|
|
||
| let request: SyncRequest<u32, BlockHash> = SyncRequest::builder() | ||
| .spks_with_indexes(vec![(0u32, spk1), (1u32, spk2)]) | ||
| .build(); | ||
|
|
||
| assert_eq!(request.spks().count(), 2); | ||
| assert_eq!(request.spks().count(), 2, "must not consume"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_txids_does_not_consume() { | ||
| let txid1 = Txid::from_byte_array([0x01; 32]); | ||
|
|
||
| let request: SyncRequest<(), BlockHash> = SyncRequest::builder().txids(vec![txid1]).build(); | ||
|
|
||
| assert_eq!(request.txids().count(), 1); | ||
| assert_eq!(request.txids().count(), 1, "must not consume"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_outpoints_does_not_consume() { | ||
| let outpoint1 = OutPoint::null(); | ||
|
|
||
| let request: SyncRequest<(), BlockHash> = | ||
| SyncRequest::builder().outpoints(vec![outpoint1]).build(); | ||
|
|
||
| assert_eq!(request.outpoints().count(), 1); | ||
| assert_eq!(request.outpoints().count(), 1, "must not consume"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_drain_txids_still_consumes_all_items() { | ||
| let txid1 = Txid::from_byte_array([0x01; 32]); | ||
| let txid2 = Txid::from_byte_array([0x02; 32]); | ||
|
|
||
| let mut request: SyncRequest<(), BlockHash> = | ||
| SyncRequest::builder().txids(vec![txid1, txid2]).build(); | ||
|
|
||
| assert_eq!(request.txids().count(), 2); | ||
|
|
||
| let consumed: Vec<_> = request.drain_txids().collect(); | ||
| assert_eq!( | ||
| consumed.len(), | ||
| 2, | ||
| "drain_txids must still consume all items" | ||
| ); | ||
| } |
There was a problem hiding this comment.
These tests don't earn their keep imo. It's apparent from the method's signature.
There was a problem hiding this comment.
Thanks for the feedback! I removed those tests since the non-consuming behavior is already apparent from the method signatures. I've updated the PR accordingly. PTAL when you have a chance.
|
Hi @evanlinjin, After removing the tests per your suggestion, the Codecov patch coverage dropped because these new accessors are no longer exercised. Would you prefer adding a small focused test for the new APIs, or is the coverage drop acceptable in this case? |
Description
This PR introduces dedicated consuming and non-consuming iteration APIs for
SyncRequestwhile preserving backwards compatibility, as proposed in #2220.Previously,
SyncRequestexposediter_txids(&mut self)anditer_outpoints(&mut self)as consuming iterators(draining the request viaSyncIter), despite theiriter_*naming suggesting read-only iteration. At the same time, there was no API for inspecting pendingspks,txids, oroutpointswithout consuming the request.This PR addresses these issues while preserving backwards compatibility.
API Changes
Adds new read-only accessors:
SyncRequest::spks(&self)SyncRequest::txids(&self)SyncRequest::outpoints(&self)Renames the consuming API to:
SyncRequest::drain_txids(&mut self)SyncRequest::drain_outpoints(&mut self)Reintroduces:
SyncRequest::iter_txids(&mut self)SyncRequest::iter_outpoints(&mut self)as deprecated compatibilty wrappers that delegate to the corresponding
drain_*methods. This preserves existing downstream code while providing a migration path to the clearer API.Backend updates
Updated all in-tree call-sites to use the new consuming APIs:
bdk_esplora(blocking and async)bdk_electrumTesting
Added tests verifying that:
spks(),txids(), andoutpoints()are non-consuming.drain_txids()continues to consume all items as before.Design rationale
This follows the Rust API Guidelines:
drain_*clearly indicates consuming iteration over the request contents.spks(),txids(), andoutpoints()provide borrowed, read-only access.iter_*APIs remain available as deprecated compatibility wrappers, avoiding an immediate breaking change for downstream users.Fixes #2220
Notes to the reviewers
drain_*spks(),txids(), andoutpoints()iter_*methods retained as deprecated compatibility wrappersimpl ExactSizeIterator + '_, matching the capabilities of the underlying collections.bdk_electrum'stest_syncduring local testing (trusted_pendingvsconfirmedbalance assertion). Re-running the same test on the same commit passed without any code changes, suggesting pre-existing test flakiness rather than a regression introduced by this PR.Verified locally with:
cargo fmtcargo buildcargo test -p bdk_core --test test_spk_clientcargo test -p bdk_electrum --test test_electrumChangelog notice
Added
SyncRequest::spks,SyncRequest::txids, andSyncRequest::outpointsfor non-consuming inspection of pending sync data.Changed
SyncRequest::drain_txidsandSyncRequest::drain_outpointsas the consuming iterator APIs.SyncRequest::iter_txidsandSyncRequest::iter_outpointsin favor ofdrain_*for consuming iteration or the new read-only accessors.Checklists
All Submissions
New Features
Bugfixes