@@ -15,6 +15,7 @@ use io;
1515use prelude:: * ;
1616use core:: cmp;
1717use sync:: { Mutex , Arc } ;
18+ #[ cfg( test) ] use sync:: MutexGuard ;
1819
1920use bitcoin:: blockdata:: transaction:: { Transaction , SigHashType } ;
2021use bitcoin:: util:: bip143;
@@ -35,12 +36,17 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
3536/// - When signing, the holder transaction has not been revoked
3637/// - When revoking, the holder transaction has not been signed
3738/// - The holder commitment number is monotonic and without gaps
39+ /// - The revoked holder commitment number is monotonic and without gaps
40+ /// - There is at least one unrevoked holder transaction at all times
3841/// - The counterparty commitment number is monotonic and without gaps
3942/// - The pre-derived keys and pre-built transaction in CommitmentTransaction were correctly built
4043///
4144/// Eventually we will probably want to expose a variant of this which would essentially
4245/// be what you'd want to run on a hardware wallet.
4346///
47+ /// Note that counterparty signatures on the holder transaction are not checked, but it should
48+ /// be in a complete implementation.
49+ ///
4450/// Note that before we do so we should ensure its serialization format has backwards- and
4551/// forwards-compatibility prefix/suffixes!
4652#[ derive( Clone ) ]
@@ -74,6 +80,11 @@ impl EnforcingSigner {
7480 disable_revocation_policy_check
7581 }
7682 }
83+
84+ #[ cfg( test) ]
85+ pub fn get_enforcement_state ( & self ) -> MutexGuard < EnforcementState > {
86+ self . state . lock ( ) . unwrap ( )
87+ }
7788}
7889
7990impl BaseSign for EnforcingSigner {
@@ -84,12 +95,20 @@ impl BaseSign for EnforcingSigner {
8495 fn release_commitment_secret ( & self , idx : u64 ) -> [ u8 ; 32 ] {
8596 {
8697 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;
98+ 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) ;
99+ assert ! ( idx > state. last_holder_commitment, "cannot revoke the last holder commitment - attempted to revoke {} last commitment {}" , idx, state. last_holder_commitment) ;
100+ state. last_holder_revoked_commitment = idx;
89101 }
90102 self . inner . release_commitment_secret ( idx)
91103 }
92104
105+ fn validate_holder_commitment ( & self , holder_tx : & HolderCommitmentTransaction ) {
106+ let mut state = self . state . lock ( ) . unwrap ( ) ;
107+ let idx = holder_tx. commitment_number ( ) ;
108+ 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) ;
109+ state. last_holder_commitment = idx;
110+ }
111+
93112 fn pubkeys ( & self ) -> & ChannelPublicKeys { self . inner . pubkeys ( ) }
94113 fn channel_keys_id ( & self ) -> [ u8 ; 32 ] { self . inner . channel_keys_id ( ) }
95114
@@ -116,10 +135,10 @@ impl BaseSign for EnforcingSigner {
116135
117136 let state = self . state . lock ( ) . unwrap ( ) ;
118137 let commitment_number = trusted_tx. commitment_number ( ) ;
119- if state. revoked_commitment - 1 != commitment_number && state. revoked_commitment - 2 != commitment_number {
138+ if state. last_holder_revoked_commitment - 1 != commitment_number && state. last_holder_revoked_commitment - 2 != commitment_number {
120139 if !self . disable_revocation_policy_check {
121140 panic ! ( "can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}" ,
122- state. revoked_commitment , commitment_number, self . inner. commitment_seed[ 0 ] )
141+ state. last_holder_revoked_commitment , commitment_number, self . inner. commitment_seed[ 0 ] )
123142 }
124143 }
125144
@@ -212,16 +231,18 @@ pub struct EnforcementState {
212231 /// The last counterparty commitment number we signed, backwards counting
213232 pub last_counterparty_commitment : u64 ,
214233 /// The last holder commitment number we revoked, backwards counting
215- pub revoked_commitment : u64 ,
216-
234+ pub last_holder_revoked_commitment : u64 ,
235+ /// The last validated holder commitment number, backwards counting
236+ pub last_holder_commitment : u64 ,
217237}
218238
219239impl EnforcementState {
220240 /// Enforcement state for a new channel
221241 pub fn new ( ) -> Self {
222242 EnforcementState {
223243 last_counterparty_commitment : INITIAL_REVOKED_COMMITMENT_NUMBER ,
224- revoked_commitment : INITIAL_REVOKED_COMMITMENT_NUMBER ,
244+ last_holder_revoked_commitment : INITIAL_REVOKED_COMMITMENT_NUMBER ,
245+ last_holder_commitment : INITIAL_REVOKED_COMMITMENT_NUMBER ,
225246 }
226247 }
227248}
0 commit comments