2017-01-10 06:08:33 +01:00
# include "lightningd.h"
# include "peer_control.h"
2017-03-10 11:49:43 +01:00
# include "subd.h"
2017-10-23 06:14:38 +02:00
# include <arpa/inet.h>
2017-03-07 02:03:55 +01:00
# include <bitcoin/script.h>
2017-02-24 06:52:56 +01:00
# include <bitcoin/tx.h>
2017-06-24 08:25:53 +02:00
# include <ccan/fdpass/fdpass.h>
2017-01-10 06:08:33 +01:00
# include <ccan/io/io.h>
# include <ccan/noerr/noerr.h>
2017-09-04 05:41:34 +02:00
# include <ccan/str/str.h>
2017-01-10 06:08:33 +01:00
# include <ccan/take/take.h>
2017-01-10 06:08:33 +01:00
# include <ccan/tal/str/str.h>
2017-08-29 06:12:04 +02:00
# include <channeld/gen_channel_wire.h>
# include <closingd/gen_closing_wire.h>
2017-08-28 18:02:01 +02:00
# include <common/close_tx.h>
2017-08-28 18:05:01 +02:00
# include <common/dev_disconnect.h>
2018-01-12 14:35:52 +01:00
# include <common/features.h>
2017-08-28 18:02:01 +02:00
# include <common/funding_tx.h>
# include <common/initial_commit_tx.h>
2017-08-28 18:05:01 +02:00
# include <common/key_derive.h>
# include <common/status.h>
2017-08-28 18:04:01 +02:00
# include <common/timeout.h>
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
# include <common/wire_error.h>
2017-01-10 06:08:33 +01:00
# include <errno.h>
2017-06-24 08:25:51 +02:00
# include <fcntl.h>
2017-08-29 06:12:04 +02:00
# include <gossipd/gen_gossip_wire.h>
2018-01-25 11:44:30 +01:00
# include <gossipd/routing.h>
2017-11-28 17:35:37 +01:00
# include <hsmd/capabilities.h>
2017-11-30 17:07:38 +01:00
# include <hsmd/gen_hsm_client_wire.h>
2017-01-10 06:08:33 +01:00
# include <inttypes.h>
2018-02-06 15:46:34 +01:00
# include <lightningd/bitcoind.h>
2017-02-24 06:52:56 +01:00
# include <lightningd/build_utxos.h>
2017-08-28 18:04:01 +02:00
# include <lightningd/chaintopology.h>
2017-05-22 13:24:59 +02:00
# include <lightningd/gen_peer_state_names.h>
2017-06-24 08:50:23 +02:00
# include <lightningd/hsm_control.h>
2017-08-28 18:04:01 +02:00
# include <lightningd/jsonrpc.h>
# include <lightningd/log.h>
2017-10-23 06:17:38 +02:00
# include <lightningd/netaddress.h>
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
# include <lightningd/options.h>
2017-06-20 07:45:03 +02:00
# include <lightningd/peer_htlcs.h>
2017-08-29 06:12:04 +02:00
# include <onchaind/gen_onchain_wire.h>
# include <onchaind/onchain_wire.h>
# include <openingd/gen_opening_wire.h>
2017-06-24 08:25:51 +02:00
# include <unistd.h>
2017-05-23 13:07:42 +02:00
# include <wally_bip32.h>
2017-04-01 12:58:30 +02:00
# include <wire/gen_onion_wire.h>
2017-06-27 04:55:01 +02:00
# include <wire/peer_wire.h>
2017-06-24 08:25:51 +02:00
# include <wire/wire_sync.h>
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct connect {
struct list_node list ;
struct pubkey id ;
struct command * cmd ;
} ;
/* FIXME: Reorder */
struct funding_channel ;
static void peer_offer_channel ( struct lightningd * ld ,
struct funding_channel * fc ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures , const u8 * lfeatures ,
int peer_fd , int gossip_fd ) ;
static bool peer_start_channeld ( struct peer * peer ,
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
int peer_fd , int gossip_fd ,
const u8 * funding_signed ,
bool reconnected ) ;
static void peer_start_closingd ( struct peer * peer ,
struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
int peer_fd , int gossip_fd ,
bool reconnected ) ;
static void peer_accept_channel ( struct lightningd * ld ,
const struct pubkey * peer_id ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures , const u8 * lfeatures ,
int peer_fd , int gossip_fd ,
const u8 * open_msg ) ;
2017-10-12 08:35:03 +02:00
static void peer_set_owner ( struct peer * peer , struct subd * owner )
{
struct subd * old_owner = peer - > owner ;
peer - > owner = owner ;
if ( old_owner )
subd_release_peer ( old_owner , peer ) ;
}
2017-01-10 06:08:33 +01:00
static void destroy_peer ( struct peer * peer )
{
2017-11-10 03:01:10 +01:00
/* Must not have any HTLCs! */
struct htlc_out_map_iter outi ;
struct htlc_out * hout ;
struct htlc_in_map_iter ini ;
struct htlc_in * hin ;
for ( hout = htlc_out_map_first ( & peer - > ld - > htlcs_out , & outi ) ;
hout ;
hout = htlc_out_map_next ( & peer - > ld - > htlcs_out , & outi ) ) {
if ( hout - > key . peer ! = peer )
continue ;
fatal ( " Freeing peer %s has hout %s " ,
peer_state_name ( peer - > state ) ,
htlc_state_name ( hout - > hstate ) ) ;
}
for ( hin = htlc_in_map_first ( & peer - > ld - > htlcs_in , & ini ) ;
hin ;
hin = htlc_in_map_next ( & peer - > ld - > htlcs_in , & ini ) ) {
if ( hin - > key . peer ! = peer )
continue ;
fatal ( " Freeing peer %s has hin %s " ,
peer_state_name ( peer - > state ) ,
htlc_state_name ( hin - > hstate ) ) ;
}
2017-10-12 08:35:03 +02:00
/* Free any old owner still hanging around. */
peer_set_owner ( peer , NULL ) ;
2017-01-10 06:08:33 +01:00
list_del_from ( & peer - > ld - > peers , & peer - > list ) ;
}
2017-09-26 06:57:31 +02:00
static void sign_last_tx ( struct peer * peer )
2017-06-20 08:17:03 +02:00
{
2017-08-18 06:43:52 +02:00
const tal_t * tmpctx = tal_tmpctx ( peer ) ;
u8 * funding_wscript ;
struct pubkey local_funding_pubkey ;
struct secrets secrets ;
secp256k1_ecdsa_signature sig ;
2017-12-15 11:29:37 +01:00
assert ( ! peer - > last_tx - > input [ 0 ] . witness ) ;
2017-08-18 06:43:52 +02:00
derive_basepoints ( peer - > seed , & local_funding_pubkey , NULL , & secrets ,
NULL ) ;
funding_wscript = bitcoin_redeem_2of2 ( tmpctx ,
& local_funding_pubkey ,
& peer - > channel_info - > remote_fundingkey ) ;
/* Need input amount for signing */
peer - > last_tx - > input [ 0 ] . amount = tal_dup ( peer - > last_tx - > input , u64 ,
& peer - > funding_satoshi ) ;
sign_tx_input ( peer - > last_tx , 0 , NULL , funding_wscript ,
& secrets . funding_privkey ,
& local_funding_pubkey ,
& sig ) ;
peer - > last_tx - > input [ 0 ] . witness
= bitcoin_witness_2of2 ( peer - > last_tx - > input ,
peer - > last_sig ,
& sig ,
& peer - > channel_info - > remote_fundingkey ,
& local_funding_pubkey ) ;
2017-09-26 06:57:31 +02:00
tal_free ( tmpctx ) ;
}
2017-12-15 11:29:37 +01:00
static void remove_sig ( struct bitcoin_tx * signed_tx )
{
signed_tx - > input [ 0 ] . amount = tal_free ( signed_tx - > input [ 0 ] . amount ) ;
signed_tx - > input [ 0 ] . witness = tal_free ( signed_tx - > input [ 0 ] . witness ) ;
}
2017-09-26 06:57:31 +02:00
static void drop_to_chain ( struct peer * peer )
{
sign_last_tx ( peer ) ;
2017-08-18 06:43:52 +02:00
/* Keep broadcasting until we say stop (can fail due to dup,
* if they beat us to the broadcast ) . */
broadcast_tx ( peer - > ld - > topology , peer , peer - > last_tx , NULL ) ;
2017-12-15 11:29:37 +01:00
remove_sig ( peer - > last_tx ) ;
2017-06-20 08:17:03 +02:00
}
2017-12-06 00:34:27 +01:00
/* This lets us give a more detailed error than just a destructor. */
2018-01-03 06:59:35 +01:00
static void free_peer ( struct peer * peer , const char * why )
2017-12-06 00:34:27 +01:00
{
if ( peer - > opening_cmd ) {
2018-01-03 06:59:35 +01:00
command_fail ( peer - > opening_cmd , " %s " , why ) ;
2017-12-06 00:34:27 +01:00
peer - > opening_cmd = NULL ;
}
tal_free ( peer ) ;
}
2018-01-03 06:59:35 +01:00
void peer_fail_permanent ( struct peer * peer , const char * fmt , . . . )
2017-06-20 08:17:03 +02:00
{
2018-01-03 06:59:35 +01:00
va_list ap ;
2017-12-06 04:22:35 +01:00
char * why ;
2018-01-23 22:15:29 +01:00
u8 * msg ;
2017-12-06 04:22:35 +01:00
2018-01-03 06:59:35 +01:00
va_start ( ap , fmt ) ;
why = tal_vfmt ( peer , fmt , ap ) ;
va_end ( ap ) ;
2017-06-20 08:17:03 +02:00
2018-01-23 22:15:29 +01:00
if ( peer - > scid ) {
msg = towire_gossip_disable_channel ( peer , peer - > scid , peer - > direction , false ) ;
subd_send_msg ( peer - > ld - > gossip , take ( msg ) ) ;
}
2017-12-06 00:34:27 +01:00
log_unusual ( peer - > log , " Peer permanent failure in %s: %s " ,
peer_state_name ( peer - > state ) , why ) ;
2017-10-12 08:35:07 +02:00
/* We can have multiple errors, eg. onchaind failures. */
2018-01-03 06:59:35 +01:00
if ( ! peer - > error ) {
/* BOLT #1:
*
* The channel is referred to by ` channel_id ` unless ` channel_id ` is
* zero ( ie . all bytes zero ) , in which case it refers to all
* channels . */
static const struct channel_id all_channels ;
u8 * msg = tal_dup_arr ( peer , u8 , ( const u8 * ) why , strlen ( why ) , 0 ) ;
2017-10-12 08:35:07 +02:00
peer - > error = towire_error ( peer , & all_channels , msg ) ;
2017-06-27 05:51:05 +02:00
tal_free ( msg ) ;
2018-01-03 06:59:35 +01:00
}
2017-06-20 08:17:03 +02:00
2018-01-03 06:59:35 +01:00
peer_set_owner ( peer , NULL ) ;
2018-01-14 23:49:37 +01:00
if ( peer_persists ( peer ) ) {
2017-06-20 08:17:03 +02:00
drop_to_chain ( peer ) ;
2018-01-14 23:49:37 +01:00
tal_free ( why ) ;
} else
2017-12-06 00:34:27 +01:00
free_peer ( peer , why ) ;
2017-08-17 07:43:42 +02:00
}
2017-06-20 08:17:03 +02:00
void peer_internal_error ( struct peer * peer , const char * fmt , . . . )
{
va_list ap ;
va_start ( ap , fmt ) ;
log_broken ( peer - > log , " Peer internal error %s: " ,
peer_state_name ( peer - > state ) ) ;
logv_add ( peer - > log , fmt , ap ) ;
va_end ( ap ) ;
2018-01-03 06:59:35 +01:00
peer_fail_permanent ( peer , " Internal error " ) ;
2017-06-20 08:17:03 +02:00
}
void peer_fail_transient ( struct peer * peer , const char * fmt , . . . )
2017-05-22 09:28:07 +02:00
{
va_list ap ;
2017-12-06 00:34:27 +01:00
const char * why ;
2017-05-22 09:28:07 +02:00
va_start ( ap , fmt ) ;
2017-12-06 00:34:27 +01:00
why = tal_vfmt ( peer , fmt , ap ) ;
2017-05-22 09:28:07 +02:00
va_end ( ap ) ;
2017-12-06 00:34:27 +01:00
log_info ( peer - > log , " Peer transient failure in %s: %s " ,
peer_state_name ( peer - > state ) , why ) ;
2017-05-22 09:28:07 +02:00
2017-10-24 04:06:14 +02:00
# if DEVELOPER
2017-08-18 06:43:52 +02:00
if ( dev_disconnect_permanent ( peer - > ld ) ) {
2018-01-04 04:07:55 +01:00
tal_free ( why ) ;
2017-08-18 06:43:52 +02:00
peer_internal_error ( peer , " dev_disconnect permfail " ) ;
return ;
}
2017-10-24 04:06:14 +02:00
# endif
2017-08-18 06:43:52 +02:00
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , NULL ) ;
2017-06-24 08:25:53 +02:00
2017-05-22 13:25:01 +02:00
/* If we haven't reached awaiting locked, we don't need to reconnect */
if ( ! peer_persists ( peer ) ) {
log_info ( peer - > log , " Only reached state %s: forgetting " ,
peer_state_name ( peer - > state ) ) ;
2017-12-06 00:34:27 +01:00
free_peer ( peer , why ) ;
2017-06-24 08:25:53 +02:00
return ;
2017-05-22 13:25:01 +02:00
}
2017-12-06 00:34:27 +01:00
tal_free ( why ) ;
2017-05-22 13:25:01 +02:00
2017-08-23 03:55:16 +02:00
/* Reconnect unless we've dropped/are dropping to chain. */
if ( ! peer_on_chain ( peer ) & & peer - > state ! = CLOSINGD_COMPLETE ) {
2018-01-29 01:30:15 +01:00
# if DEVELOPER
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Don't schedule an attempt if we disabled reconnections with
2018-01-29 01:30:15 +01:00
* the ` - - dev - no - reconnect ` flag */
if ( peer - > ld - > no_reconnect )
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
return ;
2018-01-29 01:30:15 +01:00
# endif /* DEVELOPER */
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
u8 * msg = towire_gossipctl_reach_peer ( peer , & peer - > id ) ;
subd_send_msg ( peer - > ld - > gossip , take ( msg ) ) ;
2017-05-23 14:17:19 +02:00
}
2017-05-22 09:28:07 +02:00
}
2017-05-22 13:27:20 +02:00
void peer_set_condition ( struct peer * peer , enum peer_state old_state ,
enum peer_state state )
2017-01-10 06:08:33 +01:00
{
2018-01-24 20:33:47 +01:00
log_info ( peer - > log , " State changed from %s to %s " ,
2017-05-22 13:24:59 +02:00
peer_state_name ( peer - > state ) , peer_state_name ( state ) ) ;
2017-05-22 13:27:20 +02:00
if ( peer - > state ! = old_state )
fatal ( " peer state %s should be %s " ,
peer_state_name ( peer - > state ) , peer_state_name ( old_state ) ) ;
2017-05-22 13:24:59 +02:00
peer - > state = state ;
2017-08-14 16:02:37 +02:00
/* We only persist channels/peers that have reached the opening state */
if ( peer_persists ( peer ) ) {
assert ( peer - > channel ! = NULL ) ;
/* TODO(cdecker) Selectively save updated fields to DB */
2018-02-06 12:15:26 +01:00
wallet_channel_save ( peer - > ld - > wallet , peer - > channel ) ;
2017-08-14 16:02:37 +02:00
}
2017-01-10 06:08:33 +01:00
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static void destroy_connect ( struct connect * c )
2017-06-24 08:50:23 +02:00
{
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
list_del ( & c - > list ) ;
}
2017-06-24 08:50:23 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static struct connect * new_connect ( struct lightningd * ld ,
const struct pubkey * id ,
struct command * cmd )
{
struct connect * c = tal ( cmd , struct connect ) ;
c - > id = * id ;
c - > cmd = cmd ;
list_add ( & ld - > connects , & c - > list ) ;
tal_add_destructor ( c , destroy_connect ) ;
return c ;
}
2017-06-24 08:50:23 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static void connect_succeeded ( struct lightningd * ld , const struct pubkey * id )
{
struct connect * i , * next ;
2017-06-24 08:50:23 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Careful! Completing command frees connect. */
list_for_each_safe ( & ld - > connects , i , next , list ) {
struct json_result * response ;
2017-06-24 08:50:23 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
if ( ! pubkey_eq ( & i - > id , id ) )
continue ;
2017-06-24 08:50:23 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
response = new_json_result ( i - > cmd ) ;
json_object_start ( response , NULL ) ;
json_add_pubkey ( response , " id " , id ) ;
json_object_end ( response ) ;
command_success ( i - > cmd , response ) ;
2017-06-24 08:50:23 +02:00
}
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static void connect_failed ( struct lightningd * ld , const struct pubkey * id ,
const char * error )
2017-07-05 07:33:28 +02:00
{
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct connect * i , * next ;
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Careful! Completing command frees connect. */
list_for_each_safe ( & ld - > connects , i , next , list ) {
if ( pubkey_eq ( & i - > id , id ) )
command_fail ( i - > cmd , " %s " , error ) ;
}
2017-07-05 07:33:28 +02:00
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static struct peer * new_peer ( struct lightningd * ld ,
const struct pubkey * id ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures , const u8 * lfeatures ,
int peer_fd )
2017-07-05 07:33:28 +02:00
{
struct peer * peer ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Need to memset since storing will access all fields */
peer = talz ( ld , struct peer ) ;
peer - > error = NULL ;
peer - > id = * id ;
2017-10-23 06:13:38 +02:00
peer - > addr = * addr ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer - > funding_txid = NULL ;
peer - > remote_funding_locked = false ;
peer - > scid = NULL ;
peer - > seed = NULL ;
peer - > our_msatoshi = NULL ;
peer - > state = UNINITIALIZED ;
2017-12-06 00:34:27 +01:00
peer - > opening_cmd = NULL ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer - > channel_info = NULL ;
peer - > last_tx = NULL ;
peer - > last_sig = NULL ;
peer - > last_htlc_sigs = NULL ;
peer - > last_was_revoke = false ;
peer - > last_sent_commit = NULL ;
peer - > remote_shutdown_scriptpubkey = NULL ;
peer - > local_shutdown_idx = - 1 ;
peer - > next_index [ LOCAL ]
= peer - > next_index [ REMOTE ] = 0 ;
peer - > next_htlc_id = 0 ;
wallet_shachain_init ( ld - > wallet , & peer - > their_shachain ) ;
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* FIXME: db should be keyed by (peer_id, channel_id) */
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* If we have the peer in the DB, this'll populate the fields,
* failure just indicates that the peer wasn ' t found in the
* DB */
wallet_peer_by_nodeid ( ld - > wallet , id , peer ) ;
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* peer->channel gets populated as soon as we start opening a channel */
peer - > channel = NULL ;
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
list_add_tail ( & ld - > peers , & peer - > list ) ;
populate_peer ( ld , peer ) ;
2017-07-05 07:33:28 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
return peer ;
2017-07-05 07:33:28 +02:00
}
2017-06-24 08:50:23 +02:00
2017-08-12 16:46:50 +02:00
/**
* peer_channel_new - - Instantiate a new channel for the given peer and save it
*
* We are about to open a channel with the peer , either due to a
* nongossip message from remote , or because we initiated an
* open . This creates the ` struct wallet_channel ` for the peer and
* stores it in the database .
*
* @ w : the wallet to store the information in
* @ peer : the peer we are opening a channel to
*
* This currently overwrites peer - > channel , so can only be used if we
* allow a single channel per peer .
*/
static struct wallet_channel * peer_channel_new ( struct wallet * w ,
struct peer * peer )
{
struct wallet_channel * wc = tal ( peer , struct wallet_channel ) ;
wc - > peer = peer ;
2017-08-14 16:04:11 +02:00
wallet_peer_by_nodeid ( w , & peer - > id , peer ) ;
2017-08-12 16:46:50 +02:00
wc - > id = 0 ;
2018-02-06 12:15:26 +01:00
wc - > first_blocknum = get_block_height ( peer - > ld - > topology ) ;
wallet_channel_save ( w , wc ) ;
2017-08-12 16:46:50 +02:00
return wc ;
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static void channel_config ( struct lightningd * ld ,
struct channel_config * ours ,
u32 * max_to_self_delay ,
u32 * max_minimum_depth ,
u64 * min_effective_htlc_capacity_msat )
2017-08-17 15:30:24 +02:00
{
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* FIXME: depend on feerate. */
* max_to_self_delay = ld - > config . locktime_max ;
* max_minimum_depth = ld - > config . anchor_confirms_max ;
/* This is 1c at $1000/BTC */
* min_effective_htlc_capacity_msat = 1000000 ;
2017-08-17 15:30:24 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* BOLT #2:
*
* The sender SHOULD set ` dust_limit_satoshis ` to a sufficient
* value to allow commitment transactions to propagate through
* the Bitcoin network .
*/
ours - > dust_limit_satoshis = 546 ;
ours - > max_htlc_value_in_flight_msat = UINT64_MAX ;
2017-08-17 15:30:24 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Don't care */
ours - > htlc_minimum_msat = 0 ;
2017-08-17 15:30:24 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* BOLT #2:
*
* The sender SHOULD set ` to_self_delay ` sufficient to ensure
* the sender can irreversibly spend a commitment transaction
* output in case of misbehavior by the receiver .
*/
ours - > to_self_delay = ld - > config . locktime_blocks ;
/* BOLT #2:
*
* It MUST fail the channel if ` max_accepted_htlcs ` is greater than
* 483.
*/
ours - > max_accepted_htlcs = 483 ;
/* This is filled in by lightning_openingd, for consistency. */
ours - > channel_reserve_satoshis = 0 ;
} ;
/* Gossipd tells us a peer has connected */
void peer_connected ( struct lightningd * ld , const u8 * msg ,
int peer_fd , int gossip_fd )
2017-01-10 06:08:33 +01:00
{
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct pubkey id ;
struct crypto_state cs ;
u8 * gfeatures , * lfeatures ;
u8 * error ;
2018-01-12 14:35:52 +01:00
u8 * supported_global_features ;
u8 * supported_local_features ;
2017-05-23 14:17:19 +02:00
struct peer * peer ;
2017-10-23 06:17:38 +02:00
struct wireaddr addr ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
2017-01-10 06:08:33 +01:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
if ( ! fromwire_gossip_peer_connected ( msg , msg , NULL ,
2017-12-11 04:33:16 +01:00
& id , & addr , & cs , & gossip_index ,
2017-10-23 06:13:38 +02:00
& gfeatures , & lfeatures ) )
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
fatal ( " Gossip gave bad GOSSIP_PEER_CONNECTED message %s " ,
tal_hex ( msg , msg ) ) ;
if ( unsupported_features ( gfeatures , lfeatures ) ) {
log_unusual ( ld - > log , " peer %s offers unsupported features %s/%s " ,
type_to_string ( msg , struct pubkey , & id ) ,
tal_hex ( msg , gfeatures ) ,
tal_hex ( msg , lfeatures ) ) ;
2018-01-12 14:35:52 +01:00
supported_global_features = get_supported_global_features ( msg ) ;
supported_local_features = get_supported_local_features ( msg ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
error = towire_errorfmt ( msg , NULL ,
" We only support globalfeatures %s "
" and localfeatures %s " ,
tal_hexstr ( msg ,
supported_global_features ,
2018-01-12 14:35:52 +01:00
tal_len ( supported_global_features ) ) ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
tal_hexstr ( msg ,
supported_local_features ,
2018-01-12 14:35:52 +01:00
tal_len ( supported_local_features ) ) ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
goto send_error ;
}
/* Now, do we already know this peer? */
peer = peer_by_id ( ld , & id ) ;
if ( peer ) {
log_debug ( peer - > log , " Peer has reconnected, state %s " ,
peer_state_name ( peer - > state ) ) ;
/* FIXME: We can have errors for multiple channels. */
if ( peer - > error ) {
error = peer - > error ;
goto send_error ;
}
2017-05-23 14:17:19 +02:00
2017-10-28 04:19:10 +02:00
# if DEVELOPER
if ( dev_disconnect_permanent ( ld ) ) {
peer_internal_error ( peer , " dev_disconnect permfail " ) ;
error = peer - > error ;
goto send_error ;
}
# endif
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
switch ( peer - > state ) {
/* This can't happen. */
case UNINITIALIZED :
abort ( ) ;
/* Reconnect: discard old one. */
case OPENINGD :
2017-12-06 00:34:27 +01:00
free_peer ( peer , " peer reconnected " ) ;
peer = NULL ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
goto return_to_gossipd ;
case ONCHAIND_CHEATED :
case ONCHAIND_THEIR_UNILATERAL :
case ONCHAIND_OUR_UNILATERAL :
case FUNDING_SPEND_SEEN :
case ONCHAIND_MUTUAL :
/* If they try to reestablish channel, we'll send
* error then */
goto return_to_gossipd ;
case CHANNELD_AWAITING_LOCKIN :
case CHANNELD_NORMAL :
case CHANNELD_SHUTTING_DOWN :
/* Stop any existing daemon, without triggering error
* on this peer . */
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , NULL ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
2017-10-23 06:13:38 +02:00
peer - > addr = addr ;
2017-12-11 04:33:16 +01:00
peer_start_channeld ( peer , & cs , gossip_index ,
peer_fd , gossip_fd , NULL ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
true ) ;
2018-01-25 11:14:21 +01:00
goto connected ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
case CLOSINGD_SIGEXCHANGE :
case CLOSINGD_COMPLETE :
/* Stop any existing daemon, without triggering error
* on this peer . */
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , NULL ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
2017-10-23 06:13:38 +02:00
peer - > addr = addr ;
2017-12-11 04:33:16 +01:00
peer_start_closingd ( peer , & cs , gossip_index ,
peer_fd , gossip_fd ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
true ) ;
2018-01-25 11:14:21 +01:00
goto connected ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
abort ( ) ;
}
2017-05-22 13:26:49 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
return_to_gossipd :
/* Otherwise, we hand back to gossipd, to continue. */
2017-12-11 04:33:16 +01:00
msg = towire_gossipctl_hand_back_peer ( msg , & id , & cs , gossip_index , NULL ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
subd_send_msg ( ld - > gossip , take ( msg ) ) ;
subd_send_fd ( ld - > gossip , peer_fd ) ;
2017-12-11 04:16:50 +01:00
subd_send_fd ( ld - > gossip , gossip_fd ) ;
2017-08-14 16:04:11 +02:00
2018-01-25 11:14:21 +01:00
connected :
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* If we were waiting for connection, we succeeded. */
connect_succeeded ( ld , & id ) ;
return ;
2017-08-12 16:46:50 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
send_error :
/* Hand back to gossipd, with an error packet. */
connect_failed ( ld , & id , sanitize_error ( msg , error , NULL ) ) ;
2017-12-11 04:33:16 +01:00
msg = towire_gossipctl_hand_back_peer ( msg , & id , & cs , gossip_index ,
error ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
subd_send_msg ( ld - > gossip , take ( msg ) ) ;
subd_send_fd ( ld - > gossip , peer_fd ) ;
2017-12-11 04:16:50 +01:00
subd_send_fd ( ld - > gossip , gossip_fd ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
2018-01-10 06:30:54 +01:00
/* Gossipd tells us peer was already connected. */
void peer_already_connected ( struct lightningd * ld , const u8 * msg )
{
struct pubkey id ;
if ( ! fromwire_gossip_peer_already_connected ( msg , NULL , & id ) )
fatal ( " Gossip gave bad GOSSIP_PEER_ALREADY_CONNECTED message %s " ,
tal_hex ( msg , msg ) ) ;
/* If we were waiting for connection, we succeeded. */
connect_succeeded ( ld , & id ) ;
}
2018-01-27 16:56:12 +01:00
void peer_connection_failed ( struct lightningd * ld , const u8 * msg )
{
struct pubkey id ;
u32 attempts , timediff ;
2018-01-27 17:18:45 +01:00
struct connect * i , * next ;
bool addr_unknown ;
char * error ;
2018-01-30 00:03:07 +01:00
if ( ! fromwire_gossip_peer_connection_failed ( msg , NULL , & id , & timediff ,
& attempts , & addr_unknown ) )
2018-01-27 17:18:45 +01:00
fatal (
" Gossip gave bad GOSSIP_PEER_CONNECTION_FAILED message %s " ,
tal_hex ( msg , msg ) ) ;
if ( addr_unknown ) {
error = tal_fmt (
msg , " No address known for node %s, please provide one " ,
type_to_string ( msg , struct pubkey , & id ) ) ;
} else {
error = tal_fmt ( msg , " Could not connect to %s after %d seconds and %d attempts " ,
type_to_string ( msg , struct pubkey , & id ) , timediff ,
attempts ) ;
}
2018-01-27 16:56:12 +01:00
/* Careful! Completing command frees connect. */
list_for_each_safe ( & ld - > connects , i , next , list ) {
if ( ! pubkey_eq ( & i - > id , & id ) )
continue ;
2018-01-27 17:18:45 +01:00
command_fail ( i - > cmd , " %s " , error ) ;
2018-01-27 16:56:12 +01:00
}
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
void peer_sent_nongossip ( struct lightningd * ld ,
const struct pubkey * id ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures ,
const u8 * lfeatures ,
int peer_fd , int gossip_fd ,
const u8 * in_msg )
{
struct channel_id * channel_id , extracted_channel_id ;
struct peer * peer ;
u8 * error , * msg ;
if ( ! extract_channel_id ( in_msg , & extracted_channel_id ) )
channel_id = NULL ;
else
channel_id = & extracted_channel_id ;
/* FIXME: match state too; we can have multiple onchain
* ( ie . dead ) channels for the same peer . */
peer = peer_by_id ( ld , id ) ;
if ( peer ) {
error = towire_errorfmt ( ld , channel_id ,
" Unexpected message %i in state %s " ,
fromwire_peektype ( in_msg ) ,
peer_state_name ( peer - > state ) ) ;
goto send_error ;
}
/* Open request? */
if ( fromwire_peektype ( in_msg ) = = WIRE_OPEN_CHANNEL ) {
2017-12-11 04:33:16 +01:00
peer_accept_channel ( ld , id , addr , cs , gossip_index ,
gfeatures , lfeatures ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer_fd , gossip_fd , in_msg ) ;
2017-05-22 13:26:49 +02:00
return ;
2017-01-10 06:08:33 +01:00
}
2017-08-17 15:30:24 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Weird request. */
error = towire_errorfmt ( ld , channel_id ,
" Unexpected message %i for unknown peer " ,
fromwire_peektype ( in_msg ) ) ;
2017-08-17 15:30:24 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
send_error :
/* Hand back to gossipd, with an error packet. */
connect_failed ( ld , id , sanitize_error ( error , error , NULL ) ) ;
2017-12-11 04:33:16 +01:00
msg = towire_gossipctl_hand_back_peer ( ld , id , cs , gossip_index , error ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
subd_send_msg ( ld - > gossip , take ( msg ) ) ;
subd_send_fd ( ld - > gossip , peer_fd ) ;
2017-12-11 04:16:50 +01:00
subd_send_fd ( ld - > gossip , gossip_fd ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
tal_free ( error ) ;
}
2017-05-22 13:26:49 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* We copy per-peer entries above --log-level into the main log. */
static void copy_to_parent_log ( const char * prefix ,
enum log_level level ,
bool continued ,
2018-02-02 01:05:41 +01:00
const struct timeabs * time ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const char * str ,
2018-02-05 05:09:28 +01:00
const u8 * io ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct peer * peer )
{
2018-02-05 05:09:28 +01:00
if ( level = = LOG_IO_IN | | level = = LOG_IO_OUT )
log_io ( peer - > ld - > log , level , prefix , io , tal_len ( io ) ) ;
else if ( continued )
2018-01-30 01:44:08 +01:00
log_add ( peer - > ld - > log , " %s ... %s " , prefix , str ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
else
2018-01-30 01:44:08 +01:00
log_ ( peer - > ld - > log , level , " %s %s " , prefix , str ) ;
2017-01-10 06:08:33 +01:00
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
void populate_peer ( struct lightningd * ld , struct peer * peer )
2017-01-10 06:08:33 +01:00
{
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const char * idname ;
struct pubkey * id = & peer - > id ;
idname = type_to_string ( peer , struct pubkey , id ) ;
2017-01-10 06:08:33 +01:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer - > ld = ld ;
/* Max 128k per peer. */
peer - > log_book = new_log_book ( peer , 128 * 1024 ,
get_log_level ( ld - > log_book ) ) ;
peer - > log = new_log ( peer , peer - > log_book , " peer %s: " , idname ) ;
set_log_outfn ( peer - > log_book , copy_to_parent_log , peer ) ;
tal_free ( idname ) ;
tal_add_destructor ( peer , destroy_peer ) ;
2017-01-10 06:08:33 +01:00
}
2017-02-24 06:52:56 +01:00
struct peer * peer_by_id ( struct lightningd * ld , const struct pubkey * id )
{
struct peer * p ;
list_for_each ( & ld - > peers , p , list )
2017-06-06 05:08:42 +02:00
if ( pubkey_eq ( & p - > id , id ) )
2017-02-24 06:52:56 +01:00
return p ;
return NULL ;
}
2017-01-10 06:08:33 +01:00
static void json_connect ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
2017-12-04 10:12:22 +01:00
jsmntok_t * hosttok , * porttok , * idtok ;
2017-05-22 13:26:49 +02:00
struct pubkey id ;
2017-12-04 10:12:22 +01:00
const char * name ;
2017-10-23 06:17:38 +02:00
struct wireaddr addr ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
u8 * msg ;
2017-01-10 06:08:33 +01:00
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-01-10 06:08:33 +01:00
" id " , & idtok ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
" ?host " , & hosttok ,
2017-12-04 10:12:22 +01:00
" ?port " , & porttok ,
2017-01-10 06:08:33 +01:00
NULL ) ) {
return ;
}
2017-10-11 12:03:50 +02:00
if ( ! json_tok_pubkey ( buffer , idtok , & id ) ) {
2017-01-10 06:08:33 +01:00
command_fail ( cmd , " id %.*s not valid " ,
idtok - > end - idtok - > start ,
buffer + idtok - > start ) ;
return ;
}
2017-12-04 10:12:22 +01:00
if ( porttok & & ! hosttok ) {
command_fail ( cmd , " Can't specify port without host " ) ;
return ;
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
if ( hosttok ) {
2017-12-04 10:12:22 +01:00
name = tal_strndup ( cmd , buffer + hosttok - > start ,
hosttok - > end - hosttok - > start ) ;
if ( porttok ) {
u32 port ;
if ( ! json_tok_number ( buffer , porttok , & port ) ) {
2018-01-26 02:03:48 +01:00
command_fail ( cmd , " Port %.*s not valid " ,
2017-12-04 10:12:22 +01:00
porttok - > end - porttok - > start ,
buffer + porttok - > start ) ;
return ;
}
addr . port = port ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
} else {
2017-12-04 10:12:22 +01:00
addr . port = DEFAULT_PORT ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
2017-12-04 07:29:38 +01:00
if ( ! parse_wireaddr ( name , & addr , addr . port ) | | ! addr . port ) {
2018-01-26 02:03:48 +01:00
command_fail ( cmd , " Host %s:%u not valid " ,
2017-12-04 10:12:22 +01:00
name , addr . port ) ;
2017-12-04 07:29:38 +01:00
return ;
}
2017-10-11 12:06:50 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Tell it about the address. */
msg = towire_gossipctl_peer_addrhint ( cmd , & id , & addr ) ;
subd_send_msg ( cmd - > ld - > gossip , take ( msg ) ) ;
2017-01-10 06:08:33 +01:00
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Now tell it to try reaching it. */
msg = towire_gossipctl_reach_peer ( cmd , & id ) ;
subd_send_msg ( cmd - > ld - > gossip , take ( msg ) ) ;
/* Leave this here for gossip_peer_connected */
new_connect ( cmd - > ld , & id , cmd ) ;
2017-12-15 11:15:54 +01:00
command_still_pending ( cmd ) ;
2017-01-10 06:08:33 +01:00
}
static const struct json_command connect_command = {
" connect " ,
json_connect ,
2018-01-22 09:55:07 +01:00
" Connect to {id} at {host} (which can end in ':port' if not default) "
2017-01-10 06:08:33 +01:00
} ;
AUTODATA ( json_command , & connect_command ) ;
2017-01-10 06:08:34 +01:00
2017-10-23 06:19:38 +02:00
struct getpeers_args {
struct command * cmd ;
/* If non-NULL, they want logs too */
enum log_level * ll ;
2018-01-17 00:53:20 +01:00
/* If set, only report on a specific id. */
struct pubkey * specific_id ;
2017-10-23 06:19:38 +02:00
} ;
static void gossipd_getpeers_complete ( struct subd * gossip , const u8 * msg ,
const int * fds ,
struct getpeers_args * gpa )
2017-01-10 06:08:34 +01:00
{
2017-10-23 06:19:38 +02:00
/* This is a little sneaky... */
struct pubkey * ids ;
struct wireaddr * addrs ;
struct json_result * response = new_json_result ( gpa - > cmd ) ;
2017-01-10 06:08:34 +01:00
struct peer * p ;
2017-10-23 06:19:38 +02:00
if ( ! fromwire_gossip_getpeers_reply ( msg , msg , NULL , & ids , & addrs ) ) {
command_fail ( gpa - > cmd , " Bad response from gossipd " ) ;
2017-01-10 06:08:34 +01:00
return ;
}
2017-10-23 06:19:38 +02:00
/* First the peers not just gossiping. */
2017-01-10 06:08:34 +01:00
json_object_start ( response , NULL ) ;
json_array_start ( response , " peers " ) ;
2017-10-23 06:19:38 +02:00
list_for_each ( & gpa - > cmd - > ld - > peers , p , list ) {
2018-01-18 04:44:08 +01:00
bool connected ;
2018-01-17 00:53:20 +01:00
if ( gpa - > specific_id & & ! pubkey_eq ( gpa - > specific_id , & p - > id ) )
continue ;
2017-01-10 06:08:34 +01:00
json_object_start ( response , NULL ) ;
2018-01-17 00:53:20 +01:00
json_add_pubkey ( response , " id " , & p - > id ) ;
2018-01-18 04:44:08 +01:00
connected = ( p - > owner ! = NULL & & ! peer_state_on_chain ( p - > state ) ) ;
json_add_bool ( response , " connected " , connected ) ;
if ( connected ) {
json_array_start ( response , " netaddr " ) ;
if ( p - > addr . type ! = ADDR_TYPE_PADDING )
json_add_string ( response , NULL ,
type_to_string ( response ,
struct wireaddr ,
& p - > addr ) ) ;
json_array_end ( response ) ;
}
/* FIXME: We only support one channel per peer, but API must
* support multiple already ! */
json_array_start ( response , " channels " ) ;
json_object_start ( response , NULL ) ;
json_add_string ( response , " state " , peer_state_name ( p - > state ) ) ;
2017-01-10 06:08:34 +01:00
if ( p - > owner )
json_add_string ( response , " owner " , p - > owner - > name ) ;
2017-05-02 07:26:31 +02:00
if ( p - > scid )
2018-01-18 04:44:08 +01:00
json_add_short_channel_id ( response ,
" short_channel_id " , p - > scid ) ;
if ( p - > funding_txid )
json_add_txid ( response ,
" funding_txid " , p - > funding_txid ) ;
2017-07-05 07:33:40 +02:00
if ( p - > our_msatoshi ) {
json_add_u64 ( response , " msatoshi_to_us " ,
* p - > our_msatoshi ) ;
2017-06-20 07:59:03 +02:00
json_add_u64 ( response , " msatoshi_total " ,
p - > funding_satoshi * 1000 ) ;
2017-04-01 12:58:30 +02:00
}
2018-01-21 20:20:16 +01:00
/* channel config */
json_add_u64 ( response , " dust_limit_satoshis " , p - > our_config . dust_limit_satoshis ) ;
json_add_u64 ( response , " max_htlc_value_in_flight_msat " , p - > our_config . max_htlc_value_in_flight_msat ) ;
json_add_u64 ( response , " channel_reserve_satoshis " , p - > our_config . channel_reserve_satoshis ) ;
json_add_u64 ( response , " htlc_minimum_msat " , p - > our_config . htlc_minimum_msat ) ;
json_add_num ( response , " to_self_delay " , p - > our_config . to_self_delay ) ;
json_add_num ( response , " max_accepted_htlcs " , p - > our_config . max_accepted_htlcs ) ;
2018-01-18 04:44:08 +01:00
json_object_end ( response ) ;
json_array_end ( response ) ;
2017-06-20 07:59:03 +02:00
2018-02-05 05:09:28 +01:00
if ( gpa - > ll )
json_add_log ( response , " log " , p - > log_book , * gpa - > ll ) ;
2017-01-10 06:08:34 +01:00
json_object_end ( response ) ;
}
2017-10-23 06:19:38 +02:00
for ( size_t i = 0 ; i < tal_count ( ids ) ; i + + ) {
/* Don't report peers in both, which can happen if they're
* reconnecting */
if ( peer_by_id ( gpa - > cmd - > ld , ids + i ) )
continue ;
json_object_start ( response , NULL ) ;
/* Fake state. */
json_add_string ( response , " state " , " GOSSIPING " ) ;
2018-01-17 00:53:20 +01:00
json_add_pubkey ( response , " id " , ids + i ) ;
2017-11-11 02:39:23 +01:00
json_array_start ( response , " netaddr " ) ;
if ( addrs [ i ] . type ! = ADDR_TYPE_PADDING )
json_add_string ( response , NULL ,
type_to_string ( response , struct wireaddr ,
addrs + i ) ) ;
json_array_end ( response ) ;
2017-12-28 19:24:38 +01:00
json_add_bool ( response , " connected " , true ) ;
2017-10-23 06:19:38 +02:00
json_add_string ( response , " owner " , gossip - > name ) ;
json_object_end ( response ) ;
}
2017-01-10 06:08:34 +01:00
json_array_end ( response ) ;
json_object_end ( response ) ;
2017-10-23 06:19:38 +02:00
command_success ( gpa - > cmd , response ) ;
}
2018-01-17 00:53:20 +01:00
static void json_listpeers ( struct command * cmd ,
2017-10-23 06:19:38 +02:00
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * leveltok ;
struct getpeers_args * gpa = tal ( cmd , struct getpeers_args ) ;
2018-01-17 00:53:20 +01:00
jsmntok_t * idtok ;
2017-10-23 06:19:38 +02:00
gpa - > cmd = cmd ;
2018-01-17 00:53:20 +01:00
gpa - > specific_id = NULL ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2018-01-17 00:53:20 +01:00
" ?id " , & idtok ,
" ?level " , & leveltok ,
NULL ) ) {
Check return value of json_get_params(...) call in json_getlog(...) and json_getpeers(...)
All other users of json_get_params(...) check the return value:
```
lightningd/chaintopology.c: if (!json_get_params(buffer, params,
lightningd/chaintopology.c: if (!json_get_params(buffer, params,
lightningd/dev_ping.c: if (!json_get_params(buffer, params,
lightningd/gossip_control.c: if (!json_get_params(buffer, params,
lightningd/invoice.c: if (!json_get_params(buffer, params,
lightningd/invoice.c: if (!json_get_params(buffer, params,
lightningd/invoice.c: if (!json_get_params(buffer, params,
lightningd/invoice.c: if (!json_get_params(buffer, params,
lightningd/invoice.c: if (!json_get_params(buffer, params, "label", &labeltok, NULL)) {
lightningd/invoice.c: if (!json_get_params(buffer, params,
lightningd/jsonrpc.c: if (!json_get_params(buffer, params,
lightningd/pay.c: if (!json_get_params(buffer, params,
lightningd/pay.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
lightningd/peer_control.c: if (!json_get_params(buffer, params,
wallet/walletrpc.c: if (!json_get_params(buffer, params,
wallet/walletrpc.c: if (!json_get_params(buffer, params, "tx", &txtok, NULL)) {
```
2018-01-10 10:17:58 +01:00
return ;
}
2017-10-23 06:19:38 +02:00
2018-01-17 00:53:20 +01:00
if ( idtok ) {
gpa - > specific_id = tal_arr ( cmd , struct pubkey , 1 ) ;
if ( ! json_tok_pubkey ( buffer , idtok , gpa - > specific_id ) ) {
command_fail ( cmd , " id %.*s not valid " ,
idtok - > end - idtok - > start ,
buffer + idtok - > start ) ;
return ;
}
}
2017-10-23 06:19:38 +02:00
if ( leveltok ) {
gpa - > ll = tal ( gpa , enum log_level ) ;
2018-02-05 05:09:28 +01:00
if ( ! json_tok_loglevel ( buffer , leveltok , gpa - > ll ) ) {
2017-10-23 06:19:38 +02:00
command_fail ( cmd , " Invalid level param " ) ;
return ;
}
} else
gpa - > ll = NULL ;
/* Get peers from gossipd. */
subd_req ( cmd , cmd - > ld - > gossip ,
2018-01-17 00:53:20 +01:00
take ( towire_gossip_getpeers_request ( cmd , gpa - > specific_id ) ) ,
2017-10-23 06:19:38 +02:00
- 1 , 0 , gossipd_getpeers_complete , gpa ) ;
2017-12-15 11:15:54 +01:00
command_still_pending ( cmd ) ;
2017-01-10 06:08:34 +01:00
}
2018-01-17 00:53:20 +01:00
static const struct json_command listpeers_command = {
" listpeers " ,
json_listpeers ,
2018-02-05 17:42:19 +01:00
" Show current peers, if {level} is set, include logs for {id} "
2017-01-10 06:08:34 +01:00
} ;
2018-01-17 00:53:20 +01:00
AUTODATA ( json_command , & listpeers_command ) ;
2017-02-24 06:52:56 +01:00
2017-04-01 12:24:59 +02:00
struct peer * peer_from_json ( struct lightningd * ld ,
const char * buffer ,
jsmntok_t * peeridtok )
2017-02-24 06:52:56 +01:00
{
struct pubkey peerid ;
2017-10-11 12:03:50 +02:00
if ( ! json_tok_pubkey ( buffer , peeridtok , & peerid ) )
2017-02-24 06:52:56 +01:00
return NULL ;
return peer_by_id ( ld , & peerid ) ;
}
struct funding_channel {
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct command * cmd ; /* Which also owns us. */
/* Peer we're trying to reach. */
struct pubkey peerid ;
2017-05-23 13:07:42 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Details of how to make funding. */
2017-03-07 01:58:09 +01:00
const struct utxo * * utxomap ;
2017-02-24 06:52:56 +01:00
u64 change ;
u32 change_keyindex ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
u64 funding_satoshi , push_msat ;
/* Peer, once we have one. */
struct peer * peer ;
2017-02-24 06:52:56 +01:00
} ;
2017-03-07 02:03:55 +01:00
static void funding_broadcast_failed ( struct peer * peer ,
int exitstatus , const char * err )
{
2017-08-17 03:04:55 +02:00
peer_internal_error ( peer , " Funding broadcast exited with %i: %s " ,
exitstatus , err ) ;
2017-03-07 02:03:55 +01:00
}
2017-05-23 13:00:17 +02:00
static enum watch_result funding_announce_cb ( struct peer * peer ,
2017-08-18 06:43:53 +02:00
const struct bitcoin_tx * tx ,
2017-05-23 13:00:17 +02:00
unsigned int depth ,
void * unused )
{
if ( depth < ANNOUNCE_MIN_DEPTH ) {
return KEEP_WATCHING ;
}
2017-09-04 05:41:34 +02:00
if ( ! peer - > owner | | ! streq ( peer - > owner - > name , " lightning_channeld " ) ) {
2018-01-25 12:03:40 +01:00
log_debug ( peer - > log ,
" Funding tx announce ready, but peer state %s "
" owned by %s " ,
peer_state_name ( peer - > state ) ,
peer - > owner ? peer - > owner - > name : " none " ) ;
2017-05-23 13:00:17 +02:00
return KEEP_WATCHING ;
}
2017-09-04 05:41:34 +02:00
2017-05-23 13:00:17 +02:00
subd_send_msg ( peer - > owner ,
take ( towire_channel_funding_announce_depth ( peer ) ) ) ;
return DELETE_WATCH ;
}
2017-08-23 03:55:16 +02:00
2017-09-20 06:45:41 +02:00
/* We dump all the known preimages when onchaind starts up. */
static void onchaind_tell_fulfill ( struct peer * peer )
{
struct htlc_in_map_iter ini ;
struct htlc_in * hin ;
u8 * msg ;
for ( hin = htlc_in_map_first ( & peer - > ld - > htlcs_in , & ini ) ;
hin ;
hin = htlc_in_map_next ( & peer - > ld - > htlcs_in , & ini ) ) {
if ( hin - > key . peer ! = peer )
continue ;
2017-09-26 23:02:47 +02:00
/* BOLT #5:
*
* If the node receives ( or already knows ) a payment preimage
* for an unresolved HTLC output it was offered for which it
* has committed to an outgoing HTLC , it MUST * resolve * the
* output by spending it . Otherwise , if the other node is not
* irrevocably committed to the HTLC , it MUST NOT * resolve *
* the output by spending it .
*/
/* We only set preimage once it's irrevocably committed, and
* we spend even if we don ' t have an outgoing HTLC ( eg . local
2017-12-07 23:59:39 +01:00
* payment complete ) */
2017-09-20 06:45:41 +02:00
if ( ! hin - > preimage )
continue ;
msg = towire_onchain_known_preimage ( peer , hin - > preimage ) ;
subd_send_msg ( peer - > owner , take ( msg ) ) ;
}
}
2017-10-12 08:35:04 +02:00
static void handle_onchain_init_reply ( struct peer * peer , const u8 * msg )
2017-08-23 03:55:16 +02:00
{
u8 state ;
if ( ! fromwire_onchain_init_reply ( msg , NULL , & state ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " Invalid onchain_init_reply " ) ;
return ;
2017-08-23 03:55:16 +02:00
}
if ( ! peer_state_on_chain ( state ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer ,
" Invalid onchain_init_reply state %u (%s) " ,
state , peer_state_name ( state ) ) ;
return ;
2017-08-23 03:55:16 +02:00
}
2017-09-26 23:02:48 +02:00
peer_set_condition ( peer , FUNDING_SPEND_SEEN , state ) ;
2017-09-20 06:45:41 +02:00
/* Tell it about any preimages we know. */
onchaind_tell_fulfill ( peer ) ;
2017-08-23 03:55:16 +02:00
}
static enum watch_result onchain_tx_watched ( struct peer * peer ,
const struct bitcoin_tx * tx ,
unsigned int depth ,
void * unused )
{
u8 * msg ;
2017-12-18 07:41:52 +01:00
struct bitcoin_txid txid ;
2017-08-23 03:55:16 +02:00
if ( depth = = 0 ) {
log_unusual ( peer - > log , " Chain reorganization! " ) ;
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , NULL ) ;
2017-08-23 03:55:16 +02:00
/* FIXME!
topology_rescan ( peer - > ld - > topology , peer - > funding_txid ) ;
*/
/* We will most likely be freed, so this is a noop */
return KEEP_WATCHING ;
}
bitcoin_txid ( tx , & txid ) ;
msg = towire_onchain_depth ( peer , & txid , depth ) ;
subd_send_msg ( peer - > owner , take ( msg ) ) ;
return KEEP_WATCHING ;
}
static void watch_tx_and_outputs ( struct peer * peer ,
const struct bitcoin_tx * tx ) ;
static enum watch_result onchain_txo_watched ( struct peer * peer ,
const struct bitcoin_tx * tx ,
size_t input_num ,
const struct block * block ,
void * unused )
{
u8 * msg ;
watch_tx_and_outputs ( peer , tx ) ;
msg = towire_onchain_spent ( peer , tx , input_num , block - > height ) ;
subd_send_msg ( peer - > owner , take ( msg ) ) ;
/* We don't need to keep watching: If this output is double-spent
* ( reorg ) , we ' ll get a zero depth cb to onchain_tx_watched , and
* restart onchaind . */
return DELETE_WATCH ;
}
/* To avoid races, we watch the tx and all outputs. */
static void watch_tx_and_outputs ( struct peer * peer ,
const struct bitcoin_tx * tx )
{
2017-12-18 07:41:52 +01:00
struct bitcoin_txid txid ;
2017-08-23 03:55:16 +02:00
struct txwatch * txw ;
bitcoin_txid ( tx , & txid ) ;
/* Make txwatch a parent of txo watches, so we can unwatch together. */
txw = watch_tx ( peer - > owner , peer - > ld - > topology , peer , tx ,
onchain_tx_watched , NULL ) ;
for ( size_t i = 0 ; i < tal_count ( tx - > output ) ; i + + )
watch_txo ( txw , peer - > ld - > topology , peer , & txid , i ,
onchain_txo_watched , NULL ) ;
}
2017-10-12 08:35:04 +02:00
static void handle_onchain_broadcast_tx ( struct peer * peer , const u8 * msg )
2017-08-23 03:55:16 +02:00
{
struct bitcoin_tx * tx ;
tx = tal ( msg , struct bitcoin_tx ) ;
if ( ! fromwire_onchain_broadcast_tx ( msg , NULL , tx ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " Invalid onchain_broadcast_tx " ) ;
return ;
2017-08-23 03:55:16 +02:00
}
/* We don't really care if it fails, we'll respond via watch. */
broadcast_tx ( peer - > ld - > topology , peer , tx , NULL ) ;
}
2017-10-12 08:35:04 +02:00
static void handle_onchain_unwatch_tx ( struct peer * peer , const u8 * msg )
2017-08-23 03:55:16 +02:00
{
2018-01-29 03:21:18 +01:00
struct bitcoin_txid txid ;
struct txwatch * txw ;
if ( ! fromwire_onchain_unwatch_tx ( msg , NULL , & txid ) ) {
peer_internal_error ( peer , " Invalid onchain_unwatch_tx " ) ;
return ;
}
/* Frees the txo watches, too: see watch_tx_and_outputs() */
txw = find_txwatch ( peer - > ld - > topology , & txid , peer ) ;
if ( ! txw )
log_unusual ( peer - > log , " Can't unwatch txid %s " ,
type_to_string ( ltmp , struct bitcoin_txid , & txid ) ) ;
tal_free ( txw ) ;
2017-08-23 03:55:16 +02:00
}
2017-10-12 08:35:04 +02:00
static void handle_extracted_preimage ( struct peer * peer , const u8 * msg )
2017-08-23 03:55:16 +02:00
{
struct preimage preimage ;
if ( ! fromwire_onchain_extracted_preimage ( msg , NULL , & preimage ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " Invalid extracted_preimage " ) ;
return ;
2017-08-23 03:55:16 +02:00
}
onchain_fulfilled_htlc ( peer , & preimage ) ;
}
2017-10-12 08:35:04 +02:00
static void handle_missing_htlc_output ( struct peer * peer , const u8 * msg )
2017-09-26 23:02:47 +02:00
{
struct htlc_stub htlc ;
if ( ! fromwire_onchain_missing_htlc_output ( msg , NULL , & htlc ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " Invalid missing_htlc_output " ) ;
return ;
2017-09-26 23:02:47 +02:00
}
/* BOLT #5:
*
* For any committed HTLC which does not have an output in this
* commitment transaction , the node MUST fail the corresponding
* incoming HTLC ( if any ) once the commitment transaction has reached
* reasonable depth , and MAY fail it sooner if no valid commitment
* transaction contains an output corresponding to the HTLC .
*/
onchain_failed_our_htlc ( peer , & htlc , " missing in commitment tx " ) ;
}
2017-10-12 08:35:04 +02:00
static void handle_onchain_htlc_timeout ( struct peer * peer , const u8 * msg )
2017-09-26 23:02:47 +02:00
{
struct htlc_stub htlc ;
if ( ! fromwire_onchain_htlc_timeout ( msg , NULL , & htlc ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " Invalid onchain_htlc_timeout " ) ;
return ;
2017-09-26 23:02:47 +02:00
}
/* BOLT #5:
*
* If the HTLC output has * timed out * and not been * resolved * , the node
* MUST * resolve * the output and MUST fail the corresponding incoming
* HTLC ( if any ) once the resolving transaction has reached reasonable
* depth .
*/
onchain_failed_our_htlc ( peer , & htlc , " timed out " ) ;
}
2017-11-10 03:01:10 +01:00
/* If peer is NULL, free them all (for shutdown) */
void free_htlcs ( struct lightningd * ld , const struct peer * peer )
2017-10-12 02:25:54 +02:00
{
2017-11-10 02:47:15 +01:00
struct htlc_out_map_iter outi ;
struct htlc_out * hout ;
struct htlc_in_map_iter ini ;
struct htlc_in * hin ;
bool deleted ;
/* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */
do {
deleted = false ;
2017-11-10 03:01:10 +01:00
for ( hout = htlc_out_map_first ( & ld - > htlcs_out , & outi ) ;
2017-11-10 02:47:15 +01:00
hout ;
2017-11-10 03:01:10 +01:00
hout = htlc_out_map_next ( & ld - > htlcs_out , & outi ) ) {
if ( peer & & hout - > key . peer ! = peer )
2017-11-10 02:47:15 +01:00
continue ;
tal_free ( hout ) ;
deleted = true ;
}
2017-11-10 03:01:10 +01:00
for ( hin = htlc_in_map_first ( & ld - > htlcs_in , & ini ) ;
2017-11-10 02:47:15 +01:00
hin ;
2017-11-10 03:01:10 +01:00
hin = htlc_in_map_next ( & ld - > htlcs_in , & ini ) ) {
if ( peer & & hin - > key . peer ! = peer )
2017-11-10 02:47:15 +01:00
continue ;
tal_free ( hin ) ;
deleted = true ;
}
/* Can skip over elements due to iterating while deleting. */
} while ( deleted ) ;
2017-11-10 03:01:10 +01:00
}
static void handle_irrevocably_resolved ( struct peer * peer , const u8 * msg )
{
/* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */
free_htlcs ( peer - > ld , peer ) ;
2017-11-10 02:47:15 +01:00
2017-10-12 02:25:54 +02:00
log_info ( peer - > log , " onchaind complete, forgetting peer " ) ;
2018-01-23 14:48:09 +01:00
wallet_channel_delete ( peer - > ld - > wallet , peer - > channel - > id ) ;
2017-10-12 02:25:54 +02:00
2017-10-12 08:35:04 +02:00
/* This will also free onchaind. */
2017-12-06 00:34:27 +01:00
free_peer ( peer , " onchaind complete, forgetting peer " ) ;
2017-10-12 02:25:54 +02:00
}
2017-12-19 17:09:52 +01:00
/**
* onchain_add_utxo - - onchaind is telling us about a UTXO we own
*/
static void onchain_add_utxo ( struct peer * peer , const u8 * msg )
{
2017-12-20 23:05:32 +01:00
struct utxo * u = tal ( msg , struct utxo ) ;
u - > close_info = tal ( u , struct unilateral_close_info ) ;
u - > is_p2sh = true ;
u - > keyindex = 0 ;
u - > status = output_state_available ;
u - > close_info - > channel_id = peer - > channel - > id ;
u - > close_info - > peer_id = peer - > id ;
if ( ! fromwire_onchain_add_utxo ( msg , NULL , & u - > txid , & u - > outnum ,
& u - > close_info - > commitment_point ,
& u - > amount ) ) {
fatal ( " onchaind gave invalid add_utxo message: %s " , tal_hex ( msg , msg ) ) ;
}
wallet_add_utxo ( peer - > ld - > wallet , u , p2wpkh ) ;
2017-12-19 17:09:52 +01:00
}
2017-10-12 08:35:04 +02:00
static unsigned int onchain_msg ( struct subd * sd , const u8 * msg , const int * fds )
2017-08-23 03:55:16 +02:00
{
enum onchain_wire_type t = fromwire_peektype ( msg ) ;
switch ( t ) {
case WIRE_ONCHAIN_INIT_REPLY :
2017-10-12 08:35:04 +02:00
handle_onchain_init_reply ( sd - > peer , msg ) ;
break ;
2017-08-23 03:55:16 +02:00
case WIRE_ONCHAIN_BROADCAST_TX :
2017-10-12 08:35:04 +02:00
handle_onchain_broadcast_tx ( sd - > peer , msg ) ;
break ;
2017-08-23 03:55:16 +02:00
case WIRE_ONCHAIN_UNWATCH_TX :
2017-10-12 08:35:04 +02:00
handle_onchain_unwatch_tx ( sd - > peer , msg ) ;
break ;
2017-08-23 03:55:16 +02:00
case WIRE_ONCHAIN_EXTRACTED_PREIMAGE :
2017-10-12 08:35:04 +02:00
handle_extracted_preimage ( sd - > peer , msg ) ;
break ;
2017-08-23 03:55:16 +02:00
2017-09-26 23:02:47 +02:00
case WIRE_ONCHAIN_MISSING_HTLC_OUTPUT :
2017-10-12 08:35:04 +02:00
handle_missing_htlc_output ( sd - > peer , msg ) ;
break ;
2017-09-26 23:02:47 +02:00
2017-09-26 23:02:47 +02:00
case WIRE_ONCHAIN_HTLC_TIMEOUT :
2017-10-12 08:35:04 +02:00
handle_onchain_htlc_timeout ( sd - > peer , msg ) ;
break ;
2017-09-26 23:02:47 +02:00
2017-10-12 02:25:54 +02:00
case WIRE_ONCHAIN_ALL_IRREVOCABLY_RESOLVED :
2017-10-12 08:35:04 +02:00
handle_irrevocably_resolved ( sd - > peer , msg ) ;
break ;
2017-10-12 02:25:54 +02:00
2017-12-19 17:09:52 +01:00
case WIRE_ONCHAIN_ADD_UTXO :
onchain_add_utxo ( sd - > peer , msg ) ;
break ;
2017-08-23 03:55:16 +02:00
/* We send these, not receive them */
case WIRE_ONCHAIN_INIT :
case WIRE_ONCHAIN_SPENT :
case WIRE_ONCHAIN_DEPTH :
case WIRE_ONCHAIN_HTLC :
case WIRE_ONCHAIN_KNOWN_PREIMAGE :
break ;
}
return 0 ;
}
static u8 * p2wpkh_for_keyidx ( const tal_t * ctx , struct lightningd * ld , u64 keyidx )
{
struct pubkey shutdownkey ;
2017-08-28 18:09:01 +02:00
if ( ! bip32_pubkey ( ld - > wallet - > bip32_base , & shutdownkey , keyidx ) )
2017-08-23 03:55:16 +02:00
return NULL ;
return scriptpubkey_p2wpkh ( ctx , & shutdownkey ) ;
}
2017-09-26 23:02:47 +02:00
/* If we want to know if this HTLC is missing, return depth. */
2017-10-10 19:46:23 +02:00
static bool tell_if_missing ( const struct peer * peer , struct htlc_stub * stub ,
2017-09-26 23:02:47 +02:00
bool * tell_immediate )
{
struct htlc_out * hout ;
/* Keep valgrind happy. */
* tell_immediate = false ;
/* Is it a current HTLC? */
2017-10-10 19:46:23 +02:00
hout = find_htlc_out_by_ripemd ( peer , & stub - > ripemd ) ;
2017-09-26 23:02:47 +02:00
if ( ! hout )
return false ;
/* BOLT #5:
*
* For any committed HTLC which does not have an output in this
* commitment transaction , the node MUST fail the corresponding
* incoming HTLC ( if any ) once the commitment transaction has reached
* reasonable depth , and MAY fail it sooner if no valid commitment
* transaction contains an output corresponding to the HTLC .
*/
if ( hout - > hstate > = RCVD_ADD_REVOCATION
& & hout - > hstate < SENT_REMOVE_REVOCATION )
* tell_immediate = true ;
log_debug ( peer - > log , " We want to know if htlc % " PRIu64 " is missing (%s) " ,
hout - > key . id , * tell_immediate ? " immediate " : " later " ) ;
return true ;
}
2017-08-23 03:55:16 +02:00
/* With a reorg, this can get called multiple times; each time we'll kill
* onchaind ( like any other owner ) , and restart */
static enum watch_result funding_spent ( struct peer * peer ,
const struct bitcoin_tx * tx ,
size_t input_num ,
const struct block * block ,
void * unused )
{
u8 * msg , * scriptpubkey ;
2017-12-18 07:41:52 +01:00
struct bitcoin_txid our_last_txid ;
2017-08-23 03:55:16 +02:00
s64 keyindex ;
struct pubkey ourkey ;
2017-10-10 14:05:36 +02:00
struct htlc_stub * stubs ;
2017-12-15 11:29:32 +01:00
const tal_t * tmpctx = tal_tmpctx ( peer ) ;
2017-08-23 03:55:16 +02:00
2018-01-03 06:59:35 +01:00
peer_fail_permanent ( peer , " Funding transaction spent " ) ;
2017-09-26 23:02:48 +02:00
/* We could come from almost any state. */
peer_set_condition ( peer , peer - > state , FUNDING_SPEND_SEEN ) ;
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , new_peer_subd ( peer - > ld ,
" lightning_onchaind " , peer ,
onchain_wire_type_name ,
onchain_msg ,
NULL ) ) ;
2017-08-23 03:55:16 +02:00
if ( ! peer - > owner ) {
log_broken ( peer - > log , " Could not subdaemon onchain: %s " ,
strerror ( errno ) ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-08-23 03:55:16 +02:00
return KEEP_WATCHING ;
}
2017-12-15 11:29:32 +01:00
stubs = wallet_htlc_stubs ( tmpctx , peer - > ld - > wallet , peer - > channel ) ;
2017-10-10 14:05:36 +02:00
if ( ! stubs ) {
log_broken ( peer - > log , " Could not load htlc_stubs " ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-10-10 14:05:36 +02:00
return KEEP_WATCHING ;
}
2017-08-23 03:55:16 +02:00
/* We re-use this key to send other outputs to. */
if ( peer - > local_shutdown_idx > = 0 )
keyindex = peer - > local_shutdown_idx ;
else {
keyindex = wallet_get_newindex ( peer - > ld ) ;
if ( keyindex < 0 ) {
log_broken ( peer - > log , " Could not get keyindex " ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-08-23 03:55:16 +02:00
return KEEP_WATCHING ;
}
}
2017-12-15 11:29:32 +01:00
scriptpubkey = p2wpkh_for_keyidx ( tmpctx , peer - > ld , keyindex ) ;
2017-08-23 03:55:16 +02:00
if ( ! scriptpubkey ) {
peer_internal_error ( peer ,
" Can't get shutdown script % " PRIu64 ,
keyindex ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-08-23 03:55:16 +02:00
return DELETE_WATCH ;
}
2017-12-19 17:11:15 +01:00
txfilter_add_scriptpubkey ( peer - > ld - > owned_txfilter , scriptpubkey ) ;
2017-08-23 03:55:16 +02:00
2017-08-28 18:09:01 +02:00
if ( ! bip32_pubkey ( peer - > ld - > wallet - > bip32_base , & ourkey , keyindex ) ) {
2017-08-23 03:55:16 +02:00
peer_internal_error ( peer ,
" Can't get shutdown key % " PRIu64 ,
keyindex ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-08-23 03:55:16 +02:00
return DELETE_WATCH ;
}
/* This could be a mutual close, but it doesn't matter. */
bitcoin_txid ( peer - > last_tx , & our_last_txid ) ;
msg = towire_onchain_init ( peer , peer - > seed , & peer - > their_shachain . chain ,
peer - > funding_satoshi ,
& peer - > channel_info - > old_remote_per_commit ,
& peer - > channel_info - > remote_per_commit ,
2017-12-04 03:09:04 +01:00
/* BOLT #2:
* ` to_self_delay ` is the number of blocks
* that the other nodes to - self outputs
* must be delayed */
/* So, these are reversed: they specify ours,
* we specify theirs . */
2017-08-23 03:55:16 +02:00
peer - > channel_info - > their_config . to_self_delay ,
2017-12-04 03:09:04 +01:00
peer - > our_config . to_self_delay ,
2017-11-21 04:35:55 +01:00
get_feerate ( peer - > ld - > topology ,
FEERATE_NORMAL ) ,
2017-08-23 03:55:16 +02:00
peer - > our_config . dust_limit_satoshis ,
& peer - > channel_info - > theirbase . revocation ,
& our_last_txid ,
scriptpubkey ,
peer - > remote_shutdown_scriptpubkey ,
& ourkey ,
peer - > funder ,
& peer - > channel_info - > theirbase . payment ,
2017-11-15 07:21:39 +01:00
& peer - > channel_info - > theirbase . htlc ,
2017-08-23 03:55:16 +02:00
& peer - > channel_info - > theirbase . delayed_payment ,
tx ,
block - > height ,
2017-09-26 23:02:47 +02:00
/* FIXME: config for 'reasonable depth' */
3 ,
2017-08-23 03:55:16 +02:00
peer - > last_htlc_sigs ,
2017-10-10 14:05:36 +02:00
tal_count ( stubs ) ) ;
2017-08-23 03:55:16 +02:00
subd_send_msg ( peer - > owner , take ( msg ) ) ;
/* FIXME: Don't queue all at once, use an empty cb... */
2017-10-10 14:05:36 +02:00
for ( size_t i = 0 ; i < tal_count ( stubs ) ; i + + ) {
2017-09-26 23:02:47 +02:00
bool tell_immediate ;
2017-10-10 19:46:23 +02:00
bool tell = tell_if_missing ( peer , & stubs [ i ] , & tell_immediate ) ;
2017-10-10 14:05:36 +02:00
msg = towire_onchain_htlc ( peer , & stubs [ i ] ,
2017-09-26 23:02:47 +02:00
tell , tell_immediate ) ;
2017-08-23 03:55:16 +02:00
subd_send_msg ( peer - > owner , take ( msg ) ) ;
}
watch_tx_and_outputs ( peer , tx ) ;
2017-12-15 11:29:32 +01:00
tal_free ( tmpctx ) ;
2017-08-23 03:55:16 +02:00
/* We keep watching until peer finally deleted, for reorgs. */
return KEEP_WATCHING ;
}
2017-05-23 13:00:17 +02:00
static enum watch_result funding_lockin_cb ( struct peer * peer ,
2017-08-18 06:43:53 +02:00
const struct bitcoin_tx * tx ,
2017-05-23 13:00:17 +02:00
unsigned int depth ,
void * unused )
2017-03-07 02:03:55 +01:00
{
2017-12-18 07:41:52 +01:00
struct bitcoin_txid txid ;
2017-08-18 06:43:53 +02:00
const char * txidstr ;
2017-05-23 13:00:17 +02:00
struct txlocator * loc ;
2017-06-20 08:11:03 +02:00
bool peer_ready ;
2017-03-07 02:05:03 +01:00
2017-08-18 06:43:53 +02:00
bitcoin_txid ( tx , & txid ) ;
2017-12-18 07:41:52 +01:00
txidstr = type_to_string ( peer , struct bitcoin_txid , & txid ) ;
2017-03-07 02:05:03 +01:00
log_debug ( peer - > log , " Funding tx %s depth %u of %u " ,
2017-04-12 08:52:57 +02:00
txidstr , depth , peer - > minimum_depth ) ;
2017-05-23 13:00:17 +02:00
tal_free ( txidstr ) ;
2017-03-07 02:31:43 +01:00
2017-04-12 08:52:57 +02:00
if ( depth < peer - > minimum_depth )
2017-03-07 02:31:43 +01:00
return KEEP_WATCHING ;
2017-08-18 06:43:53 +02:00
loc = locate_tx ( peer , peer - > ld - > topology , & txid ) ;
2017-05-02 07:26:31 +02:00
2018-01-05 03:42:31 +01:00
/* If we restart, we could already have peer->scid from database */
if ( ! peer - > scid ) {
peer - > scid = tal ( peer , struct short_channel_id ) ;
peer - > scid - > blocknum = loc - > blkheight ;
peer - > scid - > txnum = loc - > index ;
peer - > scid - > outnum = peer - > funding_outnum ;
}
2017-05-23 13:00:17 +02:00
tal_free ( loc ) ;
2017-05-02 07:26:31 +02:00
2017-06-20 08:11:03 +02:00
/* In theory, it could have been buried before we got back
* from accepting openingd or disconnected : just wait for next one . */
peer_ready = ( peer - > owner & & peer - > state = = CHANNELD_AWAITING_LOCKIN ) ;
if ( ! peer_ready ) {
2018-01-24 20:52:36 +01:00
log_debug ( peer - > log ,
" Funding tx confirmed, but peer state %s %s " ,
peer_state_name ( peer - > state ) ,
peer - > owner ? peer - > owner - > name : " unowned " ) ;
2017-06-20 08:11:03 +02:00
} else {
subd_send_msg ( peer - > owner ,
take ( towire_channel_funding_locked ( peer ,
peer - > scid ) ) ) ;
}
2017-03-20 17:09:12 +01:00
2017-06-27 04:55:01 +02:00
/* BOLT #7:
*
* If the ` open_channel ` message had the ` announce_channel ` bit set ,
* then both nodes must send the ` announcement_signatures ` message ,
* otherwise they MUST NOT .
*/
if ( ! ( peer - > channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL ) )
return DELETE_WATCH ;
2017-09-04 05:41:34 +02:00
/* Tell channeld that we have reached the announce_depth and
* that it may send the announcement_signatures upon receiving
* funding_locked , or right now if it already received it
* before . If we are at the right depth , call the callback
* directly , otherwise schedule a callback */
if ( depth > = ANNOUNCE_MIN_DEPTH )
funding_announce_cb ( peer , tx , depth , NULL ) ;
else
2017-08-18 06:43:53 +02:00
watch_txid ( peer , peer - > ld - > topology , peer , & txid ,
2017-05-23 13:00:17 +02:00
funding_announce_cb , NULL ) ;
2017-03-07 02:31:43 +01:00
return DELETE_WATCH ;
2017-03-07 02:03:55 +01:00
}
2017-06-24 08:25:51 +02:00
static void opening_got_hsm_funding_sig ( struct funding_channel * fc ,
2017-06-24 08:50:23 +02:00
int peer_fd , int gossip_fd ,
2017-06-24 08:25:53 +02:00
const u8 * resp ,
2017-12-11 04:33:16 +01:00
const struct crypto_state * cs ,
u64 gossip_index )
2017-02-24 06:52:56 +01:00
{
2018-01-05 01:12:07 +01:00
struct bitcoin_tx * tx = tal ( fc , struct bitcoin_tx ) ;
2017-10-22 15:32:46 +02:00
u8 * linear ;
2017-09-01 14:40:52 +02:00
u64 change_satoshi ;
2017-10-22 15:32:46 +02:00
struct json_result * response = new_json_result ( fc - > cmd ) ;
2017-02-24 06:52:56 +01:00
2018-01-05 01:12:07 +01:00
if ( ! fromwire_hsm_sign_funding_reply ( resp , NULL , tx ) )
2017-03-10 11:49:43 +01:00
fatal ( " HSM gave bad sign_funding_reply %s " ,
2017-02-24 06:52:56 +01:00
tal_hex ( fc , resp ) ) ;
2017-03-07 02:03:55 +01:00
/* Send it out and watch for confirms. */
2017-06-24 08:25:51 +02:00
broadcast_tx ( fc - > peer - > ld - > topology , fc - > peer , tx , funding_broadcast_failed ) ;
2017-03-07 02:03:55 +01:00
watch_tx ( fc - > peer , fc - > peer - > ld - > topology , fc - > peer , tx ,
2017-05-23 13:00:17 +02:00
funding_lockin_cb , NULL ) ;
2017-05-05 08:41:46 +02:00
2017-09-01 14:40:52 +02:00
/* Extract the change output and add it to the DB */
wallet_extract_owned_outputs ( fc - > peer - > ld - > wallet , tx , & change_satoshi ) ;
2017-08-23 03:55:16 +02:00
/* FIXME: Remove arg from cb? */
watch_txo ( fc - > peer , fc - > peer - > ld - > topology , fc - > peer ,
fc - > peer - > funding_txid , fc - > peer - > funding_outnum ,
funding_spent , NULL ) ;
2017-10-22 15:32:46 +02:00
json_object_start ( response , NULL ) ;
linear = linearize_tx ( response , tx ) ;
json_add_hex ( response , " tx " , linear , tal_len ( linear ) ) ;
2018-01-17 08:29:29 +01:00
json_add_txid ( response , " txid " , fc - > peer - > funding_txid ) ;
2017-10-22 15:32:46 +02:00
json_object_end ( response ) ;
2017-12-06 00:34:27 +01:00
command_success ( fc - > peer - > opening_cmd , response ) ;
fc - > peer - > opening_cmd = NULL ;
2017-05-22 13:27:20 +02:00
/* Start normal channel daemon. */
2017-12-11 04:33:16 +01:00
peer_start_channeld ( fc - > peer , cs , gossip_index ,
peer_fd , gossip_fd , NULL , false ) ;
2017-07-01 03:41:17 +02:00
peer_set_condition ( fc - > peer , OPENINGD , CHANNELD_AWAITING_LOCKIN ) ;
2017-05-22 13:27:20 +02:00
2017-06-13 15:42:31 +02:00
wallet_confirm_utxos ( fc - > peer - > ld - > wallet , fc - > utxomap ) ;
2017-03-07 02:03:55 +01:00
tal_free ( fc ) ;
2017-02-24 06:52:56 +01:00
}
2017-05-07 01:59:48 +02:00
/* We were informed by channeld that it announced the channel and sent
* an update , so we can now start sending a node_announcement . The
* first step is to build the provisional announcement and ask the HSM
* to sign it . */
2017-10-12 08:35:04 +02:00
static void peer_got_funding_locked ( struct peer * peer , const u8 * msg )
2017-06-20 07:55:03 +02:00
{
struct pubkey next_per_commitment_point ;
if ( ! fromwire_channel_got_funding_locked ( msg , NULL ,
& next_per_commitment_point ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " bad channel_got_funding_locked %s " ,
tal_hex ( peer , msg ) ) ;
return ;
2017-06-20 07:55:03 +02:00
}
2017-06-20 08:15:03 +02:00
if ( peer - > remote_funding_locked ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " channel_got_funding_locked twice " ) ;
return ;
2017-06-20 08:15:03 +02:00
}
update_per_commit_point ( peer , & next_per_commitment_point ) ;
2017-06-20 08:11:03 +02:00
log_debug ( peer - > log , " Got funding_locked " ) ;
2017-06-20 08:15:03 +02:00
peer - > remote_funding_locked = true ;
2017-06-20 07:55:03 +02:00
}
2017-10-12 08:35:04 +02:00
static void peer_got_shutdown ( struct peer * peer , const u8 * msg )
2017-06-26 03:16:43 +02:00
{
u8 * scriptpubkey ;
if ( ! fromwire_channel_got_shutdown ( peer , msg , NULL , & scriptpubkey ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " bad channel_got_shutdown %s " ,
tal_hex ( peer , msg ) ) ;
return ;
2017-06-26 03:16:43 +02:00
}
/* FIXME: Add to spec that we must allow repeated shutdown! */
2017-12-08 16:14:59 +01:00
tal_free ( peer - > remote_shutdown_scriptpubkey ) ;
2017-06-26 03:16:43 +02:00
peer - > remote_shutdown_scriptpubkey = scriptpubkey ;
2017-06-27 05:51:07 +02:00
/* BOLT #2:
*
* A sending node MUST set ` scriptpubkey ` to one of the following forms :
*
* 1. ` OP_DUP ` ` OP_HASH160 ` ` 20 ` 20 - bytes ` OP_EQUALVERIFY ` ` OP_CHECKSIG `
* ( pay to pubkey hash ) , OR
* 2. ` OP_HASH160 ` ` 20 ` 20 - bytes ` OP_EQUAL ` ( pay to script hash ) , OR
* 3. ` OP_0 ` ` 20 ` 20 - bytes ( version 0 pay to witness pubkey ) , OR
* 4. ` OP_0 ` ` 32 ` 32 - bytes ( version 0 pay to witness script hash )
*
* A receiving node SHOULD fail the connection if the ` scriptpubkey `
* is not one of those forms . */
2017-10-26 04:58:19 +02:00
if ( ! is_p2pkh ( scriptpubkey , NULL ) & & ! is_p2sh ( scriptpubkey , NULL )
& & ! is_p2wpkh ( scriptpubkey , NULL ) & & ! is_p2wsh ( scriptpubkey , NULL ) ) {
2018-01-03 06:59:35 +01:00
peer_fail_permanent ( peer , " Bad shutdown scriptpubkey %s " ,
2017-08-17 07:43:42 +02:00
tal_hex ( peer , scriptpubkey ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-06-27 05:51:07 +02:00
}
2017-06-26 03:16:43 +02:00
if ( peer - > local_shutdown_idx = = - 1 ) {
u8 * scriptpubkey ;
peer - > local_shutdown_idx = wallet_get_newindex ( peer - > ld ) ;
if ( peer - > local_shutdown_idx = = - 1 ) {
peer_internal_error ( peer ,
" Can't get local shutdown index " ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-06-26 03:16:43 +02:00
}
peer_set_condition ( peer , CHANNELD_NORMAL , CHANNELD_SHUTTING_DOWN ) ;
/* BOLT #2:
*
* A sending node MUST set ` scriptpubkey ` to one of the
* following forms :
*
* . . .3 . ` OP_0 ` ` 20 ` 20 - bytes ( version 0 pay to witness pubkey ) ,
*/
scriptpubkey = p2wpkh_for_keyidx ( msg , peer - > ld ,
peer - > local_shutdown_idx ) ;
if ( ! scriptpubkey ) {
peer_internal_error ( peer ,
" Can't get shutdown script % " PRIu64 ,
peer - > local_shutdown_idx ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-06-26 03:16:43 +02:00
}
2017-12-16 21:04:16 +01:00
txfilter_add_scriptpubkey ( peer - > ld - > owned_txfilter , scriptpubkey ) ;
2017-06-26 03:16:43 +02:00
/* BOLT #2:
*
* A receiving node MUST reply to a ` shutdown ` message with a
* ` shutdown ` once there are no outstanding updates on the
* peer , unless it has already sent a ` shutdown ` .
*/
2017-06-26 04:04:26 +02:00
subd_send_msg ( peer - > owner ,
2017-06-26 03:16:43 +02:00
take ( towire_channel_send_shutdown ( peer ,
scriptpubkey ) ) ) ;
}
2017-08-12 16:46:50 +02:00
/* TODO(cdecker) Selectively save updated fields to DB */
2018-02-06 12:15:26 +01:00
wallet_channel_save ( peer - > ld - > wallet , peer - > channel ) ;
2017-06-26 03:16:43 +02:00
}
2017-08-18 06:43:52 +02:00
void peer_last_tx ( struct peer * peer , struct bitcoin_tx * tx ,
const secp256k1_ecdsa_signature * sig )
2017-07-04 03:53:35 +02:00
{
2017-08-18 06:43:52 +02:00
tal_free ( peer - > last_sig ) ;
peer - > last_sig = tal_dup ( peer , secp256k1_ecdsa_signature , sig ) ;
tal_free ( peer - > last_tx ) ;
peer - > last_tx = tal_steal ( peer , tx ) ;
}
2018-02-02 01:46:18 +01:00
/* Is this better than the last tx we were holding? This can happen
* even without closingd misbehaving , if we have multiple ,
* interrupted , rounds of negotiation . */
2017-08-18 06:43:52 +02:00
static bool better_closing_fee ( struct peer * peer , const struct bitcoin_tx * tx )
{
u64 weight , fee , last_fee , ideal_fee , min_fee ;
2017-07-31 08:30:39 +02:00
s64 old_diff , new_diff ;
2017-08-18 06:43:52 +02:00
size_t i ;
2017-07-31 08:30:39 +02:00
2018-02-02 01:46:18 +01:00
/* Calculate actual fee (adds in eliminated outputs) */
2017-08-18 06:43:52 +02:00
fee = peer - > funding_satoshi ;
for ( i = 0 ; i < tal_count ( tx - > output ) ; i + + )
fee - = tx - > output [ i ] . amount ;
2017-07-04 03:53:35 +02:00
2017-08-18 06:43:52 +02:00
last_fee = peer - > funding_satoshi ;
for ( i = 0 ; i < tal_count ( peer - > last_tx ) ; i + + )
last_fee - = peer - > last_tx - > output [ i ] . amount ;
2018-02-02 01:46:18 +01:00
log_debug ( peer - > log , " Their actual closing tx fee is % " PRIu64
" vs previous % " PRIu64 , fee , last_fee ) ;
2017-08-18 06:43:52 +02:00
/* Weight once we add in sigs. */
2018-02-03 01:16:23 +01:00
weight = measure_tx_weight ( tx ) + 74 * 2 ;
2017-08-18 06:43:52 +02:00
2017-11-21 04:30:29 +01:00
min_fee = get_feerate ( peer - > ld - > topology , FEERATE_SLOW ) * weight / 1000 ;
2018-02-02 01:46:18 +01:00
if ( fee < min_fee ) {
log_debug ( peer - > log , " ... That's below our min % " PRIu64
" for weight % " PRIu64 " at feerate %u " ,
min_fee , weight ,
get_feerate ( peer - > ld - > topology , FEERATE_SLOW ) ) ;
2017-08-18 06:43:52 +02:00
return false ;
2018-02-02 01:46:18 +01:00
}
2017-07-05 07:33:40 +02:00
2017-11-21 04:30:29 +01:00
ideal_fee = get_feerate ( peer - > ld - > topology , FEERATE_NORMAL ) * weight / 1000 ;
2017-07-04 03:53:35 +02:00
2017-07-31 08:30:39 +02:00
/* We prefer fee which is closest to our ideal. */
2017-08-18 06:43:52 +02:00
old_diff = imaxabs ( ( s64 ) ideal_fee - ( s64 ) last_fee ) ;
new_diff = imaxabs ( ( s64 ) ideal_fee - ( s64 ) fee ) ;
2017-07-04 03:53:35 +02:00
2018-02-02 01:46:18 +01:00
/* In case of a tie, prefer new over old: this covers the preference
* for a mutual close over a unilateral one . */
2018-02-02 01:46:18 +01:00
log_debug ( peer - > log , " ... That's %s our ideal % " PRIu64 ,
new_diff < old_diff
? " closer to "
: new_diff > old_diff
? " further from "
: " same distance to " ,
ideal_fee ) ;
2018-02-02 01:46:18 +01:00
return new_diff < = old_diff ;
2017-07-04 03:53:35 +02:00
}
2017-10-12 08:35:04 +02:00
static void peer_received_closing_signature ( struct peer * peer , const u8 * msg )
2017-07-04 03:53:35 +02:00
{
secp256k1_ecdsa_signature sig ;
2017-08-18 06:43:52 +02:00
struct bitcoin_tx * tx = tal ( msg , struct bitcoin_tx ) ;
2017-07-04 03:53:35 +02:00
2017-08-18 06:43:52 +02:00
if ( ! fromwire_closing_received_signature ( msg , NULL , & sig , tx ) ) {
2017-07-31 08:30:39 +02:00
peer_internal_error ( peer , " Bad closing_received_signature %s " ,
2017-07-04 03:53:35 +02:00
tal_hex ( peer , msg ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-07-04 03:53:35 +02:00
}
2017-07-31 08:30:39 +02:00
/* FIXME: Make sure signature is correct! */
2017-08-12 16:46:50 +02:00
if ( better_closing_fee ( peer , tx ) ) {
2018-01-10 03:43:23 +01:00
peer_last_tx ( peer , tx , & sig ) ;
2017-08-12 16:46:50 +02:00
/* TODO(cdecker) Selectively save updated fields to DB */
2018-02-06 12:15:26 +01:00
wallet_channel_save ( peer - > ld - > wallet , peer - > channel ) ;
2017-08-12 16:46:50 +02:00
}
2017-07-04 03:53:35 +02:00
/* OK, you can continue now. */
subd_send_msg ( peer - > owner ,
2017-07-31 08:30:39 +02:00
take ( towire_closing_received_signature_reply ( peer ) ) ) ;
2017-07-04 03:53:35 +02:00
}
2017-10-12 08:35:04 +02:00
static void peer_closing_complete ( struct peer * peer , const u8 * msg )
2017-07-04 03:53:35 +02:00
{
2017-12-11 04:33:16 +01:00
/* FIXME: We should save this, to return to gossipd */
u64 gossip_index ;
if ( ! fromwire_closing_complete ( msg , NULL , & gossip_index ) ) {
2017-07-04 03:53:35 +02:00
peer_internal_error ( peer , " Bad closing_complete %s " ,
tal_hex ( peer , msg ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-07-04 03:53:35 +02:00
}
2017-07-07 13:45:42 +02:00
/* Retransmission only, ignore closing. */
if ( peer - > state = = CLOSINGD_COMPLETE )
2017-10-12 08:35:04 +02:00
return ;
2017-07-07 13:45:42 +02:00
2017-08-18 06:43:52 +02:00
drop_to_chain ( peer ) ;
2017-07-05 07:33:40 +02:00
peer_set_condition ( peer , CLOSINGD_SIGEXCHANGE , CLOSINGD_COMPLETE ) ;
2017-07-04 03:53:35 +02:00
}
2017-10-12 08:35:04 +02:00
static unsigned closing_msg ( struct subd * sd , const u8 * msg , const int * fds )
2017-07-04 03:53:35 +02:00
{
enum closing_wire_type t = fromwire_peektype ( msg ) ;
switch ( t ) {
case WIRE_CLOSING_RECEIVED_SIGNATURE :
2017-10-12 08:35:04 +02:00
peer_received_closing_signature ( sd - > peer , msg ) ;
break ;
2017-07-04 03:53:35 +02:00
case WIRE_CLOSING_COMPLETE :
2017-10-12 08:35:04 +02:00
peer_closing_complete ( sd - > peer , msg ) ;
break ;
2017-07-04 03:53:35 +02:00
/* We send these, not receive them */
case WIRE_CLOSING_INIT :
case WIRE_CLOSING_RECEIVED_SIGNATURE_REPLY :
break ;
}
return 0 ;
}
2017-07-05 07:33:28 +02:00
static void peer_start_closingd ( struct peer * peer ,
struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
2017-07-05 07:33:28 +02:00
int peer_fd , int gossip_fd ,
bool reconnected )
2017-07-04 02:47:32 +02:00
{
2017-07-05 07:33:28 +02:00
const tal_t * tmpctx = tal_tmpctx ( peer ) ;
2017-07-04 03:53:35 +02:00
u8 * initmsg , * local_scriptpubkey ;
2018-02-02 01:46:18 +01:00
u64 minfee , startfee , feelimit ;
2017-08-23 02:54:54 +02:00
u64 num_revocations ;
2018-01-28 07:59:03 +01:00
u64 funding_msatoshi , our_msatoshi , their_msatoshi ;
2017-07-04 02:47:32 +02:00
if ( peer - > local_shutdown_idx = = - 1
| | ! peer - > remote_shutdown_scriptpubkey ) {
peer_internal_error ( peer ,
" Can't start closing: local %s remote %s " ,
peer - > local_shutdown_idx = = - 1
? " not shutdown " : " shutdown " ,
peer - > remote_shutdown_scriptpubkey
? " shutdown " : " not shutdown " ) ;
2017-07-05 07:33:28 +02:00
tal_free ( tmpctx ) ;
return ;
2017-07-04 02:47:32 +02:00
}
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , new_peer_subd ( peer - > ld ,
" lightning_closingd " , peer ,
closing_wire_type_name , closing_msg ,
take ( & peer_fd ) , take ( & gossip_fd ) ,
NULL ) ) ;
2017-07-04 03:53:35 +02:00
if ( ! peer - > owner ) {
log_unusual ( peer - > log , " Could not subdaemon closing: %s " ,
strerror ( errno ) ) ;
peer_fail_transient ( peer , " Failed to subdaemon closing " ) ;
2017-07-05 07:33:28 +02:00
tal_free ( tmpctx ) ;
return ;
2017-07-04 03:53:35 +02:00
}
2017-07-05 07:33:28 +02:00
local_scriptpubkey = p2wpkh_for_keyidx ( tmpctx , peer - > ld ,
2017-07-04 03:53:35 +02:00
peer - > local_shutdown_idx ) ;
if ( ! local_scriptpubkey ) {
peer_internal_error ( peer ,
" Can't generate local shutdown scriptpubkey " ) ;
2017-07-05 07:33:28 +02:00
tal_free ( tmpctx ) ;
return ;
2017-07-04 03:53:35 +02:00
}
2017-11-15 10:49:50 +01:00
/* BOLT #2:
*
* A sending node MUST set ` fee_satoshis ` lower than or equal
* to the base fee of the final commitment transaction as
* calculated in [ BOLT
* # 3 ] ( 03 - transactions . md # fee - calculation ) .
*/
2017-11-21 04:44:35 +01:00
feelimit = commit_tx_base_fee ( peer - > channel_info - > feerate_per_kw [ LOCAL ] ,
0 ) ;
2017-11-21 04:30:29 +01:00
minfee = commit_tx_base_fee ( get_feerate ( peer - > ld - > topology ,
FEERATE_SLOW ) , 0 ) ;
startfee = commit_tx_base_fee ( get_feerate ( peer - > ld - > topology ,
FEERATE_NORMAL ) , 0 ) ;
if ( startfee > feelimit )
startfee = feelimit ;
if ( minfee > feelimit )
minfee = feelimit ;
2017-07-04 03:53:35 +02:00
2017-08-23 02:54:54 +02:00
num_revocations
= revocations_received ( & peer - > their_shachain . chain ) ;
2017-07-04 03:53:35 +02:00
/* BOLT #3:
*
* The amounts for each output MUST BE rounded down to whole satoshis .
*/
2018-01-28 07:59:03 +01:00
/* Convert unit */
funding_msatoshi = peer - > funding_satoshi * 1000 ;
/* What is not ours is theirs */
our_msatoshi = * peer - > our_msatoshi ;
their_msatoshi = funding_msatoshi - our_msatoshi ;
2017-07-05 07:33:28 +02:00
initmsg = towire_closing_init ( tmpctx ,
cs ,
2017-12-11 04:33:16 +01:00
gossip_index ,
2017-07-04 03:53:35 +02:00
peer - > seed ,
peer - > funding_txid ,
peer - > funding_outnum ,
peer - > funding_satoshi ,
& peer - > channel_info - > remote_fundingkey ,
peer - > funder ,
2018-01-28 07:59:03 +01:00
our_msatoshi / 1000 , /* Rounds down */
their_msatoshi / 1000 , /* Rounds down */
2017-07-04 03:53:35 +02:00
peer - > our_config . dust_limit_satoshis ,
2018-02-02 01:46:18 +01:00
minfee , feelimit , startfee ,
2017-07-04 03:53:35 +02:00
local_scriptpubkey ,
2017-07-05 07:33:28 +02:00
peer - > remote_shutdown_scriptpubkey ,
reconnected ,
peer - > next_index [ LOCAL ] ,
peer - > next_index [ REMOTE ] ,
2018-02-02 01:55:06 +01:00
num_revocations ,
deprecated_apis ) ;
2017-07-04 03:53:35 +02:00
/* We don't expect a response: it will give us feedback on
* signatures sent and received , then closing_complete . */
subd_send_msg ( peer - > owner , take ( initmsg ) ) ;
2017-07-05 07:33:28 +02:00
tal_free ( tmpctx ) ;
}
2017-10-12 08:35:04 +02:00
static void peer_start_closingd_after_shutdown ( struct peer * peer , const u8 * msg ,
const int * fds )
2017-07-05 07:33:28 +02:00
{
struct crypto_state cs ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
2017-07-05 07:33:28 +02:00
/* We expect 2 fds. */
2017-10-12 08:35:04 +02:00
assert ( tal_count ( fds ) = = 2 ) ;
2017-07-05 07:33:28 +02:00
2017-12-11 04:33:16 +01:00
if ( ! fromwire_channel_shutdown_complete ( msg , NULL , & cs , & gossip_index ) ) {
2017-07-05 07:33:28 +02:00
peer_internal_error ( peer , " bad shutdown_complete: %s " ,
tal_hex ( peer , msg ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-07-05 07:33:28 +02:00
}
2017-10-12 08:35:04 +02:00
/* This sets peer->owner, closes down channeld. */
2017-12-11 04:33:16 +01:00
peer_start_closingd ( peer , & cs , gossip_index , fds [ 0 ] , fds [ 1 ] , false ) ;
2017-07-05 07:33:28 +02:00
peer_set_condition ( peer , CHANNELD_SHUTTING_DOWN , CLOSINGD_SIGEXCHANGE ) ;
2017-07-04 02:47:32 +02:00
}
2017-10-12 08:35:04 +02:00
static unsigned channel_msg ( struct subd * sd , const u8 * msg , const int * fds )
2017-03-07 02:31:43 +01:00
{
2017-03-10 11:56:58 +01:00
enum channel_wire_type t = fromwire_peektype ( msg ) ;
2017-03-07 02:31:43 +01:00
switch ( t ) {
case WIRE_CHANNEL_NORMAL_OPERATION :
2017-05-22 13:27:20 +02:00
peer_set_condition ( sd - > peer ,
CHANNELD_AWAITING_LOCKIN , CHANNELD_NORMAL ) ;
2017-03-07 02:31:43 +01:00
break ;
2017-06-20 07:50:03 +02:00
case WIRE_CHANNEL_SENDING_COMMITSIG :
2017-10-12 08:35:04 +02:00
peer_sending_commitsig ( sd - > peer , msg ) ;
break ;
2017-06-20 07:50:03 +02:00
case WIRE_CHANNEL_GOT_COMMITSIG :
2017-10-12 08:35:04 +02:00
peer_got_commitsig ( sd - > peer , msg ) ;
break ;
2017-06-20 07:50:03 +02:00
case WIRE_CHANNEL_GOT_REVOKE :
2017-10-12 08:35:04 +02:00
peer_got_revoke ( sd - > peer , msg ) ;
break ;
2017-06-20 07:55:03 +02:00
case WIRE_CHANNEL_GOT_FUNDING_LOCKED :
2017-10-12 08:35:04 +02:00
peer_got_funding_locked ( sd - > peer , msg ) ;
break ;
2017-06-26 03:16:43 +02:00
case WIRE_CHANNEL_GOT_SHUTDOWN :
2017-10-12 08:35:04 +02:00
peer_got_shutdown ( sd - > peer , msg ) ;
break ;
2017-07-04 02:47:32 +02:00
case WIRE_CHANNEL_SHUTDOWN_COMPLETE :
2017-10-12 08:35:04 +02:00
/* We expect 2 fds. */
if ( ! fds )
return 2 ;
peer_start_closingd_after_shutdown ( sd - > peer , msg , fds ) ;
break ;
2017-03-29 13:01:15 +02:00
2017-03-10 11:56:58 +01:00
/* And we never get these from channeld. */
case WIRE_CHANNEL_INIT :
case WIRE_CHANNEL_FUNDING_LOCKED :
2017-03-20 17:09:12 +01:00
case WIRE_CHANNEL_FUNDING_ANNOUNCE_DEPTH :
2017-03-29 13:01:15 +02:00
case WIRE_CHANNEL_OFFER_HTLC :
case WIRE_CHANNEL_FULFILL_HTLC :
case WIRE_CHANNEL_FAIL_HTLC :
2017-04-12 18:10:10 +02:00
case WIRE_CHANNEL_PING :
2017-06-20 07:50:03 +02:00
case WIRE_CHANNEL_GOT_COMMITSIG_REPLY :
case WIRE_CHANNEL_GOT_REVOKE_REPLY :
case WIRE_CHANNEL_SENDING_COMMITSIG_REPLY :
2017-06-26 03:16:43 +02:00
case WIRE_CHANNEL_SEND_SHUTDOWN :
2017-09-26 06:57:31 +02:00
case WIRE_CHANNEL_DEV_REENABLE_COMMIT :
2017-11-21 06:26:59 +01:00
case WIRE_CHANNEL_FEERATES :
2017-03-29 13:01:15 +02:00
/* Replies go to requests. */
case WIRE_CHANNEL_OFFER_HTLC_REPLY :
2017-04-12 18:10:10 +02:00
case WIRE_CHANNEL_PING_REPLY :
2017-09-26 06:57:31 +02:00
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY :
2017-03-07 02:31:43 +01:00
break ;
}
2017-03-19 21:31:35 +01:00
return 0 ;
2017-03-07 02:31:43 +01:00
}
2018-01-16 10:24:46 +01:00
u32 feerate_min ( struct lightningd * ld )
{
if ( ld - > config . ignore_fee_limits )
return 1 ;
/* Set this to average of slow and normal.*/
return ( get_feerate ( ld - > topology , FEERATE_SLOW )
+ get_feerate ( ld - > topology , FEERATE_NORMAL ) ) / 2 ;
}
/* BOLT #2:
*
* Given the variance in fees , and the fact that the transaction may
* be spent in the future , it ' s a good idea for the fee payer to keep
* a good margin , say 5 x the expected fee requirement */
u32 feerate_max ( struct lightningd * ld )
{
if ( ld - > config . ignore_fee_limits )
return UINT_MAX ;
return get_feerate ( ld - > topology , FEERATE_IMMEDIATE ) * 5 ;
}
2017-06-24 08:25:53 +02:00
static bool peer_start_channeld ( struct peer * peer ,
2017-06-24 08:25:53 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
2017-06-24 08:50:23 +02:00
int peer_fd , int gossip_fd ,
2017-07-04 03:53:36 +02:00
const u8 * funding_signed ,
bool reconnected )
2017-04-01 12:58:30 +02:00
{
2017-06-24 08:25:53 +02:00
const tal_t * tmpctx = tal_tmpctx ( peer ) ;
u8 * msg , * initmsg ;
int hsmfd ;
2017-08-28 18:09:01 +02:00
const struct config * cfg = & peer - > ld - > config ;
2017-06-20 08:04:03 +02:00
struct added_htlc * htlcs ;
enum htlc_state * htlc_states ;
2017-06-20 08:06:03 +02:00
struct fulfilled_htlc * fulfilled_htlcs ;
enum side * fulfilled_sides ;
struct failed_htlc * failed_htlcs ;
enum side * failed_sides ;
2017-06-20 08:11:03 +02:00
struct short_channel_id funding_channel_id ;
2017-06-26 03:16:43 +02:00
const u8 * shutdown_scriptpubkey ;
2017-08-23 02:54:54 +02:00
u64 num_revocations ;
2017-05-23 13:57:04 +02:00
2017-06-24 08:25:53 +02:00
/* Now we can consider balance set. */
2017-07-10 03:54:45 +02:00
if ( ! reconnected ) {
assert ( ! peer - > our_msatoshi ) ;
peer - > our_msatoshi = tal ( peer , u64 ) ;
if ( peer - > funder = = LOCAL )
* peer - > our_msatoshi
= peer - > funding_satoshi * 1000 - peer - > push_msat ;
else
* peer - > our_msatoshi = peer - > push_msat ;
} else
assert ( peer - > our_msatoshi ) ;
2017-06-24 08:25:53 +02:00
2017-11-30 17:07:38 +01:00
msg = towire_hsm_client_hsmfd ( tmpctx , & peer - > id , HSM_CAP_SIGN_GOSSIP | HSM_CAP_ECDH ) ;
2017-06-24 08:50:23 +02:00
if ( ! wire_sync_write ( peer - > ld - > hsm_fd , take ( msg ) ) )
2017-06-24 08:25:53 +02:00
fatal ( " Could not write to HSM: %s " , strerror ( errno ) ) ;
msg = hsm_sync_read ( tmpctx , peer - > ld ) ;
2017-11-30 17:07:38 +01:00
if ( ! fromwire_hsm_client_hsmfd_reply ( msg , NULL ) )
2017-06-24 08:25:53 +02:00
fatal ( " Bad reply from HSM: %s " , tal_hex ( tmpctx , msg ) ) ;
2017-06-24 08:50:23 +02:00
hsmfd = fdpass_recv ( peer - > ld - > hsm_fd ) ;
2017-06-24 08:25:53 +02:00
if ( hsmfd < 0 )
fatal ( " Could not read fd from HSM: %s " , strerror ( errno ) ) ;
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer , new_peer_subd ( peer - > ld ,
" lightning_channeld " , peer ,
channel_wire_type_name ,
channel_msg ,
take ( & peer_fd ) ,
take ( & gossip_fd ) ,
take ( & hsmfd ) , NULL ) ) ;
2017-05-23 13:57:04 +02:00
if ( ! peer - > owner ) {
log_unusual ( peer - > log , " Could not subdaemon channel: %s " ,
2017-04-01 12:58:30 +02:00
strerror ( errno ) ) ;
2017-06-20 08:17:03 +02:00
peer_fail_transient ( peer , " Failed to subdaemon channel " ) ;
2017-06-26 23:21:52 +02:00
tal_free ( tmpctx ) ;
2017-04-01 12:58:30 +02:00
return true ;
}
2017-06-24 08:25:53 +02:00
peer_htlcs ( tmpctx , peer , & htlcs , & htlc_states , & fulfilled_htlcs ,
2017-06-20 08:06:03 +02:00
& fulfilled_sides , & failed_htlcs , & failed_sides ) ;
2017-06-20 08:04:03 +02:00
2017-06-20 08:11:03 +02:00
if ( peer - > scid ) {
funding_channel_id = * peer - > scid ;
2017-06-20 08:15:03 +02:00
log_debug ( peer - > log , " Already have funding locked in " ) ;
2017-06-20 08:11:03 +02:00
} else {
log_debug ( peer - > log , " Waiting for funding confirmations " ) ;
memset ( & funding_channel_id , 0 , sizeof ( funding_channel_id ) ) ;
}
2017-06-26 03:16:43 +02:00
if ( peer - > local_shutdown_idx ! = - 1 ) {
shutdown_scriptpubkey
= p2wpkh_for_keyidx ( tmpctx , peer - > ld ,
peer - > local_shutdown_idx ) ;
} else
shutdown_scriptpubkey = NULL ;
2017-08-23 02:54:54 +02:00
num_revocations = revocations_received ( & peer - > their_shachain . chain ) ;
2018-01-16 10:24:46 +01:00
/* Warn once. */
if ( peer - > ld - > config . ignore_fee_limits )
2018-01-22 09:31:49 +01:00
log_debug ( peer - > log , " Ignoring fee limits! " ) ;
2018-01-16 10:24:46 +01:00
2018-01-25 11:44:30 +01:00
peer - > direction = get_channel_direction ( & peer - > ld - > id , & peer - > id ) ;
2018-01-23 22:11:44 +01:00
2017-06-24 08:25:53 +02:00
initmsg = towire_channel_init ( tmpctx ,
2017-08-28 18:09:01 +02:00
& get_chainparams ( peer - > ld )
- > genesis_blockhash ,
2017-05-23 13:57:04 +02:00
peer - > funding_txid ,
peer - > funding_outnum ,
2017-06-20 08:04:03 +02:00
peer - > funding_satoshi ,
2017-05-23 13:57:04 +02:00
& peer - > our_config ,
& peer - > channel_info - > their_config ,
2017-06-29 18:55:52 +02:00
peer - > channel_info - > feerate_per_kw ,
2018-01-16 10:24:46 +01:00
feerate_min ( peer - > ld ) ,
feerate_max ( peer - > ld ) ,
2017-08-18 06:43:53 +02:00
peer - > last_sig ,
2017-12-11 04:33:16 +01:00
cs , gossip_index ,
2017-05-23 13:57:04 +02:00
& peer - > channel_info - > remote_fundingkey ,
& peer - > channel_info - > theirbase . revocation ,
& peer - > channel_info - > theirbase . payment ,
2017-11-15 07:21:39 +01:00
& peer - > channel_info - > theirbase . htlc ,
2017-05-23 13:57:04 +02:00
& peer - > channel_info - > theirbase . delayed_payment ,
2017-06-20 08:15:03 +02:00
& peer - > channel_info - > remote_per_commit ,
& peer - > channel_info - > old_remote_per_commit ,
2017-07-04 02:45:28 +02:00
peer - > funder ,
2017-05-23 13:57:04 +02:00
cfg - > fee_base ,
cfg - > fee_per_satoshi ,
2017-07-05 07:33:40 +02:00
* peer - > our_msatoshi ,
2017-05-23 13:57:04 +02:00
peer - > seed ,
2017-08-28 18:09:01 +02:00
& peer - > ld - > id ,
2017-06-06 05:08:42 +02:00
& peer - > id ,
2017-05-23 13:57:04 +02:00
time_to_msec ( cfg - > commit_time ) ,
2017-10-23 06:16:57 +02:00
cfg - > cltv_expiry_delta ,
2017-06-20 08:03:03 +02:00
peer - > last_was_revoke ,
peer - > last_sent_commit ,
2017-06-27 04:55:06 +02:00
peer - > next_index [ LOCAL ] ,
peer - > next_index [ REMOTE ] ,
2017-08-23 02:54:54 +02:00
num_revocations ,
2017-06-20 08:04:03 +02:00
peer - > next_htlc_id ,
htlcs , htlc_states ,
2017-06-20 08:06:03 +02:00
fulfilled_htlcs , fulfilled_sides ,
failed_htlcs , failed_sides ,
2017-06-20 08:11:03 +02:00
peer - > scid ! = NULL ,
2017-06-20 08:15:03 +02:00
peer - > remote_funding_locked ,
2017-06-20 08:11:03 +02:00
& funding_channel_id ,
2017-07-04 03:53:36 +02:00
reconnected ,
2017-06-26 03:16:43 +02:00
shutdown_scriptpubkey ,
2017-07-04 02:47:32 +02:00
peer - > remote_shutdown_scriptpubkey ! = NULL ,
2017-06-29 16:02:37 +02:00
peer - > channel_flags ,
2017-06-24 08:25:53 +02:00
funding_signed ) ;
2017-05-22 13:27:20 +02:00
2017-04-01 12:58:30 +02:00
/* We don't expect a response: we are triggered by funding_depth_cb. */
2017-05-23 13:57:04 +02:00
subd_send_msg ( peer - > owner , take ( initmsg ) ) ;
2017-06-26 23:21:52 +02:00
tal_free ( tmpctx ) ;
2017-04-01 12:58:30 +02:00
return true ;
}
2017-06-20 08:18:03 +02:00
static bool peer_commit_initial ( struct peer * peer )
{
2017-06-27 04:55:06 +02:00
peer - > next_index [ LOCAL ] = peer - > next_index [ REMOTE ] = 1 ;
2017-06-20 08:18:03 +02:00
return true ;
}
2017-10-12 08:35:04 +02:00
static void opening_funder_finished ( struct subd * opening , const u8 * resp ,
2017-05-23 13:07:42 +02:00
const int * fds ,
struct funding_channel * fc )
2017-02-24 06:52:56 +01:00
{
2018-01-05 01:12:07 +01:00
tal_t * tmpctx = tal_tmpctx ( fc ) ;
2017-02-24 06:52:56 +01:00
u8 * msg ;
2017-05-23 13:57:04 +02:00
struct channel_info * channel_info ;
2017-05-23 13:06:17 +02:00
struct utxo * utxos ;
2018-01-05 01:12:07 +01:00
struct bitcoin_tx * fundingtx ;
2017-12-18 07:41:52 +01:00
struct bitcoin_txid funding_txid ;
2017-05-23 13:07:42 +02:00
struct pubkey changekey ;
2017-05-23 13:57:04 +02:00
struct pubkey local_fundingkey ;
2017-06-24 08:25:53 +02:00
struct crypto_state cs ;
2017-08-18 06:43:53 +02:00
secp256k1_ecdsa_signature remote_commit_sig ;
struct bitcoin_tx * remote_commit ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
2017-02-24 06:52:56 +01:00
2017-06-24 08:50:23 +02:00
assert ( tal_count ( fds ) = = 2 ) ;
2017-03-19 21:31:30 +01:00
2017-05-23 13:57:04 +02:00
/* At this point, we care about peer */
fc - > peer - > channel_info = channel_info
= tal ( fc - > peer , struct channel_info ) ;
2017-08-18 06:43:53 +02:00
remote_commit = tal ( resp , struct bitcoin_tx ) ;
2017-05-23 13:57:04 +02:00
2017-08-12 16:46:50 +02:00
/* This is a new channel_info->their_config so set its ID to 0 */
fc - > peer - > channel_info - > their_config . id = 0 ;
2017-05-23 13:07:42 +02:00
if ( ! fromwire_opening_funder_reply ( resp , NULL ,
2017-05-23 13:57:04 +02:00
& channel_info - > their_config ,
2017-08-18 06:43:53 +02:00
remote_commit ,
& remote_commit_sig ,
2017-06-24 08:25:53 +02:00
& cs ,
2017-12-11 04:33:16 +01:00
& gossip_index ,
2017-05-23 13:57:04 +02:00
& channel_info - > theirbase . revocation ,
& channel_info - > theirbase . payment ,
2017-11-15 07:21:39 +01:00
& channel_info - > theirbase . htlc ,
2017-05-23 13:57:04 +02:00
& channel_info - > theirbase . delayed_payment ,
2017-06-20 08:15:03 +02:00
& channel_info - > remote_per_commit ,
2017-05-23 13:07:42 +02:00
& fc - > peer - > minimum_depth ,
2017-05-23 13:57:04 +02:00
& channel_info - > remote_fundingkey ,
2017-06-29 18:45:47 +02:00
& funding_txid ,
2017-11-21 04:44:35 +01:00
& channel_info - > feerate_per_kw [ REMOTE ] ) ) {
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer_internal_error ( fc - > peer , " bad funder_reply: %s " ,
2017-08-17 03:04:55 +02:00
tal_hex ( resp , resp ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-03-07 02:31:43 +01:00
}
2017-11-21 04:44:35 +01:00
/* Feerates begin identical. */
channel_info - > feerate_per_kw [ LOCAL ]
= channel_info - > feerate_per_kw [ REMOTE ] ;
2017-05-23 13:07:42 +02:00
2017-06-20 08:15:03 +02:00
/* old_remote_per_commit not valid yet, copy valid one. */
channel_info - > old_remote_per_commit = channel_info - > remote_per_commit ;
2017-12-07 23:59:39 +01:00
/* Now, keep the initial commit as our last-tx-to-broadcast. */
2017-08-18 06:43:53 +02:00
peer_last_tx ( fc - > peer , remote_commit , & remote_commit_sig ) ;
2017-05-23 13:07:42 +02:00
/* Generate the funding tx. */
if ( fc - > change
2017-08-28 18:09:01 +02:00
& & ! bip32_pubkey ( fc - > peer - > ld - > wallet - > bip32_base ,
2017-05-23 13:07:42 +02:00
& changekey , fc - > change_keyindex ) )
fatal ( " Error deriving change key %u " , fc - > change_keyindex ) ;
2017-06-20 08:10:03 +02:00
derive_basepoints ( fc - > peer - > seed , & local_fundingkey , NULL , NULL , NULL ) ;
2017-05-23 13:07:42 +02:00
2018-01-05 01:12:07 +01:00
fundingtx = funding_tx ( tmpctx , & fc - > peer - > funding_outnum ,
fc - > utxomap , fc - > peer - > funding_satoshi ,
& local_fundingkey ,
& channel_info - > remote_fundingkey ,
fc - > change , & changekey ,
fc - > peer - > ld - > wallet - > bip32_base ) ;
2017-09-12 13:50:47 +02:00
log_debug ( fc - > peer - > log , " Funding tx has %zi inputs, %zu outputs: " ,
2018-01-05 01:12:07 +01:00
tal_count ( fundingtx - > input ) ,
tal_count ( fundingtx - > output ) ) ;
for ( size_t i = 0 ; i < tal_count ( fundingtx - > input ) ; i + + ) {
2017-09-12 13:50:47 +02:00
log_debug ( fc - > peer - > log , " %zi: % " PRIu64 " satoshi (%s) %s \n " ,
i , fc - > utxomap [ i ] - > amount ,
fc - > utxomap [ i ] - > is_p2sh ? " P2SH " : " SEGWIT " ,
2017-12-18 07:41:52 +01:00
type_to_string ( ltmp , struct bitcoin_txid ,
2018-01-05 01:12:07 +01:00
& fundingtx - > input [ i ] . txid ) ) ;
2017-09-12 13:50:47 +02:00
}
2017-12-18 07:41:52 +01:00
fc - > peer - > funding_txid = tal ( fc - > peer , struct bitcoin_txid ) ;
2018-01-05 01:12:07 +01:00
bitcoin_txid ( fundingtx , fc - > peer - > funding_txid ) ;
2017-05-23 13:07:42 +02:00
if ( ! structeq ( fc - > peer - > funding_txid , & funding_txid ) ) {
2017-06-20 08:17:03 +02:00
peer_internal_error ( fc - > peer ,
" Funding txid mismatch: "
" satoshi % " PRIu64 " change % " PRIu64
" changeidx %u "
" localkey %s remotekey %s " ,
fc - > peer - > funding_satoshi ,
fc - > change , fc - > change_keyindex ,
type_to_string ( fc , struct pubkey ,
& local_fundingkey ) ,
type_to_string ( fc , struct pubkey ,
& channel_info - > remote_fundingkey ) ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-05-23 13:07:42 +02:00
}
2017-02-24 06:52:56 +01:00
2017-06-20 08:18:03 +02:00
if ( ! peer_commit_initial ( fc - > peer ) ) {
peer_internal_error ( fc - > peer , " Initial peer to db failed " ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-06-20 08:02:03 +02:00
}
2017-02-24 06:52:56 +01:00
/* Get HSM to sign the funding tx. */
2017-05-23 13:07:42 +02:00
log_debug ( fc - > peer - > log , " Getting HSM to sign funding tx " ) ;
2018-01-05 01:12:07 +01:00
utxos = from_utxoptr_arr ( tmpctx , fc - > utxomap ) ;
msg = towire_hsm_sign_funding ( tmpctx , fc - > peer - > funding_satoshi ,
fc - > change , fc - > change_keyindex ,
& local_fundingkey ,
& channel_info - > remote_fundingkey ,
utxos ) ;
2017-10-12 08:35:03 +02:00
/* Unowned (will free openingd). */
peer_set_owner ( fc - > peer , NULL ) ;
2017-06-24 08:25:51 +02:00
2017-06-24 08:50:23 +02:00
if ( ! wire_sync_write ( fc - > peer - > ld - > hsm_fd , take ( msg ) ) )
2017-06-24 08:25:51 +02:00
fatal ( " Could not write to HSM: %s " , strerror ( errno ) ) ;
2018-01-05 01:12:07 +01:00
tal_free ( tmpctx ) ;
2017-06-24 08:25:51 +02:00
msg = hsm_sync_read ( fc , fc - > peer - > ld ) ;
2017-12-11 04:33:16 +01:00
opening_got_hsm_funding_sig ( fc , fds [ 0 ] , fds [ 1 ] , msg , & cs , gossip_index ) ;
2017-02-24 06:52:56 +01:00
}
2017-10-12 08:35:04 +02:00
static void opening_fundee_finished ( struct subd * opening ,
const u8 * reply ,
const int * fds ,
struct peer * peer )
2017-02-24 06:52:56 +01:00
{
2017-05-24 12:10:17 +02:00
u8 * funding_signed ;
2017-05-23 13:57:04 +02:00
struct channel_info * channel_info ;
2017-06-24 08:25:53 +02:00
struct crypto_state cs ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
2017-08-18 06:43:53 +02:00
secp256k1_ecdsa_signature remote_commit_sig ;
struct bitcoin_tx * remote_commit ;
2017-12-15 11:29:14 +01:00
const tal_t * tmpctx = tal_tmpctx ( peer ) ;
2017-03-07 02:03:55 +01:00
2017-05-23 13:04:17 +02:00
log_debug ( peer - > log , " Got opening_fundee_finish_response " ) ;
2017-06-24 08:50:23 +02:00
assert ( tal_count ( fds ) = = 2 ) ;
2017-03-19 21:31:30 +01:00
2017-08-18 06:43:53 +02:00
remote_commit = tal ( reply , struct bitcoin_tx ) ;
2017-05-23 13:57:04 +02:00
/* At this point, we care about peer */
peer - > channel_info = channel_info = tal ( peer , struct channel_info ) ;
2017-08-12 16:46:50 +02:00
/* This is a new channel_info->their_config, set its ID to 0 */
peer - > channel_info - > their_config . id = 0 ;
2017-12-18 07:41:52 +01:00
peer - > funding_txid = tal ( peer , struct bitcoin_txid ) ;
2017-12-15 11:29:14 +01:00
if ( ! fromwire_opening_fundee_reply ( tmpctx , reply , NULL ,
2017-05-23 13:57:04 +02:00
& channel_info - > their_config ,
2017-08-18 06:43:53 +02:00
remote_commit ,
& remote_commit_sig ,
2017-06-24 08:25:53 +02:00
& cs ,
2017-12-11 04:33:16 +01:00
& gossip_index ,
2017-05-23 13:57:04 +02:00
& channel_info - > theirbase . revocation ,
& channel_info - > theirbase . payment ,
2017-11-15 07:21:39 +01:00
& channel_info - > theirbase . htlc ,
2017-05-23 13:57:04 +02:00
& channel_info - > theirbase . delayed_payment ,
2017-06-20 08:15:03 +02:00
& channel_info - > remote_per_commit ,
2017-05-23 13:57:04 +02:00
& channel_info - > remote_fundingkey ,
2017-05-23 13:07:42 +02:00
peer - > funding_txid ,
& peer - > funding_outnum ,
& peer - > funding_satoshi ,
& peer - > push_msat ,
2017-06-27 04:55:01 +02:00
& peer - > channel_flags ,
2017-11-21 04:44:35 +01:00
& channel_info - > feerate_per_kw [ REMOTE ] ,
2017-10-11 06:31:57 +02:00
& funding_signed ) ) {
2017-10-12 08:35:04 +02:00
peer_internal_error ( peer , " bad OPENING_FUNDEE_REPLY %s " ,
tal_hex ( reply , reply ) ) ;
2017-12-15 11:29:14 +01:00
tal_free ( tmpctx ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-03-07 02:03:55 +01:00
}
2017-11-15 07:20:39 +01:00
2017-11-21 04:44:35 +01:00
/* Feerates begin identical. */
channel_info - > feerate_per_kw [ LOCAL ]
= channel_info - > feerate_per_kw [ REMOTE ] ;
2017-06-20 08:15:03 +02:00
/* old_remote_per_commit not valid yet, copy valid one. */
channel_info - > old_remote_per_commit = channel_info - > remote_per_commit ;
2017-03-07 02:03:55 +01:00
2017-12-07 23:59:39 +01:00
/* Now, keep the initial commit as our last-tx-to-broadcast. */
2017-08-18 06:43:53 +02:00
peer_last_tx ( peer , remote_commit , & remote_commit_sig ) ;
2017-12-15 11:29:14 +01:00
if ( ! peer_commit_initial ( peer ) ) {
tal_free ( tmpctx ) ;
2017-10-12 08:35:04 +02:00
return ;
2017-12-15 11:29:14 +01:00
}
2017-06-20 08:02:03 +02:00
2017-05-23 13:07:42 +02:00
log_debug ( peer - > log , " Watching funding tx %s " ,
2017-12-18 07:41:52 +01:00
type_to_string ( reply , struct bitcoin_txid ,
2017-05-23 13:07:42 +02:00
peer - > funding_txid ) ) ;
watch_txid ( peer , peer - > ld - > topology , peer , peer - > funding_txid ,
funding_lockin_cb , NULL ) ;
2017-08-23 03:55:16 +02:00
/* FIXME: Remove arg from cb? */
watch_txo ( peer , peer - > ld - > topology , peer , peer - > funding_txid ,
peer - > funding_outnum , funding_spent , NULL ) ;
2017-10-12 08:35:03 +02:00
/* Unowned (will free openingd). */
peer_set_owner ( peer , NULL ) ;
2017-06-24 08:25:53 +02:00
2017-03-07 02:31:43 +01:00
/* On to normal operation! */
2017-12-11 04:33:16 +01:00
peer_start_channeld ( peer , & cs , gossip_index ,
fds [ 0 ] , fds [ 1 ] , funding_signed , false ) ;
2017-07-01 03:41:17 +02:00
peer_set_condition ( peer , OPENINGD , CHANNELD_AWAITING_LOCKIN ) ;
2017-12-15 11:29:14 +01:00
tal_free ( tmpctx ) ;
2017-03-07 02:05:03 +01:00
}
2017-12-06 04:22:35 +01:00
/* Negotiation failed, but we can keep gossipping */
static unsigned int opening_negotiation_failed ( struct subd * openingd ,
const u8 * msg ,
const int * fds )
{
struct crypto_state cs ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
2017-12-06 04:22:35 +01:00
struct peer * peer = openingd - > peer ;
u8 * err ;
const char * why ;
2017-12-11 04:16:50 +01:00
/* We need the peer fd and gossip fd. */
2017-12-06 04:22:35 +01:00
if ( tal_count ( fds ) = = 0 )
2017-12-11 04:16:50 +01:00
return 2 ;
2017-12-12 23:25:50 +01:00
2017-12-11 04:33:16 +01:00
if ( ! fromwire_opening_negotiation_failed ( msg , msg , NULL ,
& cs , & gossip_index , & err ) ) {
2017-12-06 04:22:35 +01:00
peer_internal_error ( peer ,
" bad OPENING_NEGOTIATION_FAILED %s " ,
tal_hex ( msg , msg ) ) ;
return 0 ;
}
2017-12-11 04:33:16 +01:00
msg = towire_gossipctl_hand_back_peer ( msg , & peer - > id , & cs , gossip_index ,
NULL ) ;
2017-12-06 04:22:35 +01:00
subd_send_msg ( openingd - > ld - > gossip , take ( msg ) ) ;
subd_send_fd ( openingd - > ld - > gossip , fds [ 0 ] ) ;
2017-12-11 04:16:50 +01:00
subd_send_fd ( openingd - > ld - > gossip , fds [ 1 ] ) ;
2017-12-06 04:22:35 +01:00
why = tal_strndup ( peer , ( const char * ) err , tal_len ( err ) ) ;
log_unusual ( peer - > log , " Opening negotiation failed: %s " , why ) ;
/* This will free openingd, since that's peer->owner */
free_peer ( peer , why ) ;
return 0 ;
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Peer has spontaneously exited from gossip due to open msg */
static void peer_accept_channel ( struct lightningd * ld ,
const struct pubkey * peer_id ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures , const u8 * lfeatures ,
int peer_fd , int gossip_fd ,
const u8 * open_msg )
2017-02-24 06:52:56 +01:00
{
u32 max_to_self_delay , max_minimum_depth ;
u64 min_effective_htlc_capacity_msat ;
u8 * msg ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
struct peer * peer ;
2017-02-24 06:52:56 +01:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
assert ( fromwire_peektype ( open_msg ) = = WIRE_OPEN_CHANNEL ) ;
/* We make a new peer. */
2017-10-23 06:13:38 +02:00
peer = new_peer ( ld , peer_id , addr , gfeatures , lfeatures , peer_fd ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer_set_condition ( peer , UNINITIALIZED , OPENINGD ) ;
2017-10-12 08:35:03 +02:00
peer_set_owner ( peer ,
new_peer_subd ( ld , " lightning_openingd " , peer ,
2017-12-06 04:22:35 +01:00
opening_wire_type_name ,
opening_negotiation_failed ,
2017-10-12 08:35:03 +02:00
take ( & peer_fd ) , take ( & gossip_fd ) , NULL ) ) ;
if ( ! peer - > owner ) {
2017-06-20 08:17:03 +02:00
peer_fail_transient ( peer , " Failed to subdaemon opening: %s " ,
strerror ( errno ) ) ;
2017-02-24 06:52:56 +01:00
return ;
}
2017-05-22 13:24:47 +02:00
/* They will open channel. */
peer - > funder = REMOTE ;
2017-04-12 08:52:57 +02:00
/* BOLT #2:
*
2017-06-06 01:48:10 +02:00
* The sender SHOULD set ` minimum_depth ` to a number of blocks it
* considers reasonable to avoid double - spending of the funding
* transaction .
2017-04-12 08:52:57 +02:00
*/
2017-08-28 18:09:01 +02:00
peer - > minimum_depth = ld - > config . anchor_confirms ;
2017-04-12 08:52:57 +02:00
2017-03-07 02:09:53 +01:00
channel_config ( ld , & peer - > our_config ,
2017-02-24 06:52:56 +01:00
& max_to_self_delay , & max_minimum_depth ,
& min_effective_htlc_capacity_msat ) ;
2017-08-21 11:25:15 +02:00
/* Store the channel in the database in order to get a channel
* ID that is unique and which we can base the peer_seed on */
peer - > channel = peer_channel_new ( ld - > wallet , peer ) ;
2017-03-07 02:09:53 +01:00
peer - > seed = tal ( peer , struct privkey ) ;
2017-08-21 11:25:15 +02:00
derive_peer_seed ( ld , peer - > seed , & peer - > id , peer - > channel - > id ) ;
2017-08-28 18:09:01 +02:00
msg = towire_opening_init ( peer , get_chainparams ( ld ) - > index ,
2017-07-10 13:35:43 +02:00
& peer - > our_config ,
2017-02-24 06:52:56 +01:00
max_to_self_delay ,
min_effective_htlc_capacity_msat ,
2017-12-11 04:33:16 +01:00
cs , gossip_index , peer - > seed ) ;
2017-02-24 06:52:56 +01:00
2017-03-10 11:57:17 +01:00
subd_send_msg ( peer - > owner , take ( msg ) ) ;
2017-11-21 04:33:38 +01:00
/* BOLT #2:
*
* Given the variance in fees , and the fact that the transaction may
* be spent in the future , it ' s a good idea for the fee payer to keep
* a good margin , say 5 x the expected fee requirement */
2017-05-23 13:04:17 +02:00
msg = towire_opening_fundee ( peer , peer - > minimum_depth ,
2017-11-21 04:33:38 +01:00
get_feerate ( ld - > topology , FEERATE_SLOW ) ,
get_feerate ( ld - > topology , FEERATE_IMMEDIATE )
* 5 ,
open_msg ) ;
2017-02-24 06:52:56 +01:00
2017-06-24 08:50:23 +02:00
subd_req ( peer , peer - > owner , take ( msg ) , - 1 , 2 ,
2017-05-23 13:07:42 +02:00
opening_fundee_finished , peer ) ;
2017-02-24 06:52:56 +01:00
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
static void peer_offer_channel ( struct lightningd * ld ,
struct funding_channel * fc ,
2017-10-23 06:17:38 +02:00
const struct wireaddr * addr ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const struct crypto_state * cs ,
2017-12-11 04:33:16 +01:00
u64 gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * gfeatures , const u8 * lfeatures ,
int peer_fd , int gossip_fd )
2017-02-24 06:52:56 +01:00
{
u8 * msg ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
u32 max_to_self_delay , max_minimum_depth ;
u64 min_effective_htlc_capacity_msat ;
2017-05-23 13:07:42 +02:00
struct utxo * utxos ;
2017-02-24 06:52:56 +01:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* We make a new peer. */
2017-10-23 06:13:38 +02:00
fc - > peer = new_peer ( ld , & fc - > peerid , addr ,
gfeatures , lfeatures , peer_fd ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
fc - > peer - > funding_satoshi = fc - > funding_satoshi ;
fc - > peer - > push_msat = fc - > push_msat ;
2017-06-24 08:25:53 +02:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
peer_set_condition ( fc - > peer , UNINITIALIZED , OPENINGD ) ;
2017-10-12 08:35:03 +02:00
peer_set_owner ( fc - > peer ,
new_peer_subd ( ld ,
" lightning_openingd " , fc - > peer ,
2017-12-06 04:22:35 +01:00
opening_wire_type_name ,
opening_negotiation_failed ,
2017-10-12 08:35:03 +02:00
take ( & peer_fd ) , take ( & gossip_fd ) , NULL ) ) ;
if ( ! fc - > peer - > owner ) {
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
fc - > peer = tal_free ( fc - > peer ) ;
command_fail ( fc - > cmd ,
" Failed to launch openingd: %s " ,
strerror ( errno ) ) ;
return ;
2017-02-24 06:52:56 +01:00
}
2017-03-10 11:56:53 +01:00
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* FIXME: This is wrong in several ways.
*
* 1. We should set the temporary channel id * now * , so that ' s the
* key .
* 2. We don ' t need the peer or channel in db until peer_persists ( ) .
*/
2017-08-21 11:25:15 +02:00
/* Store the channel in the database in order to get a channel
* ID that is unique and which we can base the peer_seed on */
2017-08-07 14:36:37 +02:00
fc - > peer - > channel = peer_channel_new ( ld - > wallet , fc - > peer ) ;
2017-08-21 11:25:15 +02:00
fc - > peer - > seed = tal ( fc - > peer , struct privkey ) ;
derive_peer_seed ( ld , fc - > peer - > seed , & fc - > peer - > id ,
fc - > peer - > channel - > id ) ;
2017-08-07 14:36:37 +02:00
2017-05-22 13:24:47 +02:00
/* We will fund channel */
fc - > peer - > funder = LOCAL ;
2017-03-07 02:09:53 +01:00
channel_config ( ld , & fc - > peer - > our_config ,
2017-02-24 06:52:56 +01:00
& max_to_self_delay , & max_minimum_depth ,
& min_effective_htlc_capacity_msat ) ;
2017-06-27 04:55:01 +02:00
fc - > peer - > channel_flags = OUR_CHANNEL_FLAGS ;
2017-08-28 18:09:01 +02:00
msg = towire_opening_init ( fc ,
get_chainparams ( ld ) - > index ,
2017-07-10 13:35:43 +02:00
& fc - > peer - > our_config ,
2017-02-24 06:52:56 +01:00
max_to_self_delay ,
min_effective_htlc_capacity_msat ,
2017-12-11 04:33:16 +01:00
cs , gossip_index , fc - > peer - > seed ) ;
2017-10-12 08:35:03 +02:00
subd_send_msg ( fc - > peer - > owner , take ( msg ) ) ;
2017-05-23 13:07:42 +02:00
utxos = from_utxoptr_arr ( fc , fc - > utxomap ) ;
2017-05-23 13:04:17 +02:00
msg = towire_opening_funder ( fc , fc - > peer - > funding_satoshi ,
fc - > peer - > push_msat ,
2017-12-28 10:36:41 +01:00
get_feerate ( ld - > topology , FEERATE_NORMAL ) ,
2017-11-21 04:33:38 +01:00
max_minimum_depth ,
2017-05-23 13:07:42 +02:00
fc - > change , fc - > change_keyindex ,
2017-06-27 04:55:01 +02:00
fc - > peer - > channel_flags ,
2017-08-28 18:09:01 +02:00
utxos , fc - > peer - > ld - > wallet - > bip32_base ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* Peer now owns fc; if it dies, we fail fc. */
tal_steal ( fc - > peer , fc ) ;
2017-12-06 00:34:27 +01:00
fc - > peer - > opening_cmd = fc - > cmd ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
2017-10-12 08:35:03 +02:00
subd_req ( fc , fc - > peer - > owner ,
take ( msg ) , - 1 , 2 , opening_funder_finished , fc ) ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
/* Peer has been released from gossip. Start opening. */
2017-10-12 08:35:04 +02:00
static void gossip_peer_released ( struct subd * gossip ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
const u8 * resp ,
const int * fds ,
struct funding_channel * fc )
{
struct lightningd * ld = gossip - > ld ;
struct crypto_state cs ;
2017-12-11 04:33:16 +01:00
u64 gossip_index ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
u8 * gfeatures , * lfeatures ;
2017-10-23 06:17:38 +02:00
struct wireaddr addr ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
/* We could have raced with peer doing something else. */
fc - > peer = peer_by_id ( ld , & fc - > peerid ) ;
2017-10-23 06:13:38 +02:00
if ( ! fromwire_gossipctl_release_peer_reply ( fc , resp , NULL , & addr , & cs ,
2017-12-11 04:33:16 +01:00
& gossip_index ,
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
& gfeatures , & lfeatures ) ) {
if ( ! fromwire_gossipctl_release_peer_replyfail ( resp , NULL ) ) {
fatal ( " Gossip daemon gave invalid reply %s " ,
tal_hex ( gossip , resp ) ) ;
}
if ( fc - > peer )
command_fail ( fc - > cmd , " Peer already %s " ,
peer_state_name ( fc - > peer - > state ) ) ;
else
command_fail ( fc - > cmd , " Peer not connected " ) ;
2017-10-12 08:35:04 +02:00
return ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
assert ( tal_count ( fds ) = = 2 ) ;
/* We asked to release this peer, but another raced in? Corner case,
* close this is easiest . */
if ( fc - > peer ) {
command_fail ( fc - > cmd , " Peer already %s " ,
peer_state_name ( fc - > peer - > state ) ) ;
close ( fds [ 0 ] ) ;
close ( fds [ 1 ] ) ;
2017-10-12 08:35:04 +02:00
return ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
}
/* OK, offer peer a channel. */
2017-12-11 04:33:16 +01:00
peer_offer_channel ( ld , fc , & addr , & cs , gossip_index ,
gfeatures , lfeatures ,
2017-10-23 06:13:38 +02:00
fds [ 0 ] , fds [ 1 ] ) ;
2017-02-24 06:52:56 +01:00
}
static void json_fund_channel ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * peertok , * satoshitok ;
struct funding_channel * fc = tal ( cmd , struct funding_channel ) ;
u8 * msg ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-02-24 06:52:56 +01:00
" id " , & peertok ,
" satoshi " , & satoshitok ,
NULL ) ) {
return ;
}
fc - > cmd = cmd ;
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
if ( ! pubkey_from_hexstr ( buffer + peertok - > start ,
peertok - > end - peertok - > start , & fc - > peerid ) ) {
command_fail ( cmd , " Could not parse id " ) ;
2017-02-24 06:52:56 +01:00
return ;
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
if ( ! json_tok_u64 ( buffer , satoshitok , & fc - > funding_satoshi ) ) {
2017-02-24 06:52:56 +01:00
command_fail ( cmd , " Invalid satoshis " ) ;
return ;
}
2018-01-15 05:29:55 +01:00
if ( fc - > funding_satoshi > MAX_FUNDING_SATOSHI ) {
command_fail ( cmd , " Funding satoshi must be <= %d " ,
MAX_FUNDING_SATOSHI ) ;
2018-01-12 19:40:09 +01:00
return ;
}
2017-05-23 13:07:42 +02:00
/* FIXME: Support push_msat? */
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
fc - > push_msat = 0 ;
2017-05-23 13:07:42 +02:00
2017-02-24 06:52:56 +01:00
/* Try to do this now, so we know if insufficient funds. */
2017-11-21 04:33:54 +01:00
/* FIXME: dustlimit */
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
fc - > utxomap = build_utxos ( fc , cmd - > ld , fc - > funding_satoshi ,
2017-11-21 04:33:54 +01:00
get_feerate ( cmd - > ld - > topology , FEERATE_NORMAL ) ,
2017-12-20 07:05:01 +01:00
600 , BITCOIN_SCRIPTPUBKEY_P2WSH_LEN ,
& fc - > change , & fc - > change_keyindex ) ;
2017-03-07 01:58:09 +01:00
if ( ! fc - > utxomap ) {
2017-02-24 06:52:56 +01:00
command_fail ( cmd , " Cannot afford funding transaction " ) ;
return ;
}
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
msg = towire_gossipctl_release_peer ( cmd , & fc - > peerid ) ;
2017-08-28 18:09:01 +02:00
subd_req ( fc , cmd - > ld - > gossip , msg , - 1 , 2 , gossip_peer_released , fc ) ;
2017-12-15 11:15:54 +01:00
command_still_pending ( cmd ) ;
2017-02-24 06:52:56 +01:00
}
static const struct json_command fund_channel_command = {
" fundchannel " ,
json_fund_channel ,
2018-01-22 09:55:07 +01:00
" Fund channel with {id} using {satoshi} satoshis "
2017-02-24 06:52:56 +01:00
} ;
AUTODATA ( json_command , & fund_channel_command ) ;
2017-05-22 13:24:59 +02:00
2017-06-26 03:16:43 +02:00
static void json_close ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * peertok ;
struct peer * peer ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-06-26 03:16:43 +02:00
" id " , & peertok ,
NULL ) ) {
return ;
}
2017-08-28 18:09:01 +02:00
peer = peer_from_json ( cmd - > ld , buffer , peertok ) ;
2017-06-26 03:16:43 +02:00
if ( ! peer ) {
command_fail ( cmd , " Could not find peer with that id " ) ;
return ;
}
/* Easy case: peer can simply be forgotten. */
if ( ! peer_persists ( peer ) ) {
2018-01-03 06:59:35 +01:00
peer_fail_permanent ( peer , " Peer closed in state %s " ,
peer_state_name ( peer - > state ) ) ;
2017-06-26 03:16:43 +02:00
command_success ( cmd , null_response ( cmd ) ) ;
return ;
}
/* Normal case. */
if ( peer - > state = = CHANNELD_NORMAL ) {
u8 * shutdown_scriptpubkey ;
peer - > local_shutdown_idx = wallet_get_newindex ( peer - > ld ) ;
if ( peer - > local_shutdown_idx = = - 1 ) {
command_fail ( cmd , " Failed to get new key for shutdown " ) ;
return ;
}
shutdown_scriptpubkey = p2wpkh_for_keyidx ( cmd , peer - > ld ,
peer - > local_shutdown_idx ) ;
if ( ! shutdown_scriptpubkey ) {
command_fail ( cmd , " Failed to get script for shutdown " ) ;
return ;
}
peer_set_condition ( peer , CHANNELD_NORMAL , CHANNELD_SHUTTING_DOWN ) ;
2017-12-16 21:04:16 +01:00
txfilter_add_scriptpubkey ( peer - > ld - > owned_txfilter , shutdown_scriptpubkey ) ;
2017-06-26 03:16:43 +02:00
if ( peer - > owner )
subd_send_msg ( peer - > owner ,
take ( towire_channel_send_shutdown ( peer ,
shutdown_scriptpubkey ) ) ) ;
command_success ( cmd , null_response ( cmd ) ) ;
} else
command_fail ( cmd , " Peer is in state %s " ,
peer_state_name ( peer - > state ) ) ;
}
static const struct json_command close_command = {
" close " ,
json_close ,
2018-01-22 09:55:07 +01:00
" Close the channel with peer {id} "
2017-06-26 03:16:43 +02:00
} ;
AUTODATA ( json_command , & close_command ) ;
2017-05-22 13:24:59 +02:00
const char * peer_state_name ( enum peer_state state )
{
size_t i ;
for ( i = 0 ; enum_peer_state_names [ i ] . name ; i + + )
if ( enum_peer_state_names [ i ] . v = = state )
return enum_peer_state_names [ i ] . name ;
return " unknown " ;
}
2017-10-24 04:06:14 +02:00
2018-01-03 06:26:44 +01:00
static void activate_peer ( struct peer * peer )
{
2018-01-11 07:19:53 +01:00
u8 * msg ;
/* Pass gossipd any addrhints we currently have */
msg = towire_gossipctl_peer_addrhint ( peer , & peer - > id , & peer - > addr ) ;
subd_send_msg ( peer - > ld - > gossip , take ( msg ) ) ;
2018-01-03 06:26:44 +01:00
/* FIXME: We should never have these in the database! */
if ( ! peer - > funding_txid ) {
log_broken ( peer - > log , " activate_peer(%s) with no funding txid? " ,
2018-01-03 06:26:44 +01:00
peer_state_name ( peer - > state ) ) ;
2018-01-03 06:26:44 +01:00
return ;
}
/* This may be unnecessary, but it's harmless. */
watch_txid ( peer , peer - > ld - > topology , peer , peer - > funding_txid ,
funding_lockin_cb , NULL ) ;
watch_txo ( peer , peer - > ld - > topology , peer , peer - > funding_txid , peer - > funding_outnum ,
funding_spent , NULL ) ;
2018-02-07 16:47:12 +01:00
/* If peer->owner then we had a reconnect while loading and
* activating the peers , don ' t ask gossipd to connect in that
* case */
if ( ! peer - > owner & & peer_wants_reconnect ( peer ) ) {
2018-01-11 07:19:53 +01:00
msg = towire_gossipctl_reach_peer ( peer , & peer - > id ) ;
2018-01-03 06:26:44 +01:00
subd_send_msg ( peer - > ld - > gossip , take ( msg ) ) ;
2018-01-03 06:26:44 +01:00
}
}
void activate_peers ( struct lightningd * ld )
{
struct peer * p ;
list_for_each ( & ld - > peers , p , list )
activate_peer ( p ) ;
}
2017-10-24 04:06:14 +02:00
# if DEVELOPER
static void json_sign_last_tx ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * peertok ;
struct peer * peer ;
struct json_result * response = new_json_result ( cmd ) ;
u8 * linear ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-10-24 04:06:14 +02:00
" id " , & peertok ,
NULL ) ) {
return ;
}
peer = peer_from_json ( cmd - > ld , buffer , peertok ) ;
if ( ! peer ) {
command_fail ( cmd , " Could not find peer with that id " ) ;
return ;
}
if ( ! peer - > last_tx ) {
command_fail ( cmd , " Peer has no final transaction " ) ;
return ;
}
log_debug ( peer - > log , " dev-sign-last-tx: signing tx with %zu outputs " ,
tal_count ( peer - > last_tx - > output ) ) ;
sign_last_tx ( peer ) ;
linear = linearize_tx ( cmd , peer - > last_tx ) ;
2017-12-15 11:29:37 +01:00
remove_sig ( peer - > last_tx ) ;
2017-10-24 04:06:14 +02:00
json_object_start ( response , NULL ) ;
json_add_hex ( response , " tx " , linear , tal_len ( linear ) ) ;
json_object_end ( response ) ;
command_success ( cmd , response ) ;
}
static const struct json_command dev_sign_last_tx = {
" dev-sign-last-tx " ,
json_sign_last_tx ,
2018-01-22 09:55:07 +01:00
" Sign and show the last commitment transaction with peer {id} "
2017-10-24 04:06:14 +02:00
} ;
AUTODATA ( json_command , & dev_sign_last_tx ) ;
static void json_dev_fail ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * peertok ;
struct peer * peer ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-10-24 04:06:14 +02:00
" id " , & peertok ,
NULL ) ) {
return ;
}
peer = peer_from_json ( cmd - > ld , buffer , peertok ) ;
if ( ! peer ) {
command_fail ( cmd , " Could not find peer with that id " ) ;
return ;
}
peer_internal_error ( peer , " Failing due to dev-fail command " ) ;
command_success ( cmd , null_response ( cmd ) ) ;
}
static const struct json_command dev_fail_command = {
" dev-fail " ,
json_dev_fail ,
2018-01-22 09:55:07 +01:00
" Fail with peer {id} "
2017-10-24 04:06:14 +02:00
} ;
AUTODATA ( json_command , & dev_fail_command ) ;
static void dev_reenable_commit_finished ( struct subd * channeld ,
const u8 * resp ,
const int * fds ,
struct command * cmd )
{
command_success ( cmd , null_response ( cmd ) ) ;
}
static void json_dev_reenable_commit ( struct command * cmd ,
const char * buffer , const jsmntok_t * params )
{
jsmntok_t * peertok ;
struct peer * peer ;
u8 * msg ;
2018-01-29 01:34:28 +01:00
if ( ! json_get_params ( cmd , buffer , params ,
2017-10-24 04:06:14 +02:00
" id " , & peertok ,
NULL ) ) {
return ;
}
peer = peer_from_json ( cmd - > ld , buffer , peertok ) ;
if ( ! peer ) {
command_fail ( cmd , " Could not find peer with that id " ) ;
return ;
}
if ( ! peer - > owner ) {
command_fail ( cmd , " Peer has no owner " ) ;
return ;
}
if ( ! streq ( peer - > owner - > name , " lightning_channeld " ) ) {
command_fail ( cmd , " Peer owned by %s " , peer - > owner - > name ) ;
return ;
}
msg = towire_channel_dev_reenable_commit ( peer ) ;
subd_req ( peer , peer - > owner , take ( msg ) , - 1 , 0 ,
dev_reenable_commit_finished , cmd ) ;
2017-12-15 11:15:54 +01:00
command_still_pending ( cmd ) ;
2017-10-24 04:06:14 +02:00
}
static const struct json_command dev_reenable_commit = {
" dev-reenable-commit " ,
json_dev_reenable_commit ,
2018-01-22 09:55:07 +01:00
" Re-enable the commit timer on peer {id} "
2017-10-24 04:06:14 +02:00
} ;
AUTODATA ( json_command , & dev_reenable_commit ) ;
2018-02-06 15:46:34 +01:00
struct dev_forget_channel_cmd {
struct short_channel_id scid ;
struct peer * peer ;
bool force ;
struct command * cmd ;
} ;
static void process_dev_forget_channel ( struct bitcoind * bitcoind UNUSED ,
const struct bitcoin_tx_output * txout ,
void * arg )
{
struct json_result * response ;
struct dev_forget_channel_cmd * forget = arg ;
if ( txout ! = NULL & & ! forget - > force ) {
command_fail ( forget - > cmd ,
" Cowardly refusing to forget channel with an "
" unspent funding output, if you know what "
" you're doing you can override with "
" `force=true`, otherwise consider `close` or "
" `dev-fail`! If you force and the channel "
" confirms we will not track the funds in the "
" channel " ) ;
return ;
}
response = new_json_result ( forget - > cmd ) ;
json_object_start ( response , NULL ) ;
json_add_bool ( response , " forced " , forget - > force ) ;
json_add_bool ( response , " funding_unspent " , txout ! = NULL ) ;
json_add_txid ( response , " funding_txid " , forget - > peer - > funding_txid ) ;
json_object_end ( response ) ;
if ( peer_persists ( forget - > peer ) )
wallet_channel_delete ( forget - > cmd - > ld - > wallet , forget - > peer - > channel - > id ) ;
free_peer ( forget - > peer , " dev-forget-channel called " ) ;
command_success ( forget - > cmd , response ) ;
}
static void json_dev_forget_channel ( struct command * cmd , const char * buffer ,
const jsmntok_t * params )
{
jsmntok_t * nodeidtok , * forcetok ;
struct dev_forget_channel_cmd * forget = tal ( cmd , struct dev_forget_channel_cmd ) ;
forget - > cmd = cmd ;
if ( ! json_get_params ( cmd , buffer , params ,
" id " , & nodeidtok ,
" ?force " , & forcetok ,
NULL ) ) {
tal_free ( forget ) ;
return ;
}
forget - > force = false ;
if ( forcetok )
json_tok_bool ( buffer , forcetok , & forget - > force ) ;
forget - > peer = peer_from_json ( cmd - > ld , buffer , nodeidtok ) ;
if ( ! forget - > peer )
command_fail ( cmd , " Could not find channel with that peer " ) ;
if ( ! forget - > peer - > funding_txid ) {
process_dev_forget_channel ( cmd - > ld - > topology - > bitcoind , NULL , forget ) ;
} else {
bitcoind_gettxout ( cmd - > ld - > topology - > bitcoind ,
forget - > peer - > funding_txid ,
forget - > peer - > funding_outnum ,
process_dev_forget_channel , forget ) ;
command_still_pending ( cmd ) ;
}
}
static const struct json_command dev_forget_channel_command = {
" dev-forget-channel " , json_dev_forget_channel ,
" Forget the channel with peer {id}, ignore UTXO check with {force}='true'. " , false ,
" Forget the channel with peer {id}. Checks if the channel is still active by checking its funding transaction. Check can be ignored by setting {force} to 'true' "
} ;
AUTODATA ( json_command , & dev_forget_channel_command ) ;
2017-10-24 04:06:14 +02:00
# endif /* DEVELOPER */