X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fonchaintx.rs;h=bbed782bb57bd0a2e6da0fc4e9ca65ddadde6d5f;hb=65e37fdc2909d9c8bb86ca4872725f9175aefd99;hp=5d44ea640f03ecbef942febb5d9f5536e918953f;hpb=a9d9d266557abccb4ac55aa9fc2ba90ebb755c55;p=rust-lightning diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index 5d44ea64..bbed782b 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -12,10 +12,10 @@ //! OnchainTxHandler objects are fully-part of ChannelMonitor and encapsulates all //! building, tracking, bumping and notifications functions. -use bitcoin::PackedLockTime; +use bitcoin::blockdata::locktime::absolute::LockTime; use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; -use bitcoin::blockdata::script::Script; +use bitcoin::blockdata::script::{Script, ScriptBuf}; use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hash_types::{Txid, BlockHash}; @@ -23,15 +23,13 @@ use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; use bitcoin::secp256k1; use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight; -use crate::events::bump_transaction::{ChannelDerivationParameters, HTLCDescriptor}; -use crate::sign::{ChannelSigner, EntropySource, SignerProvider}; +use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, ecdsa::WriteableEcdsaChannelSigner}; use crate::ln::msgs::DecodeError; use crate::ln::PaymentPreimage; use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction}; use crate::chain::ClaimId; use crate::chain::chaininterface::{ConfirmationTarget, FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator}; use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER}; -use crate::sign::WriteableEcdsaChannelSigner; use crate::chain::package::{PackageSolvingData, PackageTemplate}; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter}; @@ -198,7 +196,7 @@ pub(crate) enum ClaimEvent { BumpHTLC { target_feerate_sat_per_1000_weight: u32, htlcs: Vec, - tx_lock_time: PackedLockTime, + tx_lock_time: LockTime, }, } @@ -218,7 +216,7 @@ pub(crate) enum OnchainClaim { pub struct OnchainTxHandler { channel_value_satoshis: u64, channel_keys_id: [u8; 32], - destination_script: Script, + destination_script: ScriptBuf, holder_commitment: HolderCommitmentTransaction, prev_holder_commitment: Option, @@ -341,7 +339,7 @@ impl OnchainTxHandler } } -impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler { +impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler { fn read(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result { let entropy_source = args.0; let signer_provider = args.1; @@ -435,7 +433,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP impl OnchainTxHandler { pub(crate) fn new( - channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: Script, + channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf, signer: ChannelSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1 ) -> Self { @@ -475,14 +473,13 @@ impl OnchainTxHandler /// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend /// invoking this every 30 seconds, or lower if running in an environment with spotty /// connections, like on mobile. - pub(crate) fn rebroadcast_pending_claims( + pub(super) fn rebroadcast_pending_claims( &mut self, current_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator, logger: &L, ) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, - L::Target: Logger, { let mut bump_requests = Vec::with_capacity(self.pending_claim_requests.len()); for (claim_id, request) in self.pending_claim_requests.iter() { @@ -530,13 +527,11 @@ impl OnchainTxHandler /// /// Panics if there are signing errors, because signing operations in reaction to on-chain /// events are not expected to fail, and if they do, we may lose funds. - fn generate_claim( + fn generate_claim( &mut self, cur_height: u32, cached_request: &PackageTemplate, force_feerate_bump: bool, fee_estimator: &LowerBoundedFeeEstimator, logger: &L, ) -> Option<(u32, u64, OnchainClaim)> - where - F::Target: FeeEstimator, - L::Target: Logger, + where F::Target: FeeEstimator, { let request_outpoints = cached_request.outpoints(); if request_outpoints.is_empty() { @@ -582,7 +577,7 @@ impl OnchainTxHandler if cached_request.is_malleable() { if cached_request.requires_external_funding() { let target_feerate_sat_per_1000_weight = cached_request.compute_package_feerate( - fee_estimator, ConfirmationTarget::HighPriority, force_feerate_bump + fee_estimator, ConfirmationTarget::OnChainSweep, force_feerate_bump ); if let Some(htlcs) = cached_request.construct_malleable_package_with_external_funding(self) { return Some(( @@ -591,7 +586,7 @@ impl OnchainTxHandler OnchainClaim::Event(ClaimEvent::BumpHTLC { target_feerate_sat_per_1000_weight, htlcs, - tx_lock_time: PackedLockTime(cached_request.package_locktime(cur_height)), + tx_lock_time: LockTime::from_consensus(cached_request.package_locktime(cur_height)), }), )); } else { @@ -610,7 +605,7 @@ impl OnchainTxHandler cur_height, self, output_value, self.destination_script.clone(), logger ).unwrap(); log_trace!(logger, "...with timer {} and feerate {}", new_timer, new_feerate); - assert!(predicted_weight >= transaction.weight()); + assert!(predicted_weight >= transaction.weight().to_wu()); return Some((new_timer, new_feerate, OnchainClaim::Tx(transaction))); } } else { @@ -633,13 +628,13 @@ impl OnchainTxHandler debug_assert_eq!(tx.txid(), self.holder_commitment.trust().txid(), "Holder commitment transaction mismatch"); - let conf_target = ConfirmationTarget::HighPriority; + let conf_target = ConfirmationTarget::OnChainSweep; let package_target_feerate_sat_per_1000_weight = cached_request .compute_package_feerate(fee_estimator, conf_target, force_feerate_bump); if let Some(input_amount_sat) = output.funding_amount { let fee_sat = input_amount_sat - tx.output.iter().map(|output| output.value).sum::(); let commitment_tx_feerate_sat_per_1000_weight = - compute_feerate_sat_per_1000_weight(fee_sat, tx.weight() as u64); + compute_feerate_sat_per_1000_weight(fee_sat, tx.weight().to_wu()); if commitment_tx_feerate_sat_per_1000_weight >= package_target_feerate_sat_per_1000_weight { log_debug!(logger, "Pre-signed {} already has feerate {} sat/kW above required {} sat/kW", log_tx!(tx), commitment_tx_feerate_sat_per_1000_weight, @@ -690,13 +685,12 @@ impl OnchainTxHandler /// `conf_height` represents the height at which the request was generated. This /// does not need to equal the current blockchain tip height, which should be provided via /// `cur_height`, however it must never be higher than `cur_height`. - pub(crate) fn update_claims_view_from_requests( + pub(super) fn update_claims_view_from_requests( &mut self, requests: Vec, conf_height: u32, cur_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator, logger: &L ) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, - L::Target: Logger, { log_debug!(logger, "Updating claims view at height {} with {} claim requests", cur_height, requests.len()); let mut preprocessed_requests = Vec::with_capacity(requests.len()); @@ -765,7 +759,7 @@ impl OnchainTxHandler OnchainClaim::Tx(tx) => { log_info!(logger, "Broadcasting onchain {}", log_tx!(tx)); broadcaster.broadcast_transactions(&[&tx]); - ClaimId(tx.txid().into_inner()) + ClaimId(tx.txid().to_byte_array()) }, OnchainClaim::Event(claim_event) => { log_info!(logger, "Yielding onchain event to spend inputs {:?}", req.outpoints()); @@ -773,7 +767,7 @@ impl OnchainTxHandler ClaimEvent::BumpCommitment { ref commitment_tx, .. } => // For commitment claims, we can just use their txid as it should // already be unique. - ClaimId(commitment_tx.txid().into_inner()), + ClaimId(commitment_tx.txid().to_byte_array()), ClaimEvent::BumpHTLC { ref htlcs, .. } => { // For HTLC claims, commit to the entire set of HTLC outputs to // claim, which will always be unique per request. Once a claim ID @@ -781,10 +775,10 @@ impl OnchainTxHandler // underlying set of HTLCs changes. let mut engine = Sha256::engine(); for htlc in htlcs { - engine.input(&htlc.commitment_txid.into_inner()); + engine.input(&htlc.commitment_txid.to_byte_array()); engine.input(&htlc.htlc.transaction_output_index.unwrap().to_be_bytes()); } - ClaimId(Sha256::from_engine(engine).into_inner()) + ClaimId(Sha256::from_engine(engine).to_byte_array()) }, }; debug_assert!(self.pending_claim_requests.get(&claim_id).is_none()); @@ -811,13 +805,12 @@ impl OnchainTxHandler /// `conf_height` represents the height at which the transactions in `txn_matched` were /// confirmed. This does not need to equal the current blockchain tip height, which should be /// provided via `cur_height`, however it must never be higher than `cur_height`. - pub(crate) fn update_claims_view_from_matched_txn( + pub(super) fn update_claims_view_from_matched_txn( &mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash, cur_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator, logger: &L ) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, - L::Target: Logger, { log_debug!(logger, "Updating claims view at height {} with {} matched transactions in block {}", cur_height, txn_matched.len(), conf_height); let mut bump_candidates = HashMap::new(); @@ -979,16 +972,15 @@ impl OnchainTxHandler } } - pub(crate) fn transaction_unconfirmed( + pub(super) fn transaction_unconfirmed( &mut self, txid: &Txid, broadcaster: B, fee_estimator: &LowerBoundedFeeEstimator, - logger: L, + logger: &L, ) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, - L::Target: Logger, { let mut height = None; for entry in self.onchain_events_awaiting_threshold_conf.iter() { @@ -1003,10 +995,9 @@ impl OnchainTxHandler } } - pub(crate) fn block_disconnected(&mut self, height: u32, broadcaster: B, fee_estimator: &LowerBoundedFeeEstimator, logger: L) + pub(super) fn block_disconnected(&mut self, height: u32, broadcaster: B, fee_estimator: &LowerBoundedFeeEstimator, logger: &L) where B::Target: BroadcasterInterface, - F::Target: FeeEstimator, - L::Target: Logger, + F::Target: FeeEstimator, { let mut bump_candidates = HashMap::new(); let onchain_events_awaiting_threshold_conf = @@ -1036,7 +1027,7 @@ impl OnchainTxHandler // `height` is the height being disconnected, so our `current_height` is 1 lower. let current_height = height - 1; if let Some((new_timer, new_feerate, bump_claim)) = self.generate_claim( - current_height, &request, true /* force_feerate_bump */, fee_estimator, &&*logger + current_height, &request, true /* force_feerate_bump */, fee_estimator, logger ) { request.set_timer(new_timer); request.set_feerate(new_feerate); @@ -1078,13 +1069,13 @@ impl OnchainTxHandler self.claimable_outpoints.get(outpoint).is_some() } - pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, Option)> { - let mut txids: Vec<(Txid, Option)> = self.onchain_events_awaiting_threshold_conf + pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option)> { + let mut txids: Vec<(Txid, u32, Option)> = self.onchain_events_awaiting_threshold_conf .iter() - .map(|entry| (entry.txid, entry.block_hash)) + .map(|entry| (entry.txid, entry.height, entry.block_hash)) .collect(); - txids.sort_unstable_by_key(|(txid, _)| *txid); - txids.dedup(); + txids.sort_unstable_by(|a, b| a.0.cmp(&b.0).then(b.1.cmp(&a.1))); + txids.dedup_by_key(|(txid, _, _)| *txid); txids } @@ -1101,13 +1092,13 @@ impl OnchainTxHandler // before providing a initial commitment transaction. For outbound channel, init ChannelMonitor at Channel::funding_signed, there is nothing // to monitor before. pub(crate) fn get_fully_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction { - let (sig, _) = self.signer.sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment"); + let sig = self.signer.sign_holder_commitment(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment"); self.holder_commitment.add_holder_sig(funding_redeemscript, sig) } #[cfg(any(test, feature="unsafe_revoked_tx_signing"))] pub(crate) fn get_fully_signed_copy_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction { - let (sig, _) = self.signer.unsafe_sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("sign holder commitment"); + let sig = self.signer.unsafe_sign_holder_commitment(&self.holder_commitment, &self.secp_ctx).expect("sign holder commitment"); self.holder_commitment.add_holder_sig(funding_redeemscript, sig) }