Skip to content

Commit 269fd07

Browse files
committed
Revocation enforcement in signer
We want to make sure that we don't sign revoked transactions. Given that ChannelKeys are not singletons and revocation enforcement is stateful, we need to store the revocation state in KeysInterface.
1 parent 70bb3b3 commit 269fd07

File tree

4 files changed

+94
-44
lines changed

4 files changed

+94
-44
lines changed

lightning/src/ln/functional_tests.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,27 +1616,26 @@ fn test_fee_spike_violation_fails_htlc() {
16161616

16171617
// Get the EnforcingChannelKeys for each channel, which will be used to (1) get the keys
16181618
// needed to sign the new commitment tx and (2) sign the new commitment tx.
1619-
let (local_revocation_basepoint, local_htlc_basepoint, local_secret, local_secret2) = {
1619+
let (local_revocation_basepoint, local_htlc_basepoint, local_secret, next_local_point) = {
16201620
let chan_lock = nodes[0].node.channel_state.lock().unwrap();
16211621
let local_chan = chan_lock.by_id.get(&chan.2).unwrap();
16221622
let chan_keys = local_chan.get_keys();
16231623
let pubkeys = chan_keys.pubkeys();
16241624
(pubkeys.revocation_basepoint, pubkeys.htlc_basepoint,
1625-
chan_keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER), chan_keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 2))
1625+
chan_keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER),
1626+
chan_keys.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 2, &secp_ctx))
16261627
};
1627-
let (remote_delayed_payment_basepoint, remote_htlc_basepoint, remote_secret1) = {
1628+
let (remote_delayed_payment_basepoint, remote_htlc_basepoint,remote_point) = {
16281629
let chan_lock = nodes[1].node.channel_state.lock().unwrap();
16291630
let remote_chan = chan_lock.by_id.get(&chan.2).unwrap();
16301631
let chan_keys = remote_chan.get_keys();
16311632
let pubkeys = chan_keys.pubkeys();
16321633
(pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint,
1633-
chan_keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 1))
1634+
chan_keys.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &secp_ctx))
16341635
};
16351636

16361637
// Assemble the set of keys we can use for signatures for our commitment_signed message.
1637-
let commitment_secret = SecretKey::from_slice(&remote_secret1).unwrap();
1638-
let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &commitment_secret);
1639-
let commit_tx_keys = chan_utils::TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, &remote_delayed_payment_basepoint,
1638+
let commit_tx_keys = chan_utils::TxCreationKeys::derive_new(&secp_ctx, &remote_point, &remote_delayed_payment_basepoint,
16401639
&remote_htlc_basepoint, &local_revocation_basepoint, &local_htlc_basepoint).unwrap();
16411640

16421641
// Build the remote commitment transaction so we can sign it, and then later use the
@@ -1680,10 +1679,11 @@ fn test_fee_spike_violation_fails_htlc() {
16801679
let _ = nodes[1].node.get_and_clear_pending_msg_events();
16811680

16821681
// Send the RAA to nodes[1].
1683-
let per_commitment_secret = local_secret;
1684-
let next_secret = SecretKey::from_slice(&local_secret2).unwrap();
1685-
let next_per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &next_secret);
1686-
let raa_msg = msgs::RevokeAndACK{ channel_id: chan.2, per_commitment_secret, next_per_commitment_point};
1682+
let raa_msg = msgs::RevokeAndACK {
1683+
channel_id: chan.2,
1684+
per_commitment_secret: local_secret,
1685+
next_per_commitment_point: next_local_point
1686+
};
16871687
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &raa_msg);
16881688

16891689
let events = nodes[1].node.get_and_clear_pending_msg_events();
@@ -4269,7 +4269,6 @@ fn test_no_txn_manager_serialize_deserialize() {
42694269
let fee_estimator: test_utils::TestFeeEstimator;
42704270
let persister: test_utils::TestPersister;
42714271
let new_chain_monitor: test_utils::TestChainMonitor;
4272-
let keys_manager: test_utils::TestKeysInterface;
42734272
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
42744273
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
42754274

@@ -4284,12 +4283,12 @@ fn test_no_txn_manager_serialize_deserialize() {
42844283
logger = test_utils::TestLogger::new();
42854284
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
42864285
persister = test_utils::TestPersister::new();
4287-
keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
4288-
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, &keys_manager);
4286+
let keys_manager = &chanmon_cfgs[0].keys_manager;
4287+
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
42894288
nodes[0].chain_monitor = &new_chain_monitor;
42904289
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
42914290
let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
4292-
&mut chan_0_monitor_read, &keys_manager).unwrap();
4291+
&mut chan_0_monitor_read, keys_manager).unwrap();
42934292
assert!(chan_0_monitor_read.is_empty());
42944293

