Skip to content

Commit a2b1906

Browse files
committed
Introduce EnforcementState for EnforcingSigner
as we add more enforcement state variables, we want to keep track of them under a single structure
1 parent 479ff90 commit a2b1906

File tree

3 files changed

+67
-54
lines changed

3 files changed

+67
-54
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
4141
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
4242
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, UpdateAddHTLC, Init};
4343
use lightning::ln::script::ShutdownScript;
44-
use lightning::util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
44+
use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
4545
use lightning::util::errors::APIError;
4646
use lightning::util::events;
4747
use lightning::util::logger::Logger;
@@ -161,7 +161,7 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
161161
struct KeyProvider {
162162
node_id: u8,
163163
rand_bytes_id: atomic::AtomicU32,
164-
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
164+
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
165165
}
166166
impl KeysInterface for KeyProvider {
167167
type Signer = EnforcingSigner;
@@ -198,7 +198,7 @@ impl KeysInterface for KeyProvider {
198198
channel_value_satoshis,
199199
[0; 32],
200200
);
201-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
201+
let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed);
202202
EnforcingSigner::new_with_revoked(keys, revoked_commitment, false)
203203
}
204204

@@ -213,14 +213,11 @@ impl KeysInterface for KeyProvider {
213213
let mut reader = std::io::Cursor::new(buffer);
214214

215215
let inner: InMemorySigner = Readable::read(&mut reader)?;
216-
let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
217-
218-
let last_commitment_number = Readable::read(&mut reader)?;
216+
let state = self.make_enforcement_state_cell(inner.commitment_seed);
219217

220218
Ok(EnforcingSigner {
221219
inner,
222-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
223-
revoked_commitment,
220+
state,
224221
disable_revocation_policy_check: false,
225222
})
226223
}
@@ -231,10 +228,10 @@ impl KeysInterface for KeyProvider {
231228
}
232229

233230
impl KeyProvider {
234-
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {
235-
let mut revoked_commitments = self.revoked_commitments.lock().unwrap();
231+
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
232+
let mut revoked_commitments = self.enforcement_states.lock().unwrap();
236233
if !revoked_commitments.contains_key(&commitment_seed) {
237-
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)));
234+
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(EnforcementState::new())));
238235
}
239236
let cell = revoked_commitments.get(&commitment_seed).unwrap();
240237
Arc::clone(cell)
@@ -351,7 +348,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
351348
macro_rules! make_node {
352349
($node_id: expr, $fee_estimator: expr) => { {
353350
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
354-
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), revoked_commitments: Mutex::new(HashMap::new()) });
351+
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
355352
let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), $fee_estimator.clone(), Arc::new(TestPersister{}), Arc::clone(&keys_manager)));
356353

357354
let mut config = UserConfig::default();

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,31 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
4646
#[derive(Clone)]
4747
pub struct EnforcingSigner {
4848
pub inner: InMemorySigner,
49-
/// The last counterparty commitment number we signed, backwards counting
50-
pub last_commitment_number: Arc<Mutex<Option<u64>>>,
51-
/// The last holder commitment number we revoked, backwards counting
52-
pub revoked_commitment: Arc<Mutex<u64>>,
49+
/// Channel state used for policy enforcement
50+
pub state: Arc<Mutex<EnforcementState>>,
5351
pub disable_revocation_policy_check: bool,
5452
}
5553

