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