Skip to main content

ChangeSet

Struct ChangeSet 

Source
pub struct ChangeSet {
    pub descriptor: Option<Descriptor<DescriptorPublicKey>>,
    pub change_descriptor: Option<Descriptor<DescriptorPublicKey>>,
    pub network: Option<Network>,
    pub local_chain: ChangeSet,
    pub tx_graph: ChangeSet<ConfirmationBlockTime>,
    pub indexer: ChangeSet,
    pub locked_outpoints: ChangeSet,
}
Expand description

A change set for Wallet.

§Definition

The change set is responsible for transmitting data between the persistent storage layer and the core library components. Specifically, it serves two primary functions:

  1. Recording incremental changes to the in-memory representation that need to be persisted to disk
  2. Applying aggregate changes from the persistence layer to the in-memory representation at startup

§Contract

The change set maintains and enforces the following properties:

  • Change sets must implement Serialize and Deserialize to meet the definition from above.
  • Change sets must implement Default as a way of instantiating new empty objects.
  • Change sets must implement Merge so that many instances can be aggregated into a single instance.
  • A change set is composed of a number of individual “sub-change sets” that adhere to the same rules as above. This is for increased modularity and portability. For example the core modules each have their own change set (tx_graph, local_chain, etc).

§Members and required fields

The change set has certain required fields without which a Wallet cannot function. These include the descriptor and the bitcoin::Network in use. These are required to be non-empty in the aggregate, meaning the field must be present and non-null in the union of all persisted changes, but may be empty in any one change set, where “empty” is defined by the Merge implementation of that change set. This requirement also applies to the local_chain field in that the aggregate change set must include a genesis block.

For example, the descriptor and bitcoin::Network are present in the first change set after wallet creation, but are usually omitted in subsequent updates, as they are not permitted to change at any point thereafter.

Other fields of the change set are not required to be non-empty, that is they may be empty even in the aggregate. However, in practice they should contain the data needed to recover a wallet state between sessions. These include:

The change_descriptor is special in that its presence is optional, however the value of the change descriptor should be defined at wallet creation time and respected for the life of the wallet, meaning that if a change descriptor is originally defined, it must also be present in the aggregate change set.

§Staging

For greater efficiency the Wallet is able to stage the to-be-persisted changes. Many operations result in staged changes which require persistence on the part of the user. These include address revelation, applying an Update, and introducing transactions and chain data to the wallet. To get the staged changes see Wallet::staged and similar methods. Once the changes are committed to the persistence layer the contents of the stage should be discarded.

Users should persist early and often generally speaking, however in principle there is no limit to the number or type of changes that can be staged prior to persisting or the order in which they’re staged. This is because change sets are designed to be merged. The change that is ultimately persisted will encompass the combined effect of each change individually.

§Extensibility

Existing fields may be extended in the future with additional sub-fields. New top-level fields are likely to be added as new features and core components are implemented. Existing fields may be removed in future versions of the library following the deprecation policy below.

§Version Compatibility

Any change to the ChangeSet data structure MUST correlate with a major version bump per Semantic Versioning. We guarantee that version N can read and deserialize ChangeSet data written by version N-1 (one major version back), but this guarantee does NOT extend to version N-2 or earlier. New fields added in version N must implement Default so that when reading N-1 data, absent fields are populated with default values.

Limited forward compatibility is provided for downgrades: version N-1 will successfully deserialize version N data without errors by ignoring unknown fields. Users should be aware that features introduced in version N will not be available when downgrading to N-1, and that downgrading can result in loss of data if not backed up. For this reason we recommend carefully planning major upgrades and backing up necessary data to avoid compatibility issues.

Fields can be removed using a 3-version deprecation cycle: fields are marked deprecated in version N with a reason and instructions for migrating, the field is retained in version N+1 for compatibility where it deserializes but may not be used, and finally removed in version N+2. This ensures the standard backwards compatibility guarantees while allowing the removal of deprecated fields.

§Responsibilities

Library authors SHOULD test all upgrade paths using the persistence test suite and in CI. Library authors MUST document API changes prominently in the release notes and CHANGELOG, clearly mark deprecated fields including migration instructions, and follow the 3-version deprecation cycle before removing fields.

