283 Commits

Author SHA1 Message Date
Steve Myers
a112b4d97c
Merge bitcoindevkit/bdk#1416: [chain] Change tx_last_seen to Option<u64>
af75817d4bedbb5e148812d1073fd0729a23358b ref(tx_graph): Change last_seen to `HashMap<Txid, u64>` (valued mammal)
6204d2c766f968af6b63c664dda61fa8fc897e85 feat(tx_graph): Add method `txs_with_no_anchor_or_last_seen` (valued mammal)
496601b8b148afd2199a530d40edeafcb7967d46 test(tx_graph): Add test for `list_canonical_txs` (valued mammal)
c4057297a96ccbd49d984b7139994b801c2120dc wallet: delete method `insert_anchor` (valued mammal)
b34790c6b6d612661a4595bf10910294af862323 ref(tx_graph)!: Rename `list_chain_txs` to `list_canonical_txs` (valued mammal)
2ce4bb4dfc4f7b779a815eca45a3f6cee3d6c4e0 test(indexed_tx_graph): Add test_get_chain_position (valued mammal)
36f58870cb6eb24fe8c50ba4cf3ede910dd11fe8 test(wallet): Add test_insert_tx_balance_and_utxos (valued mammal)
bbc19c3536b25c78be8b5f3fe0cd9810aa679742 fix(tx_graph)!: Change tx_last_seen to `Option<u64>` (valued mammal)
324eeb3eb4e5231c6a81e6d197df788ad08b23a8 fix(wallet)!: Rework `Wallet::insert_tx` to no longer insert anchors (valued mammal)

Pull request description:

  The PR changes the type of last_seen to `Option<u64>` for `txs` member of `TxGraph`.

  This fixes an issue where unbroadcast and otherwise non-canonical transactions were returned from methods `list_chain_txs` and `Wallet::transactions` because every new tx inserted had a last_seen of 0 making it appear unconfirmed.

  fixes #1446
  fixes #1396

  ### Notes to the reviewers

  ### Changelog notice

  Changed
  - Member `last_seen_unconfirmed` of `TxNode` is changed to `Option<u64>`
  - Renamed `TxGraph` method `list_chain_txs` to `list_canonical_txs`
  - Changed `Wallet::insert_tx` to take a single `tx: Transaction` as parameter

  Added
  - Add method `txs_with_no_anchor_or_last_seen` for `TxGraph`
  - Add method `unbroadcast_transactions` for `Wallet`

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### Bugfixes:

  * [x] This pull request breaks the existing API
  * [x] I've added tests to reproduce the issue which are now passing
  * [x] I'm linking the issue being fixed by this PR

ACKs for top commit:
  notmandatory:
    Re ACK af75817d4bedbb5e148812d1073fd0729a23358b

Tree-SHA512: e664b3b49e2f547873923f15dffbbc7fa032b6240e5b856b180e9e26123ca141864d10448912dc4a31bbb200c75bef4251a910a4330dac17ee6841b564612d13
2024-07-02 16:50:26 -05:00
valued mammal
af75817d4b
ref(tx_graph): Change last_seen to HashMap<Txid, u64> 2024-06-30 11:26:15 -04:00
valued mammal
6204d2c766
feat(tx_graph): Add method txs_with_no_anchor_or_last_seen 2024-06-30 10:08:54 -04:00
valued mammal
496601b8b1
test(tx_graph): Add test for list_canonical_txs 2024-06-30 10:08:54 -04:00
valued mammal
b34790c6b6
ref(tx_graph)!: Rename list_chain_txs to list_canonical_txs 2024-06-30 10:08:54 -04:00
valued mammal
2ce4bb4dfc
test(indexed_tx_graph): Add test_get_chain_position 2024-06-30 10:08:54 -04:00
valued mammal
bbc19c3536
fix(tx_graph)!: Change tx_last_seen to Option<u64>
Also fixup `test_list_owned_txouts` to check that the right
outputs, utxos, and balance are returned at different local
chain heights.

This fixes an issue where unbroadcast and otherwise non-canonical
transactions were returned from methods `list_chain_txs` and
`Wallet::transactions` because every tx inserted had a last_seen
of 0 making it appear unconfirmed.

