Skip to content

Commit 3b76c77

Browse files
authored
Merge pull request #419 from TheBlueMatt/2019-12-simple-signer-api-step
Few more simple signer API additions
2 parents edab29e + 4ebe64f commit 3b76c77

File tree

5 files changed

+105
-33
lines changed

5 files changed

+105
-33
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ use bitcoin_hashes::sha256d::Hash as Sha256d;
2424
use lightning::chain::chaininterface;
2525
use lightning::chain::transaction::OutPoint;
2626
use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
27-
use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface};
27+
use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
2828
use lightning::ln::channelmonitor;
2929
use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate};
3030
use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, ChannelManagerReadArgs};
3131
use lightning::ln::router::{Route, RouteHop};
3232
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, LightningError, UpdateAddHTLC, LocalFeatures};
33+
use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
3334
use lightning::util::events;
3435
use lightning::util::logger::Logger;
3536
use lightning::util::config::UserConfig;
@@ -130,7 +131,7 @@ struct KeyProvider {
130131
channel_id: atomic::AtomicU8,
131132
}
132133
impl KeysInterface for KeyProvider {
133-
type ChanKeySigner = InMemoryChannelKeys;
134+
type ChanKeySigner = EnforcingChannelKeys;
134135

135136
fn get_node_secret(&self) -> SecretKey {
136137
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id]).unwrap()
@@ -148,15 +149,15 @@ impl KeysInterface for KeyProvider {
148149
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_id]).unwrap())
149150
}
150151

151-
fn get_channel_keys(&self, _inbound: bool) -> InMemoryChannelKeys {
152-
InMemoryChannelKeys {
152+
fn get_channel_keys(&self, _inbound: bool) -> EnforcingChannelKeys {
153+
EnforcingChannelKeys::new(InMemoryChannelKeys {
153154
funding_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_id]).unwrap(),
154155
revocation_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(),
155156
payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, self.node_id]).unwrap(),
156157
delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, self.node_id]).unwrap(),
157158
htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
158159
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
159-
}
160+
})
160161
}
161162

