Skip to content

Conversation

oleonardolima
Copy link
Contributor

@oleonardolima oleonardolima commented Sep 11, 2025

Description

It introduces a new method for topological ordering canonical transactions, list_ordered_canonical_txs. It now ensures the dependency-based transaction processing, guaranteeing that parent transactions always appears before their children transaction.

The existing list_canonical_txs and try_list_canonical_txs methods have been deprecated in favor of the new ordered version.

Notes to the reviewers

"[...] For those reviewing, and wondering why we don't have a fallible try version of this method, it's because we don't have a fallible ChainOracle implementation - we will get rid of ChainOracle trait soon anyway."

This PR is intended for a point release so that bdk_wallet 2.x users can get a topologically sorted list of transactions (we need a point release on bdk_wallet 2.x as well).

It might be useful to take a look at the new test scenarios that I've added, it shows some specific scenarios where the current implementation and output of canonical_txs didn't output the transactions in topological order.

Let me know if you think the TopologicalIter algorithm and/or API could be improved.

Changelog notice

#### Added
- New `list_ordered_canonical_txs` method to `TxGraph` that returns canonical transactions in topological order, ensuring parent transactions always appear before their children

#### Deprecated
- `list_canonical_txs` method - use `list_ordered_canonical_txs` instead for guaranteed topological ordering
- `try_list_canonical_txs` method - use `list_ordered_canonical_txs` instead for guaranteed topological ordering

Checklists

All Submissions:

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

@oleonardolima oleonardolima added this to the Wallet 3.0.0 milestone Sep 11, 2025
@oleonardolima oleonardolima self-assigned this Sep 11, 2025
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch 2 times, most recently from 6b76092 to a28cfdf Compare September 11, 2025 03:07
@evanlinjin
Copy link
Member

Nice diagrams

@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch 11 times, most recently from 08e4ce8 to 70ee41b Compare September 16, 2025 04:49
@oleonardolima

This comment was marked as outdated.

@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch 2 times, most recently from 6239c8f to 0aab769 Compare September 16, 2025 06:10
@oleonardolima oleonardolima moved this to In Progress in BDK Chain Sep 16, 2025
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch from d57a580 to 3b79cba Compare September 19, 2025 01:52
Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The internals have completely changed. I don't think a point release would make any sense (we also have already merged other breaking changes). I recommend to just break the API.

Get rid of CanonicalIter. Just have a single function that returns impl Iterator<Item = ...>.

@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch 2 times, most recently from 0a17091 to 71c3744 Compare September 23, 2025 04:20
@oleonardolima oleonardolima changed the base branch from release/chain-0.23.x to release/chain-0.23.2 September 29, 2025 06:38
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch from cc0f010 to ac95bd7 Compare September 29, 2025 06:41
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch from ac95bd7 to 49bf2b3 Compare September 29, 2025 06:45
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch 2 times, most recently from 573915f to d9b9318 Compare September 29, 2025 06:54
@ValuedMammal
Copy link
Collaborator

I don't think you have to deprecate list_canonical_txs. It should just return the txs in topological order. CanonicalIter already canonicalizes the graph topologically (albeit reversed), only that it has an issue with splitting packages of related txs that should be canonicalized as a single batch.

@oleonardolima
Copy link
Contributor Author

oleonardolima commented Oct 1, 2025

I don't think you have to deprecate list_canonical_txs. It should just return the txs in topological order. [...]

I think it's good to guide users towards the method with correct output, but I'm fine with keeping both too.

CanonicalIter already canonicalizes the graph topologically (albeit reversed), only that it has an issue with splitting packages of related txs that should be canonicalized as a single batch.

It's not only reversed, but as we start canonicalizing from any given anchored tx and walk ancestors, it fails to exhaust all the spending ones from it and it's ancestors.

@evanlinjin
Copy link
Member

evanlinjin commented Oct 2, 2025

@ValuedMammal That's a good point about not deprecating list_canonical_txs since it still serves a purpose. We should update it's docs to direct users to the new method; list_ordered_canonical_txs.

Doing CanonicalIter.collect::<Vec<_>>().into_iter().rev() will not pass test_list_canonical_txs_topologically.

Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Happy to ACK after we un-deprecate list_canonical_txs and update it's docs to point to list_ordered_canonical_txs.

Also, shouldn't this PR point to the chain-0.23.x branch?

oleonardolima and others added 2 commits October 2, 2025 15:51
It deprecates the existing `list_canonical_txs` and `try_list_canonical_txs` in favor
of `list_ordered_canonical_txs` which guarantees topological ordering.

The new `list_ordered_canonical_txs` ensures that spending transactions always
appear after their inputs, topologically ordered in "spending order".

- Add `TopologicalIterator` for level-based topological sorting
- Use the `ChainPosition` for sorting within the same level
- Add the new method to the canonicalization benchmarks
- Update the new test to verify topological ordering correctness

Co-Authored-By: Claude <noreply@anthropic.com>
- Update the `TopologicalIter` to take an Iterator<Item =
  CanonicalTx<'a, Arc<Transaction>, A> of canonical txs.
- Update it's documentation to mention the Kahn's Algorithm.
- Update it to use `a_tx.cmp(&b_tx)` instead.
@oleonardolima oleonardolima force-pushed the test/add-canonical-iter-topological-order-tests branch from d9b9318 to 9c4da10 Compare October 2, 2025 05:52
@oleonardolima
Copy link
Contributor Author

Looks good. Happy to ACK after we un-deprecate list_canonical_txs and update it's docs to point to list_ordered_canonical_txs.

Also, shouldn't this PR point to the chain-0.23.x branch?

Thanks, I've removed the deprecation in 9664402.

It's valid to note that before merging the release/chain-23.x branch needs to be updated and then this PR base should be updated as well. As it will be the same commit for this base, a rebase shouldn't be needed.

@ValuedMammal
Copy link
Collaborator

ACK tested locally, and I agree with the test expectations. No real opinion on deprecating list_canonical_txs. I looked for a way to rework CanonicalIter but realized it will be better to just add an extra layer of processing that does the topological sort.

@ValuedMammal ValuedMammal changed the base branch from release/chain-0.23.2 to release/chain-0.23.x October 3, 2025 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs Review
Development

Successfully merging this pull request may close these issues.

3 participants