Skip to content

Let channeld add the outgoing channel as soon as funding locked on both sides #450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions channeld/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ static void gossip_in(struct peer *peer, const u8 *msg)
wire_type_name(type), tal_hex(msg, msg));
}

/* Send a temporary `channel_announcement` and `channel_update`. These
* are unsigned and mainly used to tell gossip about the channel
* before we have reached the `announcement_depth`, not being signed
* means they will not be relayed, but we can already rely on them for
* our own outgoing payments */
static void send_temporary_announcement(struct peer *peer)
{
tal_t *tmpctx;
u8 *msg;

/* If we are supposed to send a real announcement, don't do a
* dummy one here, hence the check for announce_depth. */
if (peer->announce_depth_reached || !peer->funding_locked[LOCAL] ||
!peer->funding_locked[REMOTE])
return;

tmpctx = tal_tmpctx(peer);

msg = towire_gossip_local_add_channel(
tmpctx, &peer->short_channel_ids[LOCAL], &peer->chain_hash,
&peer->node_ids[REMOTE], 0 /* flags */, peer->cltv_delta,
peer->conf[REMOTE].htlc_minimum_msat, peer->fee_base,
peer->fee_per_satoshi);
wire_sync_write(GOSSIP_FD, take(msg));

tal_free(tmpctx);
}

static void send_announcement_signatures(struct peer *peer)
{
/* First 2 + 256 byte are the signatures and msg type, skip them */
Expand Down Expand Up @@ -363,6 +391,8 @@ static void handle_peer_funding_locked(struct peer *peer, const u8 *msg)
take(towire_channel_normal_operation(peer)));
}

/* Send temporary or final announcements */
send_temporary_announcement(peer);
send_announcement_signatures(peer);
}

Expand Down Expand Up @@ -1808,12 +1838,14 @@ static void handle_funding_locked(struct peer *peer, const u8 *msg)
msg_enqueue(&peer->peer_out, take(msg));
peer->funding_locked[LOCAL] = true;

send_announcement_signatures(peer);

if (peer->funding_locked[REMOTE]) {
wire_sync_write(MASTER_FD,
take(towire_channel_normal_operation(peer)));
}

/* Send temporary or final announcements */
send_temporary_announcement(peer);
send_announcement_signatures(peer);
}

static void handle_funding_announce_depth(struct peer *peer, const u8 *msg)
Expand Down
55 changes: 54 additions & 1 deletion gossipd/gossip.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ccan/mem/mem.h>
#include <ccan/noerr/noerr.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/structeq/structeq.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h>
#include <ccan/timer/timer.h>
Expand Down Expand Up @@ -737,6 +738,48 @@ static void handle_get_update(struct peer *peer, const u8 *msg)
daemon_conn_send(peer->remote, take(msg));
}

static void handle_local_add_channel(struct peer *peer, u8 *msg)
{
struct routing_state *rstate = peer->daemon->rstate;
struct short_channel_id scid;
struct sha256_double chain_hash;
struct pubkey remote_node_id;
u16 flags, cltv_expiry_delta, direction;
u32 fee_base_msat, fee_proportional_millionths;
u64 htlc_minimum_msat;
struct node_connection *c;

if (!fromwire_gossip_local_add_channel(
msg, NULL, &scid, &chain_hash, &remote_node_id, &flags,
&cltv_expiry_delta, &htlc_minimum_msat, &fee_base_msat,
&fee_proportional_millionths)) {
status_trace("Unable to parse local_add_channel message: %s", tal_hex(msg, msg));
return;
}

if (!structeq(&chain_hash, &rstate->chain_hash)) {
status_trace("Received channel_announcement for unknown chain %s",
type_to_string(msg, struct sha256_double,&chain_hash));
return;
}

if (get_connection_by_scid(rstate, &scid, 0) || get_connection_by_scid(rstate, &scid, 0)) {
status_trace("Attempted to local_add_channel a know channel");
return;
}

direction = get_channel_direction(&rstate->local_id, &remote_node_id);
c = half_add_connection(rstate, &rstate->local_id, &remote_node_id, &scid, direction);

c->active = true;
c->last_timestamp = 0;
c->delay = cltv_expiry_delta;
c->htlc_minimum_msat = htlc_minimum_msat;
c->base_fee = fee_base_msat;
c->proportional_fee = fee_proportional_millionths;
status_trace("Added and updated local channel %s/%d", type_to_string(msg, struct short_channel_id, &scid), direction);
}

