@@ -594,6 +594,9 @@ pub(crate) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS: usize = 2;
594594/// exceeding this age limit will be force-closed and purged from memory.
595595pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60;
596596
597+ /// Number of blocks needed for an output from a coinbase transaction to be spendable.
598+ pub(crate) const COINBASE_MATURITY: u32 = 100;
599+
597600struct PendingChannelMonitorUpdate {
598601 update: ChannelMonitorUpdate,
599602}
@@ -4734,12 +4737,14 @@ impl<SP: Deref> Channel<SP> where
47344737 return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() });
47354738 } else {
47364739 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+ }
47434748 }
47444749 }
47454750 }
@@ -4750,6 +4755,13 @@ impl<SP: Deref> Channel<SP> where
47504755 Err(_) => panic!("Block was bogus - either height was > 16 million, had > 16 million transactions, or had > 65k outputs"),
47514756 }
47524757 }
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+ }
47534765 }
47544766 // If we allow 1-conf funding, we may need to check for channel_ready here and
47554767 // 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 {
58215833
58225834 self.context.channel_state = ChannelState::FundingCreated as u32;
58235835 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+
58245845 self.context.funding_transaction = Some(funding_transaction);
58255846
58265847 let channel = Channel {
0 commit comments