@@ -832,6 +832,208 @@ impl Readable for IrrevocablyResolvedHTLC {
832
832
}
833
833
}
834
834
835
+ /// [StubChannel] is the smallest unit of [OurPeerStorage], it contains
836
+ /// information about a single channel using which we can recover on-chain funds.
837
+ #[ derive( Clone , PartialEq , Eq ) ]
838
+ pub struct StubChannel {
839
+ pub ( crate ) channel_id : ChannelId ,
840
+ pub ( crate ) funding_outpoint : OutPoint ,
841
+ pub ( crate ) channel_value_stoshis : u64 ,
842
+ pub ( crate ) channel_keys_id : [ u8 ; 32 ] ,
843
+ pub ( crate ) commitment_secrets : CounterpartyCommitmentSecrets ,
844
+ pub ( crate ) counterparty_node_id : PublicKey ,
845
+ pub ( crate ) counterparty_delayed_payment_base_key : DelayedPaymentBasepoint ,
846
+ pub ( crate ) counterparty_htlc_base_key : HtlcBasepoint ,
847
+ pub ( crate ) on_counterparty_tx_csv : u16 ,
848
+ pub ( crate ) obscure_factor : u64 ,
849
+ pub ( crate ) latest_state : HashMap < Txid , Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
850
+ pub ( crate ) their_cur_per_commitment_points : Option < ( u64 , PublicKey , Option < PublicKey > ) > ,
851
+ pub ( crate ) features : ChannelTypeFeatures ,
852
+ }
853
+
854
+ impl StubChannel {
855
+ pub ( crate ) fn new ( channel_id : ChannelId , funding_outpoint : OutPoint , channel_value_stoshis : u64 , channel_keys_id : [ u8 ; 32 ] ,
856
+ commitment_secrets : CounterpartyCommitmentSecrets , counterparty_node_id : PublicKey , counterparty_delayed_payment_base_key : DelayedPaymentBasepoint , counterparty_htlc_base_key : HtlcBasepoint , on_counterparty_tx_csv : u16 ,
857
+ obscure_factor : u64 , latest_state : HashMap < Txid , Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > , their_cur_per_commitment_points : Option < ( u64 , PublicKey , Option < PublicKey > ) > ,
858
+ features : ChannelTypeFeatures ) -> Self {
859
+ StubChannel {
860
+ channel_id,
861
+ funding_outpoint,
862
+ channel_value_stoshis,
863
+ channel_keys_id,
864
+ commitment_secrets,
865
+ counterparty_node_id,
866
+ counterparty_delayed_payment_base_key,
867
+ counterparty_htlc_base_key,
868
+ on_counterparty_tx_csv,
869
+ obscure_factor,
870
+ latest_state,
871
+ their_cur_per_commitment_points,
872
+ features,
873
+ }
874
+ }
875
+
876
+ /// Get the min seen secret from the commitment secrets.
877
+ pub fn get_min_seen_secret ( & self ) -> u64 {
878
+ return self . commitment_secrets . get_min_seen_secret ( ) ;
879
+ }
880
+ }
881
+
882
+ impl_writeable_tlv_based ! ( StubChannel , {
883
+ ( 0 , channel_id, required) ,
884
+ ( 2 , channel_keys_id, required) ,
885
+ ( 4 , channel_value_stoshis, required) ,
886
+ ( 6 , funding_outpoint, required) ,
887
+ ( 8 , commitment_secrets, required) ,
888
+ ( 10 , counterparty_node_id, required) ,
889
+ ( 12 , counterparty_delayed_payment_base_key, required) ,
890
+ ( 14 , counterparty_htlc_base_key, required) ,
891
+ ( 16 , on_counterparty_tx_csv, required) ,
892
+ ( 18 , obscure_factor, required) ,
893
+ ( 20 , latest_state, required) ,
894
+ ( 22 , their_cur_per_commitment_points, option) ,
895
+ ( 24 , features, required) ,
896
+ } ) ;
897
+
898
+ /// [`OurPeerStorage`] is used to store our channels using which we
899
+ /// can create our PeerStorage Backup.
900
+ /// This includes timestamp to compare between two given
901
+ /// [`OurPeerStorage`] and version defines the structure.
902
+ #[ derive( Clone , PartialEq , Eq ) ]
903
+ pub struct OurPeerStorage {
904
+ version : u32 ,
905
+ timestamp : u32 ,
906
+ channels : Vec < StubChannel > ,
907
+ }
908
+
909
+ impl OurPeerStorage {
910
+ /// Returns a [`OurPeerStorage`] with version 1 and current timestamp.
911
+ pub fn new ( ) -> Self {
912
+ let duration_since_epoch = std:: time:: SystemTime :: now ( )
913
+ . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
914
+ . expect ( "Time must be > 1970" ) ;
915
+
916
+ Self {
917
+ version : 1 ,
918
+ timestamp : duration_since_epoch. as_secs ( ) as u32 ,
919
+ channels : Vec :: new ( ) ,
920
+ }
921
+ }
922
+
923
+ /// Stubs a channel inside [`OurPeerStorage`]
924
+ pub fn stub_channel ( & mut self , chan : StubChannel ) {
925
+ self . channels . push ( chan) ;
926
+ }
927
+
928
+ /// Get a reference of `channels` array from [`StubChannel::channels`]
929
+ pub fn get_channels ( & self ) -> & Vec < StubChannel > {
930
+ self . channels . as_ref ( )
931
+ }
932
+
933
+ 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 > ) > ) {
934
+ for stub_channel in & mut self . channels {
935
+ if stub_channel. channel_id == cid {
936
+ let mut latest_state = HashMap :: new ( ) ;
937
+ latest_state. insert ( txid, htlc_data) ;
938
+ stub_channel. latest_state = latest_state;
939
+ stub_channel. their_cur_per_commitment_points = their_cur_per_commitment_points;
940
+ return ;
941
+ }
942
+ }
943
+ }
944
+
945
+ pub ( crate ) fn provide_secret ( & mut self , cid : ChannelId , idx : u64 , secret : [ u8 ; 32 ] ) -> Result < ( ) , ( ) > {
946
+ for stub_channel in & mut self . channels {
947
+ if stub_channel. channel_id == cid {
948
+ return stub_channel. commitment_secrets . provide_secret ( idx, secret) ;
949
+ }
950
+ }
951
+ return Err ( ( ) ) ;
952
+ }
953
+
954
+ /// This is called to update the data of the latest state inside [`OurPeerStorage`] using
955
+ /// [`ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo`]
956
+ pub ( crate ) fn update_state_from_monitor_update ( & mut self , cid : ChannelId , monitor_update : ChannelMonitorUpdate ) -> Result < ( ) , ( ) > {
957
+ for update in monitor_update. updates . iter ( ) {
958
+ match update {
959
+ ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number,
960
+ their_per_commitment_point, .. } => {
961
+ let stub_channels = & self . channels ;
962
+ let mut cur_per_commitment_points = None ;
963
+ for stub_channel in stub_channels {
964
+ if stub_channel. channel_id == cid {
965
+ match stub_channel. their_cur_per_commitment_points {
966
+ Some ( old_points) => {
967
+ if old_points. 0 == commitment_number + 1 {
968
+ cur_per_commitment_points = Some ( ( old_points. 0 , old_points. 1 , Some ( * their_per_commitment_point) ) ) ;
969
+ } else if old_points. 0 == commitment_number + 2 {
970
+ if let Some ( old_second_point) = old_points. 2 {
971
+ cur_per_commitment_points = Some ( ( old_points. 0 - 1 , old_second_point, Some ( * their_per_commitment_point) ) ) ;
972
+ } else {
973
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
974
+ }
975
+ } else {
976
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
977
+ }
978
+ } ,
979
+ None => {
980
+ cur_per_commitment_points = Some ( ( * commitment_number, * their_per_commitment_point, None ) ) ;
981
+ }
982
+ }
983
+ }
984
+ }
985
+ let mut htlc_data = htlc_outputs. clone ( ) ;
986
+ for htlc in & mut htlc_data {
987
+ htlc. 1 = None ;
988
+ }
989
+ self . update_latest_state ( cid, * commitment_txid, htlc_data, cur_per_commitment_points) ;
990
+ return Ok ( ( ) ) ;
991
+ }
992
+ _ => { }
993
+ }
994
+ }
995
+ Err ( ( ) )
996
+ }
997
+
998
+ /// Encrypt [`OurPeerStorage`] using the `key` and return a Vec<u8> containing the result.
999
+ pub fn encrypt_our_peer_storage ( & self , key : [ u8 ; 32 ] ) -> Vec < u8 > {
1000
+ let n = 0u64 ;
1001
+ let mut peer_storage = VecWriter ( Vec :: new ( ) ) ;
1002
+ self . write ( & mut peer_storage) . unwrap ( ) ;
1003
+ let mut res = vec ! [ 0 ; peer_storage. 0 . len( ) + 16 ] ;
1004
+
1005
+ let plaintext = & peer_storage. 0 [ ..] ;
1006
+ let mut nonce = [ 0 ; 12 ] ;
1007
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
1008
+
1009
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key, & nonce, b"" ) ;
1010
+ let mut tag = [ 0 ; 16 ] ;
1011
+ chacha. encrypt ( plaintext, & mut res[ 0 ..plaintext. len ( ) ] , & mut tag) ;
1012
+ res[ plaintext. len ( ) ..] . copy_from_slice ( & tag) ;
1013
+ res
1014
+ }
1015
+
1016
+ /// Decrypt `OurPeerStorage` using the `key`, result is stored inside the `res`.
1017
+ /// Returns an error if the the `cyphertext` is not correct.
1018
+ pub fn decrypt_our_peer_storage ( & self , res : & mut [ u8 ] , cyphertext : & [ u8 ] , key : [ u8 ; 32 ] ) -> Result < ( ) , ( ) > {
1019
+ let n = 0u64 ;
1020
+ let mut nonce = [ 0 ; 12 ] ;
1021
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
1022
+
1023
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key, & nonce, b"" ) ;
1024
+ if chacha. variable_time_decrypt ( & cyphertext[ 0 ..cyphertext. len ( ) - 16 ] , res, & cyphertext[ cyphertext. len ( ) - 16 ..] ) . is_err ( ) {
1025
+ return Err ( ( ) ) ;
1026
+ }
1027
+ Ok ( ( ) )
1028
+ }
1029
+ }
1030
+
1031
+ impl_writeable_tlv_based ! ( OurPeerStorage , {
1032
+ ( 0 , version, ( default_value, 1 ) ) ,
1033
+ ( 2 , timestamp, required) ,
1034
+ ( 4 , channels, optional_vec) ,
1035
+ } ) ;
1036
+
835
1037
/// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates
836
1038
/// on-chain transactions to ensure no loss of funds occurs.
837
1039
///
@@ -1532,6 +1734,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1532
1734
self . inner . lock ( ) . unwrap ( ) . get_latest_update_id ( )
1533
1735
}
1534
1736
1737
+ /// Gets the latest claiming info from the ChannelMonitor to update our PeerStorageBackup.
1738
+ 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 > ) > ) > {
1739
+ let lock = self . inner . lock ( ) . unwrap ( ) ;
1740
+ if let Some ( latest_txid) = lock. current_counterparty_commitment_txid {
1741
+ return Some ( (
1742
+ latest_txid, lock. counterparty_claimable_outpoints . get ( & latest_txid) . unwrap ( ) . clone ( ) ,
1743
+ lock. their_cur_per_commitment_points
1744
+ ) )
1745
+ }
1746
+
1747
+ None
1748
+ }
1749
+
1535
1750
/// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for.
1536
1751
pub fn get_funding_txo ( & self ) -> ( OutPoint , ScriptBuf ) {
1537
1752
self . inner . lock ( ) . unwrap ( ) . get_funding_txo ( ) . clone ( )
0 commit comments