Skip to content

Commit 905e28f

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 8530078 commit 905e28f

File tree

3 files changed

+66
-53
lines changed

3 files changed

+66
-53
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
3939
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs};
4040
use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
4141
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, UpdateAddHTLC, Init};
42-
use lightning::util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
42+
use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
4343
use lightning::util::errors::APIError;
4444
use lightning::util::events;
4545
use lightning::util::logger::Logger;
@@ -148,7 +148,7 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
148148
struct KeyProvider {
149149
node_id: u8,
150150
rand_bytes_id: atomic::AtomicU32,
151-
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
151+
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
152152
}
153153
impl KeysInterface for KeyProvider {
154154
type Signer = EnforcingSigner;
@@ -183,7 +183,7 @@ impl KeysInterface for KeyProvider {
183183
channel_value_satoshis,
184184
[0; 32],
185185
);
186-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
186+
let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed);
187187
EnforcingSigner::new_with_revoked(keys, revoked_commitment, false)
188188
}
189189

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

200200
let inner: InMemorySigner = Readable::read(&mut reader)?;
201-
let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
202-
203-
let last_commitment_number = Readable::read(&mut reader)?;
201+
let state = self.make_enforcement_state_cell(inner.commitment_seed);
204202

205203
Ok(EnforcingSigner {
206204
inner,
207-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
208-
revoked_commitment,
205+
state,
209206
disable_revocation_policy_check: false,
210207
})
211208
}
@@ -216,10 +213,10 @@ impl KeysInterface for KeyProvider {
216213
}
217214

218215
impl KeyProvider {
219-
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {
220-
let mut revoked_commitments = self.revoked_commitments.lock().unwrap();
216+
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
217+
let mut revoked_commitments = self.enforcement_states.lock().unwrap();
221218
if !revoked_commitments.contains_key(&commitment_seed) {
222-
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)));
219+
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(EnforcementState::new())));
223220
}
224221
let cell = revoked_commitments.get(&commitment_seed).unwrap();
225222
Arc::clone(cell)
@@ -335,7 +332,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
335332
macro_rules! make_node {
336333
($node_id: expr) => { {
337334
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
338-
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), revoked_commitments: Mutex::new(HashMap::new()) });
335+
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
339336
let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), fee_est.clone(), Arc::new(TestPersister{}), Arc::clone(&keys_manager)));
340337

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

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 42 additions & 24 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
68+
/// so that all copies are aware of enforcement state. A pointer to this state is provided here, usually
7169
/// by an implementation of KeysInterface.
72-
pub fn new_with_revoked(inner: InMemorySigner, revoked_commitment: Arc<Mutex<u64>>, disable_revocation_policy_check: bool) -> Self {
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.unwrap_or(actual_commitment_number);
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 = Some(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: Option<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: None,
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
@@ -19,7 +19,7 @@ use chain::keysinterface;
1919
use ln::features::{ChannelFeatures, InitFeatures};
2020
use ln::msgs;
2121
use ln::msgs::OptionalField;
22-
use util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
22+
use util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
2323
use util::events;
2424
use util::logger::{Logger, Level, Record};
2525
use util::ser::{Readable, ReadableArgs, Writer, Writeable};
@@ -451,7 +451,7 @@ pub struct TestKeysInterface {
451451
pub override_session_priv: Mutex<Option<[u8; 32]>>,
452452
pub override_channel_id_priv: Mutex<Option<[u8; 32]>>,
453453
pub disable_revocation_policy_check: bool,
454-
revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
454+
enforcement_states: Mutex<HashMap<[u8;32], Arc<Mutex<EnforcementState>>>>,
455455
}
456456

457457
impl keysinterface::KeysInterface for TestKeysInterface {
@@ -462,8 +462,8 @@ impl keysinterface::KeysInterface for TestKeysInterface {
462462
fn get_shutdown_pubkey(&self) -> PublicKey { self.backing.get_shutdown_pubkey() }
463463
fn get_channel_signer(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingSigner {
464464
let keys = self.backing.get_channel_signer(inbound, channel_value_satoshis);
465-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
466-
EnforcingSigner::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
465+
let state = self.make_enforcement_state_cell(keys.commitment_seed);
466+
EnforcingSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
467467
}
468468

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

487487
let inner: InMemorySigner = Readable::read(&mut reader)?;
488-
let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
489-
490-
let last_commitment_number = Readable::read(&mut reader)?;
488+
let state = self.make_enforcement_state_cell(inner.commitment_seed);
491489

492490
Ok(EnforcingSigner {
493491
inner,
494-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
495-
revoked_commitment,
492+
state,
496493
disable_revocation_policy_check: self.disable_revocation_policy_check,
497494
})
498495
}
@@ -511,21 +508,22 @@ impl TestKeysInterface {
511508
override_session_priv: Mutex::new(None),
512509
override_channel_id_priv: Mutex::new(None),
513510
disable_revocation_policy_check: false,
514-
revoked_commitments: Mutex::new(HashMap::new()),
511+
enforcement_states: Mutex::new(HashMap::new()),
515512
}
516513
}
517514
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, id: &[u8; 32]) -> EnforcingSigner {
518515
let keys = self.backing.derive_channel_keys(channel_value_satoshis, id);
519-
let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
520-
EnforcingSigner::new_with_revoked(keys, revoked_commitment, self.disable_revocation_policy_check)
516+
let state = self.make_enforcement_state_cell(keys.commitment_seed);
517+
EnforcingSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
521518
}
522519

523-
fn make_revoked_commitment_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<u64>> {
524-
let mut revoked_commitments = self.revoked_commitments.lock().unwrap();
525-
if !revoked_commitments.contains_key(&commitment_seed) {
526-
revoked_commitments.insert(commitment_seed, Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)));
520+
fn make_enforcement_state_cell(&self, commitment_seed: [u8; 32]) -> Arc<Mutex<EnforcementState>> {
521+
let mut states = self.enforcement_states.lock().unwrap();
522+
if !states.contains_key(&commitment_seed) {
523+
let state = EnforcementState::new();
524+
states.insert(commitment_seed, Arc::new(Mutex::new(state)));
527525
}
528-
let cell = revoked_commitments.get(&commitment_seed).unwrap();
526+
let cell = states.get(&commitment_seed).unwrap();
529527
Arc::clone(cell)
530528
}
531529
}

0 commit comments

Comments
 (0)