42954294
let mut nodes_0_read = &nodes_0_serialized[..];
@@ -4299,7 +4298,7 @@ fn test_no_txn_manager_serialize_deserialize() {
42994298
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
43004299
<(BlockHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
43014300
default_config: config,
4302-
keys_manager: &keys_manager,
4301+
keys_manager,
43034302
fee_estimator: &fee_estimator,
43044303
chain_monitor: nodes[0].chain_monitor,
43054304
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
@@ -4346,7 +4345,6 @@ fn test_manager_serialize_deserialize_events() {
43464345
let persister: test_utils::TestPersister;
43474346
let logger: test_utils::TestLogger;
43484347
let new_chain_monitor: test_utils::TestChainMonitor;
4349-
let keys_manager: test_utils::TestKeysInterface;
43504348
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
43514349
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
43524350

@@ -4355,8 +4353,8 @@ fn test_manager_serialize_deserialize_events() {
43554353
let push_msat = 10001;
43564354
let a_flags = InitFeatures::known();
43574355
let b_flags = InitFeatures::known();
4358-
let node_a = nodes.pop().unwrap();
4359-
let node_b = nodes.pop().unwrap();
4356+
let node_a = nodes.remove(0);
4357+
let node_b = nodes.remove(0);
43604358
node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap();
43614359
node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()));
43624360
node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()));
@@ -4394,12 +4392,12 @@ fn test_manager_serialize_deserialize_events() {
43944392
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
43954393
logger = test_utils::TestLogger::new();
43964394
persister = test_utils::TestPersister::new();
4397-
keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
4398-
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, &keys_manager);
4395+
let keys_manager = &chanmon_cfgs[0].keys_manager;
4396+
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
43994397
nodes[0].chain_monitor = &new_chain_monitor;
44004398
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
44014399
let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(
4402-
&mut chan_0_monitor_read, &keys_manager).unwrap();
4400+
&mut chan_0_monitor_read, keys_manager).unwrap();
44034401
assert!(chan_0_monitor_read.is_empty());
44044402