Users SHOULD back up wallet data before major version upgrades, test upgrades in non-production environments first, and monitor the release notes for warnings and updates. Users MUST complete migrations within the compatibility window, and not skip major versions (i.e. upgrade major versions sequentially).

§Custom Persistence Implementations

The resulting interface is designed to give the user more control of what to persist and when to persist it. Custom implementations should consider and account for the possibility of partial or repeat writes, the atomicity of persistence operations, and the order of reads and writes among the fields of the change set. BDK comes with support for SQLite that handles the details for you and is recommended for many users. If implementing your own persistence, please refer to the documentation for WalletPersister and PersistedWallet for more information.

Fields§

§descriptor: Option<Descriptor<DescriptorPublicKey>>

Descriptor for recipient addresses.

§change_descriptor: Option<Descriptor<DescriptorPublicKey>>

Descriptor for change addresses.

§network: Option<Network>

Stores the network type of the transaction data.

§local_chain: ChangeSet

Changes to the LocalChain.

§tx_graph: ChangeSet<ConfirmationBlockTime>

Changes to TxGraph.

§indexer: ChangeSet

Changes to KeychainTxOutIndex.

§locked_outpoints: ChangeSet

Changes to locked outpoints.

Implementations§

Source§

impl ChangeSet

Source

pub const WALLET_SCHEMA_NAME: &'static str = "bdk_wallet"

Available on crate feature rusqlite only.

Schema name for wallet.

Source

pub const WALLET_TABLE_NAME: &'static str = "bdk_wallet"

Available on crate feature rusqlite only.

Name of table to store wallet descriptors and network.

Source

pub const WALLET_OUTPOINT_LOCK_TABLE_NAME: &'static str = "bdk_wallet_locked_outpoints"

Available on crate feature rusqlite only.

Name of table to store wallet locked outpoints.

Source

pub fn schema_v0() -> String

Available on crate feature rusqlite only.

Get v0 sqlite ChangeSet schema

Source

pub fn schema_v1() -> String

Available on crate feature rusqlite only.

Get v1 sqlite ChangeSet schema. Schema v1 adds a table for locked outpoints.

Source

pub fn init_sqlite_tables(db_tx: &Transaction<'_>) -> Result<()>

Available on crate feature rusqlite only.

Initialize sqlite tables for wallet tables.

Source

pub fn from_sqlite(db_tx: &Transaction<'_>) -> Result<Self>

Available on crate feature rusqlite only.

Recover a ChangeSet from sqlite database.

Source

pub fn persist_to_sqlite(&self, db_tx: &Transaction<'_>) -> Result<()>

Available on crate feature rusqlite only.

Persist ChangeSet to sqlite database.

Trait Implementations§

Source§

impl Clone for ChangeSet

Source§

fn clone(&self) -> ChangeSet

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ChangeSet

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ChangeSet

Source§

fn default() -> ChangeSet

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for ChangeSet

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<ChangeSet<ConfirmationBlockTime>> for ChangeSet

Source§

fn from(tx_graph: ChangeSet<ConfirmationBlockTime>) -> Self

Converts to this type from the input type.
Source§

impl From<ChangeSet<ConfirmationBlockTime, ChangeSet>> for ChangeSet

Source§

fn from(indexed_tx_graph: ChangeSet<ConfirmationBlockTime, ChangeSet>) -> Self

Converts to this type from the input type.
Source§

impl From<ChangeSet> for ChangeSet

Source§

fn from(chain: ChangeSet) -> Self

Converts to this type from the input type.
Source§

impl From<ChangeSet> for ChangeSet

Source§

fn from(indexer: ChangeSet) -> Self

Converts to this type from the input type.
Source§

impl From<ChangeSet> for ChangeSet

Source§

fn from(locked_outpoints: ChangeSet) -> Self

Converts to this type from the input type.
Source§

impl Merge for ChangeSet

Source§

fn merge(&mut self, other: Self)

Merge another ChangeSet into itself.

Source§

fn is_empty(&self) -> bool

Returns whether the structure is considered empty.
Source§

fn take(&mut self) -> Option<Self>

Take the value, replacing it with the default value.
Source§

impl PartialEq for ChangeSet

Source§

fn eq(&self, other: &ChangeSet) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ChangeSet

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ChangeSet

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,