3
3
//! claim outputs on-chain.
4
4
5
5
use chain:: transaction:: OutPoint ;
6
- use chain:: chaininterface:: { ChainListener , ChainWatchInterface } ;
6
+ use chain:: chaininterface:: { ChainListener , ChainWatchInterface , ChainWatchInterfaceUtil } ;
7
7
use chain:: keysinterface:: { KeysInterface , SpendableOutputDescriptor , KeysManager } ;
8
+ use chain:: keysinterface;
8
9
use ln:: channel:: { COMMITMENT_TX_BASE_WEIGHT , COMMITMENT_TX_WEIGHT_PER_HTLC } ;
9
10
use ln:: channelmanager:: { ChannelManager , ChannelManagerReadArgs , HTLCForwardInfo , RAACommitmentOrder , PaymentPreimage , PaymentHash , BREAKDOWN_TIMEOUT } ;
10
11
use ln:: channelmonitor:: { ChannelMonitor , CLTV_CLAIM_BUFFER , LATENCY_GRACE_PERIOD_BLOCKS , ManyChannelMonitor , ANTI_REORG_DELAY } ;
@@ -18,6 +19,7 @@ use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsPro
18
19
use util:: errors:: APIError ;
19
20
use util:: ser:: { Writeable , ReadableArgs } ;
20
21
use util:: config:: UserConfig ;
22
+ use util:: logger:: Logger ;
21
23
22
24
use bitcoin:: util:: hash:: BitcoinHash ;
23
25
use bitcoin_hashes:: sha256d:: Hash as Sha256dHash ;
@@ -39,7 +41,7 @@ use secp256k1::key::{PublicKey,SecretKey};
39
41
40
42
use std:: collections:: { BTreeSet , HashMap , HashSet } ;
41
43
use std:: default:: Default ;
42
- use std:: sync:: Arc ;
44
+ use std:: sync:: { Arc , Mutex } ;
43
45
use std:: sync:: atomic:: Ordering ;
44
46
use std:: mem;
45
47
@@ -5945,3 +5947,113 @@ fn test_user_configurable_csv_delay() {
5945
5947
}
5946
5948
} else { assert ! ( false ) ; }
5947
5949
}
5950
+
5951
+ #[ test]
5952
+ fn test_data_loss_protect ( ) {
5953
+ // We want to be sure that :
5954
+ // * we don't broadcast our Local Commitment Tx in case of fallen behind
5955
+ // * we close channel in case of detecting other being fallen behind
5956
+ // * we are able to claim our own outputs thanks to remote my_current_per_commitment_point
5957
+ let mut nodes = create_network ( 2 , & [ None , None ] ) ;
5958
+
5959
+ let chan = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1000000 , 1000000 , LocalFeatures :: new ( ) , LocalFeatures :: new ( ) ) ;
5960
+
5961
+ // Cache node A state before any channel update
5962
+ let previous_node_state = nodes[ 0 ] . node . encode ( ) ;
5963
+ let mut previous_chan_monitor_state = test_utils:: TestVecWriter ( Vec :: new ( ) ) ;
5964
+ nodes[ 0 ] . chan_monitor . simple_monitor . monitors . lock ( ) . unwrap ( ) . iter ( ) . next ( ) . unwrap ( ) . 1 . write_for_disk ( & mut previous_chan_monitor_state) . unwrap ( ) ;
5965
+
5966
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 8000000 ) ;
5967
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 8000000 ) ;
5968
+
5969
+ nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
5970
+ nodes[ 1 ] . node . peer_disconnected ( & nodes[ 0 ] . node . get_our_node_id ( ) , false ) ;
5971
+
5972
+ // Restore node A from previous state
5973
+ let logger: Arc < Logger > = Arc :: new ( test_utils:: TestLogger :: with_id ( format ! ( "node {}" , 0 ) ) ) ;
5974
+ let chan_monitor = <( Sha256dHash , ChannelMonitor ) >:: read ( & mut :: std:: io:: Cursor :: new ( previous_chan_monitor_state. 0 ) , Arc :: clone ( & logger) ) . unwrap ( ) . 1 ;
5975
+ let chain_monitor = Arc :: new ( ChainWatchInterfaceUtil :: new ( Network :: Testnet , Arc :: clone ( & logger) ) ) ;
5976
+ let tx_broadcaster = Arc :: new ( test_utils:: TestBroadcaster { txn_broadcasted : Mutex :: new ( Vec :: new ( ) ) } ) ;
5977
+ let feeest = Arc :: new ( test_utils:: TestFeeEstimator { sat_per_kw : 253 } ) ;
5978
+ let monitor = Arc :: new ( test_utils:: TestChannelMonitor :: new ( chain_monitor. clone ( ) , tx_broadcaster. clone ( ) , logger. clone ( ) , feeest. clone ( ) ) ) ;
5979
+ let mut channel_monitors = HashMap :: new ( ) ;
5980
+ channel_monitors. insert ( OutPoint { txid : chan. 3 . txid ( ) , index : 0 } , & chan_monitor) ;
5981
+ let node_state_0 = <( Sha256dHash , ChannelManager ) >:: read ( & mut :: std:: io:: Cursor :: new ( previous_node_state) , ChannelManagerReadArgs {
5982
+ keys_manager : Arc :: new ( keysinterface:: KeysManager :: new ( & nodes[ 0 ] . node_seed , Network :: Testnet , Arc :: clone ( & logger) , 42 , 21 ) ) ,
5983
+ fee_estimator : feeest. clone ( ) ,
5984
+ monitor : monitor. clone ( ) ,
5985
+ chain_monitor : chain_monitor. clone ( ) ,
5986
+ logger : Arc :: clone ( & logger) ,
5987
+ tx_broadcaster,
5988
+ default_config : UserConfig :: new ( ) ,
5989
+ channel_monitors : & channel_monitors
5990
+ } ) . unwrap ( ) . 1 ;
5991
+ nodes[ 0 ] . node = Arc :: new ( node_state_0) ;
5992
+ monitor. add_update_monitor ( OutPoint { txid : chan. 3 . txid ( ) , index : 0 } , chan_monitor. clone ( ) ) . is_ok ( ) ;
5993
+ nodes[ 0 ] . chan_monitor = monitor;
5994
+ nodes[ 0 ] . chain_monitor = chain_monitor;
5995
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
5996
+
5997
+ nodes[ 0 ] . node . peer_connected ( & nodes[ 1 ] . node . get_our_node_id ( ) ) ;
5998
+ nodes[ 1 ] . node . peer_connected ( & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
5999
+
6000
+ let reestablish_0 = get_chan_reestablish_msgs ! ( nodes[ 1 ] , nodes[ 0 ] ) ;
6001
+
6002
+ // Check we update monitor following learning of per_commitment_point from B
6003
+ if let Err ( err) = nodes[ 0 ] . node . handle_channel_reestablish ( & nodes[ 1 ] . node . get_our_node_id ( ) , & reestablish_0[ 0 ] ) {
6004
+ if let Some ( error) = err. action {
6005
+ match error {
6006
+ ErrorAction :: SendErrorMessage { msg } => {
6007
+ assert_eq ! ( msg. data, "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can't do any automated broadcasting" ) ;
6008
+ } ,
6009
+ _ => panic ! ( "Unexpected event!" ) ,
6010
+ }
6011
+ } else { assert ! ( false ) ; }
6012
+ } else { assert ! ( false ) ; }
6013
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
6014
+
6015
+ {
6016
+ let node_txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clone ( ) ;
6017
+ assert_eq ! ( node_txn. len( ) , 0 ) ;
6018
+ }
6019
+
6020
+ let mut reestablish_1 = Vec :: with_capacity ( 1 ) ;
6021
+ for msg in nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) {
6022
+ if let MessageSendEvent :: SendChannelReestablish { ref node_id, ref msg } = msg {
6023
+ assert_eq ! ( * node_id, nodes[ 1 ] . node. get_our_node_id( ) ) ;
6024
+ reestablish_1. push ( msg. clone ( ) ) ;
6025
+ } else if let MessageSendEvent :: BroadcastChannelUpdate { .. } = msg {
6026
+ } else {
6027
+ panic ! ( "Unexpected event" )
6028
+ }
6029
+ }
6030
+
6031
+ // Check we close channel detecting A is fallen-behind
6032
+ if let Err ( err) = nodes[ 1 ] . node . handle_channel_reestablish ( & nodes[ 0 ] . node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) {
6033
+ if let Some ( error) = err. action {
6034
+ match error {
6035
+ ErrorAction :: SendErrorMessage { msg } => {
6036
+ assert_eq ! ( msg. data, "Peer attempted to reestablish channel with a very old local commitment transaction" ) ; } ,
6037
+ _ => panic ! ( "Unexpected event!" ) ,
6038
+ }
6039
+ } else { assert ! ( false ) ; }
6040
+ } else { assert ! ( false ) ; }
6041
+
6042
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
6043
+ assert_eq ! ( events. len( ) , 1 ) ;
6044
+ match events[ 0 ] {
6045
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
6046
+ _ => panic ! ( "Unexpected event" ) ,
6047
+ }
6048
+
6049
+ // Check A is able to claim to_remote output
6050
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clone ( ) ;
6051
+ assert_eq ! ( node_txn. len( ) , 1 ) ;
6052
+ check_spends ! ( node_txn[ 0 ] , chan. 3 . clone( ) ) ;
6053
+ assert_eq ! ( node_txn[ 0 ] . output. len( ) , 2 ) ;
6054
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
6055
+ nodes[ 0 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ node_txn[ 0 ] . clone( ) ] } , 1 ) ;
6056
+ let spend_txn = check_spendable_outputs ! ( nodes[ 0 ] , 1 ) ;
6057
+ assert_eq ! ( spend_txn. len( ) , 1 ) ;
6058
+ check_spends ! ( spend_txn[ 0 ] , node_txn[ 0 ] . clone( ) ) ;
6059
+ }
0 commit comments