@ -2355,11 +2355,99 @@ static struct io_plan *peer_important(struct io_conn *conn,
return daemon_conn_read_next ( conn , & daemon - > master ) ;
}
static void gossip_disable_channel ( struct routing_state * rstate , struct chan * chan )
{
struct short_channel_id scid ;
u8 direction ;
struct half_chan * hc ;
u16 flags , cltv_expiry_delta ;
u32 timestamp , fee_base_msat , fee_proportional_millionths ;
struct bitcoin_blkid chain_hash ;
secp256k1_ecdsa_signature sig ;
u64 htlc_minimum_msat ;
u8 * err , * msg ;
direction = pubkey_eq ( & chan - > nodes [ 0 ] - > id , & rstate - > local_id ) ? 0 : 1 ;
assert ( chan ) ;
hc = & chan - > half [ direction ] ;
status_trace ( " Disabling channel %s/%d, active %d -> %d " ,
type_to_string ( tmpctx , struct short_channel_id , & chan - > scid ) ,
direction , is_halfchan_enabled ( hc ) , 0 ) ;
if ( ! is_halfchan_defined ( hc ) ) {
status_trace (
" Channel %s/%d doesn't have a channel_update yet, can't "
" disable " ,
type_to_string ( tmpctx , struct short_channel_id , & scid ) ,
direction ) ;
return ;
}
if ( ! fromwire_channel_update (
hc - > channel_update , & sig , & chain_hash , & scid , & timestamp ,
& flags , & cltv_expiry_delta , & htlc_minimum_msat , & fee_base_msat ,
& fee_proportional_millionths ) ) {
status_failed (
STATUS_FAIL_INTERNAL_ERROR ,
" Unable to parse previously accepted channel_update " ) ;
}
status_trace ( " Disabling channel %s " , type_to_string ( tmpctx , struct short_channel_id , & scid ) ) ;
timestamp = time_now ( ) . ts . tv_sec ;
if ( timestamp < = hc - > last_timestamp )
timestamp = hc - > last_timestamp + 1 ;
status_trace ( " Disabling channel %s: %d " , type_to_string ( tmpctx , struct short_channel_id , & scid ) , 0 ) ;
flags = flags | ROUTING_FLAGS_DISABLED ;
msg = towire_channel_update ( tmpctx , & sig , & chain_hash , & scid , timestamp ,
flags , cltv_expiry_delta , htlc_minimum_msat ,
fee_base_msat , fee_proportional_millionths ) ;
if ( ! wire_sync_write ( HSM_FD ,
towire_hsm_cupdate_sig_req ( tmpctx , msg ) ) ) {
status_failed ( STATUS_FAIL_HSM_IO , " Writing cupdate_sig_req: %s " ,
strerror ( errno ) ) ;
}
msg = wire_sync_read ( tmpctx , HSM_FD ) ;
if ( ! msg | | ! fromwire_hsm_cupdate_sig_reply ( tmpctx , msg , & msg ) ) {
status_failed ( STATUS_FAIL_HSM_IO ,
" Reading cupdate_sig_req: %s " ,
strerror ( errno ) ) ;
}
err = handle_channel_update ( rstate , msg , " disable_channel " ) ;
if ( err )
status_failed ( STATUS_FAIL_INTERNAL_ERROR ,
" rejected disabling channel_update: %s " ,
tal_hex ( tmpctx , err ) ) ;
}
static void peer_disable_channels ( struct routing_state * rstate , struct node * node )
{
struct chan * c ;
size_t i ;
for ( i = 0 ; i < tal_count ( node - > chans ) ; i + + ) {
c = node - > chans [ i ] ;
if ( pubkey_eq ( & other_node ( node , c ) - > id , & rstate - > local_id ) ) {
c - > half [ 0 ] . flags | = ROUTING_FLAGS_DISABLED ;
c - > half [ 1 ] . flags | = ROUTING_FLAGS_DISABLED ;
gossip_disable_channel ( rstate , c ) ;
}
}
}
static struct io_plan * peer_disconnected ( struct io_conn * conn ,
struct daemon * daemon , const u8 * msg )
{
struct pubkey id ;
struct peer * peer ;
struct node * node ;
if ( ! fromwire_gossipctl_peer_disconnected ( msg , & id ) )
master_badmsg ( WIRE_GOSSIPCTL_PEER_DISCONNECTED , msg ) ;
@ -2375,6 +2463,11 @@ static struct io_plan *peer_disconnected(struct io_conn *conn,
status_trace ( " Forgetting remote peer %s " ,
type_to_string ( tmpctx , struct pubkey , & peer - > id ) ) ;
/* Disable any channels to and from this peer */
node = get_node ( daemon - > rstate , & id ) ;
if ( node )
peer_disable_channels ( daemon - > rstate , node ) ;
tal_free ( peer ) ;
/* If there was a connecting peer waiting, wake it now */
@ -2440,92 +2533,6 @@ static struct io_plan *handle_txout_reply(struct io_conn *conn,
return daemon_conn_read_next ( conn , & daemon - > master ) ;
}
static struct io_plan * handle_disable_channel ( struct io_conn * conn ,
struct daemon * daemon , u8 * msg )
{
struct short_channel_id scid ;
u8 direction ;
struct chan * chan ;
struct half_chan * hc ;
bool active ;
u16 flags , cltv_expiry_delta ;
u32 timestamp , fee_base_msat , fee_proportional_millionths ;
struct bitcoin_blkid chain_hash ;
secp256k1_ecdsa_signature sig ;
u64 htlc_minimum_msat ;
u8 * err ;
if ( ! fromwire_gossip_disable_channel ( msg , & scid , & direction , & active ) ) {
status_unusual ( " Unable to parse %s " ,
gossip_wire_type_name ( fromwire_peektype ( msg ) ) ) ;
goto fail ;
}
chan = get_channel ( daemon - > rstate , & scid ) ;
if ( ! chan ) {
status_trace (
" Unable to find channel %s " ,
type_to_string ( msg , struct short_channel_id , & scid ) ) ;
goto fail ;
}
hc = & chan - > half [ direction ] ;
status_trace ( " Disabling channel %s/%d, active %d -> %d " ,
type_to_string ( msg , struct short_channel_id , & scid ) ,
direction , is_halfchan_enabled ( hc ) , active ) ;
if ( ! is_halfchan_defined ( hc ) ) {
status_trace (
" Channel %s/%d doesn't have a channel_update yet, can't "
" disable " ,
type_to_string ( msg , struct short_channel_id , & scid ) ,
direction ) ;
goto fail ;
}
if ( ! fromwire_channel_update (
hc - > channel_update , & sig , & chain_hash , & scid , & timestamp ,
& flags , & cltv_expiry_delta , & htlc_minimum_msat , & fee_base_msat ,
& fee_proportional_millionths ) ) {
status_failed (
STATUS_FAIL_INTERNAL_ERROR ,
" Unable to parse previously accepted channel_update " ) ;
}
timestamp = time_now ( ) . ts . tv_sec ;
if ( timestamp < = hc - > last_timestamp )
timestamp = hc - > last_timestamp + 1 ;
flags = direction ;
if ( ! active )
flags | = ROUTING_FLAGS_DISABLED ;
msg = towire_channel_update ( tmpctx , & sig , & chain_hash , & scid , timestamp ,
flags , cltv_expiry_delta , htlc_minimum_msat ,
fee_base_msat , fee_proportional_millionths ) ;
if ( ! wire_sync_write ( HSM_FD ,
towire_hsm_cupdate_sig_req ( tmpctx , msg ) ) ) {
status_failed ( STATUS_FAIL_HSM_IO , " Writing cupdate_sig_req: %s " ,
strerror ( errno ) ) ;
}
msg = wire_sync_read ( tmpctx , HSM_FD ) ;
if ( ! msg | | ! fromwire_hsm_cupdate_sig_reply ( tmpctx , msg , & msg ) ) {
status_failed ( STATUS_FAIL_HSM_IO ,
" Reading cupdate_sig_req: %s " ,
strerror ( errno ) ) ;
}
err = handle_channel_update ( daemon - > rstate , msg , " disable_channel " ) ;
if ( err )
status_failed ( STATUS_FAIL_INTERNAL_ERROR ,
" rejected disabling channel_update: %s " ,
tal_hex ( tmpctx , err ) ) ;
fail :
return daemon_conn_read_next ( conn , & daemon - > master ) ;
}
static struct io_plan * handle_routing_failure ( struct io_conn * conn ,
struct daemon * daemon ,
const u8 * msg )
@ -2615,6 +2622,7 @@ static struct io_plan *handle_local_channel_close(struct io_conn *conn,
if ( chan ) {
chan - > half [ 0 ] . flags | = ROUTING_FLAGS_DISABLED ;
chan - > half [ 1 ] . flags | = ROUTING_FLAGS_DISABLED ;
gossip_disable_channel ( rstate , chan ) ;
}
return daemon_conn_read_next ( conn , & daemon - > master ) ;
}
@ -2670,9 +2678,6 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_GET_TXOUT_REPLY :
return handle_txout_reply ( conn , daemon , master - > msg_in ) ;
case WIRE_GOSSIP_DISABLE_CHANNEL :
return handle_disable_channel ( conn , daemon , master - > msg_in ) ;
case WIRE_GOSSIP_ROUTING_FAILURE :
return handle_routing_failure ( conn , daemon , master - > msg_in ) ;