@@ -160,6 +160,21 @@ struct OnionKeys {
160
160
mu : [ u8 ; 32 ] ,
161
161
}
162
162
163
+ pub struct ChannelDetails {
164
+ /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
165
+ /// thereafter this is the txid of the funding transaction xor the funding transaction output).
166
+ /// Note that this means this value is *not* persistent - it can change once during the
167
+ /// lifetime of the channel.
168
+ pub channel_id : Uint256 ,
169
+ /// The position of the funding transaction in the chain. None if the funding transaction has
170
+ /// not yet been confirmed and the channel fully opened.
171
+ pub short_channel_id : Option < u64 > ,
172
+ pub remote_network_id : PublicKey ,
173
+ pub channel_value_satoshis : u64 ,
174
+ /// The user_id passed in to create_channel, or 0 if the channel was inbound.
175
+ pub user_id : u64 ,
176
+ }
177
+
163
178
impl ChannelManager {
164
179
/// Constructs a new ChannelManager to hold several channels and route between them. This is
165
180
/// the main "logic hub" for all channel-related actions, and implements ChannelMessageHandler.
@@ -206,6 +221,47 @@ impl ChannelManager {
206
221
}
207
222
}
208
223
224
+ /// Gets the list of open channels, in random order. See ChannelDetail field documentation for
225
+ /// more information.
226
+ pub fn list_channels ( & self ) -> Vec < ChannelDetails > {
227
+ let channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
228
+ let mut res = Vec :: with_capacity ( channel_state. by_id . len ( ) ) ;
229
+ for ( channel_id, channel) in channel_state. by_id . iter ( ) {
230
+ res. push ( ChannelDetails {
231
+ channel_id : ( * channel_id) . clone ( ) ,
232
+ short_channel_id : channel. get_short_channel_id ( ) ,
233
+ remote_network_id : channel. get_their_node_id ( ) ,
234
+ channel_value_satoshis : channel. get_value_satoshis ( ) ,
235
+ user_id : channel. get_user_id ( ) ,
236
+ } ) ;
237
+ }
238
+ res
239
+ }
240
+
241
+ /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs
242
+ /// will be accepted on the given channel, and after additional timeout/the closing of all
243
+ /// pending HTLCs, the channel will be closed on chain.
244
+ pub fn close_channel ( & self , channel_id : & Uint256 ) -> Result < msgs:: Shutdown , HandleError > {
245
+ let res = {
246
+ let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
247
+ match channel_state. by_id . entry ( channel_id. clone ( ) ) {
248
+ hash_map:: Entry :: Occupied ( mut chan_entry) => {
249
+ let res = chan_entry. get_mut ( ) . get_shutdown ( ) ?;
250
+ if chan_entry. get ( ) . is_shutdown ( ) {
251
+ chan_entry. remove_entry ( ) ;
252
+ }
253
+ res
254
+ } ,
255
+ hash_map:: Entry :: Vacant ( _) => return Err ( HandleError { err : "No such channel" , msg : None } )
256
+ }
257
+ } ;
258
+ for payment_hash in res. 1 {
259
+ // unknown_next_peer...I dunno who that is anymore....
260
+ self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , & payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 10 , data : & [ 0 ; 0 ] } ) ;
261
+ }
262
+ Ok ( res. 0 )
263
+ }
264
+
209
265
#[ inline]
210
266
fn gen_rho_mu_from_shared_secret ( shared_secret : & SharedSecret ) -> ( [ u8 ; 32 ] , [ u8 ; 32 ] ) {
211
267
( {
@@ -1438,6 +1494,7 @@ mod tests {
1438
1494
1439
1495
use bitcoin:: util:: misc:: hex_bytes;
1440
1496
use bitcoin:: util:: hash:: Sha256dHash ;
1497
+ use bitcoin:: util:: uint:: Uint256 ;
1441
1498
use bitcoin:: blockdata:: block:: BlockHeader ;
1442
1499
use bitcoin:: blockdata:: transaction:: Transaction ;
1443
1500
use bitcoin:: network:: constants:: Network ;
@@ -1452,7 +1509,7 @@ mod tests {
1452
1509
1453
1510
use rand:: { thread_rng, Rng } ;
1454
1511
1455
- use std:: sync:: Arc ;
1512
+ use std:: sync:: { Arc , Mutex } ;
1456
1513
use std:: default:: Default ;
1457
1514
use std:: time:: Instant ;
1458
1515
@@ -1617,7 +1674,7 @@ mod tests {
1617
1674
}
1618
1675
}
1619
1676
1620
- fn create_chan_between_nodes ( node_a : & ChannelManager , chain_a : & chaininterface:: ChainWatchInterfaceUtil , node_b : & ChannelManager , chain_b : & chaininterface:: ChainWatchInterfaceUtil ) -> ( msgs:: ChannelAnnouncement , msgs:: ChannelUpdate , msgs:: ChannelUpdate ) {
1677
+ fn create_chan_between_nodes ( node_a : & ChannelManager , chain_a : & chaininterface:: ChainWatchInterfaceUtil , node_b : & ChannelManager , chain_b : & chaininterface:: ChainWatchInterfaceUtil ) -> ( msgs:: ChannelAnnouncement , msgs:: ChannelUpdate , msgs:: ChannelUpdate , Uint256 ) {
1621
1678
let open_chan = node_a. create_channel ( node_b. get_our_node_id ( ) , 100000 , 42 ) . unwrap ( ) ;
1622
1679
let accept_chan = node_b. handle_open_channel ( & node_a. get_our_node_id ( ) , & open_chan) . unwrap ( ) ;
1623
1680
node_a. handle_accept_channel ( & node_b. get_our_node_id ( ) , & accept_chan) . unwrap ( ) ;
@@ -1674,12 +1731,15 @@ mod tests {
1674
1731
_ => panic ! ( "Unexpected event" ) ,
1675
1732
} ;
1676
1733
1734
+ let channel_id;
1735
+
1677
1736
confirm_transaction ( & chain_b, & tx) ;
1678
1737
let events_5 = node_b. get_and_clear_pending_events ( ) ;
1679
1738
assert_eq ! ( events_5. len( ) , 1 ) ;
1680
1739
let as_announcement_sigs = match events_5[ 0 ] {
1681
1740
Event :: SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => {
1682
1741
assert_eq ! ( * node_id, node_a. get_our_node_id( ) ) ;
1742
+ channel_id = msg. channel_id . clone ( ) ;
1683
1743
let as_announcement_sigs = node_a. handle_funding_locked ( & node_b. get_our_node_id ( ) , msg) . unwrap ( ) . unwrap ( ) ;
1684
1744
node_a. handle_announcement_signatures ( & node_b. get_our_node_id ( ) , & ( * announcement_sigs) . clone ( ) . unwrap ( ) ) . unwrap ( ) ;
1685
1745
as_announcement_sigs
@@ -1711,7 +1771,42 @@ mod tests {
1711
1771
CHAN_COUNT += 1 ;
1712
1772
}
1713
1773
1714
- ( ( * announcement) . clone ( ) , ( * as_update) . clone ( ) , ( * bs_update) . clone ( ) )
1774
+ ( ( * announcement) . clone ( ) , ( * as_update) . clone ( ) , ( * bs_update) . clone ( ) , channel_id)
1775
+ }
1776
+
1777
+ fn close_channel ( outbound_node : & ChannelManager , outbound_broadcaster : & test_utils:: TestBroadcaster , inbound_node : & ChannelManager , inbound_broadcaster : & test_utils:: TestBroadcaster , channel_id : & Uint256 , close_inbound_first : bool ) {
1778
+ let ( node_a, broadcaster_a) = if close_inbound_first { ( inbound_node, inbound_broadcaster) } else { ( outbound_node, outbound_broadcaster) } ;
1779
+ let ( node_b, broadcaster_b) = if close_inbound_first { ( outbound_node, outbound_broadcaster) } else { ( inbound_node, inbound_broadcaster) } ;
1780
+ let ( tx_a, tx_b) ;
1781
+
1782
+ let shutdown_a = node_a. close_channel ( channel_id) . unwrap ( ) ;
1783
+ let ( shutdown_b, mut closing_signed_b) = node_b. handle_shutdown ( & node_a. get_our_node_id ( ) , & shutdown_a) . unwrap ( ) ;
1784
+ if !close_inbound_first {
1785
+ assert ! ( closing_signed_b. is_none( ) ) ;
1786
+ }
1787
+ let ( empty_a, mut closing_signed_a) = node_a. handle_shutdown ( & node_b. get_our_node_id ( ) , & shutdown_b. unwrap ( ) ) . unwrap ( ) ;
1788
+ assert ! ( empty_a. is_none( ) ) ;
1789
+ if close_inbound_first {
1790
+ assert ! ( closing_signed_a. is_none( ) ) ;
1791
+ closing_signed_a = node_a. handle_closing_signed ( & node_b. get_our_node_id ( ) , & closing_signed_b. unwrap ( ) ) . unwrap ( ) ;
1792
+ assert_eq ! ( broadcaster_a. txn_broadcasted. lock( ) . unwrap( ) . len( ) , 1 ) ;
1793
+ tx_a = broadcaster_a. txn_broadcasted . lock ( ) . unwrap ( ) . remove ( 0 ) ;
1794
+
1795
+ let empty_b = node_b. handle_closing_signed ( & node_a. get_our_node_id ( ) , & closing_signed_a. unwrap ( ) ) . unwrap ( ) ;
1796
+ assert ! ( empty_b. is_none( ) ) ;
1797
+ assert_eq ! ( broadcaster_b. txn_broadcasted. lock( ) . unwrap( ) . len( ) , 1 ) ;
1798
+ tx_b = broadcaster_b. txn_broadcasted . lock ( ) . unwrap ( ) . remove ( 0 ) ;
1799
+ } else {
1800
+ closing_signed_b = node_b. handle_closing_signed ( & node_a. get_our_node_id ( ) , & closing_signed_a. unwrap ( ) ) . unwrap ( ) ;
1801
+ assert_eq ! ( broadcaster_b. txn_broadcasted. lock( ) . unwrap( ) . len( ) , 1 ) ;
1802
+ tx_b = broadcaster_b. txn_broadcasted . lock ( ) . unwrap ( ) . remove ( 0 ) ;
1803
+
1804
+ let empty_a2 = node_a. handle_closing_signed ( & node_b. get_our_node_id ( ) , & closing_signed_b. unwrap ( ) ) . unwrap ( ) ;
1805
+ assert ! ( empty_a2. is_none( ) ) ;
1806
+ assert_eq ! ( broadcaster_a. txn_broadcasted. lock( ) . unwrap( ) . len( ) , 1 ) ;
1807
+ tx_a = broadcaster_a. txn_broadcasted . lock ( ) . unwrap ( ) . remove ( 0 ) ;
1808
+ }
1809
+ assert_eq ! ( tx_a, tx_b) ;
1715
1810
}
1716
1811
1717
1812
struct SendEvent {
@@ -1925,7 +2020,7 @@ mod tests {
1925
2020
let feeest_1 = Arc :: new ( test_utils:: TestFeeEstimator { sat_per_vbyte : 1 } ) ;
1926
2021
let chain_monitor_1 = Arc :: new ( chaininterface:: ChainWatchInterfaceUtil :: new ( ) ) ;
1927
2022
let chan_monitor_1 = Arc :: new ( test_utils:: TestChannelMonitor { } ) ;
1928
- let tx_broadcaster_1 = Arc :: new ( test_utils:: TestBroadcaster { } ) ;
2023
+ let tx_broadcaster_1 = Arc :: new ( test_utils:: TestBroadcaster { txn_broadcasted : Mutex :: new ( Vec :: new ( ) ) } ) ;
1929
2024
let node_id_1 = {
1930
2025
let mut key_slice = [ 0 ; 32 ] ;
1931
2026
rng. fill_bytes ( & mut key_slice) ;
@@ -1937,7 +2032,7 @@ mod tests {
1937
2032
let feeest_2 = Arc :: new ( test_utils:: TestFeeEstimator { sat_per_vbyte : 1 } ) ;
1938
2033
let chain_monitor_2 = Arc :: new ( chaininterface:: ChainWatchInterfaceUtil :: new ( ) ) ;
1939
2034
let chan_monitor_2 = Arc :: new ( test_utils:: TestChannelMonitor { } ) ;
1940
- let tx_broadcaster_2 = Arc :: new ( test_utils:: TestBroadcaster { } ) ;
2035
+ let tx_broadcaster_2 = Arc :: new ( test_utils:: TestBroadcaster { txn_broadcasted : Mutex :: new ( Vec :: new ( ) ) } ) ;
1941
2036
let node_id_2 = {
1942
2037
let mut key_slice = [ 0 ; 32 ] ;
1943
2038
rng. fill_bytes ( & mut key_slice) ;
@@ -1949,7 +2044,7 @@ mod tests {
1949
2044
let feeest_3 = Arc :: new ( test_utils:: TestFeeEstimator { sat_per_vbyte : 1 } ) ;
1950
2045
let chain_monitor_3 = Arc :: new ( chaininterface:: ChainWatchInterfaceUtil :: new ( ) ) ;
1951
2046
let chan_monitor_3 = Arc :: new ( test_utils:: TestChannelMonitor { } ) ;
1952
- let tx_broadcaster_3 = Arc :: new ( test_utils:: TestBroadcaster { } ) ;
2047
+ let tx_broadcaster_3 = Arc :: new ( test_utils:: TestBroadcaster { txn_broadcasted : Mutex :: new ( Vec :: new ( ) ) } ) ;
1953
2048
let node_id_3 = {
1954
2049
let mut key_slice = [ 0 ; 32 ] ;
1955
2050
rng. fill_bytes ( & mut key_slice) ;
@@ -1961,7 +2056,7 @@ mod tests {
1961
2056
let feeest_4 = Arc :: new ( test_utils:: TestFeeEstimator { sat_per_vbyte : 1 } ) ;
1962
2057
let chain_monitor_4 = Arc :: new ( chaininterface:: ChainWatchInterfaceUtil :: new ( ) ) ;
1963
2058
let chan_monitor_4 = Arc :: new ( test_utils:: TestChannelMonitor { } ) ;
1964
- let tx_broadcaster_4 = Arc :: new ( test_utils:: TestBroadcaster { } ) ;
2059
+ let tx_broadcaster_4 = Arc :: new ( test_utils:: TestBroadcaster { txn_broadcasted : Mutex :: new ( Vec :: new ( ) ) } ) ;
1965
2060
let node_id_4 = {
1966
2061
let mut key_slice = [ 0 ; 32 ] ;
1967
2062
rng. fill_bytes ( & mut key_slice) ;
@@ -2093,6 +2188,12 @@ mod tests {
2093
2188
claim_payment ( & node_1, & vec ! ( & * node_2, & * node_4) [ ..] , payment_preimage_4) ;
2094
2189
claim_payment ( & node_1, & vec ! ( & * node_2, & * node_4) [ ..] , payment_preimage_5) ;
2095
2190
2191
+ // Close down the channels...
2192
+ close_channel ( & node_1, & tx_broadcaster_1, & node_2, & tx_broadcaster_2, & chan_announcement_1. 3 , true ) ;
2193
+ close_channel ( & node_2, & tx_broadcaster_2, & node_3, & tx_broadcaster_3, & chan_announcement_2. 3 , false ) ;
2194
+ close_channel ( & node_3, & tx_broadcaster_3, & node_4, & tx_broadcaster_4, & chan_announcement_3. 3 , true ) ;
2195
+ close_channel ( & node_2, & tx_broadcaster_2, & node_4, & tx_broadcaster_4, & chan_announcement_4. 3 , false ) ;
2196
+
2096
2197
// Check that we processed all pending events
2097
2198
for node in vec ! ( & node_1, & node_2, & node_3, & node_4) {
2098
2199
assert_eq ! ( node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
0 commit comments