Skip to content

Commit f7f300e

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 f7f300e

File tree

2 files changed

+58
-41
lines changed

2 files changed

+58
-41
lines changed

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,35 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
4343
///
4444
/// Note that before we do so we should ensure its serialization format has backwards- and
4545
/// forwards-compatibility prefix/suffixes!
46+
4647
#[derive(Clone)]
4748
pub struct EnforcingSigner {
4849
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>>,
50+
/// Channel state used for policy enforcement
51+
pub state: Arc<Mutex<EnforcementState>>,
5352
pub disable_revocation_policy_check: bool,
5453
}
5554

5655
impl EnforcingSigner {
5756
/// Construct an EnforcingSigner
5857
pub fn new(inner: InMemorySigner) -> Self {
58+
let state = Arc::new(Mutex::new(EnforcementState::new()));
5959
Self {
6060
inner,
61-
last_commitment_number: Arc::new(Mutex::new(None)),
62-
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
61+
state,
6362
disable_revocation_policy_check: false
6463
}
6564
}
6665

6766
/// Construct an EnforcingSigner with externally managed storage
6867
///
6968
/// 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
69+
/// so that all copies are aware of enforcement state. A pointer to this state is provided here, usually
7170
/// by an implementation of KeysInterface.
72-
pub fn new_with_revoked(inner: InMemorySigner, revoked_commitment: Arc<Mutex<u64>>, disable_revocation_policy_check: bool) -> Self {
71+
pub fn new_with_revoked(inner: InMemorySigner, state: Arc<Mutex<EnforcementState>>, disable_revocation_policy_check: bool) -> Self {
7372
Self {
7473
inner,
75-
last_commitment_number: Arc::new(Mutex::new(None)),
76-
revoked_commitment,
74+
state,
7775
disable_revocation_policy_check
7876
}
7977
}
@@ -86,9 +84,9 @@ impl BaseSign for EnforcingSigner {
8684

8785
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
8886
{
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;
87+
let mut state = self.state.lock().unwrap();
88+
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);
89+
state.revoked_commitment = idx;
9290
}
9391
self.inner.release_commitment_secret(idx)
9492
}
@@ -100,13 +98,13 @@ impl BaseSign for EnforcingSigner {
10098
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
10199

102100
{
103-
let mut last_commitment_number_guard = self.last_commitment_number.lock().unwrap();
101+
let mut state = self.state.lock().unwrap();
104102
let actual_commitment_number = commitment_tx.commitment_number();
105-
let last_commitment_number = last_commitment_number_guard.unwrap_or(actual_commitment_number);
103+
let last_commitment_number = state.last_commitment_number.unwrap_or(actual_commitment_number);
106104
// These commitment numbers are backwards counting. We expect either the same as the previously encountered,
107105
// or the next one.
108106
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))
107+
state.last_commitment_number = Some(cmp::min(last_commitment_number, actual_commitment_number))
110108
}
111109

112110
Ok(self.inner.sign_counterparty_commitment(commitment_tx, secp_ctx).unwrap())
@@ -117,12 +115,12 @@ impl BaseSign for EnforcingSigner {
117115
let commitment_txid = trusted_tx.txid();
118116
let holder_csv = self.inner.counterparty_selected_contest_delay();
119117

120-
let revoked = self.revoked_commitment.lock().unwrap();
118+
let state = self.state.lock().unwrap();
121119
let commitment_number = trusted_tx.commitment_number();
122-
if *revoked - 1 != commitment_number && *revoked - 2 != commitment_number {
120+
if state.revoked_commitment - 1 != commitment_number && state.revoked_commitment - 2 != commitment_number {
123121
if !self.disable_revocation_policy_check {
124122
panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}",
125-
*revoked, commitment_number, self.inner.commitment_seed[0])
123+
state.revoked_commitment, commitment_number, self.inner.commitment_seed[0])
126124
}
127125
}
128126

@@ -175,20 +173,18 @@ impl Sign for EnforcingSigner {}
175173
impl Writeable for EnforcingSigner {
176174
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
177175
self.inner.write(writer)?;
178-
let last = *self.last_commitment_number.lock().unwrap();
179-
last.write(writer)?;
176+
// NOTE - the commitment state is maintained by KeysInterface, so we don't persist it
180177
Ok(())
181178
}
182179
}
183180

184181
impl Readable for EnforcingSigner {
185182
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
186183
let inner = Readable::read(reader)?;
187-
let last_commitment_number = Readable::read(reader)?;
184+
let state = Arc::new(Mutex::new(EnforcementState::new()));
188185
Ok(EnforcingSigner {
189186
inner,
190-
last_commitment_number: Arc::new(Mutex::new(last_commitment_number)),
191-
revoked_commitment: Arc::new(Mutex::new(INITIAL_REVOKED_COMMITMENT_NUMBER)),
187+
state,
192188
disable_revocation_policy_check: false,
193189
})
194190
}
@@ -207,3 +203,26 @@ impl EnforcingSigner {
207203
.expect("derived different per-tx keys or built transaction")
208204
}
209205
}
206+
207+
/// The state required by [`EnforcingSigner`] in order to enforce policy checks
208+
///
209+
/// This structure is maintained by [`crate::chain::keysinteface::KeysInterface`]
210+
/// since we may have multiple copies of the signer and they must coordinate their state.
211+
#[derive(Clone)]
212+
pub struct EnforcementState {
213+
/// The last counterparty commitment number we signed, backwards counting
214+
pub last_commitment_number: Option<u64>,
215+
/// The last holder commitment number we revoked, backwards counting
216+
pub revoked_commitment: u64,
217+
218+
}
219+
220+
impl EnforcementState {
221+
/// Enforcement state for a new channel
222+
pub fn new() -> Self {
223+
EnforcementState {
224+
last_commitment_number: None,
225+
revoked_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER
226+
}
227+
}
228+
}

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(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(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(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(&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)