Skip to content

Commit 82c0b28

Browse files
committed
Construct all ChannelMonitor mutexes in the same function
When we add lockorder detection based on mutex construction site rather than mutex instance in the next commit, ChannelMonitor's PartialEq implementation causes spurious failures. This is caused by the lockorder detection logic considering the ChannelMonitor inner mutex to be two distinct mutexes - one when monitors are deserialized and one when monitors are created fresh. Instead, we attempt to tell the lockorder detection logic that they are the same by ensuring they're constructed in the same place - in this case a util method.
1 parent 0627c0c commit 82c0b28

File tree

1 file changed

+91
-84
lines changed

1 file changed

+91
-84
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 91 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,17 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
965965
}
966966

967967
impl<Signer: Sign> ChannelMonitor<Signer> {
968+
/// For lockorder enforcement purposes, we need to have a single site which constructs the
969+
/// `inner` mutex, otherwise cases where we lock two monitors at the same time (eg in our
970+
/// PartialEq implementation) we may decide a lockorder violation has occurred.
971+
///
972+
/// Note that this approach may be somewhat brittle - if this method gets inlined inner mutexes
973+
/// may be considered separate again. In that case we may need to move from considering locks
974+
/// by the instruction pointer to considering locks by the symbol module and line number.
975+
fn construct_monitor(imp: ChannelMonitorImpl<Signer>) -> Self {
976+
ChannelMonitor { inner: Mutex::new(imp) }
977+
}
978+
968979
pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: Signer, shutdown_script: Option<Script>,
969980
on_counterparty_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script),
970981
channel_parameters: &ChannelTransactionParameters,
@@ -1012,60 +1023,58 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
10121023
let mut outputs_to_watch = HashMap::new();
10131024
outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
10141025

1015-
ChannelMonitor {
1016-
inner: Mutex::new(ChannelMonitorImpl {
1017-
latest_update_id: 0,
1018-
commitment_transaction_number_obscure_factor,
1026+
Self::construct_monitor(ChannelMonitorImpl {
1027+
latest_update_id: 0,
1028+
commitment_transaction_number_obscure_factor,
10191029

1020-
destination_script: destination_script.clone(),
1021-
broadcasted_holder_revokable_script: None,
1022-
counterparty_payment_script,
1023-
shutdown_script,
1030+
destination_script: destination_script.clone(),
1031+
broadcasted_holder_revokable_script: None,
1032+
counterparty_payment_script,
1033+
shutdown_script,
10241034

1025-
channel_keys_id,
1026-
holder_revocation_basepoint,
1027-
funding_info,
1028-
current_counterparty_commitment_txid: None,
1029-
prev_counterparty_commitment_txid: None,
1035+
channel_keys_id,
1036+
holder_revocation_basepoint,
1037+
funding_info,
1038+
current_counterparty_commitment_txid: None,
1039+
prev_counterparty_commitment_txid: None,
10301040

1031-
counterparty_commitment_params,
1032-
funding_redeemscript,
1033-
channel_value_satoshis,
1034-
their_cur_per_commitment_points: None,
1041+
counterparty_commitment_params,
1042+
funding_redeemscript,
1043+
channel_value_satoshis,
1044+
their_cur_per_commitment_points: None,
10351045

1036-
on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
1046+
on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
10371047

1038-
commitment_secrets: CounterpartyCommitmentSecrets::new(),
1039-
counterparty_claimable_outpoints: HashMap::new(),
1040-
counterparty_commitment_txn_on_chain: HashMap::new(),
1041-
counterparty_hash_commitment_number: HashMap::new(),
1048+
commitment_secrets: CounterpartyCommitmentSecrets::new(),
1049+
counterparty_claimable_outpoints: HashMap::new(),
1050+
counterparty_commitment_txn_on_chain: HashMap::new(),
1051+
counterparty_hash_commitment_number: HashMap::new(),
10421052

1043-
prev_holder_signed_commitment_tx: None,
1044-
current_holder_commitment_tx: holder_commitment_tx,
1045-
current_counterparty_commitment_number: 1 << 48,
1046-
current_holder_commitment_number,
1053+
prev_holder_signed_commitment_tx: None,
1054+
current_holder_commitment_tx: holder_commitment_tx,
1055+
current_counterparty_commitment_number: 1 << 48,
1056+
current_holder_commitment_number,
10471057

1048-
payment_preimages: HashMap::new(),
1049-
pending_monitor_events: Vec::new(),
1050-
pending_events: Vec::new(),
1058+
payment_preimages: HashMap::new(),
1059+
pending_monitor_events: Vec::new(),
1060+
pending_events: Vec::new(),
10511061

1052-
onchain_events_awaiting_threshold_conf: Vec::new(),
1053-
outputs_to_watch,
1062+
onchain_events_awaiting_threshold_conf: Vec::new(),
1063+
outputs_to_watch,
10541064

1055-
onchain_tx_handler,
1065+
onchain_tx_handler,
10561066

1057-
lockdown_from_offchain: false,
1058-
holder_tx_signed: false,
1059-
funding_spend_seen: false,
1060-
funding_spend_confirmed: None,
1061-
htlcs_resolved_on_chain: Vec::new(),
1067+
lockdown_from_offchain: false,
1068+
holder_tx_signed: false,
1069+
funding_spend_seen: false,
1070+
funding_spend_confirmed: None,
1071+
htlcs_resolved_on_chain: Vec::new(),
10621072

1063-
best_block,
1064-
counterparty_node_id: Some(counterparty_node_id),
1073+
best_block,
1074+
counterparty_node_id: Some(counterparty_node_id),
10651075

1066-
secp_ctx,
1067-
}),
1068-
}
1076+
secp_ctx,
1077+
})
10691078
}
10701079

