Skip to content

Commit 142b0d6

Browse files
committed
Let some tests disable revocation policy check
When simulating a bad actor that broadcasts a revoked tx, the policy check would otherwise panic.
1 parent bd4345d commit 142b0d6

File tree

5 files changed

+54
-25
lines changed

5 files changed

+54
-25
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl KeysInterface for KeyProvider {
182182
(0, 0),
183183
);
184184
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
185-
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment)
185+
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment, false)
186186
}
187187

188188
fn get_secure_random_bytes(&self) -> [u8; 32] {
@@ -202,6 +202,7 @@ impl KeysInterface for KeyProvider {
202202
inner,
203203
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
204204
revoked_commitment,
205+
disable_revocation_policy_check: false,
205206
})
206207
}
207208
}

lightning/src/ln/functional_test_utils.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ pub struct TestChanMonCfg {
9797
pub persister: test_utils::TestPersister,
9898
pub logger: test_utils::TestLogger,
9999
pub keys_manager: test_utils::TestKeysInterface,
100-
101100
}
102101

103102
pub struct NodeCfg<'a> {

lightning/src/ln/functional_tests.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,7 +2470,9 @@ fn test_justice_tx() {
24702470
bob_config.peer_channel_config_limits.force_announced_channel_preference = false;
24712471
bob_config.own_channel_config.our_to_self_delay = 6 * 24 * 3;
24722472
let user_cfgs = [Some(alice_config), Some(bob_config)];
2473-
let chanmon_cfgs = create_chanmon_cfgs(2);
2473+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
2474+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
2475+
chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true;
24742476
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
24752477
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &user_cfgs);
24762478
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -2600,7 +2602,8 @@ fn revoked_output_claim() {
26002602
#[test]
26012603
fn claim_htlc_outputs_shared_tx() {
26022604
// Node revoked old state, htlcs haven't time out yet, claim them in shared justice tx
2603-
let chanmon_cfgs = create_chanmon_cfgs(2);
2605+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
2606+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
26042607
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
26052608
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
26062609
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -2670,7 +2673,8 @@ fn claim_htlc_outputs_shared_tx() {
26702673
#[test]
26712674
fn claim_htlc_outputs_single_tx() {
26722675
// Node revoked old state, htlcs have timed out, claim each of them in separated justice tx
2673-
let chanmon_cfgs = create_chanmon_cfgs(2);
2676+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
2677+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
26742678
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
26752679
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
26762680
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -4993,7 +4997,8 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
49934997

49944998
#[test]
49954999
fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
4996-
let chanmon_cfgs = create_chanmon_cfgs(2);
5000+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
5001+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
49975002
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
49985003
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
49995004
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -5059,7 +5064,8 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
50595064

50605065
#[test]
50615066
fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() {
5062-
let chanmon_cfgs = create_chanmon_cfgs(2);
5067+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
5068+
chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true;
50635069
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
50645070
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
50655071
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -7040,7 +7046,8 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
70407046
// We can have at most two valid local commitment tx, so both cases must be covered, and both txs must be checked to get them all as
70417047
// HTLC could have been removed from lastest local commitment tx but still valid until we get remote RAA
70427048

7043-
let chanmon_cfgs = create_chanmon_cfgs(2);
7049+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
7050+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
70447051
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
70457052
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
70467053
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -7379,7 +7386,10 @@ fn test_data_loss_protect() {
73797386
let fee_estimator;
73807387
let tx_broadcaster;
73817388
let chain_source;
7382-
let chanmon_cfgs = create_chanmon_cfgs(2);
7389+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
7390+
// We broadcast during Drop because chanmon is out of sync with chanmgr, which would cause a panic
7391+
// during signing due to revoked tx
7392+
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
73837393
let keys_manager = &chanmon_cfgs[0].keys_manager;
73847394
let monitor;
73857395
let node_state_0;
@@ -7699,7 +7709,8 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
76997709
// In case of penalty txn with too low feerates for getting into mempools, RBF-bump them to sure
77007710
// we're able to claim outputs on revoked HTLC transactions before timelocks expiration
77017711

7702-
let chanmon_cfgs = create_chanmon_cfgs(2);
7712+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
7713+
chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true;
77037714
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
77047715
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
77057716
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,49 @@ use ln::msgs::DecodeError;
2727
/// Initial value for revoked commitment downward counter
2828
pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
2929

30-
/// An implementation of ChannelKeys that enforces some policy checks.
30+
/// An implementation of ChannelKeys that enforces some policy checks. The current checks
31+
/// are an incomplete set. They include:
32+
///
33+
/// - When signing, the holder transaction has not been revoked
34+
/// - When revoking, the holder transaction has not been signed
35+
/// - The holder commitment number is monotonic and without gaps
36+
/// - The counterparty commitment number is monotonic and without gaps
37+
/// - The pre-derived keys and pre-built transaction in CommitmentTransaction were correctly built
3138
///
3239
/// Eventually we will probably want to expose a variant of this which would essentially
3340
/// be what you'd want to run on a hardware wallet.
3441
#[derive(Clone)]
3542
pub struct EnforcingChannelKeys {
3643
pub inner: InMemoryChannelKeys,
44+
/// The last counterparty commitment number we signed, backwards counting
3745
pub last_commitment_number: Arc<Mutex<Option<u64>>>,
46+
/// The last holder commitment number we revoked, backwards counting
3847
pub revoked_commitment: Arc<Mutex<u64>>,
48+
pub disable_revocation_policy_check: bool,
3949
}
4050

4151
impl EnforcingChannelKeys {
52+
/// Construct an EnforcingChannelKeys
4253
pub fn new(inner: InMemoryChannelKeys) -> Self {
4354
Self {
4455
inner,
4556
last_commitment_number: Arc::new(Mutex::new(None)),
46-
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER))
57+
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
58+
disable_revocation_policy_check: false
4759
}
4860
}
4961

50-
pub fn new_with_revoked(inner: InMemoryChannelKeys, revoked_commitment: Arc<Mutex<u64>>) -> Self {
62+
/// Construct an EnforcingChannelKeys with externally managed storage
63+
///
64+
/// Since there are multiple copies of this struct for each channel, some coordination is needed
65+
/// so that all copies are aware of revocations. A pointer to this state is provided here, usually
66+
/// by an implementation of KeysInterface.
67+
pub fn new_with_revoked(inner: InMemoryChannelKeys, revoked_commitment: Arc<Mutex<u64>>, disable_revocation_policy_check: bool) -> Self {
5168
Self {
5269
inner,
5370
last_commitment_number: Arc::new(Mutex::new(None)),
54-
revoked_commitment
71+
revoked_commitment,
72+
disable_revocation_policy_check
5573
}
5674
}
5775
}
@@ -62,8 +80,6 @@ impl ChannelKeys for EnforcingChannelKeys {
6280
}
6381

6482
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
65-
println!("XXX revoke {} for {}", idx, self.inner.commitment_seed[0]);
66-
6783
{
6884
let mut revoked = self.revoked_commitment.lock().unwrap();
6985
assert!(idx == *revoked || idx == *revoked - 1, "can only revoke the current or next unrevoked commitment - trying {}, revoked {}", idx, *revoked);
@@ -98,11 +114,11 @@ impl ChannelKeys for EnforcingChannelKeys {
98114

99115
let revoked = self.revoked_commitment.lock().unwrap();
100116
let commitment_number = trusted_tx.commitment_number();
101-
println!("XXX sign {} for {}", commitment_number, self.inner.commitment_seed[0]);
102117
if *revoked - 1 != commitment_number && *revoked - 2 != commitment_number {
103-
println!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
104-
*revoked, commitment_number, self.inner.commitment_seed[0]);
105-
return Err(());
118+
if !self.disable_revocation_policy_check {
119+
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
120+
*revoked, commitment_number, self.inner.commitment_seed[0])
121+
}
106122
}
107123

108124
for (this_htlc, sig) in trusted_tx.htlcs().iter().zip(&commitment_tx.counterparty_htlc_sigs) {
@@ -116,8 +132,6 @@ impl ChannelKeys for EnforcingChannelKeys {
116132
secp_ctx.verify(&sighash, sig, &keys.countersignatory_htlc_key).unwrap();
117133
}
118134

119-
// TODO: enforce the ChannelKeys contract - error if this commitment was already revoked
120-
// TODO: need the commitment number
121135
Ok(self.inner.sign_holder_commitment_and_htlcs(commitment_tx, secp_ctx).unwrap())
122136
}
123137

@@ -159,12 +173,13 @@ impl Writeable for EnforcingChannelKeys {
159173

160174
impl Readable for EnforcingChannelKeys {
161175
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
162-
let inner: InMemoryChannelKeys = Readable::read(reader)?;
176+
let inner = Readable::read(reader)?;
163177
let last_commitment_number = Readable::read(reader)?;
164178
Ok(EnforcingChannelKeys {
165179
inner,
166180
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
167181
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
182+
disable_revocation_policy_check: false,
168183
})
169184
}
170185
}

lightning/src/util/test_utils.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ pub struct TestKeysInterface {
422422
backing: keysinterface::KeysManager,
423423
pub override_session_priv: Mutex<Option<[u8; 32]>>,
424424
pub override_channel_id_priv: Mutex<Option<[u8; 32]>>,
425+
pub disable_revocation_policy_check: bool,
425426
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
426427
}
427428

@@ -434,7 +435,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
434435
fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys {
435436
let keys = self.backing.get_channel_keys(inbound, channel_value_satoshis);
436437
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
437-
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment)
438+
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
438439
}
439440

440441
fn get_secure_random_bytes(&self) -> [u8; 32] {
@@ -464,6 +465,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
464465
inner,
465466
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
466467
revoked_commitment,
468+
disable_revocation_policy_check: self.disable_revocation_policy_check,
467469
})
468470
}
469471
}
@@ -476,13 +478,14 @@ impl TestKeysInterface {
476478
backing: keysinterface::KeysManager::new(seed, network, now.as_secs(), now.subsec_nanos()),
477479
override_session_priv: Mutex::new(None),
478480
override_channel_id_priv: Mutex::new(None),
481+
disable_revocation_policy_check: false,
479482
revoked_commitments: Mutex::new(HashMap::new()),
480483
}
481484
}
482485
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, user_id_1: u64, user_id_2: u64) -> EnforcingChannelKeys {
483486
let keys = self.backing.derive_channel_keys(channel_value_satoshis, user_id_1, user_id_2);
484487
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
485-
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment)
488+
EnforcingChannelKeys::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
486489
}
487490

488491
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {

0 commit comments

Comments
 (0)