162163
fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) {
@@ -225,7 +226,7 @@ pub fn do_test(data: &[u8]) {
225226
channel_monitors: &monitor_refs,
226227
};
227228

228-
let res = (<(Sha256d, ChannelManager<InMemoryChannelKeys>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
229+
let res = (<(Sha256d, ChannelManager<EnforcingChannelKeys>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
229230
for (_, was_good) in $old_monitors.latest_updates_good_at_last_ser.lock().unwrap().iter() {
230231
if !was_good {
231232
// If the last time we updated a monitor we didn't successfully update (and we

fuzz/src/full_stack.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage
2626
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
2727
use lightning::ln::router::Router;
2828
use lightning::util::events::{EventsProvider,Event};
29+
use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
2930
use lightning::util::logger::Logger;
3031
use lightning::util::config::UserConfig;
3132

@@ -135,7 +136,7 @@ impl<'a> Hash for Peer<'a> {
135136
}
136137

137138
struct MoneyLossDetector<'a, 'b> {
138-
manager: Arc<ChannelManager<'b, InMemoryChannelKeys>>,
139+
manager: Arc<ChannelManager<'b, EnforcingChannelKeys>>,
139140
monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>,
140141
handler: PeerManager<Peer<'a>>,
141142

@@ -148,7 +149,7 @@ struct MoneyLossDetector<'a, 'b> {
148149
blocks_connected: u32,
149150
}
150151
impl<'a, 'b> MoneyLossDetector<'a, 'b> {
151-
pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc<ChannelManager<'b, InMemoryChannelKeys>>, monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>, handler: PeerManager<Peer<'a>>) -> Self {
152+
pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc<ChannelManager<'b, EnforcingChannelKeys>>, monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>, handler: PeerManager<Peer<'a>>) -> Self {
152153
MoneyLossDetector {
153154
manager,
154155
monitor,
@@ -228,7 +229,7 @@ struct KeyProvider {
228229
counter: AtomicU64,
229230
}
230231
impl KeysInterface for KeyProvider {
231-
type ChanKeySigner = InMemoryChannelKeys;
232+
type ChanKeySigner = EnforcingChannelKeys;
232233

233234
fn get_node_secret(&self) -> SecretKey {
234235
self.node_secret.clone()
@@ -246,9 +247,9 @@ impl KeysInterface for KeyProvider {
246247
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap())
247248
}
248249

249-
fn get_channel_keys(&self, inbound: bool) -> InMemoryChannelKeys {
250+
fn get_channel_keys(&self, inbound: bool) -> EnforcingChannelKeys {
250251
let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
251-
if inbound {
252+
EnforcingChannelKeys::new(if inbound {
252253
InMemoryChannelKeys {
253254
funding_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr]).unwrap(),
254255
revocation_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr]).unwrap(),
@@ -266,7 +267,7 @@ impl KeysInterface for KeyProvider {
266267
htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(),
267268
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr],
268269
}
269-
}
270+
})
270271
}
271272

272273
fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) {

lightning/src/chain/keysinterface.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use bitcoin::util::bip143;
1212
use bitcoin_hashes::{Hash, HashEngine};
1313
use bitcoin_hashes::sha256::HashEngine as Sha256State;
1414
use bitcoin_hashes::sha256::Hash as Sha256;
15+
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
1516
use bitcoin_hashes::hash160::Hash as Hash160;
1617

1718
use secp256k1::key::{SecretKey, PublicKey};
@@ -20,9 +21,11 @@ use secp256k1;
2021

2122
use util::byte_utils;
2223
use util::logger::Logger;
24+
use util::ser::Writeable;
2325

2426
use ln::chan_utils;
2527
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment};
28+
use ln::msgs;
2629

2730
use std::sync::Arc;
2831
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -139,7 +142,21 @@ pub trait ChannelKeys : Send {
139142
/// TODO: Document the things someone using this interface should enforce before signing.
140143
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
141144
/// making the callee generate it via some util function we expose)!
142-
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_script: &Script, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
145+
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, absolute_fee: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
146+
147+
/// Create a signature for a (proposed) closing transaction.
148+
///
149+
/// Note that, due to rounding, there may be one "missing" satoshi, and either party may have
150+
/// chosen to forgo their output as dust.
151+
fn sign_closing_transaction<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
152+
153+
/// Signs a channel announcement message with our funding key, proving it comes from one
154+
/// of the channel participants.
155+
///
156+
/// Note that if this fails or is rejected, the channel will not be publicly announced and
157+
/// our counterparty may (though likely will not) close the channel on us for violating the
158+
/// protocol.
159+
fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
143160
}
144161

145162
#[derive(Clone)]
@@ -167,10 +184,9 @@ impl ChannelKeys for InMemoryChannelKeys {
167184
fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key }
168185
fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed }
169186

170-
171-
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_script: &Script, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
187+
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
172188
if commitment_tx.input.len() != 1 { return Err(()); }
173-
let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_script, channel_value_satoshis)[..]);
189+
let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, channel_value_satoshis)[..]);
174190
let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key);
175191

176192
let commitment_txid = commitment_tx.txid();
@@ -191,6 +207,21 @@ impl ChannelKeys for InMemoryChannelKeys {
191207

192208
Ok((commitment_sig, htlc_sigs))
193209
}
210+
211+
fn sign_closing_transaction<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
212+
if closing_tx.input.len() != 1 { return Err(()); }
213+
if closing_tx.input[0].witness.len() != 0 { return Err(()); }
214+
if closing_tx.output.len() > 2 { return Err(()); }
215+
216+
let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx)
217+
.sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, channel_value_satoshis)[..]);
218+
Ok(secp_ctx.sign(&sighash, &self.funding_key))
219+
}
220+
221+
fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
222+
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
223+
Ok(secp_ctx.sign(&msghash, &self.funding_key))
224+
}
194225
}
195226

