X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fenforcing_trait_impls.rs;h=18ed0ea834c207425dacf211b735970e7ab397c3;hb=241e448d37a9fa6c8ed149b934acefb15b69ee92;hp=cd3ead6492f7d95bc8fe1df2b48a51bf4d634c18;hpb=50966e25ba4bc9792d10702d46b75baa5a013b30;p=rust-lightning diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index cd3ead64..18ed0ea8 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -15,6 +15,7 @@ use io; use prelude::*; use core::cmp; use sync::{Mutex, Arc}; +#[cfg(test)] use sync::MutexGuard; use bitcoin::blockdata::transaction::{Transaction, SigHashType}; use bitcoin::util::bip143; @@ -35,12 +36,17 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48; /// - When signing, the holder transaction has not been revoked /// - When revoking, the holder transaction has not been signed /// - The holder commitment number is monotonic and without gaps +/// - The revoked holder commitment number is monotonic and without gaps +/// - There is at least one unrevoked holder transaction at all times /// - The counterparty commitment number is monotonic and without gaps /// - The pre-derived keys and pre-built transaction in CommitmentTransaction were correctly built /// /// Eventually we will probably want to expose a variant of this which would essentially /// be what you'd want to run on a hardware wallet. /// +/// Note that counterparty signatures on the holder transaction are not checked, but it should +/// be in a complete implementation. +/// /// Note that before we do so we should ensure its serialization format has backwards- and /// forwards-compatibility prefix/suffixes! #[derive(Clone)] @@ -74,6 +80,11 @@ impl EnforcingSigner { disable_revocation_policy_check } } + + #[cfg(test)] + pub fn get_enforcement_state(&self) -> MutexGuard { + self.state.lock().unwrap() + } } impl BaseSign for EnforcingSigner { @@ -84,12 +95,20 @@ impl BaseSign for EnforcingSigner { fn release_commitment_secret(&self, idx: u64) -> [u8; 32] { { let mut state = self.state.lock().unwrap(); - 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); - state.revoked_commitment = idx; + 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); + assert!(idx > state.last_holder_commitment, "cannot revoke the last holder commitment - attempted to revoke {} last commitment {}", idx, state.last_holder_commitment); + state.last_holder_revoked_commitment = idx; } self.inner.release_commitment_secret(idx) } + fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction) { + let mut state = self.state.lock().unwrap(); + let idx = holder_tx.commitment_number(); + assert!(idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, "expecting to validate the current or next holder commitment - trying {}, current {}", idx, state.last_holder_commitment); + state.last_holder_commitment = idx; + } + fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() } fn channel_keys_id(&self) -> [u8; 32] { self.inner.channel_keys_id() } @@ -116,10 +135,10 @@ impl BaseSign for EnforcingSigner { let state = self.state.lock().unwrap(); let commitment_number = trusted_tx.commitment_number(); - if state.revoked_commitment - 1 != commitment_number && state.revoked_commitment - 2 != commitment_number { + if state.last_holder_revoked_commitment - 1 != commitment_number && state.last_holder_revoked_commitment - 2 != commitment_number { if !self.disable_revocation_policy_check { panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}", - state.revoked_commitment, commitment_number, self.inner.commitment_seed[0]) + state.last_holder_revoked_commitment, commitment_number, self.inner.commitment_seed[0]) } } @@ -212,8 +231,9 @@ pub struct EnforcementState { /// The last counterparty commitment number we signed, backwards counting pub last_counterparty_commitment: u64, /// The last holder commitment number we revoked, backwards counting - pub revoked_commitment: u64, - + pub last_holder_revoked_commitment: u64, + /// The last validated holder commitment number, backwards counting + pub last_holder_commitment: u64, } impl EnforcementState { @@ -221,7 +241,8 @@ impl EnforcementState { pub fn new() -> Self { EnforcementState { last_counterparty_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER, - revoked_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER, + last_holder_revoked_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER, + last_holder_commitment: INITIAL_REVOKED_COMMITMENT_NUMBER, } } }