Skip to content

Commit 5ad0440

Browse files
committed
Optionally disable all state-based policy checks in test signer
The signer we use in tests tracks the state of the channel and refuses to sign when the channel attempts an invalid state transition. In the next commit, however, we'll add an upgrade test which will fail these checks as the the state won't get copied from previous versions of LDK to this version. Thus, here, we add the ability to disable all state-based checks in the signer.
1 parent 17d6644 commit 5ad0440

File tree

4 files changed

+62
-45
lines changed

4 files changed

+62
-45
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ impl SignerProvider for KeyProvider {
382382
channel_keys_id,
383383
);
384384
let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed);
385-
TestChannelSigner::new_with_revoked(keys, revoked_commitment, false)
385+
TestChannelSigner::new_with_revoked(keys, revoked_commitment, false, false)
386386
}
387387

388388
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::EcdsaSigner, DecodeError> {
@@ -391,7 +391,7 @@ impl SignerProvider for KeyProvider {
391391
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
392392
let state = self.make_enforcement_state_cell(inner.commitment_seed);
393393

394-
Ok(TestChannelSigner::new_with_revoked(inner, state, false))
394+
Ok(TestChannelSigner::new_with_revoked(inner, state, false, false))
395395
}
396396

397397
fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> {

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,14 +462,14 @@ impl SignerProvider for KeyProvider {
462462
f = key;
463463
let signer = InMemorySigner::new(&secp_ctx, a, b, c, d, e, f, value, keys_id, keys_id);
464464

465-
TestChannelSigner::new_with_revoked(signer, state, false)
465+
TestChannelSigner::new_with_revoked(signer, state, false, false)
466466
}
467467

468468
fn read_chan_signer(&self, mut data: &[u8]) -> Result<TestChannelSigner, DecodeError> {
469469
let inner: InMemorySigner = ReadableArgs::read(&mut data, self)?;
470470
let state = Arc::new(Mutex::new(EnforcementState::new()));
471471

472-
Ok(TestChannelSigner::new_with_revoked(inner, state, false))
472+
Ok(TestChannelSigner::new_with_revoked(inner, state, false, false))
473473
}
474474

475475
fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> {

lightning/src/util/test_channel_signer.rs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub struct TestChannelSigner {
7575
/// Channel state used for policy enforcement
7676
pub state: Arc<Mutex<EnforcementState>>,
7777
pub disable_revocation_policy_check: bool,
78+
pub disable_all_state_policy_checks: bool,
7879
}
7980

8081
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -124,7 +125,12 @@ impl TestChannelSigner {
124125
/// Construct an TestChannelSigner
125126
pub fn new(inner: InMemorySigner) -> Self {
126127
let state = Arc::new(Mutex::new(EnforcementState::new()));
127-
Self { inner, state, disable_revocation_policy_check: false }
128+
Self {
129+
inner,
130+
state,
131+
disable_revocation_policy_check: false,
132+
disable_all_state_policy_checks: false,
133+
}
128134
}
129135

130136
/// Construct an TestChannelSigner with externally managed storage
@@ -134,9 +140,9 @@ impl TestChannelSigner {
134140
/// here, usually by an implementation of KeysInterface.
135141
pub fn new_with_revoked(
136142
inner: InMemorySigner, state: Arc<Mutex<EnforcementState>>,
137-
disable_revocation_policy_check: bool,
143+
disable_revocation_policy_check: bool, disable_all_state_policy_checks: bool,
138144
) -> Self {
139-
Self { inner, state, disable_revocation_policy_check }
145+
Self { inner, state, disable_revocation_policy_check, disable_all_state_policy_checks }
140146
}
141147

142148
pub fn channel_type_features(&self) -> &ChannelTypeFeatures {
@@ -180,12 +186,12 @@ impl ChannelSigner for TestChannelSigner {
180186
if !self.is_signer_available(SignerOp::ReleaseCommitmentSecret) {
181187
return Err(());
182188
}
183-
{
184-
let mut state = self.state.lock().unwrap();
189+
let mut state = self.state.lock().unwrap();
190+
if !self.disable_all_state_policy_checks {
185191
assert!(idx == state.last_holder_revoked_commitment || idx == state.last_holder_revoked_commitment - 1, "can only revoke the current or next unrevoked commitment - trying {}, last revoked {}", idx, state.last_holder_revoked_commitment);
186192
assert!(idx > state.last_holder_commitment, "cannot revoke the last holder commitment - attempted to revoke {} last commitment {}", idx, state.last_holder_commitment);
187-
state.last_holder_revoked_commitment = idx;
188193
}
194+
state.last_holder_revoked_commitment = idx;
189195
self.inner.release_commitment_secret(idx)
190196
}
191197

@@ -195,12 +201,14 @@ impl ChannelSigner for TestChannelSigner {
195201
) -> Result<(), ()> {
196202
let mut state = self.state.lock().unwrap();
197203
let idx = holder_tx.commitment_number();
198-
assert!(
199-
idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1,
200-
"expecting to validate the current or next holder commitment - trying {}, current {}",
201-
idx,
202-
state.last_holder_commitment
203-
);
204+
if !self.disable_all_state_policy_checks {
205+
assert!(
206+
idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1,
207+
"expecting to validate the current or next holder commitment - trying {}, current {}",
208+
idx,
209+
state.last_holder_commitment
210+
);
211+
}
204212
state.last_holder_commitment = idx;
205213
Ok(())
206214
}
@@ -211,7 +219,9 @@ impl ChannelSigner for TestChannelSigner {
211219
return Err(());
212220
}
213221
let mut state = self.state.lock().unwrap();
214-
assert!(idx == state.last_counterparty_revoked_commitment || idx == state.last_counterparty_revoked_commitment - 1, "expecting to validate the current or next counterparty revocation - trying {}, current {}", idx, state.last_counterparty_revoked_commitment);
222+
if !self.disable_all_state_policy_checks {
223+
assert!(idx == state.last_counterparty_revoked_commitment || idx == state.last_counterparty_revoked_commitment - 1, "expecting to validate the current or next counterparty revocation - trying {}, current {}", idx, state.last_counterparty_revoked_commitment);
224+
}
215225
state.last_counterparty_revoked_commitment = idx;
216226
Ok(())
217227
}
@@ -236,14 +246,14 @@ impl EcdsaChannelSigner for TestChannelSigner {
236246
) -> Result<(Signature, Vec<Signature>), ()> {
237247
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
238248

239-
{
240-
#[cfg(test)]
241-
if !self.is_signer_available(SignerOp::SignCounterpartyCommitment) {
242-
return Err(());
243-
}
244-
let mut state = self.state.lock().unwrap();
245-
let actual_commitment_number = commitment_tx.commitment_number();
246-
let last_commitment_number = state.last_counterparty_commitment;
249+
#[cfg(test)]
250+
if !self.is_signer_available(SignerOp::SignCounterpartyCommitment) {
251+
return Err(());
252+
}
253+
let mut state = self.state.lock().unwrap();
254+
let actual_commitment_number = commitment_tx.commitment_number();
255+
let last_commitment_number = state.last_counterparty_commitment;
256+
if !self.disable_all_state_policy_checks {
247257
// These commitment numbers are backwards counting. We expect either the same as the previously encountered,
248258
// or the next one.
249259
assert!(
@@ -261,9 +271,9 @@ impl EcdsaChannelSigner for TestChannelSigner {
261271
actual_commitment_number,
262272
state.last_counterparty_revoked_commitment
263273
);
264-
state.last_counterparty_commitment =
265-
cmp::min(last_commitment_number, actual_commitment_number)
266274
}
275+
state.last_counterparty_commitment =
276+
cmp::min(last_commitment_number, actual_commitment_number);
267277

268278
Ok(self
269279
.inner
@@ -284,14 +294,16 @@ impl EcdsaChannelSigner for TestChannelSigner {
284294
return Err(());
285295
}
286296
let trusted_tx = self.verify_holder_commitment_tx(commitment_tx, secp_ctx);
287-
let state = self.state.lock().unwrap();
288-
let commitment_number = trusted_tx.commitment_number();
289-
if state.last_holder_revoked_commitment - 1 != commitment_number
290-
&& state.last_holder_revoked_commitment - 2 != commitment_number
291-
{
292-
if !self.disable_revocation_policy_check {
293-
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
294-
state.last_holder_revoked_commitment, commitment_number, self.inner.commitment_seed[0])
297+
if !self.disable_all_state_policy_checks {
298+
let state = self.state.lock().unwrap();
299+
let commitment_number = trusted_tx.commitment_number();
300+
if state.last_holder_revoked_commitment - 1 != commitment_number
301+
&& state.last_holder_revoked_commitment - 2 != commitment_number
302+
{
303+
if !self.disable_revocation_policy_check {
304+
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
305+
state.last_holder_revoked_commitment, commitment_number, self.inner.commitment_seed[0])
306+
}
295307
}
296308
}
297309
Ok(self.inner.sign_holder_commitment(commitment_tx, secp_ctx).unwrap())
@@ -351,13 +363,15 @@ impl EcdsaChannelSigner for TestChannelSigner {
351363
if !self.is_signer_available(SignerOp::SignHolderHtlcTransaction) {
352364
return Err(());
353365
}
354-
let state = self.state.lock().unwrap();
355-
if state.last_holder_revoked_commitment - 1 != htlc_descriptor.per_commitment_number
356-
&& state.last_holder_revoked_commitment - 2 != htlc_descriptor.per_commitment_number
357-
{
358-
if !self.disable_revocation_policy_check {
359-
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
360-
state.last_holder_revoked_commitment, htlc_descriptor.per_commitment_number, self.inner.commitment_seed[0])
366+
if !self.disable_all_state_policy_checks {
367+
let state = self.state.lock().unwrap();
368+
if state.last_holder_revoked_commitment - 1 != htlc_descriptor.per_commitment_number
369+
&& state.last_holder_revoked_commitment - 2 != htlc_descriptor.per_commitment_number
370+
{
371+
if !self.disable_revocation_policy_check {
372+
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
373+
state.last_holder_revoked_commitment, htlc_descriptor.per_commitment_number, self.inner.commitment_seed[0])
374+
}
361375
}
362376
}
363377
assert_eq!(htlc_tx.input[input], htlc_descriptor.unsigned_tx_input());

lightning/src/util/test_utils.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ impl SignerProvider for OnlyReadsKeysInterface {
375375
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
376376
let state = Arc::new(Mutex::new(EnforcementState::new()));
377377

378-
Ok(TestChannelSigner::new_with_revoked(inner, state, false))
378+
Ok(TestChannelSigner::new_with_revoked(inner, state, false, false))
379379
}
380380

381381
fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> {
@@ -1451,6 +1451,7 @@ pub struct TestKeysInterface {
14511451
pub backing: sign::PhantomKeysManager,
14521452
pub override_random_bytes: Mutex<Option<[u8; 32]>>,
14531453
pub disable_revocation_policy_check: bool,
1454+
pub disable_all_state_policy_checks: bool,
14541455
enforcement_states: Mutex<HashMap<[u8; 32], Arc<Mutex<EnforcementState>>>>,
14551456
expectations: Mutex<Option<VecDeque<OnGetShutdownScriptpubkey>>>,
14561457
pub unavailable_signers_ops: Mutex<HashMap<[u8; 32], HashSet<SignerOp>>>,
@@ -1515,8 +1516,9 @@ impl SignerProvider for TestKeysInterface {
15151516
) -> TestChannelSigner {
15161517
let keys = self.backing.derive_channel_signer(channel_value_satoshis, channel_keys_id);
15171518
let state = self.make_enforcement_state_cell(keys.commitment_seed);
1518-
let signer =
1519-
TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check);
1519+
let rev_checks = self.disable_revocation_policy_check;
1520+
let state_checks = self.disable_all_state_policy_checks;
1521+
let signer = TestChannelSigner::new_with_revoked(keys, state, rev_checks, state_checks);
15201522
#[cfg(test)]
15211523
if let Some(ops) = self.unavailable_signers_ops.lock().unwrap().get(&channel_keys_id) {
15221524
for &op in ops {
@@ -1556,6 +1558,7 @@ impl TestKeysInterface {
15561558
backing: sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed),
15571559
override_random_bytes: Mutex::new(None),
15581560
disable_revocation_policy_check: false,
1561+
disable_all_state_policy_checks: false,
15591562
enforcement_states: Mutex::new(new_hash_map()),
15601563
expectations: Mutex::new(None),
15611564
unavailable_signers_ops: Mutex::new(new_hash_map()),

0 commit comments

Comments
 (0)