This commit is contained in:
Daniela Brozzoni 2023-03-02 11:12:13 +01:00
parent b5559767db
commit 303a1703c9
No known key found for this signature in database
GPG Key ID: 7DE4F1FDCED0AB87
5 changed files with 140 additions and 41 deletions

View File

@ -24,8 +24,14 @@
//! /* Updating an empty sparsechain will always succeed */
//!
//! let update = SparseChain::from_checkpoints(vec![
//! BlockId { height: 1, hash: hash_a },
//! BlockId { height: 2, hash: hash_b },
//! BlockId {
//! height: 1,
//! hash: hash_a,
//! },
//! BlockId {
//! height: 2,
//! hash: hash_b,
//! },
//! ]);
//! let _ = chain
//! .apply_update(update)
@ -34,8 +40,14 @@
//! /* To update a non-empty sparsechain, the update must connect */
//!
//! let update = SparseChain::from_checkpoints(vec![
//! BlockId { height: 2, hash: hash_b },
//! BlockId { height: 3, hash: hash_c },
//! BlockId {
//! height: 2,
//! hash: hash_b,
//! },
//! BlockId {
//! height: 3,
//! hash: hash_c,
//! },
//! ]);
//! let _ = chain
//! .apply_update(update)
@ -56,17 +68,29 @@
//! # let hash_d = new_hash::<BlockHash>("d");
//! // our sparsechain has 2 checkpoints
//! let chain = SparseChain::<TxHeight>::from_checkpoints(vec![
//! BlockId { height: 1, hash: hash_a },
//! BlockId { height: 2, hash: hash_b },
//! BlockId {
//! height: 1,
//! hash: hash_a,
//! },
//! BlockId {
//! height: 2,
//! hash: hash_b,
//! },
//! ]);
//!
//! /* Example of an ambiguous update that does not fully connect */
//!
//! let ambiguous_update = SparseChain::from_checkpoints(vec![
//! // the update sort of "connects" at checkpoint 1, but...
//! BlockId { height: 1, hash: hash_a },
//! BlockId {
//! height: 1,
//! hash: hash_a,
//! },
//! // we cannot determine whether checkpoint 3 connects with checkpoint 2
//! BlockId { height: 3, hash: hash_c },
//! BlockId {
//! height: 3,
//! hash: hash_c,
//! },
//! ]);
//! let _ = chain
//! .determine_changeset(&ambiguous_update)
@ -76,8 +100,14 @@
//!
//! let disconnected_update = SparseChain::from_checkpoints(vec![
//! // the last checkpoint in chain is 2, so 3 and 4 do not connect
//! BlockId { height: 3, hash: hash_c },
//! BlockId { height: 4, hash: hash_d },
//! BlockId {
//! height: 3,
//! hash: hash_c,
//! },
//! BlockId {
//! height: 4,
//! hash: hash_d,
//! },
//! ]);
//! let _ = chain
//! .determine_changeset(&disconnected_update)
@ -97,14 +127,21 @@
//! # let hash_c = new_hash::<BlockHash>("c");
//! # let hash_d = new_hash::<BlockHash>("d");
//! // our chain has a single checkpoint at height 11
//! let mut chain = SparseChain::<TxHeight>::from_checkpoints(vec![
//! BlockId { height: 11, hash: hash_a },
//! ]);
//! let mut chain = SparseChain::<TxHeight>::from_checkpoints(vec![BlockId {
//! height: 11,
//! hash: hash_a,
//! }]);
//!
//! // we detect a reorg at height 11, and we introduce a new checkpoint at height 12
//! let update = SparseChain::from_checkpoints(vec![
//! BlockId { height: 11, hash: hash_b },
//! BlockId { height: 12, hash: hash_c },
//! BlockId {
//! height: 11,
//! hash: hash_b,
//! },
//! BlockId {
//! height: 12,
//! hash: hash_c,
//! },
//! ]);
//! let _ = chain
//! .apply_update(update)
@ -114,8 +151,14 @@
//! // we detect another reorg, this time at height 12...
//! let update = SparseChain::from_checkpoints(vec![
//! // we connect at checkpoint 11 as this is our "point of agreement"
//! BlockId { height: 11, hash: hash_b },
//! BlockId { height: 12, hash: hash_d },
//! BlockId {
//! height: 11,
//! hash: hash_b,
//! },
//! BlockId {
//! height: 12,
//! hash: hash_d,
//! },
//! ]);
//! let _ = chain
//! .apply_update(update)
@ -166,48 +209,102 @@
//! }
//!
//! impl Default for TxPosition {
//! fn default() -> Self { Self::Unconfirmed }
//! fn default() -> Self {
//! Self::Unconfirmed
//! }
//! }
//!
//! impl ChainPosition for TxPosition {
//! fn height(&self) -> TxHeight {
//! match self {
//! Self::Confirmed{ height, .. } => TxHeight::Confirmed(*height),
//! Self::Confirmed { height, .. } => TxHeight::Confirmed(*height),
//! Self::Unconfirmed => TxHeight::Unconfirmed,
//! }
//! }
//!
//! fn max_ord_of_height(height: TxHeight) -> Self {
//! match height {
//! TxHeight::Confirmed(height) => Self::Confirmed{ height, position: u32::MAX },
//! TxHeight::Confirmed(height) => Self::Confirmed {
//! height,
//! position: u32::MAX,
//! },
//! TxHeight::Unconfirmed => Self::Unconfirmed,
//! }
//! }
//!
//! fn min_ord_of_height(height: TxHeight) -> Self {
//! match height {
//! TxHeight::Confirmed(height) => Self::Confirmed{ height, position: u32::MIN },
//! TxHeight::Confirmed(height) => Self::Confirmed {
//! height,
//! position: u32::MIN,
//! },
//! TxHeight::Unconfirmed => Self::Unconfirmed,
//! }
//! }
//! }
//!
//! let mut chain = SparseChain::<TxPosition>::default();
//! let _ = chain.insert_checkpoint(BlockId { height: 10, hash: hash_a }).unwrap();
//! let _ = chain.insert_tx(txid_1, TxPosition::Confirmed{ height: 9, position: 4321 }).unwrap();
//! let _ = chain.insert_tx(txid_2, TxPosition::Confirmed{ height: 9, position: 1234 }).unwrap();
//! let _ = chain.insert_tx(txid_3, TxPosition::Confirmed{ height: 10, position: 321 }).unwrap();
//! let _ = chain
//! .insert_checkpoint(BlockId {
//! height: 10,
//! hash: hash_a,
//! })
//! .unwrap();
//! let _ = chain
//! .insert_tx(
//! txid_1,
//! TxPosition::Confirmed {
//! height: 9,
//! position: 4321,
//! },
//! )
//! .unwrap();
//! let _ = chain
//! .insert_tx(
//! txid_2,
//! TxPosition::Confirmed {
//! height: 9,
//! position: 1234,
//! },
//! )
//! .unwrap();
//! let _ = chain
//! .insert_tx(
//! txid_3,
//! TxPosition::Confirmed {
//! height: 10,
//! position: 321,
//! },
//! )
//! .unwrap();
//!
//! // transactions are ordered correctly
//! assert_eq!(
//! chain.txids().collect::<Vec<_>>(),
//! vec![
//! &(TxPosition::Confirmed{ height: 9, position: 1234 }, txid_2),
//! &(TxPosition::Confirmed{ height: 9, position: 4321 }, txid_1),
//! &(TxPosition::Confirmed{ height: 10, position: 321 }, txid_3),
//! &(
//! TxPosition::Confirmed {
//! height: 9,
//! position: 1234
//! },
//! txid_2
//! ),
//! &(
//! TxPosition::Confirmed {
//! height: 9,
//! position: 4321
//! },
//! txid_1
//! ),
//! &(
//! TxPosition::Confirmed {
//! height: 10,
//! position: 321
//! },
//! txid_3
//! ),
//! ],
//! );
//!
//! ```
use core::{
fmt::Debug,
@ -853,7 +950,7 @@ impl<P: ChainPosition> SparseChain<P> {
.iter()
.filter(|(&txid, pos)| {
pos.is_some() /*it was not a deletion*/ &&
self.tx_position(txid).is_none() /*we don't have the txid already*/
self.tx_position(txid).is_none() /* we don't have the txid already */
})
.map(|(&txid, _)| txid)
}

View File

@ -195,11 +195,11 @@ impl<I: Clone + Ord> SpkTxOutIndex<I> {
/// # use bdk_chain::SpkTxOutIndex;
///
/// // imagine our spks are indexed like (keychain, derivation_index).
/// let txout_index = SpkTxOutIndex::<(u32,u32)>::default();
/// let txout_index = SpkTxOutIndex::<(u32, u32)>::default();
/// let all_unused_spks = txout_index.unused_spks(..);
/// let change_index = 1;
/// let unused_change_spks = txout_index
/// .unused_spks((change_index, u32::MIN)..(change_index, u32::MAX));
/// let unused_change_spks =
/// txout_index.unused_spks((change_index, u32::MIN)..(change_index, u32::MAX));
/// ```
pub fn unused_spks<R>(&self, range: R) -> impl DoubleEndedIterator<Item = (&I, &Script)>
where

View File

@ -52,7 +52,6 @@
//! let additions = graph.apply_update(update);
//! assert!(additions.is_empty());
//! ```
//!
use crate::{collections::*, AsTransaction, ForEachTxOut, IntoOwned};
use alloc::vec::Vec;
use bitcoin::{OutPoint, Transaction, TxOut, Txid};

View File

@ -5,11 +5,11 @@ use bdk_chain::{
};
use bdk_file_store::{FileError, IterError, KeychainStore, MAGIC_BYTES, MAGIC_BYTES_LEN};
use serde;
use tempfile::NamedTempFile;
use std::{
io::{Read, Write},
vec::Vec,
};
use tempfile::NamedTempFile;
#[derive(
Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
)]
@ -49,8 +49,7 @@ fn new_fails_if_magic_bytes_are_invalid() {
let invalid_magic_bytes = "ldkfs0000000";
let mut file = NamedTempFile::new().unwrap();
file
.write_all(invalid_magic_bytes.as_bytes())
file.write_all(invalid_magic_bytes.as_bytes())
.expect("should write");
match KeychainStore::<TestKeychain, TxHeight, Transaction>::new(file.reopen().unwrap()) {
@ -83,8 +82,9 @@ fn append_changeset_truncates_invalid_bytes() {
let mut file = NamedTempFile::new().unwrap();
file.write_all(&data).expect("should write");
let mut store = KeychainStore::<TestKeychain, TxHeight, Transaction>::new(file.reopen().unwrap())
.expect("should open");
let mut store =
KeychainStore::<TestKeychain, TxHeight, Transaction>::new(file.reopen().unwrap())
.expect("should open");
match store.iter_changesets().expect("seek should succeed").next() {
Some(Err(IterError::Bincode(_))) => {}
unexpected_res => panic!("unexpected result: {:?}", unexpected_res),
@ -96,7 +96,10 @@ fn append_changeset_truncates_invalid_bytes() {
let got_bytes = {
let mut buf = Vec::new();
file.reopen().unwrap().read_to_end(&mut buf).expect("should read");
file.reopen()
.unwrap()
.read_to_end(&mut buf)
.expect("should read");
buf
};

View File

@ -35,7 +35,7 @@ pub struct PlanKey<Ak> {
impl<Ak> TemplateItem<Ak> {
pub fn expected_size(&self) -> usize {
match self {
TemplateItem::Sign { .. } => 64, /*size of sig TODO: take into consideration sighash falg*/
TemplateItem::Sign { .. } => 64, /* size of sig TODO: take into consideration sighash falg */
TemplateItem::Pk { .. } => 32,
TemplateItem::One => varint_len(1),
TemplateItem::Zero => 0, /* zero means an empty witness element */