@@ -2,53 +2,97 @@ use bdk_chain::{
22 indexed_tx_graph, keychain_txout, local_chain, tx_graph, ConfirmationBlockTime , Merge ,
33} ;
44use miniscript:: { Descriptor , DescriptorPublicKey } ;
5+ use serde:: { Deserialize , Serialize } ;
56
67type 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 ) ]
5296pub struct ChangeSet {
5397 /// Descriptor for recipient addresses.
5498 pub descriptor : Option < Descriptor < DescriptorPublicKey > > ,
0 commit comments