@@ -764,6 +764,173 @@ impl Readable for IrrevocablyResolvedHTLC {
764
764
}
765
765
}
766
766
767
+ /// [StubChannel] is the smallest unit of [OurPeerStorage], it contains
768
+ /// information about a single channel using which we can recover on-chain funds.
769
+ #[ derive( Clone , PartialEq , Eq ) ]
770
+ pub struct StubChannel {
771
+ pub channel_id : ChannelId ,
772
+ pub funding_outpoint : OutPoint ,
773
+ pub channel_value_stoshis : u64 ,
774
+ pub channel_keys_id : [ u8 ; 32 ] ,
775
+ pub commitment_secrets : CounterpartyCommitmentSecrets ,
776
+ pub counterparty_node_id : PublicKey ,
777
+ pub obscure_factor : u64 ,
778
+ pub ( crate ) latest_state : HashMap < Txid , Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
779
+ pub their_cur_per_commitment_points : Option < ( u64 , PublicKey , Option < PublicKey > ) > ,
780
+ pub features : ChannelTypeFeatures ,
781
+ }
782
+
783
+ impl StubChannel {
784
+ pub ( crate ) fn new ( channel_id : ChannelId , funding_outpoint : OutPoint , channel_value_stoshis : u64 , channel_keys_id : [ u8 ; 32 ] ,
785
+ commitment_secrets : CounterpartyCommitmentSecrets , counterparty_node_id : PublicKey , obscure_factor : u64 ,
786
+ latest_state : HashMap < Txid , Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > , their_cur_per_commitment_points : Option < ( u64 , PublicKey , Option < PublicKey > ) > ,
787
+ features : ChannelTypeFeatures ) -> Self {
788
+ StubChannel {
789
+ channel_id,
790
+ funding_outpoint,
791
+ channel_value_stoshis,
792
+ channel_keys_id,
793
+ commitment_secrets,
794
+ counterparty_node_id,
795
+ obscure_factor,
796
+ latest_state,
797
+ their_cur_per_commitment_points,
798
+ features,
799
+ }
800
+ }
801
+ }
802
+
803
+ impl_writeable_tlv_based ! ( StubChannel , {
804
+ ( 0 , channel_id, required) ,
805
+ ( 2 , channel_keys_id, required) ,
806
+ ( 4 , channel_value_stoshis, required) ,
807
+ ( 6 , funding_outpoint, required) ,
808
+ ( 8 , commitment_secrets, required) ,
809
+ ( 10 , counterparty_node_id, required) ,
810
+ ( 12 , obscure_factor, required) ,
811
+ ( 14 , latest_state, required) ,
812
+ ( 16 , their_cur_per_commitment_points, option) ,
813
+ ( 18 , features, required) ,
814
+ } ) ;
815
+
816
+ /// [OurPeerStorage] is used to store our channels using which we
817
+ /// can create our PeerStorage Backup.
818
+ /// This includes timestamp to compare between two given
819
+ /// [OurPeerStorage] and version defines the structure.
820
+ #[ derive( Clone , PartialEq , Eq ) ]
821
+ pub struct OurPeerStorage {
822
+ pub version : u32 ,
823
+ pub timestamp : u32 ,
824
+ pub channels : Vec < StubChannel > ,
825
+ }
826
+
827
+ impl OurPeerStorage {
828
+ pub fn new ( ) -> Self {
829
+ let duration_since_epoch = std:: time:: SystemTime :: now ( )
830
+ . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
831
+ . expect ( "Time must be > 1970" ) ;
832
+
833
+ Self {
834
+ version : 1 ,
835
+ timestamp : duration_since_epoch. as_secs ( ) as u32 ,
836
+ channels : Vec :: new ( ) ,
837
+ }
838
+ }
839
+
840
+ pub fn stub_channel ( & mut self , chan : StubChannel ) {
841
+ self . channels . push ( chan) ;
842
+ }
843
+
844
+ pub ( crate ) fn update_latest_state ( & mut self , cid : ChannelId , txid : Txid , htlc_data : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > , their_cur_per_commitment_points : Option < ( u64 , PublicKey , Option < PublicKey > ) > ) {
845
+ for stub_channel in & mut self . channels {
846
+ if stub_channel. channel_id == cid {
847
+ let mut latest_state = HashMap :: new ( ) ;
848
+ latest_state. insert ( txid, htlc_data) ;
849
+ stub_channel. latest_state = latest_state;
850
+ stub_channel. their_cur_per_commitment_points = their_cur_per_commitment_points;
851
+ return ;
852
+ }
853
+ }
854
+ }
855
+
856
+ pub ( crate ) fn update_state_from_monitor_update ( & mut self , cid : ChannelId , monitor_update : ChannelMonitorUpdate ) -> Result < ( ) , ( ) > {
857
+ for update in monitor_update. updates . iter ( ) {
858
+ match update {
859
+ ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number,
860
+ their_per_commitment_point, .. } => {
861
+ let stub_channels = & self . channels ;
862
+ let mut cur_per_commitment_points = None ;
863
+ for stub_channel in stub_channels {
864
+ if stub_channel. channel_id == cid {
865
+ match stub_channel. their_cur_per_commitment_points {
866
+ Some ( old_points) => {
867
+ if old_points. 0 == commitment_number + 1 {
868
+ cur_per_commitment_points = Some ( ( old_points. 0 , old_points. 1 , Some ( * their_per_commitment_point) ) ) ;
869
+ } else if old_points. 0 == commitment_number + 2 {
870
+ if let Some ( old_second_point) = old_points. 2 {
871
+ cur_per_commitment_points = Some ( ( old_points. 0 - 1 , old_second_point, Some ( * their_per_commitment_point) ) ) ;
872
+ } else {
873
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
874
+ }
875
+ } else {
876
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
877
+ }
878
+ } ,
879
+ None => {
880
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
881
+ }
882
+ }
883
+ }
884
+ }
885
+ let mut htlc_data = htlc_outputs. clone ( ) ;
886
+ for htlc in & mut htlc_data {
887
+ htlc. 1 = None ;
888
+ }
889
+ self . update_latest_state ( cid, * commitment_txid, htlc_data, cur_per_commitment_points) ;
890
+ return Ok ( ( ) ) ;
891
+ }
892
+ _ => { }
893
+ }
894
+ }
895
+ Err ( ( ) )
896
+ }
897
+
898
+ pub fn encrypt_our_peer_storage ( & self , key : [ u8 ; 32 ] ) -> Vec < u8 > {
899
+ let n = 0u64 ;
900
+ let mut peer_storage = VecWriter ( Vec :: new ( ) ) ;
901
+ self . write ( & mut peer_storage) . unwrap ( ) ;
902
+ let mut res = vec ! [ 0 ; peer_storage. 0 . len( ) + 16 ] ;
903
+
904
+ let plaintext = & peer_storage. 0 [ ..] ;
905
+ let mut nonce = [ 0 ; 12 ] ;
906
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
907
+
908
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key, & nonce, b"" ) ;
909
+ let mut tag = [ 0 ; 16 ] ;
910
+ chacha. encrypt ( plaintext, & mut res[ 0 ..plaintext. len ( ) ] , & mut tag) ;
911
+ res[ plaintext. len ( ) ..] . copy_from_slice ( & tag) ;
912
+ res
913
+ }
914
+
915
+ pub fn decrypt_our_peer_storage ( & self , res : & mut [ u8 ] , cyphertext : & [ u8 ] , key : [ u8 ; 32 ] ) -> Result < ( ) , ( ) > {
916
+ let n = 0u64 ;
917
+ let mut nonce = [ 0 ; 12 ] ;
918
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
919
+
920
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key, & nonce, b"" ) ;
921
+ if chacha. variable_time_decrypt ( & cyphertext[ 0 ..cyphertext. len ( ) - 16 ] , res, & cyphertext[ cyphertext. len ( ) - 16 ..] ) . is_err ( ) {
922
+ return Err ( ( ) ) ;
923
+ }
924
+ Ok ( ( ) )
925
+ }
926
+ }
927
+
928
+ impl_writeable_tlv_based ! ( OurPeerStorage , {
929
+ ( 0 , version, ( default_value, 1 ) ) ,
930
+ ( 2 , timestamp, required) ,
931
+ ( 4 , channels, optional_vec) ,
932
+ } ) ;
933
+
767
934
/// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates
768
935
/// on-chain transactions to ensure no loss of funds occurs.
769
936
///
@@ -1439,6 +1606,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1439
1606
self . inner . lock ( ) . unwrap ( ) . get_latest_update_id ( )
1440
1607
}
1441
1608
1609
+ /// Gets the latest claiming info from the ChannelMonitor to update our PeerStorageBackup.
1610
+ pub ( crate ) fn get_latest_commitment_txn_and_its_claiming_info ( & self ) -> Option < ( Txid , Vec < ( HTLCOutputInCommitment , Option < std:: boxed:: Box < HTLCSource > > ) > , Option < ( u64 , PublicKey , Option < PublicKey > ) > ) > {
1611
+ let lock = self . inner . lock ( ) . unwrap ( ) ;
1612
+ if let Some ( latest_txid) = lock. current_counterparty_commitment_txid {
1613
+ return Some ( (
1614
+ latest_txid, lock. counterparty_claimable_outpoints . get ( & latest_txid) . unwrap ( ) . clone ( ) ,
1615
+ lock. their_cur_per_commitment_points
1616
+ ) )
1617
+ }
1618
+
1619
+ None
1620
+ }
1621
+
1442
1622
/// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for.
1443
1623
pub fn get_funding_txo ( & self ) -> ( OutPoint , ScriptBuf ) {
1444
1624
self . inner . lock ( ) . unwrap ( ) . get_funding_txo ( ) . clone ( )
0 commit comments