bdk icon indicating copy to clipboard operation
bdk copied to clipboard

Remove ChainOracle trait by inverting dependency

Open LLFourn opened this issue 10 months ago • 1 comments

The ChainOracle trait is annoying. Initially designed to allow anyone to provide their own view of the chain. This is a noble goal but doing this via a trait means we force the ChainOracle to do it synchronously and have to handle errors from the ChainOracle.

ChainOracles are really only used for canonicalization. Instead of writing:

tx_graph.list_canonical_txs(&local_chain, chain_tip);

We could instead write:

let list_txs_task = tx_graph.list_canonical_txs(chain_tip);
let txs_iter = local_chain.canonicalize(list_txs_task);

Now if we want to replace the canonicalizing functionality with a bitcoin node or a CBF system. It can be sync or async, infallible or fallible and we don't have to care in BDK.

LLFourn avatar Jan 31 '25 04:01 LLFourn

As part of yesterday's in-person discussion, we came up with some ideas and goals towards this one and how to rework/refactor the canonicalization algorithm.

As the main painful points on this, we have:

i) As mentioned above in the issue, the ChainOracle trait makes it hard in the sense that it's limiting on how we access the data API-wise and outputs errors, which probably should be handled by each blockchain source in their own fashion.

ii) The canonicalization algorithm does not actually output the expected that in a topological order, i.e it does not fully use the available last_seen to tie-break the transaction ordering.

iii) The API can't be "sans-io" in the sense that it's currently blocking, but it probably could be either async/blocking.

iv) The canonicalization algorithm probably should also consider using the first_seen as a higher-level tie-break on the topological order of the transactions, for already applied/synced anchored transactions.

v) It should also be optimized in a way that we don't need to recanonicalize everything and can act in an extensible form.

--

I'm planning to work on this in the following order:

  1. Refactor and figure out the required changes on the canonicalization algorithm in order to properly use the last_seen data and return the transactions in a topological order, both mempool and achored transactions.
  2. Refactor and figure out a new API for the ChainOracle (dependency injection) that could be passed into the blockchain sources, and handled by the canonicalization algorithm in either async/blocking.
  3. How should we also take in consideration the first_seen data in order to properly canonicalize the anchored clusters, keeeping the topological order.
  4. How can we optimize the algorithm in-order to have it in an extension fashion, without needing to recanonicalize the whole graph ?

oleonardolima avatar Sep 09 '25 00:09 oleonardolima