Skip to content

Commit d3cd080

Browse files
authored
Merge pull request #3059 from jkczyz/2024-05-drop-writeable-signer
Remove `WriteableEcdsaChannelSigner` trait
2 parents 0ffa4b3 + efc7579 commit d3cd080

File tree

13 files changed

+65
-84
lines changed

13 files changed

+65
-84
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
3232
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, WithChannelMonitor};
3333
use crate::chain::transaction::{OutPoint, TransactionData};
3434
use crate::ln::types::ChannelId;
35-
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
35+
use crate::sign::ecdsa::EcdsaChannelSigner;
3636
use crate::events;
3737
use crate::events::{Event, EventHandler};
3838
use crate::util::logger::{Logger, WithContext};
@@ -101,7 +101,7 @@ use bitcoin::secp256k1::PublicKey;
101101
///
102102
/// [`TrustedCommitmentTransaction::revokeable_output_index`]: crate::ln::chan_utils::TrustedCommitmentTransaction::revokeable_output_index
103103
/// [`TrustedCommitmentTransaction::build_to_local_justice_tx`]: crate::ln::chan_utils::TrustedCommitmentTransaction::build_to_local_justice_tx
104-
pub trait Persist<ChannelSigner: WriteableEcdsaChannelSigner> {
104+
pub trait Persist<ChannelSigner: EcdsaChannelSigner> {
105105
/// Persist a new channel's data in response to a [`chain::Watch::watch_channel`] call. This is
106106
/// called by [`ChannelManager`] for new channels, or may be called directly, e.g. on startup.
107107
///
@@ -163,7 +163,7 @@ pub trait Persist<ChannelSigner: WriteableEcdsaChannelSigner> {
163163
fn archive_persisted_channel(&self, channel_funding_outpoint: OutPoint);
164164
}
165165

166-
struct MonitorHolder<ChannelSigner: WriteableEcdsaChannelSigner> {
166+
struct MonitorHolder<ChannelSigner: EcdsaChannelSigner> {
167167
monitor: ChannelMonitor<ChannelSigner>,
168168
/// The full set of pending monitor updates for this Channel.
169169
///
@@ -174,7 +174,7 @@ struct MonitorHolder<ChannelSigner: WriteableEcdsaChannelSigner> {
174174
pending_monitor_updates: Mutex<Vec<u64>>,
175175
}
176176

177-
impl<ChannelSigner: WriteableEcdsaChannelSigner> MonitorHolder<ChannelSigner> {
177+
impl<ChannelSigner: EcdsaChannelSigner> MonitorHolder<ChannelSigner> {
178178
fn has_pending_updates(&self, pending_monitor_updates_lock: &MutexGuard<Vec<u64>>) -> bool {
179179
!pending_monitor_updates_lock.is_empty()
180180
}
@@ -184,12 +184,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> MonitorHolder<ChannelSigner> {
184184
///
185185
/// Note that this holds a mutex in [`ChainMonitor`] and may block other events until it is
186186
/// released.
187-
pub struct LockedChannelMonitor<'a, ChannelSigner: WriteableEcdsaChannelSigner> {
187+
pub struct LockedChannelMonitor<'a, ChannelSigner: EcdsaChannelSigner> {
188188
lock: RwLockReadGuard<'a, HashMap<OutPoint, MonitorHolder<ChannelSigner>>>,
189189
funding_txo: OutPoint,
190190
}
191191

192-
impl<ChannelSigner: WriteableEcdsaChannelSigner> Deref for LockedChannelMonitor<'_, ChannelSigner> {
192+
impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, ChannelSigner> {
193193
type Target = ChannelMonitor<ChannelSigner>;
194194
fn deref(&self) -> &ChannelMonitor<ChannelSigner> {
195195
&self.lock.get(&self.funding_txo).expect("Checked at construction").monitor
@@ -212,7 +212,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> Deref for LockedChannelMonitor<
212212
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
213213
/// [module-level documentation]: crate::chain::chainmonitor
214214
/// [`rebroadcast_pending_claims`]: Self::rebroadcast_pending_claims
215-
pub struct ChainMonitor<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
215+
pub struct ChainMonitor<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
216216
where C::Target: chain::Filter,
217217
T::Target: BroadcasterInterface,
218218
F::Target: FeeEstimator,
@@ -236,7 +236,7 @@ pub struct ChainMonitor<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T:
236236
event_notifier: Notifier,
237237
}
238238

239-
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> ChainMonitor<ChannelSigner, C, T, F, L, P>
239+
impl<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> ChainMonitor<ChannelSigner, C, T, F, L, P>
240240
where C::Target: chain::Filter,
241241
T::Target: BroadcasterInterface,
242242
F::Target: FeeEstimator,
@@ -623,7 +623,7 @@ where C::Target: chain::Filter,
623623
}
624624
}
625625

626-
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
626+
impl<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
627627
chain::Listen for ChainMonitor<ChannelSigner, C, T, F, L, P>
628628
where
629629
C::Target: chain::Filter,
@@ -652,7 +652,7 @@ where
652652
}
653653
}
654654

655-
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
655+
impl<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>
656656
chain::Confirm for ChainMonitor<ChannelSigner, C, T, F, L, P>
657657
where
658658
C::Target: chain::Filter,
@@ -706,7 +706,7 @@ where
706706
}
707707
}
708708

709-
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref , T: Deref , F: Deref , L: Deref , P: Deref >
709+
impl<ChannelSigner: EcdsaChannelSigner, C: Deref , T: Deref , F: Deref , L: Deref , P: Deref >
710710
chain::Watch<ChannelSigner> for ChainMonitor<ChannelSigner, C, T, F, L, P>
711711
where C::Target: chain::Filter,
712712
T::Target: BroadcasterInterface,
@@ -841,7 +841,7 @@ where C::Target: chain::Filter,
841841
}
842842
}
843843

