use ln::channelmanager::HTLCSource;
use chain;
use chain::{BestBlock, WatchedOutput};
-use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
+use chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use chain::transaction::{OutPoint, TransactionData};
use chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
use chain::onchaintx::OnchainTxHandler;
// the full block_connected).
best_block: BestBlock,
+ /// The node_id of our counterparty
+ counterparty_node_id: Option<PublicKey>,
+
secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
}
(3, self.htlcs_resolved_on_chain, vec_type),
(5, self.pending_monitor_events, vec_type),
(7, self.funding_spend_seen, required),
+ (9, self.counterparty_node_id, option),
});
Ok(())
}
impl<Signer: Sign> ChannelMonitor<Signer> {
+ /// For lockorder enforcement purposes, we need to have a single site which constructs the
+ /// `inner` mutex, otherwise cases where we lock two monitors at the same time (eg in our
+ /// PartialEq implementation) we may decide a lockorder violation has occurred.
+ fn from_impl(imp: ChannelMonitorImpl<Signer>) -> Self {
+ ChannelMonitor { inner: Mutex::new(imp) }
+ }
+
pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: Signer, shutdown_script: Option<Script>,
on_counterparty_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script),
channel_parameters: &ChannelTransactionParameters,
funding_redeemscript: Script, channel_value_satoshis: u64,
commitment_transaction_number_obscure_factor: u64,
initial_holder_commitment_tx: HolderCommitmentTransaction,
- best_block: BestBlock) -> ChannelMonitor<Signer> {
+ best_block: BestBlock, counterparty_node_id: PublicKey) -> ChannelMonitor<Signer> {
assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
let mut outputs_to_watch = HashMap::new();
outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
- ChannelMonitor {
- inner: Mutex::new(ChannelMonitorImpl {
- latest_update_id: 0,
- commitment_transaction_number_obscure_factor,
+ Self::from_impl(ChannelMonitorImpl {
+ latest_update_id: 0,
+ commitment_transaction_number_obscure_factor,
- destination_script: destination_script.clone(),
- broadcasted_holder_revokable_script: None,
- counterparty_payment_script,
- shutdown_script,
+ destination_script: destination_script.clone(),
+ broadcasted_holder_revokable_script: None,
+ counterparty_payment_script,
+ shutdown_script,
- channel_keys_id,
- holder_revocation_basepoint,
- funding_info,
- current_counterparty_commitment_txid: None,
- prev_counterparty_commitment_txid: None,
+ channel_keys_id,
+ holder_revocation_basepoint,
+ funding_info,
+ current_counterparty_commitment_txid: None,
+ prev_counterparty_commitment_txid: None,
- counterparty_commitment_params,
- funding_redeemscript,
- channel_value_satoshis,
- their_cur_per_commitment_points: None,
+ counterparty_commitment_params,
+ funding_redeemscript,
+ channel_value_satoshis,
+ their_cur_per_commitment_points: None,
- on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
+ on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
- commitment_secrets: CounterpartyCommitmentSecrets::new(),
- counterparty_claimable_outpoints: HashMap::new(),
- counterparty_commitment_txn_on_chain: HashMap::new(),
- counterparty_hash_commitment_number: HashMap::new(),
+ commitment_secrets: CounterpartyCommitmentSecrets::new(),
+ counterparty_claimable_outpoints: HashMap::new(),
+ counterparty_commitment_txn_on_chain: HashMap::new(),
+ counterparty_hash_commitment_number: HashMap::new(),
- prev_holder_signed_commitment_tx: None,
- current_holder_commitment_tx: holder_commitment_tx,
- current_counterparty_commitment_number: 1 << 48,
- current_holder_commitment_number,
+ prev_holder_signed_commitment_tx: None,
+ current_holder_commitment_tx: holder_commitment_tx,
+ current_counterparty_commitment_number: 1 << 48,
+ current_holder_commitment_number,
- payment_preimages: HashMap::new(),
- pending_monitor_events: Vec::new(),
- pending_events: Vec::new(),
+ payment_preimages: HashMap::new(),
+ pending_monitor_events: Vec::new(),
+ pending_events: Vec::new(),
- onchain_events_awaiting_threshold_conf: Vec::new(),
- outputs_to_watch,
+ onchain_events_awaiting_threshold_conf: Vec::new(),
+ outputs_to_watch,
- onchain_tx_handler,
+ onchain_tx_handler,
- lockdown_from_offchain: false,
- holder_tx_signed: false,
- funding_spend_seen: false,
- funding_spend_confirmed: None,
- htlcs_resolved_on_chain: Vec::new(),
+ lockdown_from_offchain: false,
+ holder_tx_signed: false,
+ funding_spend_seen: false,
+ funding_spend_confirmed: None,
+ htlcs_resolved_on_chain: Vec::new(),
- best_block,
+ best_block,
+ counterparty_node_id: Some(counterparty_node_id),
- secp_ctx,
- }),
- }
+ secp_ctx,
+ })
}
#[cfg(test)]
payment_hash: &PaymentHash,
payment_preimage: &PaymentPreimage,
broadcaster: &B,
- fee_estimator: &F,
+ fee_estimator: &LowerBoundedFeeEstimator<F>,
logger: &L,
) where
B::Target: BroadcasterInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
self.inner.lock().unwrap().transactions_confirmed(
- header, txdata, height, broadcaster, fee_estimator, logger)
+ header, txdata, height, broadcaster, &bounded_fee_estimator, logger)
}
/// Processes a transaction that was reorganized out of the chain.
F::Target: FeeEstimator,
L::Target: Logger,
{
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
self.inner.lock().unwrap().transaction_unconfirmed(
- txid, broadcaster, fee_estimator, logger);
+ txid, broadcaster, &bounded_fee_estimator, logger);
}
/// Updates the monitor with the current best chain tip, returning new outputs to watch. See
F::Target: FeeEstimator,
L::Target: Logger,
{
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
self.inner.lock().unwrap().best_block_updated(
- header, height, broadcaster, fee_estimator, logger)
+ header, height, broadcaster, &bounded_fee_estimator, logger)
}
/// Returns the set of txids that should be monitored for re-organization out of the chain.
/// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
/// commitment_tx_infos which contain the payment hash have been revoked.
- fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage, broadcaster: &B, fee_estimator: &F, logger: &L)
+ fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(
+ &mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage, broadcaster: &B,
+ fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L)
where B::Target: BroadcasterInterface,
F::Target: FeeEstimator,
L::Target: Logger,
},
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
- self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage, broadcaster, fee_estimator, logger)
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
+ self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage, broadcaster, &bounded_fee_estimator, logger)
},
ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
log_trace!(logger, "Updating ChannelMonitor with commitment secret");
let block_hash = header.block_hash();
self.best_block = BestBlock::new(block_hash, height);
- self.transactions_confirmed(header, txdata, height, broadcaster, fee_estimator, logger)
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
+ self.transactions_confirmed(header, txdata, height, broadcaster, &bounded_fee_estimator, logger)
}
fn best_block_updated<B: Deref, F: Deref, L: Deref>(
header: &BlockHeader,
height: u32,
broadcaster: B,
- fee_estimator: F,
+ fee_estimator: &LowerBoundedFeeEstimator<F>,
logger: L,
) -> Vec<TransactionOutputs>
where
txdata: &TransactionData,
height: u32,
broadcaster: B,
- fee_estimator: F,
+ fee_estimator: &LowerBoundedFeeEstimator<F>,
logger: L,
) -> Vec<TransactionOutputs>
where
mut watch_outputs: Vec<TransactionOutputs>,
mut claimable_outpoints: Vec<PackageTemplate>,
broadcaster: &B,
- fee_estimator: &F,
+ fee_estimator: &LowerBoundedFeeEstimator<F>,
logger: &L,
) -> Vec<TransactionOutputs>
where
//- maturing spendable output has transaction paying us has been disconnected
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height < height);
- self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator, logger);
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
+ self.onchain_tx_handler.block_disconnected(height, broadcaster, &bounded_fee_estimator, logger);
self.best_block = BestBlock::new(header.prev_blockhash, height - 1);
}
&mut self,
txid: &Txid,
broadcaster: B,
- fee_estimator: F,
+ fee_estimator: &LowerBoundedFeeEstimator<F>,
logger: L,
) where
B::Target: BroadcasterInterface,
let mut funding_spend_confirmed = None;
let mut htlcs_resolved_on_chain = Some(Vec::new());
let mut funding_spend_seen = Some(false);
+ let mut counterparty_node_id = None;
read_tlv_fields!(reader, {
(1, funding_spend_confirmed, option),
(3, htlcs_resolved_on_chain, vec_type),
(5, pending_monitor_events, vec_type),
(7, funding_spend_seen, option),
+ (9, counterparty_node_id, option),
});
let mut secp_ctx = Secp256k1::new();
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
- Ok((best_block.block_hash(), ChannelMonitor {
- inner: Mutex::new(ChannelMonitorImpl {
- latest_update_id,
- commitment_transaction_number_obscure_factor,
+ Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
+ latest_update_id,
+ commitment_transaction_number_obscure_factor,
- destination_script,
- broadcasted_holder_revokable_script,
- counterparty_payment_script,
- shutdown_script,
+ destination_script,
+ broadcasted_holder_revokable_script,
+ counterparty_payment_script,
+ shutdown_script,
- channel_keys_id,
- holder_revocation_basepoint,
- funding_info,
- current_counterparty_commitment_txid,
- prev_counterparty_commitment_txid,
+ channel_keys_id,
+ holder_revocation_basepoint,
+ funding_info,
+ current_counterparty_commitment_txid,
+ prev_counterparty_commitment_txid,
- counterparty_commitment_params,
- funding_redeemscript,
- channel_value_satoshis,
- their_cur_per_commitment_points,
+ counterparty_commitment_params,
+ funding_redeemscript,
+ channel_value_satoshis,
+ their_cur_per_commitment_points,
- on_holder_tx_csv,
+ on_holder_tx_csv,
- commitment_secrets,
- counterparty_claimable_outpoints,
- counterparty_commitment_txn_on_chain,
- counterparty_hash_commitment_number,
+ commitment_secrets,
+ counterparty_claimable_outpoints,
+ counterparty_commitment_txn_on_chain,
+ counterparty_hash_commitment_number,
- prev_holder_signed_commitment_tx,
- current_holder_commitment_tx,
- current_counterparty_commitment_number,
- current_holder_commitment_number,
+ prev_holder_signed_commitment_tx,
+ current_holder_commitment_tx,
+ current_counterparty_commitment_number,
+ current_holder_commitment_number,
- payment_preimages,
- pending_monitor_events: pending_monitor_events.unwrap(),
- pending_events,
+ payment_preimages,
+ pending_monitor_events: pending_monitor_events.unwrap(),
+ pending_events,
- onchain_events_awaiting_threshold_conf,
- outputs_to_watch,
+ onchain_events_awaiting_threshold_conf,
+ outputs_to_watch,
- onchain_tx_handler,
+ onchain_tx_handler,
- lockdown_from_offchain,
- holder_tx_signed,
- funding_spend_seen: funding_spend_seen.unwrap(),
- funding_spend_confirmed,
- htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
+ lockdown_from_offchain,
+ holder_tx_signed,
+ funding_spend_seen: funding_spend_seen.unwrap(),
+ funding_spend_confirmed,
+ htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
- best_block,
+ best_block,
+ counterparty_node_id,
- secp_ctx,
- }),
- }))
+ secp_ctx,
+ })))
}
}
use hex;
+ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
+
use super::ChannelMonitorUpdateStep;
use ::{check_added_monitors, check_closed_broadcast, check_closed_event, check_spends, get_local_commitment_txn, get_monitor, get_route_and_payment_hash, unwrap_send_err};
use chain::{BestBlock, Confirm};
let secp_ctx = Secp256k1::new();
let logger = Arc::new(TestLogger::new());
let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
- let fee_estimator = Arc::new(TestFeeEstimator { sat_per_kw: Mutex::new(253) });
+ let fee_estimator = TestFeeEstimator { sat_per_kw: Mutex::new(253) };
let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
(OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
&channel_parameters,
Script::new(), 46, 0,
- HolderCommitmentTransaction::dummy(), best_block);
+ HolderCommitmentTransaction::dummy(), best_block, dummy_key);
monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
let dummy_txid = dummy_tx.txid();
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
for &(ref preimage, ref hash) in preimages.iter() {
- monitor.provide_payment_preimage(hash, preimage, &broadcaster, &fee_estimator, &logger);
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
+ monitor.provide_payment_preimage(hash, preimage, &broadcaster, &bounded_fee_estimator, &logger);
}
// Now provide a secret, pruning preimages 10-15