@@ -1068,6 +1068,8 @@ mod tests {
1068
1068
use bitcoin_hashes:: Hash ;
1069
1069
use bitcoin:: network:: constants:: Network ;
1070
1070
use bitcoin:: blockdata:: constants:: genesis_block;
1071
+ use bitcoin:: blockdata:: script:: Builder ;
1072
+ use bitcoin:: blockdata:: opcodes;
1071
1073
use bitcoin:: util:: hash:: BitcoinHash ;
1072
1074
1073
1075
use hex;
@@ -1077,6 +1079,7 @@ mod tests {
1077
1079
use secp256k1:: Secp256k1 ;
1078
1080
1079
1081
use std:: sync:: Arc ;
1082
+ use std:: collections:: btree_map:: Entry as BtreeEntry ;
1080
1083
1081
1084
fn create_router ( ) -> ( Secp256k1 < All > , PublicKey , Router ) {
1082
1085
let secp_ctx = Secp256k1 :: new ( ) ;
@@ -1969,4 +1972,195 @@ mod tests {
1969
1972
Err ( e) => assert_eq ! ( e. err, "Update older than last processed update" )
1970
1973
} ;
1971
1974
}
1975
+
1976
+ #[ test]
1977
+ fn handling_channel_announcements ( ) {
1978
+ let secp_ctx = Secp256k1 :: new ( ) ;
1979
+ let our_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice (
1980
+ & hex:: decode ( "0101010101010101010101010101010101010101010101010101010101010101" ) . unwrap ( ) [ ..] ) . unwrap ( ) ) ;
1981
+ let logger: Arc < Logger > = Arc :: new ( test_utils:: TestLogger :: new ( ) ) ;
1982
+ let chain_monitor = Arc :: new ( test_utils:: TestChainWatcher :: new ( ) ) ;
1983
+ let router = Router :: new ( our_id, chain_monitor. clone ( ) , Arc :: clone ( & logger) ) ;
1984
+
1985
+ let node_1_privkey = & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
1986
+ let node_2_privkey = & SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ;
1987
+ let node_id_1 = PublicKey :: from_secret_key ( & secp_ctx, node_1_privkey) ;
1988
+ let node_id_2 = PublicKey :: from_secret_key ( & secp_ctx, node_2_privkey) ;
1989
+ let node_1_btckey = & SecretKey :: from_slice ( & [ 40 ; 32 ] ) . unwrap ( ) ;
1990
+ let node_2_btckey = & SecretKey :: from_slice ( & [ 39 ; 32 ] ) . unwrap ( ) ;
1991
+
1992
+ let good_script = Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_PUSHNUM_2 )
1993
+ . push_slice ( & PublicKey :: from_secret_key ( & secp_ctx, node_1_btckey) . serialize ( ) )
1994
+ . push_slice ( & PublicKey :: from_secret_key ( & secp_ctx, node_2_btckey) . serialize ( ) )
1995
+ . push_opcode ( opcodes:: all:: OP_PUSHNUM_2 )
1996
+ . push_opcode ( opcodes:: all:: OP_CHECKMULTISIG ) . into_script ( ) . to_v0_p2wsh ( ) ;
1997
+
1998
+
1999
+ let mut unsigned_announcement = UnsignedChannelAnnouncement {
2000
+ features : ChannelFeatures :: supported ( ) ,
2001
+ chain_hash : genesis_block ( Network :: Testnet ) . header . bitcoin_hash ( ) ,
2002
+ short_channel_id : 0 ,
2003
+ node_id_1,
2004
+ node_id_2,
2005
+ bitcoin_key_1 : PublicKey :: from_secret_key ( & secp_ctx, node_1_btckey) ,
2006
+ bitcoin_key_2 : PublicKey :: from_secret_key ( & secp_ctx, node_2_btckey) ,
2007
+ excess_data : Vec :: new ( ) ,
2008
+ } ;
2009
+
2010
+ let channel_key = NetworkMap :: get_key ( unsigned_announcement. short_channel_id ,
2011
+ unsigned_announcement. chain_hash ) ;
2012
+
2013
+ let mut msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2014
+ let valid_announcement = ChannelAnnouncement {
2015
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2016
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2017
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2018
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2019
+ contents : unsigned_announcement. clone ( ) ,
2020
+ } ;
2021
+
2022
+ // Test if the UTXO lookups were not supported
2023
+ * chain_monitor. utxo_ret . lock ( ) . unwrap ( ) = Err ( chaininterface:: ChainError :: NotSupported ) ;
2024
+
2025
+ match router. handle_channel_announcement ( & valid_announcement) {
2026
+ Ok ( res) => assert ! ( res) ,
2027
+ _ => panic ! ( )
2028
+ } ;
2029
+ {
2030
+ let network = router. network_map . write ( ) . unwrap ( ) ;
2031
+ match network. channels . get ( & channel_key) {
2032
+ None => panic ! ( ) ,
2033
+ Some ( _) => ( )
2034
+ }
2035
+ }
2036
+
2037
+ // If we receive announcement for the same channel (with UTXO lookups disabled),
2038
+ // drop new one on the floor, since we can't see any changes.
2039
+ match router. handle_channel_announcement ( & valid_announcement) {
2040
+ Ok ( _) => panic ! ( ) ,
2041
+ Err ( e) => assert_eq ! ( e. err, "Already have knowledge of channel" )
2042
+ } ;
2043
+
2044
+
2045
+ // Test if an associated transaction were not on-chain (or not confirmed).
2046
+ * chain_monitor. utxo_ret . lock ( ) . unwrap ( ) = Err ( chaininterface:: ChainError :: UnknownTx ) ;
2047
+ unsigned_announcement. short_channel_id += 1 ;
2048
+
2049
+ msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2050
+ let valid_announcement = ChannelAnnouncement {
2051
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2052
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2053
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2054
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2055
+ contents : unsigned_announcement. clone ( ) ,
2056
+ } ;
2057
+
2058
+ match router. handle_channel_announcement ( & valid_announcement) {
2059
+ Ok ( _) => panic ! ( ) ,
2060
+ Err ( e) => assert_eq ! ( e. err, "Channel announced without corresponding UTXO entry" )
2061
+ } ;
2062
+
2063
+
2064
+ // Now test if the transaction is found in the UTXO set and the script is correct.
2065
+ unsigned_announcement. short_channel_id += 1 ;
2066
+ * chain_monitor. utxo_ret . lock ( ) . unwrap ( ) = Ok ( ( good_script. clone ( ) , 0 ) ) ;
2067
+ let channel_key = NetworkMap :: get_key ( unsigned_announcement. short_channel_id ,
2068
+ unsigned_announcement. chain_hash ) ;
2069
+
2070
+ msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2071
+ let valid_announcement = ChannelAnnouncement {
2072
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2073
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2074
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2075
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2076
+ contents : unsigned_announcement. clone ( ) ,
2077
+ } ;
2078
+ match router. handle_channel_announcement ( & valid_announcement) {
2079
+ Ok ( res) => assert ! ( res) ,
2080
+ _ => panic ! ( )
2081
+ } ;
2082
+ {
2083
+ let network = router. network_map . write ( ) . unwrap ( ) ;
2084
+ match network. channels . get ( & channel_key) {
2085
+ None => panic ! ( ) ,
2086
+ Some ( _) => ( )
2087
+ }
2088
+ }
2089
+
2090
+ // If we receive announcement for the same channel (but TX is not confirmed),
2091
+ // drop new one on the floor, since we can't see any changes.
2092
+ * chain_monitor. utxo_ret . lock ( ) . unwrap ( ) = Err ( chaininterface:: ChainError :: UnknownTx ) ;
2093
+ match router. handle_channel_announcement ( & valid_announcement) {
2094
+ Ok ( _) => panic ! ( ) ,
2095
+ Err ( e) => assert_eq ! ( e. err, "Channel announced without corresponding UTXO entry" )
2096
+ } ;
2097
+
2098
+ // But if it is confirmed, replace the channel
2099
+ * chain_monitor. utxo_ret . lock ( ) . unwrap ( ) = Ok ( ( good_script, 0 ) ) ;
2100
+ unsigned_announcement. features = ChannelFeatures :: empty ( ) ;
2101
+ msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2102
+ let valid_announcement = ChannelAnnouncement {
2103
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2104
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2105
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2106
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2107
+ contents : unsigned_announcement. clone ( ) ,
2108
+ } ;
2109
+ match router. handle_channel_announcement ( & valid_announcement) {
2110
+ Ok ( res) => assert ! ( res) ,
2111
+ _ => panic ! ( )
2112
+ } ;
2113
+ {
2114
+ let mut network = router. network_map . write ( ) . unwrap ( ) ;
2115
+ match network. channels . entry ( channel_key) {
2116
+ BtreeEntry :: Occupied ( channel_entry) => {
2117
+ assert_eq ! ( channel_entry. get( ) . features, ChannelFeatures :: empty( ) ) ;
2118
+ } ,
2119
+ _ => panic ! ( )
2120
+ }
2121
+ }
2122
+
2123
+ // Don't relay valid channels with excess data
2124
+ unsigned_announcement. short_channel_id += 1 ;
2125
+ unsigned_announcement. excess_data . push ( 1 ) ;
2126
+ msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2127
+ let valid_announcement = ChannelAnnouncement {
2128
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2129
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2130
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2131
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2132
+ contents : unsigned_announcement. clone ( ) ,
2133
+ } ;
2134
+ match router. handle_channel_announcement ( & valid_announcement) {
2135
+ Ok ( res) => assert ! ( !res) ,
2136
+ _ => panic ! ( )
2137
+ } ;
2138
+
2139
+ unsigned_announcement. excess_data = Vec :: new ( ) ;
2140
+ let invalid_sig_announcement = ChannelAnnouncement {
2141
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2142
+ node_signature_2 : secp_ctx. sign ( & msghash, node_2_privkey) ,
2143
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2144
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2145
+ contents : unsigned_announcement. clone ( ) ,
2146
+ } ;
2147
+ match router. handle_channel_announcement ( & invalid_sig_announcement) {
2148
+ Ok ( _) => panic ! ( ) ,
2149
+ Err ( e) => assert_eq ! ( e. err, "Invalid signature from remote node" )
2150
+ } ;
2151
+
2152
+ unsigned_announcement. node_id_1 = PublicKey :: from_secret_key ( & secp_ctx, node_2_privkey) ;
2153
+ msghash = hash_to_message ! ( & Sha256dHash :: hash( & unsigned_announcement. encode( ) [ ..] ) [ ..] ) ;
2154
+ let channel_to_itself_announcement = ChannelAnnouncement {
2155
+ node_signature_1 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2156
+ node_signature_2 : secp_ctx. sign ( & msghash, node_1_privkey) ,
2157
+ bitcoin_signature_1 : secp_ctx. sign ( & msghash, node_1_btckey) ,
2158
+ bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
2159
+ contents : unsigned_announcement. clone ( ) ,
2160
+ } ;
2161
+ match router. handle_channel_announcement ( & channel_to_itself_announcement) {
2162
+ Ok ( _) => panic ! ( ) ,
2163
+ Err ( e) => assert_eq ! ( e. err, "Channel announcement node had a channel with itself" )
2164
+ } ;
2165
+ }
1972
2166
}
0 commit comments