@@ -2,12 +2,105 @@ 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`](crate::Wallet).
10- #[ derive( Default , Debug , Clone , PartialEq , serde:: Deserialize , serde:: Serialize ) ]
10+ /// A change set for [`Wallet`]
11+ ///
12+ /// ## Definition
13+ ///
14+ /// The change set is responsible for transmiting data between the persistent storage layer and the
15+ /// core library components. Specifically, it serves two primary functions:
16+ ///
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
21+ ///
22+ /// ## Contract
23+ ///
24+ /// The change set maintains and enforces the following properties:
25+ ///
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+ /// instance.
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+ /// ## Members and required fields
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" is defined by the
41+ /// [`Merge`](Merge::is_empty) implementation of that change set. This requirement also applies to
42+ /// the [`local_chain`] field in that the aggregate change set must include a genesis block.
43+ ///
44+ /// For example, the descriptor and network are present in the first change set after wallet
45+ /// creation, but are usually omitted in subsequent updates, as they are not permitted to change
46+ /// at any point thereafter.
47+ ///
48+ /// Other fields of the change set are not required to be non-empty, that is they may be empty even
49+ /// in the aggregate. However in practice they should contain the data needed to recover a wallet
50+ /// state between sessions. These include:
51+ /// * [`tx_graph`](Self::tx_graph)
52+ /// * [`indexer`](Self::indexer)
53+ ///
54+ /// The [`change_descriptor`] is special in that its presence is optional, however the value of the
55+ /// change descriptor should be defined at wallet creation time and respected for the life of the
56+ /// wallet, meaning that if a change descriptor is originally defined, it must also be present in
57+ /// the aggregate change set.
58+ ///
59+ /// ## Staging
60+ ///
61+ /// For greater efficiency the [`Wallet`] is able to *stage* the to-be-persisted changes. Many
62+ /// operations result in staged changes which require persistence on the part of the user. These
63+ /// include address revelation, applying an [`Update`], and introducing transactions and chain
64+ /// data to the wallet. To get the staged changes see [`Wallet::staged`] and similar methods. Once
65+ /// the changes are committed to the persistence layer the contents of the stage should be
66+ /// discarded.
67+ ///
68+ /// Users should persist early and often generally speaking, however in principle there is no
69+ /// limit to the number or type of changes that can be staged prior to persisting or the order in
70+ /// which they're staged. This is because change sets are designed to be [merged]. The change
71+ /// that is ultimately persisted will encompass the combined effect of each change individually.
72+ ///
73+ /// ## Extensibility
74+ ///
75+ /// Existing fields may be extended in the future with additional sub-fields. New top-level fields
76+ /// are likely to be added as new features and core components are implemented. Existing fields may
77+ /// be removed in future versions of the library.
78+ ///
79+ /// The authors reserve the right to make breaking changes to the [`ChangeSet`] structure in
80+ /// a major version release. API changes affecting the types of data persisted will display
81+ /// prominently in the release notes. Users are advised to look for such changes and update their
82+ /// application accordingly.
83+ ///
84+ /// The resulting interface is designed to give the user more control of what to persist and when
85+ /// to persist it. Custom implementations should consider and account for the possibility of
86+ /// partial or repeat writes, the atomicity of persistence operations, and the order of reads and
87+ /// writes among the fields of the change set. BDK comes with support for [SQLite] that handles
88+ /// the details for you and is recommended for many users. If implementing your own persistence,
89+ /// please refer to the documentation for [`WalletPersister`] and [`PersistedWallet`] for more
90+ /// information.
91+ ///
92+ /// [`change_descriptor`]: Self::change_descriptor
93+ /// [`descriptor`]: Self::descriptor
94+ /// [`local_chain`]: Self::local_chain
95+ /// [merged]: bdk_chain::Merge
96+ /// [`network`]: Self::network
97+ /// [`PersistedWallet`]: crate::PersistedWallet
98+ /// [SQLite]: bdk_chain::rusqlite_impl
99+ /// [`Update`]: crate::Update
100+ /// [`WalletPersister`]: crate::WalletPersister
101+ /// [`Wallet::staged`]: crate::Wallet::staged
102+ /// [`Wallet`]: crate::Wallet
103+ #[ derive( Default , Debug , Clone , PartialEq , Deserialize , Serialize ) ]
11104pub struct ChangeSet {
12105 /// Descriptor for recipient addresses.
13106 pub descriptor : Option < Descriptor < DescriptorPublicKey > > ,
0 commit comments