5654
impl EnforcingSigner {
5755
/// Construct an EnforcingSigner
5856
pub fn new(inner: InMemorySigner) -> Self {
57+
let state = Arc::new(Mutex::new(EnforcementState::new()));
5958
Self {
6059
inner,
61-
last_commitment_number: Arc::new(Mutex::new(None)),
62-
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
60+
state,
6361
disable_revocation_policy_check: false
6462
}
6563
}
6664

6765
/// Construct an EnforcingSigner with externally managed storage
6866
///
6967
/// Since there are multiple copies of this struct for each channel, some coordination is needed
70-
/// so that all copies are aware of revocations. A pointer to this state is provided here, usually
71-
/// by an implementation of KeysInterface.
72-
pub fn new_with_revoked(inner: InMemorySigner, revoked_commitment: Arc<Mutex<u64>>, disable_revocation_policy_check: bool) -> Self {
68+
/// so that all copies are aware of enforcement state. A pointer to this state is provided
69+
/// here, usually by an implementation of KeysInterface.
70+
pub fn new_with_revoked(inner: InMemorySigner, state: Arc<Mutex<EnforcementState>>, disable_revocation_policy_check: bool) -> Self {
7371
Self {
7472
inner,
75-
last_commitment_number: Arc::new(Mutex::new(None)),
76-
revoked_commitment,
73+
state,
7774
disable_revocation_policy_check
7875
}
7976
}
@@ -86,9 +83,9 @@ impl BaseSign for EnforcingSigner {
8683

8784
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
8885
{
89-
let mut revoked = self.revoked_commitment.lock().unwrap();
90-
assert!(idx == *revoked || idx == *revoked - 1, "can only revoke the current or next unrevoked commitment - trying {}, revoked {}", idx, *revoked);
91-
*revoked = idx;
86+
let mut state = self.state.lock().unwrap();
87+
assert!(idx == state.revoked_commitment || idx == state.revoked_commitment - 1, "can only revoke the current or next unrevoked commitment - trying {}, revoked {}", idx, state.revoked_commitment);
88+
state.revoked_commitment = idx;
9289
}
9390
self.inner.release_commitment_secret(idx)
9491
}
@@ -100,13 +97,13 @@ impl BaseSign for EnforcingSigner {
10097
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
10198

10299
{
103-
let mut last_commitment_number_guard = self.last_commitment_number.lock().unwrap();
100+
let mut state = self.state.lock().unwrap();
104101
let actual_commitment_number = commitment_tx.commitment_number();
105-
let last_commitment_number = last_commitment_number_guard.unwrap_or(actual_commitment_number);
102+
let last_commitment_number = state.last_counterparty_commitment;
106103
// These commitment numbers are backwards counting. We expect either the same as the previously encountered,
107104
// or the next one.
108105
assert!(last_commitment_number == actual_commitment_number || last_commitment_number - 1 == actual_commitment_number, "{} doesn't come after {}", actual_commitment_number, last_commitment_number);
109-
*last_commitment_number_guard = Some(cmp::min(last_commitment_number, actual_commitment_number))
106+
state.last_counterparty_commitment = cmp::min(last_commitment_number, actual_commitment_number)
110107
}
111108

112109
Ok(self.inner.sign_counterparty_commitment(commitment_tx, secp_ctx).unwrap())
@@ -117,12 +114,12 @@ impl BaseSign for EnforcingSigner {
117114
let commitment_txid = trusted_tx.txid();
118115
let holder_csv = self.inner.counterparty_selected_contest_delay();
119116

120-
let revoked = self.revoked_commitment.lock().unwrap();
117+
let state = self.state.lock().unwrap();
121118
let commitment_number = trusted_tx.commitment_number();
122-
if *revoked - 1 != commitment_number && *revoked - 2 != commitment_number {
119+
if state.revoked_commitment - 1 != commitment_number && state.revoked_commitment - 2 != commitment_number {
123120
if !self.disable_revocation_policy_check {
124121
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
125-
*revoked, commitment_number, self.inner.commitment_seed[0])
122+
state.revoked_commitment, commitment_number, self.inner.commitment_seed[0])
126123
}
127124
}
128125

@@ -175,20 +172,18 @@ impl Sign for EnforcingSigner {}
175172
impl Writeable for EnforcingSigner {
176173
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
177174
self.inner.write(writer)?;
178-
let last = *self.last_commitment_number.lock().unwrap();
179-
last.write(writer)?;
175+
// NOTE - the commitment state is maintained by KeysInterface, so we don't persist it
180176
Ok(())
181177
}
182178
}
183179

184180
impl Readable for EnforcingSigner {
185181
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
186182
let inner = Readable::read(reader)?;
187-
let last_commitment_number = Readable::read(reader)?;
183+
let state = Arc::new(Mutex::new(EnforcementState::new()));
188184
Ok(EnforcingSigner {
189185
inner,
190-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
191-
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
186+
state,
192187
disable_revocation_policy_check: false,
193188
})
194189
}
@@ -207,3 +202,26 @@ impl EnforcingSigner {
207202
.expect("derived different per-tx keys or built transaction")
208203
}
209204
}
205+
206+
/// The state used by [`EnforcingSigner`] in order to enforce policy checks
207+
///
208+
/// This structure is maintained by KeysInterface since we may have multiple copies of
209+
/// the signer and they must coordinate their state.
210+
#[derive(Clone)]
211+
pub struct EnforcementState {
212+
/// The last counterparty commitment number we signed, backwards counting
213+
pub last_counterparty_commitment: u64,
214+
/// The last holder commitment number we revoked, backwards counting
215+
pub revoked_commitment: u64,
216+
217+
}
218+
219+
impl EnforcementState {
220+
/// Enforcement state for a new channel
221+
pub fn new() -> Self {
222+
EnforcementState {
223+
last_counterparty_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER,
224+
revoked_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER,
225+
}
226+
}
227+
}

lightning/src/util/test_utils.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use ln::features::{ChannelFeatures, InitFeatures};
2020
use ln::msgs;
2121
use ln::msgs::OptionalField;
2222
use ln::script::ShutdownScript;
23-
use util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
23+
use util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
2424
use util::events;
2525
use util::logger::{Logger, Level, Record};
2626
use util::ser::{Readable, ReadableArgs, Writer, Writeable};
@@ -452,7 +452,7 @@ pub struct TestKeysInterface {
452452
pub override_session_priv: Mutex<Option<[u8; 32]>>,
453453
pub override_channel_id_priv: Mutex<Option<[u8; 32]>>,
454454
pub disable_revocation_policy_check: bool,
455-
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
455+
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
456456
expectations: Mutex<Option<VecDeque<OnGetShutdownScriptpubkey>>>,
457457
}
458458

@@ -474,8 +474,8 @@ impl keysinterface::KeysInterface for TestKeysInterface {
474474

475475
fn get_channel_signer(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingSigner {
476476
let keys = self.backing.get_channel_signer(inbound, channel_value_satoshis);
477-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
478-
EnforcingSigner::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
477+
let state = self.make_enforcement_state_cell(keys.commitment_seed);
478+
EnforcingSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
479479
}
480480

481481
fn get_secure_random_bytes(&self) -> [u8; 32] {
@@ -497,14 +497,11 @@ impl keysinterface::KeysInterface for TestKeysInterface {
497497
let mut reader = io::Cursor::new(buffer);
498498

499499
let inner: InMemorySigner = Readable::read(&mut reader)?;
500-
let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
501-
502-
let last_commitment_number = Readable::read(&mut reader)?;
500+
let state = self.make_enforcement_state_cell(inner.commitment_seed);
503501

504502
Ok(EnforcingSigner {
505503
inner,
506-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
507-
revoked_commitment,
504+
state,
508505
disable_revocation_policy_check: self.disable_revocation_policy_check,
509506
})
510507
}
@@ -522,7 +519,7 @@ impl TestKeysInterface {
522519
override_session_priv: Mutex::new(None),
523520
override_channel_id_priv: Mutex::new(None),
524521
disable_revocation_policy_check: false,
525-
revoked_commitments: Mutex::new(HashMap::new()),
522+
enforcement_states: Mutex::new(HashMap::new()),
526523
expectations: Mutex::new(None),
527524
}
528525
}
@@ -538,16 +535,17 @@ impl TestKeysInterface {
538535

539536
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, id: &[u8; 32]) -> EnforcingSigner {
540537
let keys = self.backing.derive_channel_keys(channel_value_satoshis, id);
541-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
542-
EnforcingSigner::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
538+
let state = self.make_enforcement_state_cell(keys.commitment_seed);
539+
EnforcingSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
543540
}
544541

545-
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {
546-
let mut revoked_commitments = self.revoked_commitments.lock().unwrap();
547-
if !revoked_commitments.contains_key(&commitment_seed) {
548-
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)));
542+
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
543+
let mut states = self.enforcement_states.lock().unwrap();
544+
if !states.contains_key(&commitment_seed) {
545+
let state = EnforcementState::new();
546+
states.insert(commitment_seed, Arc::new(Mutex::new(state)));
549547
}
550-
let cell = revoked_commitments.get(&commitment_seed).unwrap();
548+
let cell = states.get(&commitment_seed).unwrap();
551549
Arc::clone(cell)
552550
}
553551
}

0 commit comments

Comments
 (0)