196227
impl_writeable!(InMemoryChannelKeys, 0, {

lightning/src/ln/channel.rs

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
303303
#[cfg(not(test))]
304304
last_local_commitment_txn: Vec<Transaction>,
305305

306-
last_sent_closing_fee: Option<(u64, u64)>, // (feerate, fee)
306+
last_sent_closing_fee: Option<(u64, u64, Signature)>, // (feerate, fee, our_sig)
307307

308308
/// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this
309309
/// to detect unconfirmation after a serialize-unserialize roundtrip where we may not see a full
@@ -2665,14 +2665,16 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
26652665
let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000;
26662666

26672667
let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false);
2668-
let funding_redeemscript = self.get_funding_redeemscript();
2669-
let sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
2668+
let our_sig = self.local_keys
2669+
.sign_closing_transaction(self.channel_value_satoshis, &self.get_funding_redeemscript(), &closing_tx, &self.secp_ctx)
2670+
.ok();
2671+
if our_sig.is_none() { return None; }
26702672

2671-
self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis));
2673+
self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis, our_sig.clone().unwrap()));
26722674
Some(msgs::ClosingSigned {
26732675
channel_id: self.channel_id,
26742676
fee_satoshis: total_fee_satoshis,
2675-
signature: self.secp_ctx.sign(&sighash, &self.local_keys.funding_key()),
2677+
signature: our_sig.unwrap(),
26762678
})
26772679
}
26782680

@@ -2749,6 +2751,28 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27492751
Ok((our_shutdown, self.maybe_propose_first_closing_signed(fee_estimator), dropped_outbound_htlcs))
27502752
}
27512753

2754+
fn build_signed_closing_transaction(&self, tx: &mut Transaction, their_sig: &Signature, our_sig: &Signature) {
2755+
if tx.input.len() != 1 { panic!("Tried to sign closing transaction that had input count != 1!"); }
2756+
if tx.input[0].witness.len() != 0 { panic!("Tried to re-sign closing transaction"); }
2757+
if tx.output.len() > 2 { panic!("Tried to sign bogus closing transaction"); }
2758+
2759+
tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
2760+
2761+
let our_funding_key = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()).serialize();
2762+
let their_funding_key = self.their_funding_pubkey.unwrap().serialize();
2763+
if our_funding_key[..] < their_funding_key[..] {
2764+
tx.input[0].witness.push(our_sig.serialize_der().to_vec());
2765+
tx.input[0].witness.push(their_sig.serialize_der().to_vec());
2766+
} else {
2767+
tx.input[0].witness.push(their_sig.serialize_der().to_vec());
2768+
tx.input[0].witness.push(our_sig.serialize_der().to_vec());
2769+
}
2770+
tx.input[0].witness[1].push(SigHashType::All as u8);
2771+
tx.input[0].witness[2].push(SigHashType::All as u8);
2772+
2773+
tx.input[0].witness.push(self.get_funding_redeemscript().into_bytes());
2774+
}
2775+
27522776
pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option<msgs::ClosingSigned>, Option<Transaction>), ChannelError> {
27532777
if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != BOTH_SIDES_SHUTDOWN_MASK {
27542778
return Err(ChannelError::Close("Remote end sent us a closing_signed before both sides provided a shutdown"));
@@ -2781,9 +2805,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27812805
},
27822806
};
27832807

