mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 15:02:20 +01:00
Merge pull request #889 from jkczyz/2021-04-electrum-trait
Define chain::Confirm trait for use by Electrum clients
This commit is contained in:
commit
0d75a63ead
11 changed files with 296 additions and 283 deletions
|
@ -30,6 +30,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
|
|||
use bitcoin::hash_types::{BlockHash, WPubkeyHash};
|
||||
|
||||
use lightning::chain;
|
||||
use lightning::chain::Confirm;
|
||||
use lightning::chain::chainmonitor;
|
||||
use lightning::chain::channelmonitor;
|
||||
use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, MonitorEvent};
|
||||
|
@ -428,11 +429,11 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
|
|||
let chain_hash = genesis_block(Network::Bitcoin).block_hash();
|
||||
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: chain_hash, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
let txdata: Vec<_> = channel_txn.iter().enumerate().map(|(i, tx)| (i + 1, tx)).collect();
|
||||
$node.transactions_confirmed(&header, 1, &txdata);
|
||||
$node.transactions_confirmed(&header, &txdata, 1);
|
||||
for _ in 2..100 {
|
||||
header = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
}
|
||||
$node.update_best_block(&header, 99);
|
||||
$node.best_block_updated(&header, 99);
|
||||
} }
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
|
|||
use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
|
||||
|
||||
use lightning::chain;
|
||||
use lightning::chain::Listen;
|
||||
use lightning::chain::{Confirm, Listen};
|
||||
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
|
||||
use lightning::chain::chainmonitor;
|
||||
use lightning::chain::transaction::OutPoint;
|
||||
|
@ -207,9 +207,10 @@ impl<'a> MoneyLossDetector<'a> {
|
|||
self.blocks_connected += 1;
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height].0, merkle_root: Default::default(), time: self.blocks_connected, bits: 42, nonce: 42 };
|
||||
self.height += 1;
|
||||
self.manager.transactions_confirmed(&header, self.height as u32, &txdata);
|
||||
self.manager.update_best_block(&header, self.height as u32);
|
||||
(*self.monitor).block_connected(&header, &txdata, self.height as u32);
|
||||
self.manager.transactions_confirmed(&header, &txdata, self.height as u32);
|
||||
self.manager.best_block_updated(&header, self.height as u32);
|
||||
(*self.monitor).transactions_confirmed(&header, &txdata, self.height as u32);
|
||||
(*self.monitor).best_block_updated(&header, self.height as u32);
|
||||
if self.header_hashes.len() > self.height {
|
||||
self.header_hashes[self.height] = (header.block_hash(), self.blocks_connected);
|
||||
} else {
|
||||
|
|
|
@ -74,7 +74,7 @@ where C::Target: chain::Filter,
|
|||
P::Target: channelmonitor::Persist<ChannelSigner>,
|
||||
{
|
||||
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
|
||||
/// of a channel and reacting accordingly based on transactions in the connected block. See
|
||||
/// of a channel and reacting accordingly based on transactions in the given chain data. See
|
||||
/// [`ChannelMonitor::block_connected`] for details. Any HTLCs that were resolved on chain will
|
||||
/// be returned by [`chain::Watch::release_pending_monitor_events`].
|
||||
///
|
||||
|
@ -82,56 +82,6 @@ where C::Target: chain::Filter,
|
|||
/// calls must not exclude any transactions matching the new outputs nor any in-block
|
||||
/// descendants of such transactions. It is not necessary to re-fetch the block to obtain
|
||||
/// updated `txdata`.
|
||||
pub fn block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
|
||||
self.process_chain_data(header, txdata, |monitor, txdata| {
|
||||
monitor.block_connected(
|
||||
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
|
||||
/// of a channel and reacting accordingly to newly confirmed transactions. For details, see
|
||||
/// [`ChannelMonitor::transactions_confirmed`].
|
||||
///
|
||||
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
|
||||
/// blocks. May be called before or after [`update_best_block`] for transactions in the
|
||||
/// corresponding block. See [`update_best_block`] for further calling expectations.
|
||||
///
|
||||
/// [`block_connected`]: Self::block_connected
|
||||
/// [`update_best_block`]: Self::update_best_block
|
||||
pub fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
|
||||
self.process_chain_data(header, txdata, |monitor, txdata| {
|
||||
monitor.transactions_confirmed(
|
||||
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
|
||||
/// of a channel and reacting accordingly based on the new chain tip. For details, see
|
||||
/// [`ChannelMonitor::update_best_block`].
|
||||
///
|
||||
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
|
||||
/// blocks. May be called before or after [`transactions_confirmed`] for the corresponding
|
||||
/// block.
|
||||
///
|
||||
/// Must be called after new blocks become available for the most recent block. Intermediary
|
||||
/// blocks, however, may be safely skipped. In the event of a chain re-organization, this only
|
||||
/// needs to be called for the most recent block assuming `transaction_unconfirmed` is called
|
||||
/// for any affected transactions.
|
||||
///
|
||||
/// [`block_connected`]: Self::block_connected
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
|
||||
pub fn update_best_block(&self, header: &BlockHeader, height: u32) {
|
||||
self.process_chain_data(header, &[], |monitor, txdata| {
|
||||
// While in practice there shouldn't be any recursive calls when given empty txdata,
|
||||
// it's still possible if a chain::Filter implementation returns a transaction.
|
||||
debug_assert!(txdata.is_empty());
|
||||
monitor.update_best_block(
|
||||
header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
fn process_chain_data<FN>(&self, header: &BlockHeader, txdata: &TransactionData, process: FN)
|
||||
where
|
||||
FN: Fn(&ChannelMonitor<ChannelSigner>, &TransactionData) -> Vec<TransactionOutputs>
|
||||
|
@ -172,46 +122,6 @@ where C::Target: chain::Filter,
|
|||
}
|
||||
}
|
||||
|
||||
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
|
||||
/// of a channel based on the disconnected block. See [`ChannelMonitor::block_disconnected`] for
|
||||
/// details.
|
||||
pub fn block_disconnected(&self, header: &BlockHeader, disconnected_height: u32) {
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
monitor.block_disconnected(header, disconnected_height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
|
||||
}
|
||||
}
|
||||
|
||||
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
|
||||
/// of a channel based on transactions unconfirmed as a result of a chain reorganization. See
|
||||
/// [`ChannelMonitor::transaction_unconfirmed`] for details.
|
||||
///
|
||||
/// Used instead of [`block_disconnected`] by clients that are notified of transactions rather
|
||||
/// than blocks. May be called before or after [`update_best_block`] for transactions in the
|
||||
/// corresponding block. See [`update_best_block`] for further calling expectations.
|
||||
///
|
||||
/// [`block_disconnected`]: Self::block_disconnected
|
||||
/// [`update_best_block`]: Self::update_best_block
|
||||
pub fn transaction_unconfirmed(&self, txid: &Txid) {
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
monitor.transaction_unconfirmed(txid, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the set of txids that should be monitored for re-organization out of the chain.
|
||||
pub fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
let mut txids = Vec::new();
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
txids.append(&mut monitor.get_relevant_txids());
|
||||
}
|
||||
|
||||
txids.sort_unstable();
|
||||
txids.dedup();
|
||||
txids
|
||||
}
|
||||
|
||||
/// Creates a new `ChainMonitor` used to watch on-chain activity pertaining to channels.
|
||||
///
|
||||
/// When an optional chain source implementing [`chain::Filter`] is provided, the chain monitor
|
||||
|
@ -231,7 +141,7 @@ where C::Target: chain::Filter,
|
|||
}
|
||||
}
|
||||
|
||||
impl<ChannelSigner: Sign, C: Deref + Send + Sync, T: Deref + Send + Sync, F: Deref + Send + Sync, L: Deref + Send + Sync, P: Deref + Send + Sync>
|
||||
impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
|
||||
chain::Listen for ChainMonitor<ChannelSigner, C, T, F, L, P>
|
||||
where
|
||||
ChannelSigner: Sign,
|
||||
|
@ -242,12 +152,67 @@ where
|
|||
P::Target: channelmonitor::Persist<ChannelSigner>,
|
||||
{
|
||||
fn block_connected(&self, block: &Block, height: u32) {
|
||||
let header = &block.header;
|
||||
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
|
||||
ChainMonitor::block_connected(self, &block.header, &txdata, height);
|
||||
self.process_chain_data(header, &txdata, |monitor, txdata| {
|
||||
monitor.block_connected(
|
||||
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
|
||||
ChainMonitor::block_disconnected(self, header, height);
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
monitor.block_disconnected(
|
||||
header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
|
||||
chain::Confirm for ChainMonitor<ChannelSigner, C, T, F, L, P>
|
||||
where
|
||||
ChannelSigner: Sign,
|
||||
C::Target: chain::Filter,
|
||||
T::Target: BroadcasterInterface,
|
||||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
P::Target: channelmonitor::Persist<ChannelSigner>,
|
||||
{
|
||||
fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
|
||||
self.process_chain_data(header, txdata, |monitor, txdata| {
|
||||
monitor.transactions_confirmed(
|
||||
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
fn transaction_unconfirmed(&self, txid: &Txid) {
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
monitor.transaction_unconfirmed(txid, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
|
||||
}
|
||||
}
|
||||
|
||||
fn best_block_updated(&self, header: &BlockHeader, height: u32) {
|
||||
self.process_chain_data(header, &[], |monitor, txdata| {
|
||||
// While in practice there shouldn't be any recursive calls when given empty txdata,
|
||||
// it's still possible if a chain::Filter implementation returns a transaction.
|
||||
debug_assert!(txdata.is_empty());
|
||||
monitor.best_block_updated(
|
||||
header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
|
||||
});
|
||||
}
|
||||
|
||||
fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
let mut txids = Vec::new();
|
||||
let monitors = self.monitors.read().unwrap();
|
||||
for monitor in monitors.values() {
|
||||
txids.append(&mut monitor.get_relevant_txids());
|
||||
}
|
||||
|
||||
txids.sort_unstable();
|
||||
txids.dedup();
|
||||
txids
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1311,11 +1311,9 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
|
|||
/// outputs to watch. See [`block_connected`] for details.
|
||||
///
|
||||
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
|
||||
/// blocks. May be called before or after [`update_best_block`] for transactions in the
|
||||
/// corresponding block. See [`update_best_block`] for further calling expectations.
|
||||
/// blocks. See [`chain::Confirm`] for calling expectations.
|
||||
///
|
||||
/// [`block_connected`]: Self::block_connected
|
||||
/// [`update_best_block`]: Self::update_best_block
|
||||
pub fn transactions_confirmed<B: Deref, F: Deref, L: Deref>(
|
||||
&self,
|
||||
header: &BlockHeader,
|
||||
|
@ -1337,11 +1335,9 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
|
|||
/// Processes a transaction that was reorganized out of the chain.
|
||||
///
|
||||
/// Used instead of [`block_disconnected`] by clients that are notified of transactions rather
|
||||
/// than blocks. May be called before or after [`update_best_block`] for transactions in the
|
||||
/// corresponding block. See [`update_best_block`] for further calling expectations.
|
||||
/// than blocks. See [`chain::Confirm`] for calling expectations.
|
||||
///
|
||||
/// [`block_disconnected`]: Self::block_disconnected
|
||||
/// [`update_best_block`]: Self::update_best_block
|
||||
pub fn transaction_unconfirmed<B: Deref, F: Deref, L: Deref>(
|
||||
&self,
|
||||
txid: &Txid,
|
||||
|
@ -1361,18 +1357,10 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
|
|||
/// [`block_connected`] for details.
|
||||
///
|
||||
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
|
||||
/// blocks. May be called before or after [`transactions_confirmed`] for the corresponding
|
||||
/// block.
|
||||
///
|
||||
/// Must be called after new blocks become available for the most recent block. Intermediary
|
||||
/// blocks, however, may be safely skipped. In the event of a chain re-organization, this only
|
||||
/// needs to be called for the most recent block assuming `transaction_unconfirmed` is called
|
||||
/// for any affected transactions.
|
||||
/// blocks. See [`chain::Confirm`] for calling expectations.
|
||||
///
|
||||
/// [`block_connected`]: Self::block_connected
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
|
||||
pub fn update_best_block<B: Deref, F: Deref, L: Deref>(
|
||||
pub fn best_block_updated<B: Deref, F: Deref, L: Deref>(
|
||||
&self,
|
||||
header: &BlockHeader,
|
||||
height: u32,
|
||||
|
@ -1385,7 +1373,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
|
|||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
{
|
||||
self.inner.lock().unwrap().update_best_block(
|
||||
self.inner.lock().unwrap().best_block_updated(
|
||||
header, height, broadcaster, fee_estimator, logger)
|
||||
}
|
||||
|
||||
|
@ -2109,7 +2097,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
|
|||
self.transactions_confirmed(header, txdata, height, broadcaster, fee_estimator, logger)
|
||||
}
|
||||
|
||||
fn update_best_block<B: Deref, F: Deref, L: Deref>(
|
||||
fn best_block_updated<B: Deref, F: Deref, L: Deref>(
|
||||
&mut self,
|
||||
header: &BlockHeader,
|
||||
height: u32,
|
||||
|
@ -2727,6 +2715,29 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Confirm for (ChannelMonitor<Signer>, T, F, L)
|
||||
where
|
||||
T::Target: BroadcasterInterface,
|
||||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
{
|
||||
fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
|
||||
self.0.transactions_confirmed(header, txdata, height, &*self.1, &*self.2, &*self.3);
|
||||
}
|
||||
|
||||
fn transaction_unconfirmed(&self, txid: &Txid) {
|
||||
self.0.transaction_unconfirmed(txid, &*self.1, &*self.2, &*self.3);
|
||||
}
|
||||
|
||||
fn best_block_updated(&self, header: &BlockHeader, height: u32) {
|
||||
self.0.best_block_updated(header, height, &*self.1, &*self.2, &*self.3);
|
||||
}
|
||||
|
||||
fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
self.0.get_relevant_txids()
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_ALLOC_SIZE: usize = 64*1024;
|
||||
|
||||
impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
|
||||
|
|
|
@ -16,7 +16,7 @@ use bitcoin::hash_types::{BlockHash, Txid};
|
|||
|
||||
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, MonitorEvent};
|
||||
use chain::keysinterface::Sign;
|
||||
use chain::transaction::OutPoint;
|
||||
use chain::transaction::{OutPoint, TransactionData};
|
||||
|
||||
pub mod chaininterface;
|
||||
pub mod chainmonitor;
|
||||
|
@ -45,10 +45,13 @@ pub trait Access: Send + Sync {
|
|||
fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> Result<TxOut, AccessError>;
|
||||
}
|
||||
|
||||
/// The `Listen` trait is used to be notified of when blocks have been connected or disconnected
|
||||
/// from the chain.
|
||||
/// The `Listen` trait is used to notify when blocks have been connected or disconnected from the
|
||||
/// chain.
|
||||
///
|
||||
/// Useful when needing to replay chain data upon startup or as new chain events occur.
|
||||
/// Useful when needing to replay chain data upon startup or as new chain events occur. Clients
|
||||
/// 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.
|
||||
pub trait Listen {
|
||||
/// Notifies the listener that a block was added at the given height.
|
||||
fn block_connected(&self, block: &Block, height: u32);
|
||||
|
@ -57,6 +60,86 @@ pub trait Listen {
|
|||
fn block_disconnected(&self, header: &BlockHeader, height: u32);
|
||||
}
|
||||
|
||||
/// The `Confirm` trait is used to notify when transactions have been confirmed on chain or
|
||||
/// unconfirmed during a chain reorganization.
|
||||
///
|
||||
/// Clients sourcing chain data using a transaction-oriented API should prefer this interface over
|
||||
/// [`Listen`]. For instance, an Electrum client may implement [`Filter`] by subscribing to activity
|
||||
/// related to registered transactions and outputs. Upon notification, it would pass along the
|
||||
/// matching transactions using this interface.
|
||||
///
|
||||
/// # Use
|
||||
///
|
||||
/// The intended use is as follows:
|
||||
/// - Call [`transactions_confirmed`] to process any on-chain activity of interest.
|
||||
/// - Call [`transaction_unconfirmed`] to process any transaction returned by [`get_relevant_txids`]
|
||||
/// that has been reorganized out of the chain.
|
||||
/// - Call [`best_block_updated`] whenever a new chain tip becomes available.
|
||||
///
|
||||
/// # Order
|
||||
///
|
||||
/// Clients must call these methods in chain order. Specifically:
|
||||
/// - Transactions confirmed in a block must be given before transactions confirmed in a later
|
||||
/// block.
|
||||
/// - Dependent transactions within the same block must be given in topological order, possibly in
|
||||
/// separate calls.
|
||||
/// - Unconfirmed transactions must be given after the original confirmations and before any
|
||||
/// reconfirmation.
|
||||
///
|
||||
/// See individual method documentation for further details.
|
||||
///
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
|
||||
/// [`best_block_updated`]: Self::best_block_updated
|
||||
/// [`get_relevant_txids`]: Self::get_relevant_txids
|
||||
pub trait Confirm {
|
||||
/// Processes transactions confirmed in a block with a given header and height.
|
||||
///
|
||||
/// Should be called for any transactions registered by [`Filter::register_tx`] or any
|
||||
/// transactions spending an output registered by [`Filter::register_output`]. Such transactions
|
||||
/// appearing in the same block do not need to be included in the same call; instead, multiple
|
||||
/// calls with additional transactions may be made so long as they are made in [chain order].
|
||||
///
|
||||
/// May be called before or after [`best_block_updated`] for the corresponding block. However,
|
||||
/// in the event of a chain reorganization, it must not be called with a `header` that is no
|
||||
/// longer in the chain as of the last call to [`best_block_updated`].
|
||||
///
|
||||
/// [chain order]: Self#order
|
||||
/// [`best_block_updated`]: Self::best_block_updated
|
||||
fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32);
|
||||
|
||||
/// Processes a transaction that is no longer confirmed as result of a chain reorganization.
|
||||
///
|
||||
/// Should be called for any transaction returned by [`get_relevant_txids`] if it has been
|
||||
/// reorganized out of the best chain. Once called, the given transaction should not be returned
|
||||
/// by [`get_relevant_txids`] unless it has been reconfirmed via [`transactions_confirmed`].
|
||||
///
|
||||
/// [`get_relevant_txids`]: Self::get_relevant_txids
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
fn transaction_unconfirmed(&self, txid: &Txid);
|
||||
|
||||
/// Processes an update to the best header connected at the given height.
|
||||
///
|
||||
/// Should be called when a new header is available but may be skipped for intermediary blocks
|
||||
/// if they become available at the same time.
|
||||
fn best_block_updated(&self, header: &BlockHeader, height: u32);
|
||||
|
||||
/// Returns transactions that should be monitored for reorganization out of the chain.
|
||||
///
|
||||
/// Should include any transactions passed to [`transactions_confirmed`] that have insufficient
|
||||
/// confirmations to be safe from a chain reorganization. Should not include any transactions
|
||||
/// passed to [`transaction_unconfirmed`] unless later reconfirmed.
|
||||
///
|
||||
/// May be called to determine the subset of transactions that must still be monitored for
|
||||
/// reorganization. Will be idempotent between calls but may change as a result of calls to the
|
||||
/// other interface methods. Thus, this is useful to determine which transactions may need to be
|
||||
/// given to [`transaction_unconfirmed`].
|
||||
///
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
|
||||
fn get_relevant_txids(&self) -> Vec<Txid>;
|
||||
}
|
||||
|
||||
/// The `Watch` trait defines behavior for watching on-chain activity pertaining to channels as
|
||||
/// blocks are connected and disconnected.
|
||||
///
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
//! There are a bunch of these as their handling is relatively error-prone so they are split out
|
||||
//! here. See also the chanmon_fail_consistency fuzz test.
|
||||
|
||||
use bitcoin::blockdata::block::BlockHeader;
|
||||
use bitcoin::blockdata::block::{Block, BlockHeader};
|
||||
use bitcoin::hash_types::BlockHash;
|
||||
use bitcoin::network::constants::Network;
|
||||
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr};
|
||||
use chain::transaction::OutPoint;
|
||||
use chain::Listen;
|
||||
use chain::Watch;
|
||||
use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
|
||||
use ln::features::InitFeatures;
|
||||
|
@ -114,7 +115,7 @@ fn test_monitor_and_persister_update_fail() {
|
|||
chain_mon
|
||||
};
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
chain_mon.chain_monitor.block_connected(&header, &[], 200);
|
||||
chain_mon.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200);
|
||||
|
||||
// Set the persister's return value to be a TemporaryFailure.
|
||||
persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure));
|
||||
|
|
|
@ -3600,7 +3600,7 @@ impl<Signer: Sign> Channel<Signer> {
|
|||
}
|
||||
}
|
||||
// If we allow 1-conf funding, we may need to check for funding_locked here and
|
||||
// send it immediately instead of waiting for an update_best_block call (which
|
||||
// send it immediately instead of waiting for a best_block_updated call (which
|
||||
// may have already happened for this block).
|
||||
if let Some(funding_locked) = self.check_get_funding_locked(height) {
|
||||
return Ok(Some(funding_locked));
|
||||
|
@ -3631,7 +3631,7 @@ impl<Signer: Sign> Channel<Signer> {
|
|||
///
|
||||
/// May return some HTLCs (and their payment_hash) which have timed out and should be failed
|
||||
/// back.
|
||||
pub fn update_best_block(&mut self, height: u32, highest_header_time: u32) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> {
|
||||
pub fn best_block_updated(&mut self, height: u32, highest_header_time: u32) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> {
|
||||
let mut timed_out_htlcs = Vec::new();
|
||||
let unforwarded_htlc_cltv_limit = height + HTLC_FAIL_BACK_BUFFER;
|
||||
self.holding_cell_htlc_updates.retain(|htlc_update| {
|
||||
|
@ -3683,14 +3683,14 @@ impl<Signer: Sign> Channel<Signer> {
|
|||
/// before the channel has reached funding_locked and we can just wait for more blocks.
|
||||
pub fn funding_transaction_unconfirmed(&mut self) -> Result<(), msgs::ErrorMessage> {
|
||||
if self.funding_tx_confirmation_height != 0 {
|
||||
// We handle the funding disconnection by calling update_best_block with a height one
|
||||
// We handle the funding disconnection by calling best_block_updated with a height one
|
||||
// below where our funding was connected, implying a reorg back to conf_height - 1.
|
||||
let reorg_height = self.funding_tx_confirmation_height - 1;
|
||||
// We use the time field to bump the current time we set on channel updates if its
|
||||
// larger. If we don't know that time has moved forward, we can just set it to the last
|
||||
// time we saw and it will be ignored.
|
||||
let best_time = self.update_time_counter;
|
||||
match self.update_best_block(reorg_height, best_time) {
|
||||
match self.best_block_updated(reorg_height, best_time) {
|
||||
Ok((funding_locked, timed_out_htlcs)) => {
|
||||
assert!(funding_locked.is_none(), "We can't generate a funding with 0 confirmations?");
|
||||
assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
|
||||
|
|
|
@ -36,6 +36,7 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
|
|||
use bitcoin::secp256k1;
|
||||
|
||||
use chain;
|
||||
use chain::Confirm;
|
||||
use chain::Watch;
|
||||
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
|
||||
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent, CLOSED_CHANNEL_UPDATE_ID};
|
||||
|
@ -3363,8 +3364,8 @@ where
|
|||
}
|
||||
|
||||
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
|
||||
self.transactions_confirmed(&block.header, height, &txdata);
|
||||
self.update_best_block(&block.header, height);
|
||||
self.transactions_confirmed(&block.header, &txdata, height);
|
||||
self.best_block_updated(&block.header, height);
|
||||
}
|
||||
|
||||
fn block_disconnected(&self, header: &BlockHeader, height: u32) {
|
||||
|
@ -3379,16 +3380,88 @@ where
|
|||
*best_block = BestBlock::new(header.prev_blockhash, new_height)
|
||||
}
|
||||
|
||||
self.do_chain_event(Some(new_height), |channel| channel.update_best_block(new_height, header.time));
|
||||
self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time));
|
||||
}
|
||||
}
|
||||
|
||||
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> chain::Confirm for ChannelManager<Signer, M, T, K, F, L>
|
||||
where
|
||||
M::Target: chain::Watch<Signer>,
|
||||
T::Target: BroadcasterInterface,
|
||||
K::Target: KeysInterface<Signer = Signer>,
|
||||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
{
|
||||
fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
|
||||
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
|
||||
// during initialization prior to the chain_monitor being fully configured in some cases.
|
||||
// See the docs for `ChannelManagerReadArgs` for more.
|
||||
|
||||
let block_hash = header.block_hash();
|
||||
log_trace!(self.logger, "{} transactions included in block {} at height {} provided", txdata.len(), block_hash, height);
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, &self.logger).map(|a| (a, Vec::new())));
|
||||
}
|
||||
|
||||
fn best_block_updated(&self, header: &BlockHeader, height: u32) {
|
||||
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
|
||||
// during initialization prior to the chain_monitor being fully configured in some cases.
|
||||
// See the docs for `ChannelManagerReadArgs` for more.
|
||||
|
||||
let block_hash = header.block_hash();
|
||||
log_trace!(self.logger, "New best block: {} at height {}", block_hash, height);
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
|
||||
*self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
|
||||
|
||||
self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time));
|
||||
|
||||
loop {
|
||||
// Update last_node_announcement_serial to be the max of its current value and the
|
||||
// block timestamp. This should keep us close to the current time without relying on
|
||||
// having an explicit local time source.
|
||||
// Just in case we end up in a race, we loop until we either successfully update
|
||||
// last_node_announcement_serial or decide we don't need to.
|
||||
let old_serial = self.last_node_announcement_serial.load(Ordering::Acquire);
|
||||
if old_serial >= header.time as usize { break; }
|
||||
if self.last_node_announcement_serial.compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
let channel_state = self.channel_state.lock().unwrap();
|
||||
let mut res = Vec::with_capacity(channel_state.short_to_id.len());
|
||||
for chan in channel_state.by_id.values() {
|
||||
if let Some(funding_txo) = chan.get_funding_txo() {
|
||||
res.push(funding_txo.txid);
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn transaction_unconfirmed(&self, txid: &Txid) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
self.do_chain_event(None, |channel| {
|
||||
if let Some(funding_txo) = channel.get_funding_txo() {
|
||||
if funding_txo.txid == *txid {
|
||||
channel.funding_transaction_unconfirmed().map(|_| (None, Vec::new()))
|
||||
} else { Ok((None, Vec::new())) }
|
||||
} else { Ok((None, Vec::new())) }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<Signer, M, T, K, F, L>
|
||||
where M::Target: chain::Watch<Signer>,
|
||||
T::Target: BroadcasterInterface,
|
||||
K::Target: KeysInterface<Signer = Signer>,
|
||||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
where
|
||||
M::Target: chain::Watch<Signer>,
|
||||
T::Target: BroadcasterInterface,
|
||||
K::Target: KeysInterface<Signer = Signer>,
|
||||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
{
|
||||
/// Calls a function which handles an on-chain event (blocks dis/connected, transactions
|
||||
/// un/confirmed, etc) on each channel, handling any resulting errors or messages generated by
|
||||
|
@ -3482,131 +3555,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates channel state to take note of transactions which were confirmed in the given block
|
||||
/// at the given height.
|
||||
///
|
||||
/// Note that you must still call (or have called) [`update_best_block`] with the block
|
||||
/// information which is included here.
|
||||
///
|
||||
/// This method may be called before or after [`update_best_block`] for a given block's
|
||||
/// transaction data and may be called multiple times with additional transaction data for a
|
||||
/// given block.
|
||||
///
|
||||
/// This method may be called for a previous block after an [`update_best_block`] call has
|
||||
/// been made for a later block, however it must *not* be called with transaction data from a
|
||||
/// block which is no longer in the best chain (ie where [`update_best_block`] has already
|
||||
/// been informed about a blockchain reorganization which no longer includes the block which
|
||||
/// corresponds to `header`).
|
||||
///
|
||||
/// [`update_best_block`]: `Self::update_best_block`
|
||||
pub fn transactions_confirmed(&self, header: &BlockHeader, height: u32, txdata: &TransactionData) {
|
||||
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
|
||||
// during initialization prior to the chain_monitor being fully configured in some cases.
|
||||
// See the docs for `ChannelManagerReadArgs` for more.
|
||||
|
||||
let block_hash = header.block_hash();
|
||||
log_trace!(self.logger, "{} transactions included in block {} at height {} provided", txdata.len(), block_hash, height);
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, &self.logger).map(|a| (a, Vec::new())));
|
||||
}
|
||||
|
||||
/// Updates channel state with the current best blockchain tip. You should attempt to call this
|
||||
/// quickly after a new block becomes available, however if multiple new blocks become
|
||||
/// available at the same time, only a single `update_best_block()` call needs to be made.
|
||||
///
|
||||
/// This method should also be called immediately after any block disconnections, once at the
|
||||
/// reorganization fork point, and once with the new chain tip. Calling this method at the
|
||||
/// blockchain reorganization fork point ensures we learn when a funding transaction which was
|
||||
/// previously confirmed is reorganized out of the blockchain, ensuring we do not continue to
|
||||
/// accept payments which cannot be enforced on-chain.
|
||||
///
|
||||
/// In both the block-connection and block-disconnection case, this method may be called either
|
||||
/// once per block connected or disconnected, or simply at the fork point and new tip(s),
|
||||
/// skipping any intermediary blocks.
|
||||
pub fn update_best_block(&self, header: &BlockHeader, height: u32) {
|
||||
// Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
|
||||
// during initialization prior to the chain_monitor being fully configured in some cases.
|
||||
// See the docs for `ChannelManagerReadArgs` for more.
|
||||
|
||||
let block_hash = header.block_hash();
|
||||
log_trace!(self.logger, "New best block: {} at height {}", block_hash, height);
|
||||
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
|
||||
*self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
|
||||
|
||||
self.do_chain_event(Some(height), |channel| channel.update_best_block(height, header.time));
|
||||
|
||||
loop {
|
||||
// Update last_node_announcement_serial to be the max of its current value and the
|
||||
// block timestamp. This should keep us close to the current time without relying on
|
||||
// having an explicit local time source.
|
||||
// Just in case we end up in a race, we loop until we either successfully update
|
||||
// last_node_announcement_serial or decide we don't need to.
|
||||
let old_serial = self.last_node_announcement_serial.load(Ordering::Acquire);
|
||||
if old_serial >= header.time as usize { break; }
|
||||
if self.last_node_announcement_serial.compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the set of txids which should be monitored for their confirmation state.
|
||||
///
|
||||
/// If you're providing information about reorganizations via [`transaction_unconfirmed`], this
|
||||
/// is the set of transactions which you may need to call [`transaction_unconfirmed`] for.
|
||||
///
|
||||
/// This may be useful to poll to determine the set of transactions which must be registered
|
||||
/// with an Electrum server or for which an Electrum server needs to be polled to determine
|
||||
/// transaction confirmation state.
|
||||
///
|
||||
/// This may update after any [`transactions_confirmed`] or [`block_connected`] call.
|
||||
///
|
||||
/// Note that this is NOT the set of transactions which must be included in calls to
|
||||
/// [`transactions_confirmed`] if they are confirmed, but a small subset of it.
|
||||
///
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
|
||||
/// [`block_connected`]: chain::Listen::block_connected
|
||||
pub fn get_relevant_txids(&self) -> Vec<Txid> {
|
||||
let channel_state = self.channel_state.lock().unwrap();
|
||||
let mut res = Vec::with_capacity(channel_state.short_to_id.len());
|
||||
for chan in channel_state.by_id.values() {
|
||||
if let Some(funding_txo) = chan.get_funding_txo() {
|
||||
res.push(funding_txo.txid);
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// Marks a transaction as having been reorganized out of the blockchain.
|
||||
///
|
||||
/// If a transaction is included in [`get_relevant_txids`], and is no longer in the main branch
|
||||
/// of the blockchain, this function should be called to indicate that the transaction should
|
||||
/// be considered reorganized out.
|
||||
///
|
||||
/// Once this is called, the given transaction will no longer appear on [`get_relevant_txids`],
|
||||
/// though this may be called repeatedly for a given transaction without issue.
|
||||
///
|
||||
/// Note that if the transaction is confirmed on the main chain in a different block (indicated
|
||||
/// via a call to [`transactions_confirmed`]), it may re-appear in [`get_relevant_txids`], thus
|
||||
/// be very wary of race-conditions wherein the final state of a transaction indicated via
|
||||
/// these APIs is not the same as its state on the blockchain.
|
||||
///
|
||||
/// [`transactions_confirmed`]: Self::transactions_confirmed
|
||||
/// [`get_relevant_txids`]: Self::get_relevant_txids
|
||||
pub fn transaction_unconfirmed(&self, txid: &Txid) {
|
||||
let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
|
||||
self.do_chain_event(None, |channel| {
|
||||
if let Some(funding_txo) = channel.get_funding_txo() {
|
||||
if funding_txo.txid == *txid {
|
||||
channel.funding_transaction_unconfirmed().map(|_| (None, Vec::new()))
|
||||
} else { Ok((None, Vec::new())) }
|
||||
} else { Ok((None, Vec::new())) }
|
||||
});
|
||||
}
|
||||
|
||||
/// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
|
||||
/// indicating whether persistence is necessary. Only one listener on
|
||||
/// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//! A bunch of useful utilities for building networks of nodes and exchanging messages between
|
||||
//! nodes for functional tests.
|
||||
|
||||
use chain::{Listen, Watch};
|
||||
use chain::{Confirm, Listen, Watch};
|
||||
use chain::channelmonitor::ChannelMonitor;
|
||||
use chain::transaction::OutPoint;
|
||||
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
|
||||
|
@ -79,17 +79,17 @@ pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &T
|
|||
/// The possible ways we may notify a ChannelManager of a new block
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum ConnectStyle {
|
||||
/// Calls update_best_block first, detecting transactions in the block only after receiving the
|
||||
/// Calls best_block_updated first, detecting transactions in the block only after receiving the
|
||||
/// header and height information.
|
||||
BestBlockFirst,
|
||||
/// The same as BestBlockFirst, however when we have multiple blocks to connect, we only
|
||||
/// make a single update_best_block call.
|
||||
/// make a single best_block_updated call.
|
||||
BestBlockFirstSkippingBlocks,
|
||||
/// Calls transactions_confirmed first, detecting transactions in the block before updating the
|
||||
/// header and height information.
|
||||
TransactionsFirst,
|
||||
/// The same as TransactionsFirst, however when we have multiple blocks to connect, we only
|
||||
/// make a single update_best_block call.
|
||||
/// make a single best_block_updated call.
|
||||
TransactionsFirstSkippingBlocks,
|
||||
/// Provides the full block via the chain::Listen interface. In the current code this is
|
||||
/// equivalent to TransactionsFirst with some additional assertions.
|
||||
|
@ -128,20 +128,20 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, s
|
|||
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
|
||||
match *node.connect_style.borrow() {
|
||||
ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstSkippingBlocks => {
|
||||
node.chain_monitor.chain_monitor.update_best_block(&block.header, height);
|
||||
node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
|
||||
node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
|
||||
node.node.update_best_block(&block.header, height);
|
||||
node.node.transactions_confirmed(&block.header, height, &txdata);
|
||||
node.node.best_block_updated(&block.header, height);
|
||||
node.node.transactions_confirmed(&block.header, &txdata, height);
|
||||
},
|
||||
ConnectStyle::TransactionsFirst|ConnectStyle::TransactionsFirstSkippingBlocks => {
|
||||
node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
|
||||
node.chain_monitor.chain_monitor.update_best_block(&block.header, height);
|
||||
node.node.transactions_confirmed(&block.header, height, &txdata);
|
||||
node.node.update_best_block(&block.header, height);
|
||||
node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
|
||||
node.node.transactions_confirmed(&block.header, &txdata, height);
|
||||
node.node.best_block_updated(&block.header, height);
|
||||
},
|
||||
ConnectStyle::FullBlockViaListen => {
|
||||
node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
|
||||
Listen::block_connected(node.node, &block, height);
|
||||
node.chain_monitor.chain_monitor.block_connected(&block, height);
|
||||
node.node.block_connected(&block, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,13 +162,13 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32)
|
|||
},
|
||||
ConnectStyle::BestBlockFirstSkippingBlocks|ConnectStyle::TransactionsFirstSkippingBlocks => {
|
||||
if i == count - 1 {
|
||||
node.chain_monitor.chain_monitor.update_best_block(&prev_header.0, prev_header.1);
|
||||
node.node.update_best_block(&prev_header.0, prev_header.1);
|
||||
node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
|
||||
node.node.best_block_updated(&prev_header.0, prev_header.1);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
node.chain_monitor.chain_monitor.update_best_block(&prev_header.0, prev_header.1);
|
||||
node.node.update_best_block(&prev_header.0, prev_header.1);
|
||||
node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
|
||||
node.node.best_block_updated(&prev_header.0, prev_header.1);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
//! claim outputs on-chain.
|
||||
|
||||
use chain;
|
||||
use chain::Listen;
|
||||
use chain::Watch;
|
||||
use chain::channelmonitor;
|
||||
use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
|
||||
|
@ -8225,7 +8226,7 @@ fn test_update_err_monitor_lockdown() {
|
|||
watchtower
|
||||
};
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
watchtower.chain_monitor.block_connected(&header, &[], 200);
|
||||
watchtower.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200);
|
||||
|
||||
// Try to update ChannelMonitor
|
||||
assert!(nodes[1].node.claim_funds(preimage, &None, 9_000_000));
|
||||
|
@ -8284,7 +8285,7 @@ fn test_concurrent_monitor_claim() {
|
|||
watchtower
|
||||
};
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
watchtower_alice.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
|
||||
// Watchtower Alice should have broadcast a commitment/HTLC-timeout
|
||||
{
|
||||
|
@ -8310,7 +8311,7 @@ fn test_concurrent_monitor_claim() {
|
|||
watchtower
|
||||
};
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
watchtower_bob.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
watchtower_bob.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
|
||||
// Route another payment to generate another update with still previous HTLC pending
|
||||
let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
|
||||
|
@ -8336,7 +8337,8 @@ fn test_concurrent_monitor_claim() {
|
|||
check_added_monitors!(nodes[0], 1);
|
||||
|
||||
//// Provide one more block to watchtower Bob, expect broadcast of commitment and HTLC-Timeout
|
||||
watchtower_bob.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
watchtower_bob.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
|
||||
// Watchtower Bob should have broadcast a commitment/HTLC-timeout
|
||||
let bob_state_y;
|
||||
|
@ -8348,7 +8350,8 @@ fn test_concurrent_monitor_claim() {
|
|||
};
|
||||
|
||||
// We confirm Bob's state Y on Alice, she should broadcast a HTLC-timeout
|
||||
watchtower_alice.chain_monitor.block_connected(&header, &vec![(0, &bob_state_y)], CHAN_CONFIRM_DEPTH + 2 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
|
||||
watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![bob_state_y.clone()] }, CHAN_CONFIRM_DEPTH + 2 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
|
||||
{
|
||||
let htlc_txn = chanmon_cfgs[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
|
||||
// We broadcast twice the transaction, once due to the HTLC-timeout, once due
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//! Further functional tests which test blockchain reorganizations.
|
||||
|
||||
use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor};
|
||||
use chain::Watch;
|
||||
use chain::{Confirm, Watch};
|
||||
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs};
|
||||
use ln::features::InitFeatures;
|
||||
use ln::msgs::{ChannelMessageHandler, ErrorAction, HTLCFailChannelUpdate};
|
||||
|
|
Loading…
Add table
Reference in a new issue