Skip to content

Commit 0f14fef

Browse files
committed
docs(wallet): expand docs for ChangeSet
1 parent a8d5f69 commit 0f14fef

File tree

1 file changed

+74
-30
lines changed

1 file changed

+74
-30
lines changed

crates/wallet/src/wallet/changeset.rs

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,97 @@ use bdk_chain::{
22
indexed_tx_graph, keychain_txout, local_chain, tx_graph, ConfirmationBlockTime, Merge,
33
};
44
use miniscript::{Descriptor, DescriptorPublicKey};
5+
use serde::{Deserialize, Serialize};
56

67
type IndexedTxGraphChangeSet =
78
indexed_tx_graph::ChangeSet<ConfirmationBlockTime, keychain_txout::ChangeSet>;
89

9-
/// A changeset for [`Wallet`].
10+
/// A change set for [`Wallet`]
1011
///
11-
/// The changeset is used to persist and recover changes and additions made during the
12-
/// life of the wallet. The kinds of changes that frequently make up this set are new
13-
/// transactions, blocks in the local chain, and derivation indexes. The changeset is
14-
/// also responsible for transmitting persistent metadata such as the public descriptor(s)
15-
/// and configured network. All of these are necessary for the correct functioning of a
16-
/// wallet.
12+
/// ## Definition
1713
///
18-
/// For greater efficiency the wallet is able to stage changes before committing them.
19-
/// Many operations result in staged changes which require persistence on the part of the
20-
/// user. These include address revelation, applying an [`Update`], and introducing
21-
/// transactions and related data to the wallet. To get the staged changes see
22-
/// [`Wallet::staged`] and similar methods. Once the changes are committed to the persistence
23-
/// layer the contents of the stage should be discarded.
14+
/// The change set is responsible for transmiting data between the persistent storage layer and the
15+
/// core components of the library. Specifically, it serves two primary functions:
2416
///
25-
/// You should persist early and often generally speaking, however in principle there is
26-
/// no limitation on the number or type of changes that can be staged prior to persistence
27-
/// or the order in which they're staged. This is because changesets are designed to be
28-
/// [merged]. The change that is eventually persisted will include the combined effect of
29-
/// each change individually.
17+
/// 1) Recording incremental changes to the in-memory representation that need to be persisted
18+
/// to disk
19+
/// 2) Applying aggregate changes from the persistence layer to the in-memory representation at
20+
/// startup
3021
///
31-
/// The [`ChangeSet`] is backwards compatible in the sense that it is intended to interoperate
32-
/// with earlier versions of the library. Specifically this means that the orginal fields will
33-
/// remain unchanged and that the addition of new fields corresponds to new feature upgrades.
22+
/// ## Contract
3423
///
35-
/// The API of [`Wallet`] is designed to give the user control of what data to persist, when
36-
/// to persist it, and to determine when committed changes can be safely discarded. You should
37-
/// consider how your database handles partial or repeat writes, whether the persistence
38-
/// operation proceeds atomically, and whether the order of writes matters among the fields
39-
/// of the [`ChangeSet`]. BDK has no strict requirements regarding these details but
40-
/// provides a straightforward solution in the case of [SQLite]. If implementing your own
41-
/// persistence layer, please see the docs for [`PersistedWallet`] and [`WalletPersister`]
42-
/// as a reference.
24+
/// The change set maintains and enforces the following properties:
4325
///
26+
/// * Change sets must implement [`Serialize`] and [`Deserialize`] to meet the definition from
27+
/// above.
28+
/// * Change sets must implement [`Default`] as a way of instantiating new empty objects.
29+
/// * Change sets must implement [`Merge`] so that many instances can be aggregated into a single
30+
/// one.
31+
/// * A change set is composed of a number of individual "sub-change sets" that adhere to the same
32+
/// rules as above. This is for increased modularity and portability. For example the core
33+
/// modules each have their own change set (`tx_graph`, `local_chain`, etc).
34+
///
35+
/// ## Note
36+
///
37+
/// The change set has certain required fields without which a `Wallet` cannot function.
38+
/// These include the [`descriptor`] and the [`network`] in use. These are required to be non-empty
39+
/// _in the aggregate_, meaning the field must be present and non-null in the union of all
40+
/// persisted changes, but may be empty in any one change set (where "empty" can describe an empty
41+
/// container or the `Option::None` variant). For example, the descriptor and network are
42+
/// present in the first change set after wallet creation, but are usually omitted from subsequent
43+
/// updates, as they are not permitted to change during the course of wallet operation.
44+
///
45+
/// Other fields of the change set are not required to be non-empty, that is they may be empty even
46+
/// in the aggregate. However in practice certain fields should always contain the data needed to
47+
/// recover a wallet state between sessions. These include:
48+
/// * [`change_descriptor`](Self::change_descriptor)
49+
/// * [`local_chain`](Self::local_chain)
50+
/// * [`tx_graph`](Self::tx_graph)
51+
/// * [`indexer`](Self::indexer)
52+
///
53+
/// ## Staging
54+
///
55+
/// For greater efficiency the [`Wallet`] is able to _stage_ the to-be-persisted changes. Many
56+
/// operations result in staged changes which require persistence on the part of the user. These
57+
/// include address revelation, applying an [`Update`], and introducing transactions and chain
58+
/// data to the wallet. To get the staged changes see [`Wallet::staged`] and similar methods. Once
59+
/// the changes are committed to the persistence layer the contents of the stage should be
60+
/// discarded.
61+
///
62+
/// Users should persist early and often generally speaking, however in principle there is no
63+
/// limit to the number or type of changes that can be staged prior to persistence or the order in
64+
/// in which they're staged. This is because changesets are designed to be [merged]. The change
65+
/// that is ultimately persisted will encompass the combined effect of each change individually.
66+
///
67+
/// ## Extensibility
68+
///
69+
/// Existing fields may continue to exist in future versions and may be extended with additional
70+
/// sub-fields. New top-level fields may be added in the future to accommodate new features and
71+
/// data types.
72+
///
73+
/// BDK reserves the right to introduce breaking changes to the [`ChangeSet`] structure in a major
74+
/// version release. API changes that affect the kinds of data persisted will be displayed
75+
/// prominently in the release notes of newer versions. Users are advised to look for any such
76+
/// changes and update their application accordingly.
77+
///
78+
/// The resulting interface is designed to give the user greater control of what to persist and
79+
/// when to persist it. Custom implementations should consider and account for the possibility of
80+
/// partial or repeat writes, the atomicity of persistence operations, and the order of reads and
81+
/// writes among the fields of the change set. BDK imposes no strict requirements regarding these
82+
/// aspects but provides a straightforward solution in the case of [SQLite]. If implementing your
83+
/// own persistence, please refer to the documentation for [`WalletPersister`] and
84+
/// [`PersistedWallet`] for more information.
85+
///
86+
/// [`descriptor`]: Self::descriptor
87+
/// [`network`]: Self::network
4488
/// [merged]: bdk_chain::Merge
4589
/// [`PersistedWallet`]: crate::PersistedWallet
4690
/// [SQLite]: bdk_chain::rusqlite_impl
4791
/// [`Update`]: crate::Update
4892
/// [`WalletPersister`]: crate::WalletPersister
4993
/// [`Wallet::staged`]: crate::Wallet::staged
5094
/// [`Wallet`]: crate::Wallet
51-
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
95+
#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
5296
pub struct ChangeSet {
5397
/// Descriptor for recipient addresses.
5498
pub descriptor: Option<Descriptor<DescriptorPublicKey>>,

0 commit comments

Comments
 (0)