10711080
#[cfg(test)]
@@ -3361,60 +3370,58 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
33613370
let mut secp_ctx = Secp256k1::new();
33623371
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
33633372

3364-
Ok((best_block.block_hash(), ChannelMonitor {
3365-
inner: Mutex::new(ChannelMonitorImpl {
3366-
latest_update_id,
3367-
commitment_transaction_number_obscure_factor,
3373+
Ok((best_block.block_hash(), ChannelMonitor::construct_monitor(ChannelMonitorImpl {
3374+
latest_update_id,
3375+
commitment_transaction_number_obscure_factor,
33683376

3369-
destination_script,
3370-
broadcasted_holder_revokable_script,
3371-
counterparty_payment_script,
3372-
shutdown_script,
3377+
destination_script,
3378+
broadcasted_holder_revokable_script,
3379+
counterparty_payment_script,
3380+
shutdown_script,
33733381

3374-
channel_keys_id,
3375-
holder_revocation_basepoint,
3376-
funding_info,
3377-
current_counterparty_commitment_txid,
3378-
prev_counterparty_commitment_txid,
3382+
channel_keys_id,
3383+
holder_revocation_basepoint,
3384+
funding_info,
3385+
current_counterparty_commitment_txid,
3386+
prev_counterparty_commitment_txid,
33793387

3380-
counterparty_commitment_params,
3381-
funding_redeemscript,
3382-
channel_value_satoshis,
3383-
their_cur_per_commitment_points,
3388+
counterparty_commitment_params,
3389+
funding_redeemscript,
3390+
channel_value_satoshis,
3391+
their_cur_per_commitment_points,
33843392

3385-
on_holder_tx_csv,
3393+
on_holder_tx_csv,
33863394

3387-
commitment_secrets,
3388-
counterparty_claimable_outpoints,
3389-
counterparty_commitment_txn_on_chain,
3390-
counterparty_hash_commitment_number,
3395+
commitment_secrets,
3396+
counterparty_claimable_outpoints,
3397+
counterparty_commitment_txn_on_chain,
3398+
counterparty_hash_commitment_number,
33913399

3392-
prev_holder_signed_commitment_tx,
3393-
current_holder_commitment_tx,
3394-
current_counterparty_commitment_number,
3395-
current_holder_commitment_number,
3400+
prev_holder_signed_commitment_tx,
3401+
current_holder_commitment_tx,
3402+
current_counterparty_commitment_number,
3403+
current_holder_commitment_number,
33963404

3397-
payment_preimages,
3398-
pending_monitor_events: pending_monitor_events.unwrap(),
3399-
pending_events,
3405+
payment_preimages,
3406+
pending_monitor_events: pending_monitor_events.unwrap(),
3407+
pending_events,
34003408

3401-
onchain_events_awaiting_threshold_conf,
3402-
outputs_to_watch,
3409+
onchain_events_awaiting_threshold_conf,
3410+
outputs_to_watch,
34033411

3404-
onchain_tx_handler,
3412+
onchain_tx_handler,
34053413

3406-
lockdown_from_offchain,
3407-
holder_tx_signed,
3408-
funding_spend_seen: funding_spend_seen.unwrap(),
3409-
funding_spend_confirmed,
3410-
htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
3414+
lockdown_from_offchain,
3415+
holder_tx_signed,
3416+
funding_spend_seen: funding_spend_seen.unwrap(),
3417+
funding_spend_confirmed,
3418+
htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
34113419

3412-
best_block,
3413-
counterparty_node_id,
3420+
best_block,
3421+
counterparty_node_id,
34143422

3415-
secp_ctx,
3416-
}),
3417-
}))
3423+
secp_ctx,
3424+
})))
34183425
}
34193426
}
34203427

0 commit comments

Comments
 (0)