2784-
if let Some((_, last_fee)) = self.last_sent_closing_fee {
2808+
if let Some((_, last_fee, our_sig)) = self.last_sent_closing_fee {
27852809
if last_fee == msg.fee_satoshis {
2786-
self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
2810+
self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
27872811
self.channel_state = ChannelState::ShutdownComplete as u32;
27882812
self.channel_update_count += 1;
27892813
return Ok((None, Some(closing_tx)));
@@ -2794,9 +2818,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27942818
($new_feerate: expr) => {
27952819
let closing_tx_max_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap());
27962820
let (closing_tx, used_total_fee) = self.build_closing_transaction($new_feerate * closing_tx_max_weight / 1000, false);
2797-
sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
2798-
let our_sig = self.secp_ctx.sign(&sighash, &self.local_keys.funding_key());
2799-
self.last_sent_closing_fee = Some(($new_feerate, used_total_fee));
2821+
let our_sig = self.local_keys
2822+
.sign_closing_transaction(self.channel_value_satoshis, &funding_redeemscript, &closing_tx, &self.secp_ctx)
2823+
.map_err(|_| ChannelError::Close("External signer refused to sign closing transaction"))?;
2824+
self.last_sent_closing_fee = Some(($new_feerate, used_total_fee, our_sig.clone()));
28002825
return Ok((Some(msgs::ClosingSigned {
28012826
channel_id: self.channel_id,
28022827
fee_satoshis: used_total_fee,
@@ -2809,7 +2834,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28092834
if self.channel_outbound {
28102835
let our_max_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
28112836
if proposed_sat_per_kw > our_max_feerate {
2812-
if let Some((last_feerate, _)) = self.last_sent_closing_fee {
2837+
if let Some((last_feerate, _, _)) = self.last_sent_closing_fee {
28132838
if our_max_feerate <= last_feerate {
28142839
return Err(ChannelError::Close("Unable to come to consensus about closing feerate, remote wanted something higher than our Normal feerate"));
28152840
}
@@ -2819,7 +2844,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28192844
} else {
28202845
let our_min_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
28212846
if proposed_sat_per_kw < our_min_feerate {
2822-
if let Some((last_feerate, _)) = self.last_sent_closing_fee {
2847+
if let Some((last_feerate, _, _)) = self.last_sent_closing_fee {
28232848
if our_min_feerate >= last_feerate {
28242849
return Err(ChannelError::Close("Unable to come to consensus about closing feerate, remote wanted something lower than our Background feerate"));
28252850
}
@@ -2828,7 +2853,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
28282853
}
28292854
}
28302855

2831-
let our_sig = self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
2856+
let our_sig = self.local_keys
2857+
.sign_closing_transaction(self.channel_value_satoshis, &funding_redeemscript, &closing_tx, &self.secp_ctx)
2858+
.map_err(|_| ChannelError::Close("External signer refused to sign closing transaction"))?;
2859+
self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
2860+
28322861
self.channel_state = ChannelState::ShutdownComplete as u32;
28332862
self.channel_update_count += 1;
28342863

@@ -3310,8 +3339,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
33103339
excess_data: Vec::new(),
33113340
};
33123341

3313-
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
3314-
let sig = self.secp_ctx.sign(&msghash, self.local_keys.funding_key());
3342+
let sig = self.local_keys.sign_channel_announcement(&msg, &self.secp_ctx)
3343+
.map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement"))?;
33153344

33163345
Ok((msg, sig))
33173346
}
@@ -3855,10 +3884,11 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
38553884
}
38563885

38573886
match self.last_sent_closing_fee {
3858-
Some((feerate, fee)) => {
3887+
Some((feerate, fee, sig)) => {
38593888
1u8.write(writer)?;
38603889
feerate.write(writer)?;
38613890
fee.write(writer)?;
3891+
sig.write(writer)?;
38623892
},
38633893
None => 0u8.write(writer)?,
38643894
}
@@ -4022,7 +4052,7 @@ impl<R : ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
40224052

40234053
let last_sent_closing_fee = match <u8 as Readable<R>>::read(reader)? {
40244054
0 => None,
4025-
1 => Some((Readable::read(reader)?, Readable::read(reader)?)),
4055+
1 => Some((Readable::read(reader)?, Readable::read(reader)?, Readable::read(reader)?)),
40264056
_ => return Err(DecodeError::InvalidValue),
40274057
};
40284058

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys};
2+
use ln::msgs;
23
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};
34

45
use std::cmp;
@@ -50,6 +51,14 @@ impl ChannelKeys for EnforcingChannelKeys {
5051

5152
Ok(self.inner.sign_remote_commitment(channel_value_satoshis, channel_funding_script, feerate_per_kw, commitment_tx, keys, htlcs, to_self_delay, secp_ctx).unwrap())
5253
}
54+
55+
fn sign_closing_transaction<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
56+
Ok(self.inner.sign_closing_transaction(channel_value_satoshis, channel_funding_redeemscript, closing_tx, secp_ctx).unwrap())
57+
}
58+
59+
fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
60+
self.inner.sign_channel_announcement(msg, secp_ctx)
61+
}
5362
}
5463

5564
impl_writeable!(EnforcingChannelKeys, 0, {

0 commit comments

Comments
 (0)