Note this commit changes the way `Balance` is represented due to
new logic in `try_get_chain_position` that no longer considers
txs with non-canonical anchors. Before this change, a tx anchored
to a block that is reorged out had a permanent effect on the
pending balance, and now only txs with a last_seen time or an
anchor confirmed in the best chain will return a `ChainPosition`.
2024-06-30 10:08:54 -04:00
Steve Myers
46c6f18cc3
refactor(chain): calculate DescriptorId as sha256 hash of spk at index 0
Also update docs to explain how KeychainTxOutIndex handles descriptors that
generate the same spks.
2024-06-27 07:56:08 -05:00
Steve Myers
e21affdbbb
Bump bdk version to 1.0.0-alpha.13
bdk_chain to 0.16.0
bdk_bitcoind_rpc to 0.12.0
bdk_electrum to 0.15.0
bdk_esplora to 0.15.0
bdk_file_store to 0.13.0
bdk_sqlite keep at 0.2.0
bdk_testenv to 0.6.0
bdk_hwi to 0.3.0
2024-06-14 21:24:55 -05:00
Steve Myers
a0bf45bef1
docs: remove PersistBackend from docs, Cargo.toml and wallet README.md 2024-06-14 18:16:14 -05: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
志宇
2e40b0118c
feat(chain): reintroduce a way to stage changesets before persisting
A staging area is helpful because we can contain logic to ignore empty
changesets and not clear staging area if the persistence backend fails.
2024-06-13 12:56:31 -05:00
志宇
36e82ec686
chore(chain): relax miniscript feature flag scope
Still enable the `persist` submodule without `miniscript` feature flag.
Only disable `CombinedChangeSet`.

Also stop `cargo clippy` from complaining about unused imports when
`miniscript` is disabled.
2024-06-13 12:56:30 -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
Steve Myers
54b0c11cbe
feat(persist): add PersistAsync trait and StagedPersistAsync struct 2024-06-13 12:40:50 -05:00
Steve Myers
aa640ab277
refactor(persist): rename PersistBackend to Persist, move to chain crate
Also add refactored StagedPersist to chain crate with tests.
2024-06-13 12:40:49 -05:00
志宇
8dd174479f
refactor(chain): compute txid once for KeychainTxOutIndex::index_tx 2024-06-13 23:03:34 +08:00
志宇
639d735ca0
refactor(chain): change field names to be more sane 2024-06-13 22:52:47 +08:00
志宇
5a02f40122
docs(chain): fix docs 2024-06-13 22:52:47 +08:00
志宇
c77e12bae7
refactor(chain): KeychainTxOutIndex use HashMap for fields
Instead of `BTreeMap` which is less performant.
2024-06-13 22:52:47 +08:00
LLFourn
4d3846abf4
chore(chain): s/replenish_lookahead/replenish_inner_index/ 2024-06-13 22:52:46 +08:00
LLFourn
8779afdb0b
chore(chain): document insert_descriptor invariants better 2024-06-13 22:52:46 +08:00
LLFourn
69f2a695f7
refactor(chain): improve replenish lookeahd internals
see: 4eb1e288a9 (r1630943639)
2024-06-13 22:52:45 +08:00
Lloyd Fournier
5a584d0fd8
chore(chain): Fix Indexed and KeychainIndexed documentaion
Co-authored-by: ValuedMammal <valuedmammal@protonmail.com>
2024-06-13 22:52:45 +08:00
LLFourn
b8ba5a0206
chore(chain): Improve documentation of keychain::ChangeSet 2024-06-13 22:52:45 +08:00
LLFourn
101a09a97f
chore(chain): Standardise KeychainTxOutIndex return types
The previous commit b9c5b9d08b040faf6c6b2d9b3745918031555b72 added
IndexSpk. This goes further and adds `Indexed` and `KeychainIndexed`
type alises (IndexSpk is Indexed<ScriptBuf>) and attempts to standardize
the structure of return types more generally.
2024-06-13 22:52:44 +08:00
Steve Myers
bce070b1d6
chore(chain): add type IndexSpk, fix clippy type complexity warning 2024-06-13 22:52:44 +08:00
LLFourn
4d2442c37f
chore(chain): misc docs and insert_descriptor fixes 2024-06-13 22:52:43 +08: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
LLFourn
3b2ff0cc95
Write failing test for keychain range querying 2024-06-13 22:52:42 +08:00
Leonardo Lima
2a4564097b
deps(bdk): bump bitcoin to 0.32.0, miniscript to 12.0.0
deps(chain): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0`

fix(chain): use `minimal_non_dust()` instead of `dust_value()`

fix(chain): use `compute_txid()` instead of `txid`

deps(testenv): bump `electrsd` to `0.28.0`

deps(electrum): bump `electrum-client` to `0.20.0`

fix(electrum): use `compute_txid()` instead of `txid`

deps(esplora): bump `esplora-client` to `0.8.0`

deps(bitcoind_rpc): bump `bitcoin` to `0.32.0`, `bitcoincore-rpc` to
`0.19.0`

fix(bitcoind_rpc): use `compute_txid()` instead of `txid`

fix(nursery/tmp_plan): use proper `sighash` errors, and fix the expected
`Signature` fields

fix(sqlite): use `compute_txid()` instead of `txid`

deps(hwi): bump `hwi` to `0.9.0`

deps(wallet): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0`

