25 Commits

Author SHA1 Message Date
志宇
6b43001951
feat!: Rework sqlite, changesets, persistence and wallet-construction
Rework sqlite: Instead of only supported one schema (defined in
`bdk_sqlite`), we have a schema per changeset type for more flexiblity.

* rm `bdk_sqlite` crate (as we don't need `bdk_sqlite::Store` anymore).
* add `sqlite` feature on `bdk_chain` which adds methods on each
  changeset type for initializing tables, loading the changeset and
  writing.

Rework changesets: Some callers may want to use `KeychainTxOutIndex`
where `K` may change per descriptor on every run. So we only want to
persist the last revealed indices by `DescriptorId` (which uniquely-ish
identifies the descriptor).

* rm `keychain_added` field from `keychain_txout`'s changeset.
* Add `keychain_added` to `CombinedChangeSet` (which is renamed to
  `WalletChangeSet`).

Rework persistence: add back some safety and convenience when persisting
our types. Working with changeset directly (as we were doing before) can
be cumbersome.

* Intoduce `struct Persisted<T>` which wraps a type `T` which stores
  staged changes to it. This adds safety when creating and or loading
  `T` from db.
* `struct Persisted<T>` methods, `create`, `load` and `persist`, are
  avaliable if `trait PersistWith<Db>` is implemented for `T`. `Db`
  represents the database connection and `PersistWith` should be
  implemented per database-type.
* For async, we have `trait PersistedAsyncWith<Db>`.
* `Wallet` has impls of `PersistedWith<rusqlite::Connection>`,
  `PersistedWith<rusqlite::Transaction>` and
  `PersistedWith<bdk_file_store::Store>` by default.

Rework wallet-construction: Before, we had multiple methods for loading
and creating with different input-counts so it would be unwieldly to add
more parameters in the future. This also makes it difficult to impl
`PersistWith` (which has a single method for `load` that takes in
`PersistWith::LoadParams` and a single method for `create` that takes in
`PersistWith::CreateParams`).

* Introduce a builder pattern when constructing a `Wallet`. For loading
  from persistence or `ChangeSet`, we have `LoadParams`. For creating a
  new wallet, we have `CreateParams`.
2024-07-18 03:25:41 +00:00
Wei Chen
1a62488abf
feat(chain)!: Implement ConfirmationBlockTime
Both `bdk_electrum` and `bdk_esplora` now report the exact block
that the transaction is in, which removes the need for having the
old `ConfirmationTimeHeightAnchor` and `ConfirmationHeightAnchor`.
This PR introduces a new, simpler anchor type that can be modified
to support additional data in the future.
2024-07-09 00:23:02 +08:00
Wei Chen
962305f415
chore(chain)!: Rename Append to Merge 2024-07-07 16:46:10 +08:00
valued mammal
c3fc1dd123
ref(chain)!: create module indexer
and replace keychain module with `balance.rs`
2024-07-05 12:22:28 -04:00
志宇
feb27df180
feat(chain)!: add take convenience method to Append trait
This is useful if the caller wishes to use the type as a staging area.

This is breaking as `Append` has a `Default` bound now.
2024-06-15 00:52:23 +08:00
志宇
1eca568be5
feat!: rm persist submodule
Remove `PersistBackend`, `PersistBackendAsync`, `StageExt` and
`StageExtAsync`. Remove `async` feature flag and dependency. Update
examples and wallet.
2024-06-15 00:52:23 +08:00
志宇
ec36c7ecca
feat(example): use changeset staging with rpc polling example 2024-06-13 12:58:39 -05:00
Steve Myers
9e97ac0330
refactor(persist): update file_store, sqlite, wallet to use bdk_chain::persist
Also update examples and remove bdk_persist crate.
2024-06-13 12:56:25 -05:00
LLFourn
bc2a8be979
refactor(keychain): Fix KeychainTxOutIndex range queries
The underlying SpkTxOutIndex should not use DescriptorIds to index
because this loses the ordering relationship of the spks so queries on
subranges of keychains work.

Along with that we enforce that there is a strict 1-to-1 relationship
between descriptors and keychains. Violating this leads to an error in
insert_descriptor now.

In general I try to make the translation layer between the SpkTxOutIndex
and the KeychainTxOutIndex thinner. Ergonomics of this will be improved
in next commit.

The test from the previous commit passes.
2024-06-13 22:52:43 +08:00
Daniela Brozzoni
4f05441a00
keychain::ChangeSet includes the descriptor
- The KeychainTxOutIndex's internal SpkIterator now uses DescriptorId
  instead of K. The DescriptorId -> K translation is made at the
  KeychainTxOutIndex level.
- The keychain::Changeset is now a struct, which includes a map for last
  revealed indexes, and one for newly added keychains and their
  descriptor.

API changes in bdk:
- Wallet::keychains returns a `impl Iterator` instead of `BTreeMap`
- Wallet::load doesn't take descriptors anymore, since they're stored in
  the db
- Wallet::new_or_load checks if the loaded descriptor from db is the
  same as the provided one

API changes in bdk_chain:
- `ChangeSet` is now a struct, which includes a map for last revealed
  indexes, and one for keychains and descriptors.
- `KeychainTxOutIndex::inner` returns a `SpkIterator<(DescriptorId, u32)>`
- `KeychainTxOutIndex::outpoints` returns a `impl Iterator` instead of `&BTreeSet`
- `KeychainTxOutIndex::keychains` returns a `impl Iterator` instead of
  `&BTreeMap`
- `KeychainTxOutIndex::txouts` doesn't return a ExactSizeIterator
  anymore
- `KeychainTxOutIndex::unbounded_spk_iter` returns an `Option`
- `KeychainTxOutIndex::next_index` returns an `Option`
- `KeychainTxOutIndex::last_revealed_indices` returns a `BTreeMap`
  instead of `&BTreeMap`
- `KeychainTxOutIndex::reveal_to_target` returns an `Option`
- `KeychainTxOutIndex::reveal_next_spk` returns an `Option`
- `KeychainTxOutIndex::next_unused_spk` returns an `Option`
- `KeychainTxOutIndex::add_keychain` has been renamed to
  `KeychainTxOutIndex::insert_descriptor`, and now it returns a
  ChangeSet
2024-05-08 15:49:41 +02:00
志宇
77d35954c1
feat(chain)!: rm local_chain::Update
The intention is to remove the `Update::introduce_older_blocks`
parameter and update the local chain directly with `CheckPoint`.

This simplifies the API and there is a way to do this efficiently.
2024-04-17 10:57:50 +08:00
vmammal
1c15cb2f91
ref(example_cli): Add new struct Init
for holding the items returned from `example_cli::init`
2024-01-31 11:50:41 -05:00
志宇
3fa44a58ec
Merge bitcoindevkit/bdk#1292: fix(store): Remove lifetime
e6433fb2c1526cff37e3a17cc71986759ebac30f feat(persist): Add stage_and_commit to Persist (LLFourn)
0bee46e75bc99112abc15de59984e6059ff874e5 fix(store): Remove lifetime (LLFourn)

Pull request description:

  Remove gratuitous use of lifetimes in the main persistence struct `Store`. Having lifetimes on this means that you have to keep the magic bytes alive longer than the database which is particularly offensive if you have to send the database to another thread. On top of that the bytes aren't even read.

ACKs for top commit:
  evanlinjin:
    ACK e6433fb2c1526cff37e3a17cc71986759ebac30f

Tree-SHA512: 7f6d9d60951a8ceaee30719d0771e15632c6fad0702294af15409c5df492669a07299874ef5ee34e3d75bdecbbd41df29bced3ff16b2360d5d5c7687ef677ffc
2024-01-19 23:28:56 +08:00
LLFourn
e6433fb2c1
feat(persist): Add stage_and_commit to Persist
In the example_cli we were not always committing (seemingly by mistake).
This then caused all the examples to have to compensate by manually
committing.
2024-01-19 11:28:56 +11:00
Vladimir Fomene
8ec65f0b8e
feat(example): add RPC wallet example
Co-authored-by: Vladimir Fomene <vladimirfomene@gmail.com>
Co-authored-by: 志宇 <hello@evanlinjin.me>
2024-01-16 00:27:02 +08:00
志宇
e0512acf94
feat(bitcoind_rpc)!: emissions include checkpoint and connected_to data
Previously, emissions are purely blocks + the block height. This means
emitted blocks can only connect to previous-adjacent blocks. Hence, sync
must start from genesis and include every block.
2024-01-16 00:27:02 +08:00
志宇
bc796f412a
fix(example): bitcoind_rpc_polling now initializes local_chain properly
Previously, the genesis block is not initialized properly. Thank you
@notmandatory for identifying this bug.
2023-12-28 12:51:11 +08:00
Antoine Poinsot
4fd539b647
feat(chain)!: KeychainTxOutIndex uses a universal lookahead
The wallet is currently created without setting any lookahead value for
the keychain. This implicitly makes it a lookahead of 0. As this is a
high-level interface we should avoid footguns and aim for a reasonable
default.

Instead of simply patching it for wallet, we alter `KeychainTxOutIndex`
to have a default lookahead value. Additionally, instead of a
per-keychain lookahead, the constructor asks for a `lookahead` value.
This avoids the footguns of having methods which allows the caller the
decrease the `lookahead` (and therefore panicing). This also simplifies
the API.

Co-authored-by: Antoine Poisot <darosior@protonmail.com>
Co-authored-by: 志宇 <hello@evanlinjin.me>
2023-12-28 12:51:11 +08:00
Einherjar
27a63abd1e
chore: typos fixed 2023-11-16 07:25:20 -06:00
志宇
5998a22819
feat!: LocalChain with hardwired genesis checkpoint
This ensures that `LocalChain` will always have a tip. The `ChainOracle`
trait's `get_chain_tip` method no longer needs to return an option.
2023-11-16 06:41:18 +08:00
Wei Chen
0112c67b60
chore: rename ConfirmationTimeAnchor to ConfirmationTimeHeightAnchor
An `Anchor` implementation that records both height and time should have
both attributes included in the name.
2023-11-12 21:31:47 +08:00
志宇
b69c13ddf6
example_bitcoind_rpc: tweaks
* avoid holding mutex lock over io
* document `CHANNEL_BOUND` const
* use the `relevant` variant of `batch_insert_unconfirmed`
* print elapsed time in stdout for various updates
2023-10-10 01:04:30 +08:00
志宇
5f34df8489
bitcoind_rpc!: bring back CheckPoints to Emitter
* `bdk_chain` dependency is added. In the future, we will introduce a
  separate `bdk_core` crate to contain shared types.
* replace `Emitter::new` with `from_height` and `from_checkpoint`
  * `from_height` emits from the given start height
  * `from_checkpoint` uses the provided cp to find agreement point
* introduce logic that ensures emitted blocks can connect with
  receiver's `LocalChain`
* in our rpc example, we can now `expect()` chain updates to always
  since we are using checkpoints and receiving blocks in order
2023-10-09 22:14:04 +08:00
志宇
4f5695d43a
chain: improvements to IndexedTxGraph and TxGraph APIs
For `IndexedTxGraph`:
- Remove `InsertTxItem` type (this is too complex).
    - `batch_insert_relevant` now uses a simple tuple `(&tx, anchors)`.
    - `batch_insert` is now also removed, as the same functionality can be
      done elsewhere.
- Add internal helper method `index_tx_graph_changeset` so we don't need
  to create a seprate `TxGraph` update in each method.
- `batch_insert_<relevant>_unconfirmed` no longer takes in an option of
  last_seen.
- `batch_insert_unconfirmed` no longer takes a reference of a
  transaction (since we apply all transactions anyway, so there is no
  need to clone).

For `TxGraph`:
- Add `batch_insert_unconfirmed` method.
2023-10-09 22:14:04 +08:00
志宇
150d6f8ab6
feat(example_bitcoind_rpc_polling): add example for RPC polling 2023-10-09 22:14:03 +08:00