844-
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> events::EventsProvider for ChainMonitor<ChannelSigner, C, T, F, L, P>
844+
impl<ChannelSigner: EcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> events::EventsProvider for ChainMonitor<ChannelSigner, C, T, F, L, P>
845845
where C::Target: chain::Filter,
846846
T::Target: BroadcasterInterface,
847847
F::Target: FeeEstimator,

lightning/src/chain/channelmonitor.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::chain;
4343
use crate::chain::{BestBlock, WatchedOutput};
4444
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
4545
use crate::chain::transaction::{OutPoint, TransactionData};
46-
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, ecdsa::WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
46+
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, ecdsa::EcdsaChannelSigner, SignerProvider, EntropySource};
4747
use crate::chain::onchaintx::{ClaimEvent, FeerateStrategy, OnchainTxHandler};
4848
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
4949
use crate::chain::Filter;
@@ -774,22 +774,22 @@ impl Readable for IrrevocablyResolvedHTLC {
774774
/// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
775775
/// returned block hash and the the current chain and then reconnecting blocks to get to the
776776
/// best chain) upon deserializing the object!
777-
pub struct ChannelMonitor<Signer: WriteableEcdsaChannelSigner> {
777+
pub struct ChannelMonitor<Signer: EcdsaChannelSigner> {
778778
#[cfg(test)]
779779
pub(crate) inner: Mutex<ChannelMonitorImpl<Signer>>,
780780
#[cfg(not(test))]
781781
pub(super) inner: Mutex<ChannelMonitorImpl<Signer>>,
782782
}
783783

784-
impl<Signer: WriteableEcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer: Clone {
784+
impl<Signer: EcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer: Clone {
785785
fn clone(&self) -> Self {
786786
let inner = self.inner.lock().unwrap().clone();
787787
ChannelMonitor::from_impl(inner)
788788
}
789789
}
790790

791791
#[derive(Clone, PartialEq)]
792-
pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
792+
pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
793793
latest_update_id: u64,
794794
commitment_transaction_number_obscure_factor: u64,
795795

@@ -943,7 +943,7 @@ pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
943943
/// Transaction outputs to watch for on-chain spends.
944944
pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
945945

946-
impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> where Signer: PartialEq {
946+
impl<Signer: EcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> where Signer: PartialEq {
947947
fn eq(&self, other: &Self) -> bool {
948948
// We need some kind of total lockorder. Absent a better idea, we sort by position in
949949
// memory and take locks in that order (assuming that we can't move within memory while a
@@ -955,7 +955,7 @@ impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> w
955955
}
956956
}
957957

958-
impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitor<Signer> {
958+
impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitor<Signer> {
959959
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
960960
self.inner.lock().unwrap().write(writer)
961961
}
@@ -965,7 +965,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitor<Signer> {
965965
const SERIALIZATION_VERSION: u8 = 1;
966966
const MIN_SERIALIZATION_VERSION: u8 = 1;
967967

968-
impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
968+
impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
969969
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
970970
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
971971

@@ -1208,11 +1208,11 @@ impl<'a, L: Deref> Logger for WithChannelMonitor<'a, L> where L::Target: Logger
12081208
}
12091209

12101210
impl<'a, L: Deref> WithChannelMonitor<'a, L> where L::Target: Logger {
1211-
pub(crate) fn from<S: WriteableEcdsaChannelSigner>(logger: &'a L, monitor: &ChannelMonitor<S>, payment_hash: Option<PaymentHash>) -> Self {
1211+
pub(crate) fn from<S: EcdsaChannelSigner>(logger: &'a L, monitor: &ChannelMonitor<S>, payment_hash: Option<PaymentHash>) -> Self {
12121212
Self::from_impl(logger, &*monitor.inner.lock().unwrap(), payment_hash)
12131213
}
12141214

1215-
pub(crate) fn from_impl<S: WriteableEcdsaChannelSigner>(logger: &'a L, monitor_impl: &ChannelMonitorImpl<S>, payment_hash: Option<PaymentHash>) -> Self {
1215+
pub(crate) fn from_impl<S: EcdsaChannelSigner>(logger: &'a L, monitor_impl: &ChannelMonitorImpl<S>, payment_hash: Option<PaymentHash>) -> Self {
12161216
let peer_id = monitor_impl.counterparty_node_id;
12171217
let channel_id = Some(monitor_impl.channel_id());
12181218
WithChannelMonitor {
@@ -1221,7 +1221,7 @@ impl<'a, L: Deref> WithChannelMonitor<'a, L> where L::Target: Logger {
12211221
}
12221222
}
12231223

1224-
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1224+
impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
12251225
/// For lockorder enforcement purposes, we need to have a single site which constructs the
12261226
/// `inner` mutex, otherwise cases where we lock two monitors at the same time (eg in our
12271227
/// PartialEq implementation) we may decide a lockorder violation has occurred.
@@ -1929,7 +1929,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
19291929
}
19301930
}
19311931

1932-
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
1932+
impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
19331933
/// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
19341934
/// to one `Balance` for the HTLC.
19351935
fn get_htlc_balance(&self, htlc: &HTLCOutputInCommitment, holder_commitment: bool,
@@ -2108,7 +2108,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
21082108
}
21092109
}
21102110

2111-
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
2111+
impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
21122112
/// Gets the balances in this channel which are either claimable by us if we were to
21132113
/// force-close the channel now or which are claimable on-chain (possibly awaiting
21142114
/// confirmation).
@@ -2520,7 +2520,7 @@ pub fn deliberately_bogus_accepted_htlc_witness() -> Vec<Vec<u8>> {
25202520
vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into()
25212521
}
25222522

2523-
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2523+
impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
25242524
/// Inserts a revocation secret into this channel monitor. Prunes old preimages if neither
25252525
/// needed by holder commitment transactions HTCLs nor by counterparty ones. Unless we haven't already seen
25262526
/// counterparty commitment transaction's secret, they are de facto pruned (we can use revocation key).
@@ -4429,7 +4429,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
44294429
}
44304430
}
44314431

4432-
impl<Signer: WriteableEcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
4432+
impl<Signer: EcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
44334433
where
44344434
T::Target: BroadcasterInterface,
44354435
F::Target: FeeEstimator,
@@ -4444,7 +4444,7 @@ where
44444444
}
44454445
}
44464446

4447-
impl<Signer: WriteableEcdsaChannelSigner, M, T: Deref, F: Deref, L: Deref> chain::Confirm for (M, T, F, L)
4447+
impl<Signer: EcdsaChannelSigner, M, T: Deref, F: Deref, L: Deref> chain::Confirm for (M, T, F, L)
44484448
where
44494449
M: Deref<Target = ChannelMonitor<Signer>>,
44504450
T::Target: BroadcasterInterface,

lightning/src/chain/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use bitcoin::secp256k1::PublicKey;
1818

1919
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, MonitorEvent};
2020
use crate::ln::types::ChannelId;
21-
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
21+
use crate::sign::ecdsa::EcdsaChannelSigner;
2222
use crate::chain::transaction::{OutPoint, TransactionData};
2323
use crate::impl_writeable_tlv_based;
2424

@@ -257,7 +257,7 @@ pub enum ChannelMonitorUpdateStatus {
257257
/// application crashes.
258258
///
259259
/// See method documentation and [`ChannelMonitorUpdateStatus`] for specific requirements.
260-
pub trait Watch<ChannelSigner: WriteableEcdsaChannelSigner> {
260+
pub trait Watch<ChannelSigner: EcdsaChannelSigner> {
261261
/// Watches a channel identified by `funding_txo` using `monitor`.
262262
///
263263
/// Implementations are responsible for watching the chain for the funding transaction along

lightning/src/chain/onchaintx.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
2323
use bitcoin::secp256k1;
2424

2525
use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight;
26-
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, ecdsa::WriteableEcdsaChannelSigner};
26+
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, ecdsa::EcdsaChannelSigner};
2727
use crate::ln::msgs::DecodeError;
2828
use crate::ln::types::PaymentPreimage;
2929
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
@@ -33,7 +33,7 @@ use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
3333
use crate::chain::package::{PackageSolvingData, PackageTemplate};
3434
use crate::chain::transaction::MaybeSignedTransaction;
3535
use crate::util::logger::Logger;
36-
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
36+
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable};
3737

3838
use crate::io;
3939
use crate::prelude::*;
@@ -225,7 +225,7 @@ pub(crate) enum FeerateStrategy {
225225
/// OnchainTxHandler receives claiming requests, aggregates them if it's sound, broadcast and
226226
/// do RBF bumping if possible.
227227
#[derive(Clone)]
228-
pub struct OnchainTxHandler<ChannelSigner: WriteableEcdsaChannelSigner> {
228+
pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
229229
channel_value_satoshis: u64,
230230
channel_keys_id: [u8; 32],
231231
destination_script: ScriptBuf,
@@ -281,7 +281,7 @@ pub struct OnchainTxHandler<ChannelSigner: WriteableEcdsaChannelSigner> {
281281
pub(super) secp_ctx: Secp256k1<secp256k1::All>,
282282
}
283283

284-
impl<ChannelSigner: WriteableEcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
284+
impl<ChannelSigner: EcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
285285
fn eq(&self, other: &Self) -> bool {
286286
// `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
287287
self.channel_value_satoshis == other.channel_value_satoshis &&
@@ -300,7 +300,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> PartialEq for OnchainTxHandler<
300300
const SERIALIZATION_VERSION: u8 = 1;
301301
const MIN_SERIALIZATION_VERSION: u8 = 1;
302302

303-
impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
303+
impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
304304
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
305305
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
306306

@@ -312,12 +312,9 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
312312

313313
self.channel_transaction_parameters.write(writer)?;
314314

315-
let mut key_data = VecWriter(Vec::new());
316-
self.signer.write(&mut key_data)?;
317-
assert!(key_data.0.len() < core::usize::MAX);
318-
assert!(key_data.0.len() < core::u32::MAX as usize);
319-
(key_data.0.len() as u32).write(writer)?;
320-
writer.write_all(&key_data.0[..])?;
315+
// Write a zero-length signer. The data is no longer deserialized as of version 0.0.113 and
316+
// downgrades before version 0.0.113 are no longer supported as of version 0.0.119.
317+
0u32.write(writer)?;
321318

322319
writer.write_all(&(self.pending_claim_requests.len() as u64).to_be_bytes())?;
323320
for (ref ancestor_claim_txid, request) in self.pending_claim_requests.iter() {
@@ -443,7 +440,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
443440
}
444441
}
445442

446-
impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
443+
impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
447444
pub(crate) fn new(
448445
channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: ScriptBuf,
449446
signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,

0 commit comments

Comments
 (0)