fix(wallet): use `compute_txid()` and `minimal_non_dust()`

- update to use `compute_txid()` instead of deprecated `txid()`
- update to use `minimal_non_dust()` instead of `dust_value()`
- remove unused `bitcoin::hex::FromHex`.

fix(wallet): uses `.into` conversion on `Network` for `NetworkKind`

- uses `.into()` when appropriate, otherwise use the explicit
  `NetworkKind`, and it's `.is_mainnet()` method.

fix(wallet): add P2wpkh, Taproot, InputsIndex errors to `SignerError`

fix(wallet): fields on taproot, and ecdsa `Signature` structure

fix(wallet/wallet): convert `Weight` to `usize` for now

- converts the `bitcoin-units::Weight` type to `usize` with help of
  `to_wu()` method.
- it should be updated/refactored in the future to handle the `Weight`
  type throughout the code instead of current `usize`, only converting
  it for now.
- allows the usage of deprecated `is_provably_unspendable()`, needs
  further discussion if suggested `is_op_return` is suitable.
- update the expect field to `signature`, as it was renamed from `sig`.

fix(wallet/wallet): use `is_op_return` instead of
`is_provably_unspendable`

fix(wallet/wallet): use `relative::Locktime` instead of `Sequence`

fix(wallet/descriptor): use `ParsePublicKeyError`

fix(wallet/descriptor): use `.into()` to convert from `AbsLockTime` and
`RelLockTime` to `absolute::LockTime` and `relative::LockTime`

fix(wallet/wallet): use `Message::from_digest()` instead of relying on
deprecated `ThirtyTwoByteHash` trait.

fix(wallet/descriptor+wallet): expect `Threshold` type, and handle it
internally

fix(wallet/wallet): remove `0x` prefix from expected `TxId` display

fix(examples): use `compute_txid()` instead of `txid`

fix(ci): remove usage of `bitcoin/no-std` feature

- remove comment: `# The `no-std` feature it's implied when the `std` feature is disabled.`
2024-06-12 10:31:50 -03:00
志宇
8eef350bd0
Merge bitcoindevkit/bdk#1453: refactor(electrum) put the tx cache in electrum
2d2656acfa83ab4c4846c0aab14072efb64c5cc3 feat(electrum): re-export `transaction_broadcast` method (志宇)
53fa35096fbeea2b82b28987e8ef6f7d39ffc80b refactor(electrum)!: put the tx cache in electrum (LLFourn)

Pull request description:

  Previously there was a `TxCache` that you passed in as part of the sync request. There are lots of downsides to this:

  1. If the user forgets to do this you cache nothing
  2. where are you meant to keep this cache? The example shows it being recreated every time which seems very suboptimal.
  3. More API and documentation surface area.

  Instead just do a plain old simple cache inside the electrum client. This way at least you only download transactions once. You can pre-populate the cache with a method also and I did this in the examples.

  * [x] This pull request breaks the existing API

ACKs for top commit:
  evanlinjin:
    self-ACK 2d2656acfa83ab4c4846c0aab14072efb64c5cc3
  notmandatory:
    ACK 2d2656acfa83ab4c4846c0aab14072efb64c5cc3

Tree-SHA512: 6c29fd4f99ea5bd66234d5cdaf4b157a192ddd3baacc91076e402d8df0de7010bc482e24895e85fcb2f805ec6d1ce6cdb7654f8f552c90ba75ed35f80a00b856
2024-06-05 10:19:00 +08:00
LLFourn
53fa35096f
refactor(electrum)!: put the tx cache in electrum
Previously there was a tx cache that you passed in as part of the sync
request. This seems bad and the example show'd that you should copy all
your transactions from the transaction graph into the sync request every
time you sync'd. If you forgot to do this then you would always download everything.