44054403
let mut nodes_0_read = &nodes_0_serialized[..];
@@ -4409,7 +4407,7 @@ fn test_manager_serialize_deserialize_events() {
44094407
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
44104408
<(BlockHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
44114409
default_config: config,
4412-
keys_manager: &keys_manager,
4410+
keys_manager,
44134411
fee_estimator: &fee_estimator,
44144412
chain_monitor: nodes[0].chain_monitor,
44154413
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
@@ -4470,7 +4468,6 @@ fn test_simple_manager_serialize_deserialize() {
44704468
let fee_estimator: test_utils::TestFeeEstimator;
44714469
let persister: test_utils::TestPersister;
44724470
let new_chain_monitor: test_utils::TestChainMonitor;
4473-
let keys_manager: &test_utils::TestKeysInterface;
44744471
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
44754472
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
44764473
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
@@ -4487,7 +4484,7 @@ fn test_simple_manager_serialize_deserialize() {
44874484
logger = test_utils::TestLogger::new();
44884485
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
44894486
persister = test_utils::TestPersister::new();
4490-
keys_manager = &chanmon_cfgs[0].keys_manager;
4487+
let keys_manager = &chanmon_cfgs[0].keys_manager;
44914488
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
44924489
nodes[0].chain_monitor = &new_chain_monitor;
44934490
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
@@ -4532,7 +4529,6 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
45324529
let fee_estimator: test_utils::TestFeeEstimator;
45334530
let persister: test_utils::TestPersister;
45344531
let new_chain_monitor: test_utils::TestChainMonitor;
4535-
let keys_manager: &test_utils::TestKeysInterface;
45364532
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
45374533
let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
45384534
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
@@ -4568,7 +4564,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
45684564
logger = test_utils::TestLogger::new();
45694565
fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
45704566
persister = test_utils::TestPersister::new();
4571-
keys_manager = &chanmon_cfgs[0].keys_manager;
4567+
let keys_manager = &chanmon_cfgs[0].keys_manager;
45724568
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
45734569
nodes[0].chain_monitor = &new_chain_monitor;
45744570

@@ -7374,8 +7370,10 @@ fn test_user_configurable_csv_delay() {
73747370
fn test_data_loss_protect() {
73757371
// We want to be sure that :
73767372
// * we don't broadcast our Local Commitment Tx in case of fallen behind
7373+
// (but this is not quite true - we broadcast during Drop because chanmon is out of sync with chanmgr)
73777374
// * we close channel in case of detecting other being fallen behind
73787375
// * we are able to claim our own outputs thanks to to_remote being static
7376+
// TODO: this test is incomplete and the data_loss_protect implementation is incomplete - see issue #775
73797377
let persister;
73807378
let logger;
73817379
let fee_estimator;
@@ -8084,9 +8082,11 @@ fn test_counterparty_raa_skip_no_crash() {
80848082
let mut guard = nodes[0].node.channel_state.lock().unwrap();
80858083
let keys = &guard.by_id.get_mut(&channel_id).unwrap().holder_keys;
80868084
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
8085+
let per_commitment_secret = keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER);
8086+
// Must revoke without gaps
8087+
keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 1);
80878088
let next_per_commitment_point = PublicKey::from_secret_key(&Secp256k1::new(),
80888089
&SecretKey::from_slice(&keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 2)).unwrap());
8089-
let per_commitment_secret = keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER);
80908090

80918091
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(),
80928092
&msgs::RevokeAndACK { channel_id, per_commitment_secret, next_per_commitment_point });

lightning/src/ln/onchaintx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
955955
#[cfg(any(test, feature="unsafe_revoked_tx_signing"))]
956956
pub(crate) fn get_fully_signed_copy_holder_tx(&mut self, funding_redeemscript: &Script) -> Option<Transaction> {
957957
if let Some(ref mut holder_commitment) = self.holder_commitment {
958-
match self.key_storage.sign_holder_commitment(holder_commitment, &self.secp_ctx) {
958+
match self.key_storage.unsafe_sign_holder_commitment(holder_commitment, &self.secp_ctx) {
959959
Ok(sig) => {
960960
Some(holder_commitment.add_holder_sig(funding_redeemscript, sig))
961961
},

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,34 @@ use util::ser::{Writeable, Writer, Readable};
2424
use std::io::Error;
2525
use ln::msgs::DecodeError;
2626

27+
/// Initial value for revoked commitment downward counter
28+
pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
29+
2730
/// An implementation of ChannelKeys that enforces some policy checks.
2831
///
2932
/// Eventually we will probably want to expose a variant of this which would essentially
3033
/// be what you'd want to run on a hardware wallet.
3134
#[derive(Clone)]
3235
pub struct EnforcingChannelKeys {
3336
pub inner: InMemoryChannelKeys,
34-
last_commitment_number: Arc<Mutex<Option<u64>>>,
37+
pub(crate) last_commitment_number: Arc<Mutex<Option<u64>>>,
38+
pub(crate) revoked_commitment: Arc<Mutex<u64>>,
3539
}
3640

3741
impl EnforcingChannelKeys {
3842
pub fn new(inner: InMemoryChannelKeys) -> Self {
3943
Self {
4044
inner,
4145
last_commitment_number: Arc::new(Mutex::new(None)),
46+
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER))
47+
}
48+
}
49+
50+
pub fn new_with_revoked(inner: InMemoryChannelKeys, revoked_commitment: Arc<Mutex<u64>>) -> Self {
51+
Self {
52+
inner,
53+
last_commitment_number: Arc::new(Mutex::new(None)),
54+
revoked_commitment
4255
}
4356
}
4457
}
@@ -49,7 +62,11 @@ impl ChannelKeys for EnforcingChannelKeys {
4962
}
5063

5164
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
52-
// TODO: enforce the ChannelKeys contract - error here if we already signed this commitment
65+
{
66+
let mut revoked = self.revoked_commitment.lock().unwrap();
67+
assert!(idx == *revoked || idx == *revoked - 1, "can only revoke the current or next unrevoked commitment - trying {}, revoked {}", idx, *revoked);
68+
*revoked = idx;
69+
}
5370
self.inner.release_commitment_secret(idx)
5471
}
5572

@@ -72,12 +89,17 @@ impl ChannelKeys for EnforcingChannelKeys {
7289
Ok(self.inner.sign_counterparty_commitment(commitment_tx, secp_ctx).unwrap())
7390
}
7491

75-
fn sign_holder_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
76-
self.verify_holder_commitment_tx(commitment_tx, secp_ctx);
92+
fn sign_holder_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, holder_commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
93+
let trusted_tx = self.verify_holder_commitment_tx(holder_commitment_tx, secp_ctx);
7794

78-
// TODO: enforce the ChannelKeys contract - error if this commitment was already revoked
79-
// TODO: need the commitment number
80-
Ok(self.inner.sign_holder_commitment(commitment_tx, secp_ctx).unwrap())
95+
let revoked = self.revoked_commitment.lock().unwrap();
96+
let commitment_number = trusted_tx.commitment_number();
97+
if *revoked - 1 != commitment_number && *revoked - 2 != commitment_number {
98+
println!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
99+
*revoked, commitment_number, self.inner.commitment_seed[0]);
100+
return Err(());
101+
}
102+
Ok(self.inner.sign_holder_commitment(holder_commitment_tx, secp_ctx).unwrap())
81103
}
82104

83105
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
@@ -137,11 +159,12 @@ impl Writeable for EnforcingChannelKeys {
137159

138160
impl Readable for EnforcingChannelKeys {
139161
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
140-
let inner = Readable::read(reader)?;
162+
let inner: InMemoryChannelKeys = Readable::read(reader)?;
141163
let last_commitment_number = Readable::read(reader)?;
142164
Ok(EnforcingChannelKeys {
143165
inner,
144-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number))
166+
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
167+
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
145168
})
146169
}
147170
}

0 commit comments

Comments
 (0)