//! Structs and traits which allow other parts of rust-lightning to interact with the blockchain.
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::{Block, Header};
use bitcoin::blockdata::constants::genesis_block;
-use bitcoin::blockdata::script::Script;
+use bitcoin::blockdata::script::{Script, ScriptBuf};
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::network::constants::Network;
use bitcoin::secp256k1::PublicKey;
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, MonitorEvent};
-use crate::sign::WriteableEcdsaChannelSigner;
+use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
use crate::chain::transaction::{OutPoint, TransactionData};
use crate::prelude::*;
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);
+ fn filtered_block_connected(&self, header: &Header, txdata: &TransactionData, height: u32);
/// Notifies the listener that a block was added at the given height.
fn block_connected(&self, block: &Block, height: u32) {
}
/// Notifies the listener that a block was removed at the given height.
- fn block_disconnected(&self, header: &BlockHeader, height: u32);
+ fn block_disconnected(&self, header: &Header, height: u32);
}
/// The `Confirm` trait is used to notify LDK when relevant transactions have been confirmed on
///
/// [chain order]: Confirm#order
/// [`best_block_updated`]: Self::best_block_updated
- fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32);
+ fn transactions_confirmed(&self, header: &Header, txdata: &TransactionData, height: u32);
/// Notifies LDK of a transaction that is no longer confirmed as result of a chain reorganization.
///
/// Must be called for any transaction returned by [`get_relevant_txids`] if it has been
///
/// Must be called whenever a new chain tip becomes available. May be skipped for intermediary
/// blocks.
- fn best_block_updated(&self, header: &BlockHeader, height: u32);
+ fn best_block_updated(&self, header: &Header, height: u32);
/// Returns transactions that must be monitored for reorganization out of the chain along
- /// with the hash of the block as part of which it had been previously confirmed.
+ /// with the height and the hash of the block as part of which it had been previously confirmed.
///
/// Note that the returned `Option<BlockHash>` might be `None` for channels created with LDK
/// 0.0.112 and prior, in which case you need to manually track previous confirmations.
/// given to [`transaction_unconfirmed`].
///
/// If any of the returned transactions are confirmed in a block other than the one with the
- /// given hash, they need to be unconfirmed and reconfirmed via [`transaction_unconfirmed`] and
- /// [`transactions_confirmed`], respectively.
+ /// given hash at the given height, they need to be unconfirmed and reconfirmed via
+ /// [`transaction_unconfirmed`] and [`transactions_confirmed`], respectively.
///
/// [`transactions_confirmed`]: Self::transactions_confirmed
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)>;
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)>;
}
/// An enum representing the status of a channel monitor update persistence.
///
-/// Note that there is no error variant - any failure to persist a [`ChannelMonitor`] should be
-/// retried indefinitely, the node shut down (as if we cannot update stored data we can't do much
-/// of anything useful).
+/// These are generally used as the return value for an implementation of [`Persist`] which is used
+/// as the storage layer for a [`ChainMonitor`]. See the docs on [`Persist`] for a high-level
+/// explanation of how to handle different cases.
+///
+/// While `UnrecoverableError` is provided as a failure variant, it is not truly "handled" on the
+/// calling side, and generally results in an immediate panic. For those who prefer to avoid
+/// panics, `InProgress` can be used and you can retry the update operation in the background or
+/// shut down cleanly.
///
/// Note that channels should generally *not* be force-closed after a persistence failure.
/// Force-closing with the latest [`ChannelMonitorUpdate`] applied may result in a transaction
/// latest [`ChannelMonitor`] is not durably persisted anywhere and exists only in memory, naively
/// calling [`ChannelManager::force_close_broadcasting_latest_txn`] *may result in loss of funds*!
///
+/// [`Persist`]: chainmonitor::Persist
+/// [`ChainMonitor`]: chainmonitor::ChainMonitor
/// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChannelMonitorUpdateStatus {
/// until a [`MonitorEvent::Completed`] is provided, even if you return no error on a later
/// monitor update for the same channel.
///
- /// For deployments where a copy of ChannelMonitors and other local state are backed up in a
- /// remote location (with local copies persisted immediately), it is anticipated that all
+ /// For deployments where a copy of [`ChannelMonitor`]s and other local state are backed up in
+ /// a remote location (with local copies persisted immediately), it is anticipated that all
/// updates will return [`InProgress`] until the remote copies could be updated.
///
/// Note that while fully asynchronous persistence of [`ChannelMonitor`] data is generally
///
/// [`InProgress`]: ChannelMonitorUpdateStatus::InProgress
InProgress,
+ /// Indicates that an update has failed and will not complete at any point in the future.
+ ///
+ /// Currently returning this variant will cause LDK to immediately panic to encourage immediate
+ /// shutdown. In the future this may be updated to disconnect peers and refuse to continue
+ /// normal operation without a panic.
+ ///
+ /// Applications which wish to perform an orderly shutdown after failure should consider
+ /// returning [`InProgress`] instead and simply shut down without ever marking the update
+ /// complete.
+ ///
+ /// [`InProgress`]: ChannelMonitorUpdateStatus::InProgress
+ UnrecoverableError,
}
/// The `Watch` trait defines behavior for watching on-chain activity pertaining to channels as
/// on-chain or the [`ChannelMonitor`] having decided to do so and broadcasted a transaction),
/// and the [`ChannelManager`] state will be updated once it sees the funding spend on-chain.
///
- /// If persistence fails, this should return [`ChannelMonitorUpdateStatus::InProgress`] and
- /// the node should shut down immediately.
+ /// In general, persistence failures should be retried after returning
+ /// [`ChannelMonitorUpdateStatus::InProgress`] and eventually complete. If a failure truly
+ /// cannot be retried, the node should shut down immediately after returning
+ /// [`ChannelMonitorUpdateStatus::UnrecoverableError`], see its documentation for more info.
///
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
fn update_channel(&self, funding_txo: OutPoint, update: &ChannelMonitorUpdate) -> ChannelMonitorUpdateStatus;
pub outpoint: OutPoint,
/// Spending condition of the transaction output.
- pub script_pubkey: Script,
+ pub script_pubkey: ScriptBuf,
}
-impl<T: Listen> Listen for core::ops::Deref<Target = T> {
- fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+impl<T: Listen> Listen for dyn core::ops::Deref<Target = T> {
+ fn filtered_block_connected(&self, header: &Header, txdata: &TransactionData, height: u32) {
(**self).filtered_block_connected(header, txdata, height);
}
- fn block_disconnected(&self, header: &BlockHeader, height: u32) {
+ fn block_disconnected(&self, header: &Header, height: u32) {
(**self).block_disconnected(header, height);
}
}
T::Target: Listen,
U::Target: Listen,
{
- fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+ fn filtered_block_connected(&self, header: &Header, 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) {
+ fn block_disconnected(&self, header: &Header, height: u32) {
self.0.block_disconnected(header, height);
self.1.block_disconnected(header, height);
}