Instead just do a plain old simple cache inside the electrum client.
This way at least you only download transactions once. You can
pre-populate the cache with a method also and I did this in the examples.
2024-06-04 12:23:01 +08:00
Leonardo Lima
a03949adb0
feat: use Amount on calculate_fee, fee_absolute, fee_amount and others
- update to use `bitcoin::Amount` on `CreateTxError::FeeTooLow` variant.
- update to use `bitcoin::Amount` on `Wallet::calculate_fee()`.
- update to use `bitcoin::Amount` on `FeePolicy::fee_absolute()`.
- update to use `bitcoin::SignedAmount` on
  `CalculateFeeError::NegativeFee` variant.
- update to use `bitcoin::Amount` on `TxGraph::calculate_fee()`.
- update to use `bitcoin::Amount` on `PsbUtils::fee_amount()`
2024-06-03 13:19:16 -03:00
Steve Myers
108061dddb
Bump bdk version to 1.0.0-alpha.12
bdk_chain to 0.15.0
bdk_bitcoind_rpc to 0.11.0
bdk_electrum to 0.14.0
bdk_esplora to 0.14.0
bdk_persist to 0.3.0
bdk_file_store to 0.12.0
bdk_sqlite keep at 0.1.0
bdk_testenv to 0.5.0
bdk_hwi to 0.1.0
bdk_wallet to 1.0.0-alpha.12
2024-05-23 11:15:30 -05:00
Steve Myers
54942a902d
ci: bump build_docs rust version to nightly-2024-05-12 2024-05-22 23:02:52 -05:00
Steve Myers
db9fdccc18
Bump bdk version to 1.0.0-alpha.11
bdk_chain to 0.14.0
bdk_bitcoind_rpc to 0.10.0
bdk_electrum to 0.13.0
bdk_esplora to 0.13.0
bdk_file_store to 0.11.0
bdk_testenv to 0.4.0
bdk_persist to 0.2.0
2024-05-10 14:05:40 -05:00
志宇
58f27b38eb
feat(chain): introduce TxCache to SyncRequest and FullScanRequest
This transaction cache can be provided so the chain-source can avoid
re-fetching transactions.
2024-05-10 14:11:19 +08:00
志宇
721bb7f519
fix(chain): Make Anchor type in FullScanResult generic 2024-05-10 14:11:19 +08:00
志宇
e3cfb84898
feat(chain): TxGraph::insert_tx reuses Arc
When we insert a transaction that is already wrapped in `Arc`, we should
reuse the `Arc`.
2024-05-10 14:11:19 +08:00
Daniela Brozzoni
86711d4f46
doc(chain): add section for non-recommended K to descriptor assignments 2024-05-09 14:40:19 +08:00
Daniela Brozzoni
de53d72191
test: Only the highest ord keychain is returned 2024-05-08 15:49:51 +02:00
志宇
9d8023bf56
fix(chain): introduce keychain-variant-ranking to KeychainTxOutIndex
This fixes the bug with changesets not being monotone. Previously, the
result of applying changesets individually v.s. applying the aggregate
of changesets may result in different `KeychainTxOutIndex` states.

The nature of the changeset allows different keychain types to share the
same descriptor. However, the previous design did not take this into
account. To do this properly, we should keep track of all keychains
currently associated with a given descriptor. However, the API only
allows returning one keychain per spk/txout/outpoint (which is a good
API).

Therefore, we rank keychain variants by `Ord`. Earlier keychain variants
have a higher rank, and the first keychain will be returned.
2024-05-08 15:49:50 +02:00
志宇
6c8748124f
chore(chain): move use in indexed_tx_graph.rs so clippy is happy 2024-05-08 15:49:48 +02:00
志宇
537aa03ae0
chore(chain): update test so clippy does not complain 2024-05-08 15:49:47 +02:00
志宇
ed117de7a5
test(chain): applying changesets one-by-one vs aggregate should be same 2024-05-08 15:49:46 +02:00
志宇
6a3fb849e8
fix(chain): simplify Append::append impl for keychain::ChangeSet
We only need to loop though entries of `other`. The logic before was
wasteful because we were also looping though all entries of `self` even
if we do not need to modify the `self` entry.
2024-05-08 15:49:45 +02:00
Daniela Brozzoni
1d294b734d
fix: Run tests only if the miniscript feature is..
..enabled, enable it by default
2024-05-08 15:49:44 +02: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