mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
lightningd/channel: handle adding HTLC, generalize handler.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4839916038
commit
64b50e5cb6
@ -66,6 +66,7 @@ struct peer {
|
||||
struct channel *channel;
|
||||
|
||||
struct msg_queue peer_out;
|
||||
struct io_conn *peer_conn;
|
||||
|
||||
struct daemon_conn gossip_client;
|
||||
struct daemon_conn master;
|
||||
@ -168,53 +169,162 @@ static struct io_plan *peer_out(struct io_conn *conn, struct peer *peer)
|
||||
return peer_write_message(conn, &peer->pcs, out, peer_out);
|
||||
}
|
||||
|
||||
static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
||||
static void handle_peer_funding_locked(struct peer *peer, const u8 *msg)
|
||||
{
|
||||
struct channel_id chanid;
|
||||
int type = fromwire_peektype(msg);
|
||||
|
||||
if (fromwire_funding_locked(msg, NULL, &chanid,
|
||||
&peer->next_per_commit[REMOTE])) {
|
||||
if (!structeq(&chanid, &peer->channel_id))
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Wrong channel id in %s",
|
||||
tal_hex(trc, msg));
|
||||
if (peer->funding_locked[REMOTE])
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Funding locked twice");
|
||||
peer->funding_locked[REMOTE] = true;
|
||||
daemon_conn_send(&peer->master,
|
||||
if (!fromwire_funding_locked(msg, NULL, &chanid,
|
||||
&peer->next_per_commit[REMOTE]))
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Bad funding_locked %s", tal_hex(msg, msg));
|
||||
|
||||
if (!structeq(&chanid, &peer->channel_id))
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Wrong channel id in %s", tal_hex(trc, msg));
|
||||
if (peer->funding_locked[REMOTE])
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Funding locked twice");
|
||||
|
||||
peer->funding_locked[REMOTE] = true;
|
||||
daemon_conn_send(&peer->master,
|
||||
take(towire_channel_received_funding_locked(peer)));
|
||||
|
||||
if (peer->funding_locked[LOCAL]) {
|
||||
daemon_conn_send(&peer->master,
|
||||
if (peer->funding_locked[LOCAL]) {
|
||||
daemon_conn_send(&peer->master,
|
||||
take(towire_channel_normal_operation(peer)));
|
||||
}
|
||||
} else if (type == WIRE_ANNOUNCEMENT_SIGNATURES) {
|
||||
fromwire_announcement_signatures(
|
||||
msg, NULL, &chanid, &peer->short_channel_ids[REMOTE],
|
||||
&peer->announcement_node_sigs[REMOTE],
|
||||
&peer->announcement_bitcoin_sigs[REMOTE]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we agree on the channel ids */
|
||||
if (!structeq(&chanid, &peer->channel_id)) {
|
||||
status_failed(
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Wrong channel_id or short_channel_id in %s or %s",
|
||||
tal_hexstr(trc, &chanid, sizeof(struct channel_id)),
|
||||
tal_hexstr(trc, &peer->short_channel_ids[REMOTE],
|
||||
sizeof(struct short_channel_id)));
|
||||
}
|
||||
if (peer->funding_locked[LOCAL]) {
|
||||
send_channel_announcement(peer);
|
||||
send_channel_update(peer, false);
|
||||
}
|
||||
} else if (type == WIRE_CHANNEL_ANNOUNCEMENT ||
|
||||
type == WIRE_CHANNEL_UPDATE ||
|
||||
type == WIRE_NODE_ANNOUNCEMENT) {
|
||||
daemon_conn_send(&peer->gossip_client, msg);
|
||||
static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg)
|
||||
{
|
||||
struct channel_id chanid;
|
||||
|
||||
if (!fromwire_announcement_signatures(msg, NULL,
|
||||
&chanid,
|
||||
&peer->short_channel_ids[REMOTE],
|
||||
&peer->announcement_node_sigs[REMOTE],
|
||||
&peer->announcement_bitcoin_sigs[REMOTE]))
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Bad announcement_signatures %s",
|
||||
tal_hex(msg, msg));
|
||||
|
||||
/* Make sure we agree on the channel ids */
|
||||
/* FIXME: Check short_channel_id */
|
||||
if (!structeq(&chanid, &peer->channel_id)) {
|
||||
status_failed(WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Wrong channel_id or short_channel_id in %s or %s",
|
||||
tal_hexstr(trc, &chanid, sizeof(struct channel_id)),
|
||||
tal_hexstr(trc, &peer->short_channel_ids[REMOTE],
|
||||
sizeof(struct short_channel_id)));
|
||||
}
|
||||
|
||||
if (peer->funding_locked[LOCAL]) {
|
||||
send_channel_announcement(peer);
|
||||
send_channel_update(peer, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
|
||||
{
|
||||
struct channel_id channel_id;
|
||||
u64 id;
|
||||
u32 amount_msat;
|
||||
u32 cltv_expiry;
|
||||
struct sha256 payment_hash;
|
||||
u8 onion_routing_packet[1254];
|
||||
enum channel_add_err add_err;
|
||||
|
||||
if (!fromwire_update_add_htlc(msg, NULL, &channel_id, &id, &amount_msat,
|
||||
&cltv_expiry, &payment_hash,
|
||||
onion_routing_packet))
|
||||
peer_failed(io_conn_fd(peer->peer_conn),
|
||||
&peer->pcs.cs,
|
||||
&peer->channel_id,
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Bad peer_add_htlc %s", tal_hex(msg, msg));
|
||||
|
||||
add_err = channel_add_htlc(peer->channel, REMOTE, id, amount_msat,
|
||||
cltv_expiry, &payment_hash,
|
||||
onion_routing_packet);
|
||||
if (add_err != CHANNEL_ERR_ADD_OK)
|
||||
peer_failed(io_conn_fd(peer->peer_conn),
|
||||
&peer->pcs.cs,
|
||||
&peer->channel_id,
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Bad peer_add_htlc: %u", add_err);
|
||||
}
|
||||
|
||||
static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
||||
{
|
||||
enum wire_type type = fromwire_peektype(msg);
|
||||
|
||||
/* Must get funding_locked before almost anything. */
|
||||
if (!peer->funding_locked[REMOTE]) {
|
||||
/* We can get gossup before funging, too */
|
||||
if (type != WIRE_FUNDING_LOCKED
|
||||
&& type != WIRE_CHANNEL_ANNOUNCEMENT
|
||||
&& type != WIRE_CHANNEL_UPDATE
|
||||
&& type != WIRE_NODE_ANNOUNCEMENT) {
|
||||
peer_failed(io_conn_fd(peer->peer_conn),
|
||||
&peer->pcs.cs,
|
||||
&peer->channel_id,
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"%s (%u) before funding locked",
|
||||
wire_type_name(type), type);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case WIRE_FUNDING_LOCKED:
|
||||
handle_peer_funding_locked(peer, msg);
|
||||
goto done;
|
||||
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
||||
handle_peer_announcement_signatures(peer, msg);
|
||||
goto done;
|
||||
case WIRE_CHANNEL_ANNOUNCEMENT:
|
||||
case WIRE_CHANNEL_UPDATE:
|
||||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
/* Forward to gossip daemon */
|
||||
daemon_conn_send(&peer->gossip_client, msg);
|
||||
goto done;
|
||||
|
||||
case WIRE_UPDATE_ADD_HTLC:
|
||||
handle_peer_add_htlc(peer, msg);
|
||||
goto done;
|
||||
|
||||
case WIRE_INIT:
|
||||
case WIRE_ERROR:
|
||||
case WIRE_OPEN_CHANNEL:
|
||||
case WIRE_ACCEPT_CHANNEL:
|
||||
case WIRE_FUNDING_CREATED:
|
||||
case WIRE_FUNDING_SIGNED:
|
||||
goto badmessage;
|
||||
|
||||
case WIRE_SHUTDOWN:
|
||||
case WIRE_CLOSING_SIGNED:
|
||||
case WIRE_UPDATE_FULFILL_HTLC:
|
||||
case WIRE_UPDATE_FAIL_HTLC:
|
||||
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
|
||||
case WIRE_COMMITMENT_SIGNED:
|
||||
case WIRE_REVOKE_AND_ACK:
|
||||
case WIRE_UPDATE_FEE:
|
||||
peer_failed(io_conn_fd(peer->peer_conn),
|
||||
&peer->pcs.cs,
|
||||
&peer->channel_id,
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Unimplemented message %u (%s)",
|
||||
type, wire_type_name(type));
|
||||
}
|
||||
|
||||
badmessage:
|
||||
peer_failed(io_conn_fd(peer->peer_conn),
|
||||
&peer->pcs.cs,
|
||||
&peer->channel_id,
|
||||
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||
"Peer sent unknown message %u (%s)",
|
||||
type, wire_type_name(type));
|
||||
|
||||
done:
|
||||
return peer_read_message(conn, &peer->pcs, peer_in);
|
||||
}
|
||||
|
||||
@ -279,8 +389,8 @@ static void init_channel(struct peer *peer, const u8 *msg)
|
||||
&peer->node_ids[LOCAL], &peer->node_ids[REMOTE]);
|
||||
|
||||
/* OK, now we can process peer messages. */
|
||||
io_set_finish(io_new_conn(peer, PEER_FD, setup_peer_conn, peer),
|
||||
peer_conn_broken, peer);
|
||||
peer->peer_conn = io_new_conn(peer, PEER_FD, setup_peer_conn, peer);
|
||||
io_set_finish(peer->peer_conn, peer_conn_broken, peer);
|
||||
}
|
||||
|
||||
static void handle_funding_locked(struct peer *peer, const u8 *msg)
|
||||
|
@ -55,6 +55,9 @@ RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
|
||||
|
||||
lcli1 dev-newhtlc $ID2 100000 $(( $(blockheight) + 10 )) $RHASH
|
||||
|
||||
sleep 1
|
||||
check "lcli2 getpeers | tr -s '\012\011\" ' ' ' | $FGREP 'condition : Normal operation'"
|
||||
|
||||
lcli1 stop
|
||||
lcli2 stop
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user