@@ -594,6 +594,9 @@ pub(crate) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS: usize = 2;
594
594
/// exceeding this age limit will be force-closed and purged from memory.
595
595
pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60;
596
596
597
+ /// Number of blocks needed for an output from a coinbase transaction to be spendable.
598
+ pub(crate) const COINBASE_MATURITY: u32 = 100;
599
+
597
600
struct PendingChannelMonitorUpdate {
598
601
update: ChannelMonitorUpdate,
599
602
}
@@ -4734,12 +4737,14 @@ impl<SP: Deref> Channel<SP> where
4734
4737
return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() });
4735
4738
} else {
4736
4739
if self.context.is_outbound() {
4737
- for input in tx.input.iter() {
4738
- if input.witness.is_empty() {
4739
- // We generated a malleable funding transaction, implying we've
4740
- // just exposed ourselves to funds loss to our counterparty.
4741
- #[cfg(not(fuzzing))]
4742
- panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
4740
+ if !tx.is_coin_base() {
4741
+ for input in tx.input.iter() {
4742
+ if input.witness.is_empty() {
4743
+ // We generated a malleable funding transaction, implying we've
4744
+ // just exposed ourselves to funds loss to our counterparty.
4745
+ #[cfg(not(fuzzing))]
4746
+ panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
4747
+ }
4743
4748
}
4744
4749
}
4745
4750
}
@@ -4750,6 +4755,13 @@ impl<SP: Deref> Channel<SP> where
4750
4755
Err(_) => panic!("Block was bogus - either height was > 16 million, had > 16 million transactions, or had > 65k outputs"),
4751
4756
}
4752
4757
}
4758
+ // If this is a coinbase transaction and not a 0-conf channel
4759
+ // we should update our min_depth to 100 to handle coinbase maturity
4760
+ if tx.is_coin_base() &&
4761
+ self.context.minimum_depth.unwrap_or(0) > 0 &&
4762
+ self.context.minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
4763
+ self.context.minimum_depth = Some(COINBASE_MATURITY);
4764
+ }
4753
4765
}
4754
4766
// If we allow 1-conf funding, we may need to check for channel_ready here and
4755
4767
// send it immediately instead of waiting for a best_block_updated call (which
@@ -5821,6 +5833,15 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
5821
5833
5822
5834
self.context.channel_state = ChannelState::FundingCreated as u32;
5823
5835
self.context.channel_id = funding_txo.to_channel_id();
5836
+
5837
+ // If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
5838
+ // We can skip this if it is a zero-conf channel.
5839
+ if funding_transaction.is_coin_base() &&
5840
+ self.context.minimum_depth.unwrap_or(0) > 0 &&
5841
+ self.context.minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
5842
+ self.context.minimum_depth = Some(COINBASE_MATURITY);
5843
+ }
5844
+
5824
5845
self.context.funding_transaction = Some(funding_transaction);
5825
5846
5826
5847
let channel = Channel {
0 commit comments