pub struct KeychainTxOutIndex<K> { /* private fields */ }
Expand description

KeychainTxOutIndex controls how script pubkeys are revealed for multiple keychains, and indexes [TxOut]s with them.

A single keychain is a chain of script pubkeys derived from a single Descriptor. Keychains are identified using the K generic. Script pubkeys are identified by the keychain that they are derived from K, as well as the derivation index u32.

Revealed script pubkeys

Tracking how script pubkeys are revealed is useful for collecting chain data. For example, if the user has requested 5 script pubkeys (to receive money with), we only need to use those script pubkeys to scan for chain data.

Call reveal_to_target or reveal_next_spk to reveal more script pubkeys. Call revealed_keychain_spks or revealed_spks to iterate through revealed script pubkeys.

Lookahead script pubkeys

When an user first recovers a wallet (i.e. from a recovery phrase and/or descriptor), we will NOT have knowledge of which script pubkeys are revealed. So when we index a transaction or txout (using index_tx/index_txout) we scan the txouts against script pubkeys derived above the last revealed index. These additionally-derived script pubkeys are called the lookahead.

The KeychainTxOutIndex is constructed with the lookahead and cannot be altered. The default lookahead count is 1000. Use new to set a custom lookahead.

Unbounded script pubkey iterator

For script-pubkey-based chain sources (such as Electrum/Esplora), an initial scan is best done by iterating though derived script pubkeys one by one and requesting transaction histories for each script pubkey. We will stop after x-number of script pubkeys have empty histories. An unbounded script pubkey iterator is useful to pass to such a chain source.

Call unbounded_spk_iter to get an unbounded script pubkey iterator for a given keychain. Call all_unbounded_spk_iters to get unbounded script pubkey iterators for all keychains.

Change sets

Methods that can update the last revealed index or add keychains will return super::ChangeSet to report these changes. This can be persisted for future recovery.

Synopsis

use bdk_chain::keychain::KeychainTxOutIndex;

// imagine our service has internal and external addresses but also addresses for users
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
enum MyKeychain {
    External,
    Internal,
    MyAppUser {
        user_id: u32
    }
}

let mut txout_index = KeychainTxOutIndex::<MyKeychain>::default();

let _ = txout_index.insert_descriptor(MyKeychain::External, external_descriptor);
let _ = txout_index.insert_descriptor(MyKeychain::Internal, internal_descriptor);
let _ = txout_index.insert_descriptor(MyKeychain::MyAppUser { user_id: 42 }, descriptor_42);

let new_spk_for_user = txout_index.reveal_next_spk(&MyKeychain::MyAppUser{ user_id: 42 });

Non-recommend keychain to descriptor assignments

A keychain (K) is used to identify a descriptor. However, the following keychain to descriptor arrangements result in behavior that is harder to reason about and is not recommended.

Multiple keychains identifying the same descriptor

Although a single keychain variant can only identify a single descriptor, multiple keychain variants can identify the same descriptor.

If multiple keychains identify the same descriptor:

  1. Methods that take in a keychain (such as reveal_next_spk) will work normally when any keychain (that identifies that descriptor) is passed in.
  2. Methods that return data which associates with a descriptor (such as outpoints, txouts, unused_spks, etc.) the method will return the highest-ranked keychain variant that identifies the descriptor. Rank is determined by the Ord implementation of the keychain type.

This arrangement is not recommended since some methods will return a single keychain variant even though multiple keychain variants identify the same descriptor.

Reassigning the descriptor of a single keychain

Descriptors added to KeychainTxOutIndex are never removed. However, a keychain that identifies a descriptor can be reassigned to identify a different descriptor. This may result in a situation where a descriptor has no associated keychain(s), and relevant [TxOut]s, [OutPoint]s and [Script]s (of that descriptor) will not be return by KeychainTxOutIndex. Therefore, reassigning the descriptor of a single keychain is not recommended.

Implementations§

Construct a KeychainTxOutIndex with the given lookahead.

The lookahead is the number of script pubkeys to derive and cache from the internal descriptors over and above the last revealed script index. Without a lookahead the index will miss outputs you own when processing transactions whose output script pubkeys lie beyond the last revealed index. In certain situations, such as when performing an initial scan of the blockchain during wallet import, it may be uncertain or unknown what the index of the last revealed script pubkey actually is.

Refer to struct-level docs for more about lookahead.

Methods that are re-exposed from the internal SpkTxOutIndex.

Return a reference to the internal SpkTxOutIndex.

WARNING: The internal index will contain lookahead spks. Refer to struct-level docs for more about lookahead.

Get the set of indexed outpoints, corresponding to tracked keychains.

Iterate over known txouts that spend to tracked script pubkeys.

Finds all txouts on a transaction that has previously been scanned and indexed.

Return the [TxOut] of outpoint if it has been indexed, and if it corresponds to a tracked keychain.

The associated keychain and keychain index of the txout’s spk is also returned.

This calls SpkTxOutIndex::txout internally.

Return the script that exists under the given keychain’s index.

This calls SpkTxOutIndex::spk_at_index internally.

Returns the keychain and keychain index associated with the spk.

This calls SpkTxOutIndex::index_of_spk internally.

Returns whether the spk under the keychain’s index has been used.

Here, “unused” means that after the script pubkey was stored in the index, the index has never scanned a transaction output with it.