/**
* owner_msg_in - Called by the `peer->owner_conn` upon receiving a
* message
Expand All @@ -753,7 +796,15 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
handle_gossip_msg(peer->daemon, dc->msg_in);
} else if (type == WIRE_GOSSIP_GET_UPDATE) {
handle_get_update(peer, dc->msg_in);
} else if (type == WIRE_GOSSIP_LOCAL_ADD_CHANNEL) {
handle_local_add_channel(peer, dc->msg_in);
} else {
status_failed(
STATUS_FAIL_INTERNAL_ERROR,
"Gossip received unknown message of type %s from owner",
gossip_wire_type_name(type));
}

return daemon_conn_read_next(conn, dc);
}

Expand Down Expand Up @@ -1539,6 +1590,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_GETPEERS_REQUEST:
return get_peers(conn, daemon, master->msg_in);

/* We send these, we don't receive them */
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIP_GETNODES_REPLY:
Expand All @@ -1552,7 +1604,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_GET_UPDATE:
case WIRE_GOSSIP_GET_UPDATE_REPLY:
case WIRE_GOSSIP_SEND_GOSSIP:
break;
case WIRE_GOSSIP_LOCAL_ADD_CHANNEL:
break;
}

/* Master shouldn't give bad requests. */
Expand Down
13 changes: 13 additions & 0 deletions gossipd/gossip_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,16 @@ gossip_send_gossip,3016
gossip_send_gossip,,gossip_index,u64
gossip_send_gossip,,len,u16
gossip_send_gossip,,gossip,len*u8

# Both sides have seen the funding tx being locked, but we have not
# yet reached the announcement depth. So we add the channel locally so
# we can use it already.
gossip_local_add_channel,3017
gossip_local_add_channel,,short_channel_id,struct short_channel_id
gossip_local_add_channel,,chain_hash,struct sha256_double
gossip_local_add_channel,,remote_node_id,struct pubkey
gossip_local_add_channel,,flags,u16
gossip_local_add_channel,,cltv_expiry_delta,u16
gossip_local_add_channel,,htlc_minimum_msat,u64
gossip_local_add_channel,,fee_base_msat,u32
gossip_local_add_channel,,fee_proportional_millionths,u32
4 changes: 4 additions & 0 deletions lightningd/gossip_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
break;
/* These are inter-daemon messages, not received by us */
case WIRE_GOSSIP_LOCAL_ADD_CHANNEL:
break;

case WIRE_GOSSIP_PEER_CONNECTED:
if (tal_count(fds) != 2)
return 2;
Expand Down
11 changes: 8 additions & 3 deletions tests/test_lightningd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,13 +1266,18 @@ def test_permfail_htlc_out(self):
l2.daemon.wait_for_log('onchaind complete, forgetting peer')

def test_gossip_jsonrpc(self):
l1,l2 = self.connect()

self.fund_channel(l1,l2,10**5)
l1, l2 = self.line_graph(n=2)

# Shouldn't send announce signatures until 6 deep.
assert not l1.daemon.is_in_log('peer_out WIRE_ANNOUNCEMENT_SIGNATURES')

# Channels should be activated locally
wait_for(lambda: [c['active'] for c in l1.rpc.getchannels()['channels']] == [True])

# Make sure we can route through the channel, will raise on failure
l1.rpc.getroute(l2.info['id'], 100, 1)

# Now proceed to funding-depth and do a full gossip round
l1.bitcoin.generate_block(5)
# Could happen in either order.
l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES',
Expand Down