use crate::{BlockSource, BlockSourceResult, Cache, ChainNotifier};
use crate::poll::{ChainPoller, Validate, ValidatedBlockHeader};
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
use bitcoin::hash_types::BlockHash;
use bitcoin::network::constants::Network;
struct DynamicChainListener<'a, L: chain::Listen + ?Sized>(&'a L);
impl<'a, L: chain::Listen + ?Sized> chain::Listen for DynamicChainListener<'a, L> {
- fn block_connected(&self, _block: &Block, _height: u32) {
+ fn filtered_block_connected(&self, _header: &BlockHeader, _txdata: &chain::transaction::TransactionData, _height: u32) {
unreachable!()
}
struct ChainListenerSet<'a, L: chain::Listen + ?Sized>(Vec<(u32, &'a L)>);
impl<'a, L: chain::Listen + ?Sized> chain::Listen for ChainListenerSet<'a, L> {
- fn block_connected(&self, block: &Block, height: u32) {
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &chain::transaction::TransactionData, height: u32) {
for (starting_height, chain_listener) in self.0.iter() {
if height > *starting_height {
- chain_listener.block_connected(block, height);
+ chain_listener.filtered_block_connected(header, txdata, height);
}
}
}
pub struct NullChainListener;
impl chain::Listen for NullChainListener {
- fn block_connected(&self, _block: &Block, _height: u32) {}
+ fn filtered_block_connected(&self, _header: &BlockHeader, _txdata: &chain::transaction::TransactionData, _height: u32) {}
fn block_disconnected(&self, _header: &BlockHeader, _height: u32) {}
}
}
impl chain::Listen for MockChainListener {
- fn block_connected(&self, block: &Block, height: u32) {
+ fn filtered_block_connected(&self, header: &BlockHeader, _txdata: &chain::transaction::TransactionData, height: u32) {
match self.expected_blocks_connected.borrow_mut().pop_front() {
None => {
- panic!("Unexpected block connected: {:?}", block.block_hash());
+ panic!("Unexpected block connected: {:?}", header.block_hash());
},
Some(expected_block) => {
- assert_eq!(block.block_hash(), expected_block.header.block_hash());
+ assert_eq!(header.block_hash(), expected_block.header.block_hash());
assert_eq!(height, expected_block.height);
},
}
//! events. The remote server would make use of [`ChainMonitor`] for block processing and for
//! servicing [`ChannelMonitor`] updates from the client.
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
use bitcoin::hash_types::Txid;
use chain;
L::Target: Logger,
P::Target: Persist<ChannelSigner>,
{
- fn block_connected(&self, block: &Block, height: u32) {
- let header = &block.header;
- let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
log_debug!(self.logger, "New best block {} at height {} provided via block_connected", header.block_hash(), height);
self.process_chain_data(header, Some(height), &txdata, |monitor, txdata| {
monitor.block_connected(
//! security-domain-separated system design, you should consider having multiple paths for
//! ChannelMonitors to get out of the HSM and onto monitoring devices.
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
use bitcoin::blockdata::transaction::{TxOut,Transaction};
use bitcoin::blockdata::script::{Script, Builder};
use bitcoin::blockdata::opcodes;
F::Target: FeeEstimator,
L::Target: Logger,
{
- fn block_connected(&self, block: &Block, height: u32) {
- let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
- self.0.block_connected(&block.header, &txdata, height, &*self.1, &*self.2, &*self.3);
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+ self.0.block_connected(header, txdata, height, &*self.1, &*self.2, &*self.3);
}
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
/// sourcing chain data using a block-oriented API should prefer this interface over [`Confirm`].
/// Such clients fetch the entire header chain whereas clients using [`Confirm`] only fetch headers
/// when needed.
+///
+/// By using [`Listen::filtered_block_connected`] this interface supports clients fetching the
+/// entire header chain and only blocks with matching transaction data using BIP 157 filters or
+/// other similar filtering.
pub trait Listen {
+ /// Notifies the listener that a block was added at the given height, with the transaction data
+ /// possibly filtered.
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32);
+
/// Notifies the listener that a block was added at the given height.
- fn block_connected(&self, block: &Block, height: u32);
+ fn block_connected(&self, block: &Block, height: u32) {
+ let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
+ self.filtered_block_connected(&block.header, &txdata, height);
+ }
/// Notifies the listener that a block was removed at the given height.
fn block_disconnected(&self, header: &BlockHeader, height: u32);
}
impl<T: Listen> Listen for core::ops::Deref<Target = T> {
- fn block_connected(&self, block: &Block, height: u32) {
- (**self).block_connected(block, height);
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+ (**self).filtered_block_connected(header, txdata, height);
}
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
T::Target: Listen,
U::Target: Listen,
{
- fn block_connected(&self, block: &Block, height: u32) {
- self.0.block_connected(block, height);
- self.1.block_connected(block, height);
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+ self.0.filtered_block_connected(header, txdata, height);
+ self.1.filtered_block_connected(header, txdata, height);
}
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
//! imply it needs to fail HTLCs/payments/channels it manages).
//!
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::blockdata::constants::genesis_block;
use bitcoin::network::constants::Network;
F::Target: FeeEstimator,
L::Target: Logger,
{
- fn block_connected(&self, block: &Block, height: u32) {
+ fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
{
let best_block = self.best_block.read().unwrap();
- assert_eq!(best_block.block_hash(), block.header.prev_blockhash,
+ assert_eq!(best_block.block_hash(), header.prev_blockhash,
"Blocks must be connected in chain-order - the connected header must build on the last connected header");
assert_eq!(best_block.height(), height - 1,
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
}
- let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
- self.transactions_confirmed(&block.header, &txdata, height);
- self.best_block_updated(&block.header, height);
+ self.transactions_confirmed(header, txdata, height);
+ self.best_block_updated(header, height);
}
fn block_disconnected(&self, header: &BlockHeader, height: u32) {