This calls SpkTxOutIndex::is_used internally.

Marks the script pubkey at index as used even though the tracker hasn’t seen an output with it.

This only has an effect when the index had been added to self already and was unused.

Returns whether the spk under the given keychain and index is successfully marked as used. Returns false either when there is no descriptor under the given keychain, or when the spk is already marked as used.

This is useful when you want to reserve a script pubkey for something but don’t want to add the transaction output using it to the index yet. Other callers will consider index on keychain used until you call unmark_used.

This calls SpkTxOutIndex::mark_used internally.

Undoes the effect of mark_used. Returns whether the index is inserted back into unused.

Note that if self has scanned an output with this script pubkey, then this will have no effect.

This calls SpkTxOutIndex::unmark_used internally.

Computes the total value transfer effect tx has on the script pubkeys belonging to the keychains in range. Value is sent when a script pubkey in the range is on an input and received when it is on an output. For sent to be computed correctly, the output being spent must have already been scanned by the index. Calculating received just uses the [Transaction] outputs directly, so it will be correct even if it has not been scanned.

Computes the net value that this transaction gives to the script pubkeys in the index and takes from the transaction outputs in the index. Shorthand for calling sent_and_received and subtracting sent from received.

This calls SpkTxOutIndex::net_value internally.

Return the map of the keychain to descriptors.

Insert a descriptor with a keychain associated to it.

Adding a descriptor means you will be able to derive new script pubkeys under it and the txout index will discover transaction outputs with those script pubkeys.

When trying to add a keychain that already existed under a different descriptor, or a descriptor that already existed with a different keychain, the old keychain (or descriptor) will be overwritten.

Gets the descriptor associated with the keychain. Returns None if the keychain doesn’t have a descriptor associated with it.

Get the lookahead setting.

Refer to new for more information on the lookahead.

Store lookahead scripts until target_index (inclusive).

This does not change the global lookahead setting.

Get an unbounded spk iterator over a given keychain. Returns None if the provided keychain doesn’t exist

Get unbounded spk iterators for all keychains.

Iterate over revealed spks of keychains in range

Iterate over revealed spks of the given keychain.

Iterate over revealed, but unused, spks of all keychains.

Iterate over revealed, but unused, spks of the given keychain. Returns an empty iterator if the provided keychain doesn’t exist.

Get the next derivation index for keychain. The next index is the index after the last revealed derivation index.

The second field in the returned tuple represents whether the next derivation index is new. There are two scenarios where the next derivation index is reused (not new):

  1. The keychain’s descriptor has no wildcard, and a script has already been revealed.
  2. The number of revealed scripts has already reached 2^31 (refer to BIP-32).

Not checking the second field of the tuple may result in address reuse.

Returns None if the provided keychain doesn’t exist.

Get the last derivation index that is revealed for each keychain.

Keychains with no revealed indices will not be included in the returned BTreeMap.

Get the last derivation index revealed for keychain. Returns None if the keychain doesn’t exist, or if the keychain doesn’t have any revealed scripts.

Convenience method to call Self::reveal_to_target on multiple keychains.

Reveals script pubkeys of the keychain’s descriptor up to and including the target_index.

If the target_index cannot be reached (due to the descriptor having no wildcard and/or the target_index is in the hardened index range), this method will make a best-effort and reveal up to the last possible index.

This returns an iterator of newly revealed indices (alongside their scripts) and a super::ChangeSet, which reports updates to the latest revealed index. If no new script pubkeys are revealed, then both of these will be empty.

Returns None if the provided keychain doesn’t exist.

Attempts to reveal the next script pubkey for keychain.

Returns the derivation index of the revealed script pubkey, the revealed script pubkey and a super::ChangeSet which represents changes in the last revealed index (if any). Returns None if the provided keychain doesn’t exist.

When a new script cannot be revealed, we return the last revealed script and an empty super::ChangeSet. There are two scenarios when a new script pubkey cannot be derived:

  1. The descriptor has no wildcard and already has one script revealed.
  2. The descriptor has already revealed scripts up to the numeric bound.
  3. There is no descriptor associated with the given keychain.

Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest index that has not been used yet.

This will derive and reveal a new script pubkey if no more unused script pubkeys exist.

If the descriptor has no wildcard and already has a used script pubkey or if a descriptor has used all scripts up to the derivation bounds, then the last derived script pubkey will be returned.

Returns None if the provided keychain doesn’t exist.

Iterate over all [OutPoint]s that have TxOuts with script pubkeys derived from keychain.

Iterate over [OutPoint]s that have script pubkeys derived from keychains in range.

Returns the highest derivation index of the keychain where KeychainTxOutIndex has found a [TxOut] with it’s script pubkey.

Returns the highest derivation index of each keychain that KeychainTxOutIndex has found a [TxOut] with it’s script pubkey.

Applies the derivation changeset to the KeychainTxOutIndex, as specified in the ChangeSet::append documentation:

  • Extends the number of derived scripts per keychain
  • Adds new descriptors introduced
  • If a descriptor is introduced for a keychain that already had a descriptor, overwrites the old descriptor

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
The resultant “changeset” when new transaction data is indexed.
Scan and index the given outpoint and txout.
Scans a transaction for relevant outpoints, which are stored and indexed internally.
Determines the ChangeSet between self and an empty Indexer.
Apply changeset to itself.
Determines whether the transaction should be included in the index.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.