2017-03-07 02:26:12 +01:00
|
|
|
#include <bitcoin/privkey.h>
|
|
|
|
#include <bitcoin/script.h>
|
2017-06-20 07:49:03 +02:00
|
|
|
#include <ccan/cast/cast.h>
|
2017-03-10 14:17:23 +01:00
|
|
|
#include <ccan/container_of/container_of.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
|
|
|
|
#include <ccan/fdpass/fdpass.h>
|
|
|
|
#include <ccan/io/io.h>
|
2017-04-01 12:58:30 +02:00
|
|
|
#include <ccan/mem/mem.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <ccan/structeq/structeq.h>
|
2017-03-11 21:49:52 +01:00
|
|
|
#include <ccan/take/take.h>
|
2017-03-29 13:01:15 +02:00
|
|
|
#include <ccan/tal/str/str.h>
|
2017-03-11 21:49:52 +01:00
|
|
|
#include <ccan/time/time.h>
|
2017-03-22 16:46:48 +01:00
|
|
|
#include <daemon/routing.h>
|
2017-04-01 12:28:39 +02:00
|
|
|
#include <daemon/timeout.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <errno.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <lightningd/channel.h>
|
2017-03-10 11:56:58 +01:00
|
|
|
#include <lightningd/channel/gen_channel_wire.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <lightningd/commit_tx.h>
|
|
|
|
#include <lightningd/crypto_sync.h>
|
|
|
|
#include <lightningd/cryptomsg.h>
|
2017-03-19 21:32:44 +01:00
|
|
|
#include <lightningd/daemon_conn.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <lightningd/debug.h>
|
|
|
|
#include <lightningd/derive_basepoints.h>
|
2017-04-01 12:58:30 +02:00
|
|
|
#include <lightningd/hsm/gen_hsm_client_wire.h>
|
2017-04-01 12:28:39 +02:00
|
|
|
#include <lightningd/htlc_tx.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <lightningd/key_derive.h>
|
2017-03-13 17:24:05 +01:00
|
|
|
#include <lightningd/msg_queue.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <lightningd/peer_failed.h>
|
2017-04-12 18:10:10 +02:00
|
|
|
#include <lightningd/ping.h>
|
2017-04-28 16:28:53 +02:00
|
|
|
#include <lightningd/sphinx.h>
|
2017-03-19 21:24:12 +01:00
|
|
|
#include <lightningd/status.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <secp256k1.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <type_to_string.h>
|
|
|
|
#include <version.h>
|
2017-03-29 13:01:15 +02:00
|
|
|
#include <wire/gen_onion_wire.h>
|
2017-03-07 02:26:12 +01:00
|
|
|
#include <wire/gen_peer_wire.h>
|
|
|
|
#include <wire/wire.h>
|
|
|
|
#include <wire/wire_io.h>
|
|
|
|
#include <wire/wire_sync.h>
|
|
|
|
|
2017-04-01 12:58:30 +02:00
|
|
|
/* stdin == requests, 3 == peer, 4 = gossip, 5 = HSM */
|
2017-03-07 02:26:12 +01:00
|
|
|
#define REQ_FD STDIN_FILENO
|
|
|
|
#define PEER_FD 3
|
2017-03-19 21:32:44 +01:00
|
|
|
#define GOSSIP_FD 4
|
2017-04-01 12:58:30 +02:00
|
|
|
#define HSM_FD 5
|
2017-03-07 02:26:12 +01:00
|
|
|
|
|
|
|
struct peer {
|
|
|
|
struct peer_crypto_state pcs;
|
|
|
|
struct channel_config conf[NUM_SIDES];
|
2017-04-01 12:58:30 +02:00
|
|
|
struct pubkey old_per_commit[NUM_SIDES];
|
|
|
|
struct pubkey current_per_commit[NUM_SIDES];
|
2017-03-07 02:26:12 +01:00
|
|
|
bool funding_locked[NUM_SIDES];
|
2017-04-01 12:58:30 +02:00
|
|
|
u64 commit_index[NUM_SIDES];
|
2017-03-07 02:26:12 +01:00
|
|
|
|
|
|
|
/* Their sig for current commit. */
|
|
|
|
secp256k1_ecdsa_signature their_commit_sig;
|
|
|
|
|
|
|
|
/* Secret keys and basepoint secrets. */
|
|
|
|
struct secrets our_secrets;
|
|
|
|
|
|
|
|
/* Our shaseed for generating per-commitment-secrets. */
|
|
|
|
struct sha256 shaseed;
|
|
|
|
|
2017-03-29 13:01:15 +02:00
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A sending node MUST set `id` to 0 for the first HTLC it offers, and
|
|
|
|
* increase the value by 1 for each successive offer.
|
|
|
|
*/
|
|
|
|
u64 htlc_id;
|
|
|
|
|
2017-03-07 02:26:12 +01:00
|
|
|
struct channel_id channel_id;
|
|
|
|
struct channel *channel;
|
|
|
|
|
2017-03-13 17:24:05 +01:00
|
|
|
struct msg_queue peer_out;
|
2017-04-01 12:26:07 +02:00
|
|
|
struct io_conn *peer_conn;
|
2017-03-09 16:08:57 +01:00
|
|
|
|
2017-03-10 14:17:23 +01:00
|
|
|
struct daemon_conn gossip_client;
|
2017-03-19 21:32:44 +01:00
|
|
|
struct daemon_conn master;
|
2017-03-11 21:49:52 +01:00
|
|
|
|
2017-06-20 07:49:03 +02:00
|
|
|
/* If we're waiting for a specific reply, defer other messages. */
|
|
|
|
enum channel_wire_type master_reply_type;
|
|
|
|
void (*handle_master_reply)(struct peer *peer, const u8 *msg);
|
|
|
|
struct msg_queue master_deferred;
|
|
|
|
|
2017-04-01 12:28:39 +02:00
|
|
|
struct timers timers;
|
|
|
|
struct oneshot *commit_timer;
|
|
|
|
u32 commit_msec;
|
|
|
|
|
2017-04-12 18:10:10 +02:00
|
|
|
/* Don't accept a pong we didn't ping for. */
|
|
|
|
size_t num_pings_outstanding;
|
|
|
|
|
2017-03-11 21:49:52 +01:00
|
|
|
/* Announcement related information */
|
2017-03-11 17:16:17 +01:00
|
|
|
struct pubkey node_ids[NUM_SIDES];
|
2017-03-11 21:49:52 +01:00
|
|
|
struct short_channel_id short_channel_ids[NUM_SIDES];
|
|
|
|
secp256k1_ecdsa_signature announcement_node_sigs[NUM_SIDES];
|
|
|
|
secp256k1_ecdsa_signature announcement_bitcoin_sigs[NUM_SIDES];
|
2017-04-04 13:24:47 +02:00
|
|
|
bool have_sigs[NUM_SIDES];
|
2017-03-22 16:46:48 +01:00
|
|
|
|
|
|
|
/* Which direction of the channel do we control? */
|
|
|
|
u16 channel_direction;
|
2017-05-01 18:25:20 +02:00
|
|
|
|
|
|
|
/* CLTV delta to announce to peers */
|
|
|
|
u16 cltv_delta;
|
|
|
|
u32 fee_base;
|
|
|
|
u32 fee_per_satoshi;
|
2017-03-07 02:26:12 +01:00
|
|
|
};
|
|
|
|
|
2017-04-03 03:03:38 +02:00
|
|
|
static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer);
|
2017-06-20 07:50:03 +02:00
|
|
|
static void start_commit_timer(struct peer *peer);
|
|
|
|
|
|
|
|
/* Returns a pointer to the new end */
|
|
|
|
static void *tal_arr_append_(void **p, size_t size)
|
|
|
|
{
|
|
|
|
size_t n = tal_len(*p) / size;
|
|
|
|
tal_resize_(p, size, n+1, false);
|
|
|
|
return (char *)(*p) + n * size;
|
|
|
|
}
|
|
|
|
#define tal_arr_append(p) tal_arr_append_((void **)(p), sizeof(**(p)))
|
2017-04-03 03:03:38 +02:00
|
|
|
|
2017-03-10 14:17:23 +01:00
|
|
|
static struct io_plan *gossip_client_recv(struct io_conn *conn,
|
|
|
|
struct daemon_conn *dc)
|
|
|
|
{
|
|
|
|
u8 *msg = dc->msg_in;
|
|
|
|
struct peer *peer = container_of(dc, struct peer, gossip_client);
|
|
|
|
u16 type = fromwire_peektype(msg);
|
|
|
|
|
|
|
|
if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE ||
|
|
|
|
type == WIRE_NODE_ANNOUNCEMENT)
|
2017-03-19 21:32:44 +01:00
|
|
|
msg_enqueue(&peer->peer_out, msg);
|
2017-06-05 23:36:32 +02:00
|
|
|
else
|
|
|
|
status_failed(WIRE_CHANNEL_GOSSIP_BAD_MESSAGE,
|
|
|
|
"Got bad message from gossipd: %d", type);
|
2017-03-10 14:17:23 +01:00
|
|
|
|
|
|
|
return daemon_conn_read_next(conn, dc);
|
|
|
|
}
|
|
|
|
|
2017-03-11 21:49:52 +01:00
|
|
|
static void send_announcement_signatures(struct peer *peer)
|
|
|
|
{
|
2017-04-03 03:03:38 +02:00
|
|
|
/* First 2 + 256 byte are the signatures and msg type, skip them */
|
|
|
|
size_t offset = 258;
|
|
|
|
const tal_t *tmpctx = tal_tmpctx(peer);
|
|
|
|
struct sha256_double hash;
|
2017-03-11 21:49:52 +01:00
|
|
|
u8 *msg;
|
2017-04-03 03:03:38 +02:00
|
|
|
u8 *ca = create_channel_announcement(tmpctx, peer);
|
|
|
|
u8 *req = towire_hsm_cannouncement_sig_req(tmpctx,
|
|
|
|
&peer->channel->funding_pubkey[LOCAL],
|
|
|
|
ca);
|
|
|
|
|
|
|
|
if (!wire_sync_write(HSM_FD, req))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED,
|
|
|
|
"Writing cannouncement_sig_req");
|
|
|
|
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
|
|
if (!msg || !fromwire_hsm_cannouncement_sig_reply(msg, NULL,
|
|
|
|
&peer->announcement_node_sigs[LOCAL]))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED,
|
|
|
|
"Reading cannouncement_sig_resp");
|
|
|
|
|
|
|
|
/* Double-check that HSM gave a valid signature. */
|
|
|
|
sha256_double(&hash, ca + offset, tal_len(ca) - offset);
|
|
|
|
if (!check_signed_hash(&hash, &peer->announcement_node_sigs[LOCAL],
|
|
|
|
&peer->node_ids[LOCAL])) {
|
|
|
|
/* It's ok to fail here, the channel announcement is
|
|
|
|
* unique, unlike the channel update which may have
|
|
|
|
* been replaced in the meantime. */
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED,
|
|
|
|
"HSM returned an invalid signature");
|
|
|
|
}
|
2017-03-11 21:49:52 +01:00
|
|
|
|
2017-04-03 05:34:52 +02:00
|
|
|
/* TODO(cdecker) Move this to the HSM once we store the
|
|
|
|
* funding_privkey there */
|
|
|
|
sign_hash(&peer->our_secrets.funding_privkey, &hash,
|
|
|
|
&peer->announcement_bitcoin_sigs[LOCAL]);
|
|
|
|
|
2017-04-04 13:24:47 +02:00
|
|
|
peer->have_sigs[LOCAL] = true;
|
|
|
|
|
2017-04-03 03:03:38 +02:00
|
|
|
msg = towire_announcement_signatures(
|
|
|
|
tmpctx, &peer->channel_id, &peer->short_channel_ids[LOCAL],
|
|
|
|
&peer->announcement_node_sigs[LOCAL],
|
|
|
|
&peer->announcement_bitcoin_sigs[LOCAL]);
|
2017-03-19 21:32:44 +01:00
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
2017-03-11 21:49:52 +01:00
|
|
|
tal_free(tmpctx);
|
|
|
|
}
|
|
|
|
|
2017-03-21 21:21:17 +01:00
|
|
|
static void send_channel_update(struct peer *peer, bool disabled)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(peer);
|
|
|
|
u32 timestamp = time_now().ts.tv_sec;
|
|
|
|
u16 flags;
|
2017-04-03 05:57:03 +02:00
|
|
|
u8 *cupdate, *msg;
|
|
|
|
|
|
|
|
/* Set the signature to empty so that valgrind doesn't complain */
|
2017-03-21 21:21:17 +01:00
|
|
|
secp256k1_ecdsa_signature *sig =
|
|
|
|
talz(tmpctx, secp256k1_ecdsa_signature);
|
|
|
|
|
2017-03-22 16:46:48 +01:00
|
|
|
flags = peer->channel_direction | (disabled << 1);
|
2017-03-21 21:21:17 +01:00
|
|
|
cupdate = towire_channel_update(
|
2017-05-01 18:25:20 +02:00
|
|
|
tmpctx, sig, &peer->short_channel_ids[LOCAL], timestamp, flags,
|
|
|
|
peer->cltv_delta, peer->fee_base, peer->fee_per_satoshi,
|
|
|
|
peer->channel->view[LOCAL].feerate_per_kw);
|
2017-03-21 21:21:17 +01:00
|
|
|
|
2017-04-03 05:57:03 +02:00
|
|
|
msg = towire_hsm_cupdate_sig_req(tmpctx, cupdate);
|
|
|
|
|
|
|
|
if (!wire_sync_write(HSM_FD, msg))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED,
|
|
|
|
"Writing cupdate_sig_req");
|
|
|
|
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
|
|
if (!msg || !fromwire_hsm_cupdate_sig_reply(tmpctx, msg, NULL, &cupdate))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED,
|
|
|
|
"Reading cupdate_sig_req");
|
2017-03-21 21:21:17 +01:00
|
|
|
|
2017-04-03 05:57:03 +02:00
|
|
|
daemon_conn_send(&peer->gossip_client, cupdate);
|
2017-03-21 21:21:17 +01:00
|
|
|
msg_enqueue(&peer->peer_out, cupdate);
|
|
|
|
tal_free(tmpctx);
|
|
|
|
}
|
|
|
|
|
2017-04-03 03:03:38 +02:00
|
|
|
/* Tentatively create a channel_announcement, possibly with invalid
|
|
|
|
* signatures. The signatures need to be collected first, by asking
|
|
|
|
* the HSM and by exchanging announcement_signature messages. */
|
|
|
|
static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer)
|
2017-03-21 21:21:17 +01:00
|
|
|
{
|
|
|
|
int first, second;
|
2017-04-03 03:03:38 +02:00
|
|
|
u8 *cannounce, *features = tal_arr(ctx, u8, 0);
|
2017-03-21 21:21:17 +01:00
|
|
|
|
2017-03-22 16:46:48 +01:00
|
|
|
if (peer->channel_direction == 0) {
|
2017-03-11 21:49:52 +01:00
|
|
|
first = LOCAL;
|
|
|
|
second = REMOTE;
|
|
|
|
} else {
|
|
|
|
first = REMOTE;
|
|
|
|
second = LOCAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cannounce = towire_channel_announcement(
|
2017-04-03 03:03:38 +02:00
|
|
|
ctx, &peer->announcement_node_sigs[first],
|
2017-03-11 21:49:52 +01:00
|
|
|
&peer->announcement_node_sigs[second],
|
|
|
|
&peer->announcement_bitcoin_sigs[first],
|
|
|
|
&peer->announcement_bitcoin_sigs[second],
|
|
|
|
&peer->short_channel_ids[LOCAL], &peer->node_ids[first],
|
2017-03-29 12:58:15 +02:00
|
|
|
&peer->node_ids[second], &peer->channel->funding_pubkey[first],
|
|
|
|
&peer->channel->funding_pubkey[second], features);
|
2017-04-03 03:03:38 +02:00
|
|
|
tal_free(features);
|
|
|
|
return cannounce;
|
|
|
|
}
|
2017-03-11 21:49:52 +01:00
|
|
|
|
2017-04-03 03:03:38 +02:00
|
|
|
static void send_channel_announcement(struct peer *peer)
|
|
|
|
{
|
|
|
|
u8 *msg = create_channel_announcement(peer, peer);
|
|
|
|
/* Makes a copy */
|
|
|
|
msg_enqueue(&peer->peer_out, msg);
|
|
|
|
/* Takes ownership */
|
|
|
|
daemon_conn_send(&peer->gossip_client, take(msg));
|
2017-03-11 21:49:52 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 02:26:12 +01:00
|
|
|
static struct io_plan *peer_out(struct io_conn *conn, struct peer *peer)
|
|
|
|
{
|
|
|
|
const u8 *out = msg_dequeue(&peer->peer_out);
|
|
|
|
if (!out)
|
2017-03-19 21:32:44 +01:00
|
|
|
return msg_queue_wait(conn, &peer->peer_out, peer_out, peer);
|
2017-03-07 02:26:12 +01:00
|
|
|
|
2017-04-04 13:31:54 +02:00
|
|
|
status_trace("peer_out %s", wire_type_name(fromwire_peektype(out)));
|
2017-03-07 02:26:12 +01:00
|
|
|
return peer_write_message(conn, &peer->pcs, out, peer_out);
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg);
|
|
|
|
|
|
|
|
static struct io_plan *handle_peer_funding_locked(struct io_conn *conn,
|
|
|
|
struct peer *peer,
|
|
|
|
const u8 *msg)
|
2017-03-07 02:26:12 +01:00
|
|
|
{
|
|
|
|
struct channel_id chanid;
|
2017-04-01 12:26:07 +02:00
|
|
|
|
|
|
|
if (!fromwire_funding_locked(msg, NULL, &chanid,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[REMOTE]))
|
2017-04-01 12:26:07 +02:00
|
|
|
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;
|
2017-06-20 07:55:03 +02:00
|
|
|
daemon_conn_send(&peer->master,
|
|
|
|
take(towire_channel_got_funding_locked(peer,
|
|
|
|
&peer->current_per_commit[REMOTE])));
|
2017-03-07 02:26:12 +01:00
|
|
|
|
2017-04-01 12:26:07 +02:00
|
|
|
if (peer->funding_locked[LOCAL]) {
|
|
|
|
daemon_conn_send(&peer->master,
|
2017-03-19 21:32:44 +01:00
|
|
|
take(towire_channel_normal_operation(peer)));
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
2017-06-20 07:44:03 +02:00
|
|
|
|
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_announcement_signatures(struct io_conn *conn,
|
|
|
|
struct peer *peer,
|
|
|
|
const u8 *msg)
|
2017-04-01 12:26:07 +02:00
|
|
|
{
|
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2017-04-04 13:24:47 +02:00
|
|
|
peer->have_sigs[REMOTE] = true;
|
|
|
|
|
|
|
|
/* We have the remote sigs, do we have the local ones as well? */
|
|
|
|
if (peer->funding_locked[LOCAL] && peer->have_sigs[LOCAL]) {
|
2017-04-01 12:26:07 +02:00
|
|
|
send_channel_announcement(peer);
|
|
|
|
send_channel_update(peer, false);
|
2017-05-07 01:59:48 +02:00
|
|
|
/* Tell the master that we just announced the channel,
|
|
|
|
* so it may announce the node */
|
|
|
|
daemon_conn_send(&peer->master, take(towire_channel_announced(msg)));
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
2017-06-20 07:44:03 +02:00
|
|
|
|
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_add_htlc(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *msg)
|
2017-04-01 12:26:07 +02:00
|
|
|
{
|
|
|
|
struct channel_id channel_id;
|
|
|
|
u64 id;
|
2017-06-06 01:49:10 +02:00
|
|
|
u64 amount_msat;
|
2017-04-01 12:26:07 +02:00
|
|
|
u32 cltv_expiry;
|
|
|
|
struct sha256 payment_hash;
|
2017-04-28 16:28:53 +02:00
|
|
|
u8 onion_routing_packet[TOTAL_PACKET_SIZE];
|
2017-04-01 12:26:07 +02:00
|
|
|
enum channel_add_err add_err;
|
|
|
|
|
|
|
|
if (!fromwire_update_add_htlc(msg, NULL, &channel_id, &id, &amount_msat,
|
2017-06-06 01:49:10 +02:00
|
|
|
&payment_hash, &cltv_expiry,
|
2017-04-01 12:26:07 +02:00
|
|
|
onion_routing_packet))
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
2017-03-11 21:49:52 +01:00
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
2017-04-01 12:26:07 +02:00
|
|
|
"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);
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
static struct changed_htlc *changed_htlc_arr(const tal_t *ctx,
|
|
|
|
const struct htlc **changed_htlcs)
|
2017-04-01 12:28:39 +02:00
|
|
|
{
|
2017-06-20 07:50:03 +02:00
|
|
|
struct changed_htlc *changed;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
changed = tal_arr(ctx, struct changed_htlc, tal_count(changed_htlcs));
|
|
|
|
for (i = 0; i < tal_count(changed_htlcs); i++) {
|
|
|
|
changed[i].id = changed_htlcs[i]->id;
|
|
|
|
changed[i].newstate = changed_htlcs[i]->state;
|
|
|
|
}
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u8 *sending_commitsig_msg(const tal_t *ctx,
|
|
|
|
u64 remote_commit_index,
|
|
|
|
const struct htlc **changed_htlcs)
|
|
|
|
{
|
|
|
|
const tal_t *tmpctx = tal_tmpctx(ctx);
|
|
|
|
struct changed_htlc *changed;
|
2017-04-01 12:28:39 +02:00
|
|
|
u8 *msg;
|
2017-06-20 07:50:03 +02:00
|
|
|
|
|
|
|
/* We tell master what (of our) HTLCs peer will now be
|
|
|
|
* committed to. */
|
|
|
|
changed = changed_htlc_arr(tmpctx, changed_htlcs);
|
|
|
|
msg = towire_channel_sending_commitsig(ctx, remote_commit_index,
|
|
|
|
changed);
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Master has acknowledged that we're sending commitment, so send it. */
|
|
|
|
static void handle_sending_commitsig_reply(struct peer *peer, const u8 *msg)
|
|
|
|
{
|
|
|
|
const tal_t *tmpctx = tal_tmpctx(peer);
|
2017-04-01 12:28:39 +02:00
|
|
|
secp256k1_ecdsa_signature commit_sig, *htlc_sigs;
|
|
|
|
size_t i;
|
|
|
|
struct bitcoin_tx **txs;
|
|
|
|
const u8 **wscripts;
|
|
|
|
const struct htlc **htlc_map;
|
|
|
|
struct pubkey localkey;
|
|
|
|
struct privkey local_secretkey;
|
|
|
|
|
|
|
|
if (!derive_simple_privkey(&peer->our_secrets.payment_basepoint_secret,
|
|
|
|
&peer->channel->basepoints[LOCAL].payment,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[REMOTE],
|
2017-04-01 12:28:39 +02:00
|
|
|
&local_secretkey))
|
|
|
|
status_failed(WIRE_CHANNEL_CRYPTO_FAILED,
|
|
|
|
"Deriving local_secretkey");
|
|
|
|
|
|
|
|
if (!derive_simple_key(&peer->channel->basepoints[LOCAL].payment,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[REMOTE],
|
2017-04-01 12:28:39 +02:00
|
|
|
&localkey))
|
|
|
|
status_failed(WIRE_CHANNEL_CRYPTO_FAILED,
|
|
|
|
"Deriving localkey");
|
|
|
|
|
|
|
|
txs = channel_txs(tmpctx, &htlc_map, &wscripts, peer->channel,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[REMOTE], REMOTE);
|
2017-04-01 12:28:39 +02:00
|
|
|
|
|
|
|
sign_tx_input(txs[0], 0, NULL,
|
|
|
|
wscripts[0],
|
|
|
|
&peer->our_secrets.funding_privkey,
|
|
|
|
&peer->channel->funding_pubkey[LOCAL],
|
|
|
|
&commit_sig);
|
|
|
|
|
|
|
|
status_trace("Creating commit_sig signature %s for tx %s wscript %s key %s",
|
|
|
|
type_to_string(trc, secp256k1_ecdsa_signature,
|
|
|
|
&commit_sig),
|
|
|
|
type_to_string(trc, struct bitcoin_tx, txs[0]),
|
|
|
|
tal_hex(trc, wscripts[0]),
|
|
|
|
type_to_string(trc, struct pubkey,
|
|
|
|
&peer->channel->funding_pubkey[LOCAL]));
|
2017-06-20 07:50:03 +02:00
|
|
|
dump_htlcs(peer->channel, "Sending commit_sig");
|
2017-04-01 12:28:39 +02:00
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2017-06-06 01:48:10 +02:00
|
|
|
* A node MUST include one `htlc_signature` for every HTLC transaction
|
2017-04-01 12:28:39 +02:00
|
|
|
* corresponding to BIP69 lexicographic ordering of the commitment
|
|
|
|
* transaction.
|
|
|
|
*/
|
|
|
|
htlc_sigs = tal_arr(tmpctx, secp256k1_ecdsa_signature,
|
|
|
|
tal_count(txs) - 1);
|
|
|
|
|
|
|
|
for (i = 0; i < tal_count(htlc_sigs); i++) {
|
|
|
|
sign_tx_input(txs[1 + i], 0,
|
|
|
|
NULL,
|
|
|
|
wscripts[1 + i],
|
|
|
|
&local_secretkey, &localkey,
|
|
|
|
&htlc_sigs[i]);
|
|
|
|
status_trace("Creating HTLC signature %s for tx %s wscript %s key %s",
|
|
|
|
type_to_string(trc, secp256k1_ecdsa_signature,
|
|
|
|
&htlc_sigs[i]),
|
|
|
|
type_to_string(trc, struct bitcoin_tx, txs[1+i]),
|
|
|
|
tal_hex(trc, wscripts[1+i]),
|
|
|
|
type_to_string(trc, struct pubkey, &localkey));
|
|
|
|
assert(check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i],
|
|
|
|
&localkey, &htlc_sigs[i]));
|
|
|
|
}
|
|
|
|
status_trace("Sending commit_sig with %zu htlc sigs",
|
|
|
|
tal_count(htlc_sigs));
|
2017-06-20 07:50:03 +02:00
|
|
|
|
2017-04-01 12:28:39 +02:00
|
|
|
msg = towire_commitment_signed(tmpctx, &peer->channel_id,
|
|
|
|
&commit_sig, htlc_sigs);
|
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
2017-06-20 07:50:03 +02:00
|
|
|
|
|
|
|
/* Timer now considered expired, you can add a new one. */
|
|
|
|
peer->commit_timer = NULL;
|
|
|
|
|
|
|
|
/* FIXME: In case we had outstanding commits, restart timer */
|
|
|
|
start_commit_timer(peer);
|
|
|
|
|
|
|
|
tal_free(tmpctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This blocks other traffic from the master until we get reply. */
|
|
|
|
static void master_sync_reply(struct peer *peer, const u8 *msg,
|
|
|
|
enum channel_wire_type replytype,
|
|
|
|
void (*handle)(struct peer *peer, const u8 *msg))
|
|
|
|
{
|
|
|
|
assert(!peer->handle_master_reply);
|
|
|
|
|
|
|
|
peer->handle_master_reply = handle;
|
|
|
|
peer->master_reply_type = replytype;
|
|
|
|
|
|
|
|
daemon_conn_send(&peer->master, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void send_commit(struct peer *peer)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(peer);
|
|
|
|
u8 *msg;
|
|
|
|
const struct htlc **changed_htlcs;
|
|
|
|
|
|
|
|
/* FIXME: Document this requirement in BOLT 2! */
|
|
|
|
/* We can't send two commits in a row. */
|
|
|
|
if (channel_awaiting_revoke_and_ack(peer->channel)
|
|
|
|
|| peer->handle_master_reply) {
|
|
|
|
status_trace("Can't send commit: waiting for revoke_and_ack %s",
|
|
|
|
peer->handle_master_reply ? "processing" : "reply");
|
|
|
|
/* Mark this as done and try again. */
|
|
|
|
peer->commit_timer = NULL;
|
|
|
|
start_commit_timer(peer);
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A node MUST NOT send a `commitment_signed` message which does not
|
|
|
|
* include any updates.
|
|
|
|
*/
|
|
|
|
changed_htlcs = tal_arr(tmpctx, const struct htlc *, 0);
|
|
|
|
if (!channel_sending_commit(peer->channel, &changed_htlcs)) {
|
|
|
|
status_trace("Can't send commit: nothing to send");
|
|
|
|
|
|
|
|
peer->commit_timer = NULL;
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
status_trace("Telling master we're about to commit...");
|
|
|
|
/* Tell master to save to database, then wait for reply. */
|
|
|
|
msg = sending_commitsig_msg(tmpctx, peer->commit_index[REMOTE],
|
|
|
|
changed_htlcs);
|
|
|
|
master_sync_reply(peer, take(msg),
|
|
|
|
WIRE_CHANNEL_SENDING_COMMITSIG_REPLY,
|
|
|
|
handle_sending_commitsig_reply);
|
2017-04-01 12:28:39 +02:00
|
|
|
tal_free(tmpctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void start_commit_timer(struct peer *peer)
|
|
|
|
{
|
|
|
|
/* Already armed? */
|
2017-06-20 07:50:03 +02:00
|
|
|
if (peer->commit_timer) {
|
|
|
|
status_trace("Commit timer already running...");
|
2017-04-01 12:28:39 +02:00
|
|
|
return;
|
2017-06-20 07:50:03 +02:00
|
|
|
}
|
2017-04-01 12:28:39 +02:00
|
|
|
|
|
|
|
peer->commit_timer = new_reltimer(&peer->timers, peer,
|
|
|
|
time_from_msec(peer->commit_msec),
|
|
|
|
send_commit, peer);
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* We come back here once master has acked the commit_sig we received */
|
|
|
|
static struct io_plan *send_revocation(struct io_conn *conn, struct peer *peer)
|
|
|
|
{
|
|
|
|
struct pubkey oldpoint = peer->old_per_commit[LOCAL], test;
|
|
|
|
struct sha256 old_commit_secret;
|
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
peer->old_per_commit[LOCAL] = peer->current_per_commit[LOCAL];
|
|
|
|
if (!next_per_commit_point(&peer->shaseed, &old_commit_secret,
|
|
|
|
&peer->current_per_commit[LOCAL],
|
|
|
|
peer->commit_index[LOCAL]))
|
|
|
|
status_failed(WIRE_CHANNEL_CRYPTO_FAILED,
|
|
|
|
"Deriving next commit_point");
|
|
|
|
|
|
|
|
pubkey_from_privkey((struct privkey *)&old_commit_secret, &test);
|
|
|
|
if (!pubkey_eq(&test, &oldpoint))
|
|
|
|
status_failed(WIRE_CHANNEL_CRYPTO_FAILED,
|
|
|
|
"Invalid secret %s for commit_point",
|
|
|
|
tal_hexstr(trc, &old_commit_secret,
|
|
|
|
sizeof(old_commit_secret)));
|
|
|
|
|
|
|
|
peer->commit_index[LOCAL]++;
|
|
|
|
|
|
|
|
/* If this queues more changes on the other end, send commit. */
|
|
|
|
if (channel_sending_revoke_and_ack(peer->channel)) {
|
|
|
|
status_trace("revoke_and_ack made pending: commit timer");
|
|
|
|
start_commit_timer(peer);
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = towire_revoke_and_ack(peer, &peer->channel_id, &old_commit_secret,
|
|
|
|
&peer->current_per_commit[LOCAL]);
|
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
|
|
|
|
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:54:03 +02:00
|
|
|
/* FIXME: We could do this earlier and call HSM async, for speed. */
|
|
|
|
static void get_shared_secret(const struct htlc *htlc,
|
|
|
|
struct secret *shared_secret)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(htlc);
|
|
|
|
struct pubkey ephemeral;
|
|
|
|
struct onionpacket *op;
|
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
/* We unwrap the onion now. */
|
|
|
|
op = parse_onionpacket(tmpctx, htlc->routing, TOTAL_PACKET_SIZE);
|
|
|
|
if (!op) {
|
|
|
|
/* Return an invalid shared secret. */
|
|
|
|
memset(shared_secret, 0, sizeof(*shared_secret));
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Because wire takes struct pubkey. */
|
|
|
|
ephemeral.pubkey = op->ephemeralkey;
|
|
|
|
msg = towire_hsm_ecdh_req(tmpctx, &ephemeral);
|
|
|
|
if (!wire_sync_write(HSM_FD, msg))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED, "Writing ecdh req");
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
|
|
/* Gives all-zero shares_secret if it was invalid. */
|
|
|
|
if (!msg || !fromwire_hsm_ecdh_resp(msg, NULL, shared_secret))
|
|
|
|
status_failed(WIRE_CHANNEL_HSM_FAILED, "Reading ecdh response");
|
|
|
|
tal_free(tmpctx);
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
static u8 *got_commitsig_msg(const tal_t *ctx,
|
|
|
|
u64 local_commit_index,
|
|
|
|
const secp256k1_ecdsa_signature *commit_sig,
|
|
|
|
const secp256k1_ecdsa_signature *htlc_sigs,
|
|
|
|
const struct htlc **changed_htlcs)
|
|
|
|
{
|
|
|
|
const tal_t *tmpctx = tal_tmpctx(ctx);
|
|
|
|
struct changed_htlc *changed;
|
|
|
|
struct fulfilled_htlc *fulfilled;
|
|
|
|
struct failed_htlc *failed;
|
|
|
|
struct added_htlc *added;
|
2017-06-20 07:54:03 +02:00
|
|
|
struct secret *shared_secret;
|
2017-06-20 07:50:03 +02:00
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
changed = tal_arr(tmpctx, struct changed_htlc, 0);
|
|
|
|
added = tal_arr(tmpctx, struct added_htlc, 0);
|
2017-06-20 07:54:03 +02:00
|
|
|
shared_secret = tal_arr(tmpctx, struct secret, 0);
|
2017-06-20 07:50:03 +02:00
|
|
|
failed = tal_arr(tmpctx, struct failed_htlc, 0);
|
|
|
|
fulfilled = tal_arr(tmpctx, struct fulfilled_htlc, 0);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(changed_htlcs); i++) {
|
|
|
|
const struct htlc *htlc = changed_htlcs[i];
|
|
|
|
if (htlc->state == RCVD_ADD_COMMIT) {
|
|
|
|
struct added_htlc *a = tal_arr_append(&added);
|
2017-06-20 07:54:03 +02:00
|
|
|
struct secret *s = tal_arr_append(&shared_secret);
|
2017-06-20 07:50:03 +02:00
|
|
|
a->id = htlc->id;
|
|
|
|
a->amount_msat = htlc->msatoshi;
|
|
|
|
a->payment_hash = htlc->rhash;
|
|
|
|
a->cltv_expiry = abs_locktime_to_blocks(&htlc->expiry);
|
|
|
|
memcpy(a->onion_routing_packet,
|
|
|
|
htlc->routing,
|
|
|
|
sizeof(a->onion_routing_packet));
|
2017-06-20 07:54:03 +02:00
|
|
|
get_shared_secret(htlc, s);
|
2017-06-20 07:50:03 +02:00
|
|
|
} else if (htlc->state == RCVD_REMOVE_COMMIT) {
|
|
|
|
if (htlc->r) {
|
|
|
|
struct fulfilled_htlc *f;
|
|
|
|
assert(!htlc->fail);
|
|
|
|
f = tal_arr_append(&fulfilled);
|
|
|
|
f->id = htlc->id;
|
|
|
|
f->payment_preimage = *htlc->r;
|
|
|
|
} else {
|
|
|
|
struct failed_htlc *f;
|
|
|
|
assert(htlc->fail);
|
|
|
|
f = tal_arr_append(&failed);
|
|
|
|
f->id = htlc->id;
|
|
|
|
f->failreason = cast_const(u8 *, htlc->fail);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
struct changed_htlc *c = tal_arr_append(&changed);
|
|
|
|
assert(htlc->state == RCVD_REMOVE_ACK_COMMIT
|
|
|
|
|| htlc->state == RCVD_ADD_ACK_COMMIT);
|
|
|
|
|
|
|
|
c->id = htlc->id;
|
|
|
|
c->newstate = htlc->state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = towire_channel_got_commitsig(ctx, local_commit_index,
|
|
|
|
commit_sig,
|
|
|
|
htlc_sigs,
|
|
|
|
added,
|
2017-06-20 07:54:03 +02:00
|
|
|
shared_secret,
|
2017-06-20 07:50:03 +02:00
|
|
|
fulfilled,
|
|
|
|
failed,
|
|
|
|
changed);
|
|
|
|
tal_free(tmpctx);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tell peer to continue now master has replied. */
|
|
|
|
static void handle_reply_wake_peer(struct peer *peer, const u8 *msg)
|
|
|
|
{
|
|
|
|
io_wake(peer);
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_commit_sig(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *msg)
|
2017-04-01 12:28:39 +02:00
|
|
|
{
|
2017-06-20 07:50:03 +02:00
|
|
|
const tal_t *tmpctx = tal_tmpctx(peer);
|
2017-04-01 12:28:39 +02:00
|
|
|
struct channel_id channel_id;
|
|
|
|
secp256k1_ecdsa_signature commit_sig, *htlc_sigs;
|
|
|
|
struct pubkey remotekey;
|
|
|
|
struct bitcoin_tx **txs;
|
2017-06-20 07:41:03 +02:00
|
|
|
const struct htlc **htlc_map, **changed_htlcs;
|
2017-04-01 12:28:39 +02:00
|
|
|
const u8 **wscripts;
|
|
|
|
size_t i;
|
|
|
|
|
2017-06-20 07:41:03 +02:00
|
|
|
changed_htlcs = tal_arr(msg, const struct htlc *, 0);
|
|
|
|
if (!channel_rcvd_commit(peer->channel, &changed_htlcs)) {
|
2017-04-01 12:28:39 +02:00
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A node MUST NOT send a `commitment_signed` message which
|
|
|
|
* does not include any updates.
|
|
|
|
*/
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"commit_sig with no changes");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fromwire_commitment_signed(tmpctx, msg, NULL,
|
|
|
|
&channel_id, &commit_sig, &htlc_sigs))
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad commit_sig %s", tal_hex(msg, msg));
|
|
|
|
|
|
|
|
txs = channel_txs(tmpctx, &htlc_map, &wscripts, peer->channel,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[LOCAL], LOCAL);
|
2017-04-01 12:28:39 +02:00
|
|
|
|
|
|
|
if (!derive_simple_key(&peer->channel->basepoints[REMOTE].payment,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[LOCAL],
|
2017-04-01 12:28:39 +02:00
|
|
|
&remotekey))
|
|
|
|
status_failed(WIRE_CHANNEL_CRYPTO_FAILED,
|
|
|
|
"Deriving remotekey");
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A receiving node MUST fail the channel if `signature` is not valid
|
|
|
|
* for its local commitment transaction once all pending updates are
|
|
|
|
* applied.
|
|
|
|
*/
|
|
|
|
if (!check_tx_sig(txs[0], 0, NULL, wscripts[0],
|
2017-06-20 07:50:03 +02:00
|
|
|
&peer->channel->funding_pubkey[REMOTE], &commit_sig)) {
|
|
|
|
dump_htlcs(peer->channel, "receiving commit_sig");
|
2017-04-01 12:28:39 +02:00
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad commit_sig signature %s for tx %s wscript %s key %s",
|
|
|
|
type_to_string(msg, secp256k1_ecdsa_signature,
|
|
|
|
&commit_sig),
|
|
|
|
type_to_string(msg, struct bitcoin_tx, txs[0]),
|
|
|
|
tal_hex(msg, wscripts[0]),
|
|
|
|
type_to_string(msg, struct pubkey,
|
|
|
|
&peer->channel->funding_pubkey
|
|
|
|
[REMOTE]));
|
2017-06-20 07:50:03 +02:00
|
|
|
}
|
2017-04-01 12:28:39 +02:00
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2017-06-06 01:48:10 +02:00
|
|
|
* A receiving node MUST fail the channel if `num_htlcs` is not equal
|
2017-04-01 12:28:39 +02:00
|
|
|
* to the number of HTLC outputs in the local commitment transaction
|
|
|
|
* once all pending updates are applied.
|
|
|
|
*/
|
|
|
|
if (tal_count(htlc_sigs) != tal_count(txs) - 1)
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Expected %zu htlc sigs, not %zu",
|
|
|
|
tal_count(txs) - 1, tal_count(htlc_sigs));
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A receiving node MUST fail
|
2017-06-06 01:48:10 +02:00
|
|
|
* the channel if any `htlc_signature` is not valid for the
|
2017-04-01 12:28:39 +02:00
|
|
|
* corresponding HTLC transaction.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < tal_count(htlc_sigs); i++) {
|
|
|
|
if (!check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i],
|
|
|
|
&remotekey, &htlc_sigs[i]))
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad commit_sig signature %s for htlc %s wscript %s key %s",
|
|
|
|
type_to_string(msg, secp256k1_ecdsa_signature, &htlc_sigs[i]),
|
|
|
|
type_to_string(msg, struct bitcoin_tx, txs[1+i]),
|
|
|
|
tal_hex(msg, wscripts[1+i]),
|
|
|
|
type_to_string(msg, struct pubkey, &remotekey));
|
|
|
|
}
|
|
|
|
|
|
|
|
status_trace("Received commit_sig with %zu htlc sigs",
|
|
|
|
tal_count(htlc_sigs));
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* Tell master daemon, then wait for ack. */
|
|
|
|
msg = got_commitsig_msg(tmpctx, peer->commit_index[LOCAL], &commit_sig,
|
|
|
|
htlc_sigs, changed_htlcs);
|
2017-04-01 12:58:30 +02:00
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
master_sync_reply(peer, take(msg),
|
|
|
|
WIRE_CHANNEL_GOT_COMMITSIG_REPLY,
|
|
|
|
handle_reply_wake_peer);
|
2017-06-20 07:44:03 +02:00
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* And peer waits for reply. */
|
|
|
|
return io_wait(conn, peer, send_revocation, peer);
|
2017-04-01 12:28:39 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num,
|
|
|
|
const struct sha256 *per_commitment_secret,
|
2017-06-20 07:55:03 +02:00
|
|
|
const struct pubkey *next_per_commit_point,
|
2017-06-20 07:50:03 +02:00
|
|
|
const struct htlc **changed_htlcs)
|
|
|
|
{
|
|
|
|
tal_t *tmpctx = tal_tmpctx(ctx);
|
|
|
|
u8 *msg;
|
|
|
|
struct changed_htlc *changed = tal_arr(tmpctx, struct changed_htlc, 0);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(changed_htlcs); i++) {
|
2017-06-20 07:54:03 +02:00
|
|
|
struct changed_htlc *c = tal_arr_append(&changed);
|
2017-06-20 07:50:03 +02:00
|
|
|
const struct htlc *htlc = changed_htlcs[i];
|
2017-06-20 07:54:03 +02:00
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
status_trace("HTLC %"PRIu64"[%s] => %s",
|
|
|
|
htlc->id, side_to_str(htlc_owner(htlc)),
|
|
|
|
htlc_state_name(htlc->state));
|
|
|
|
|
2017-06-20 07:54:03 +02:00
|
|
|
c->id = changed_htlcs[i]->id;
|
|
|
|
c->newstate = changed_htlcs[i]->state;
|
2017-04-01 12:58:30 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret,
|
2017-06-20 07:55:03 +02:00
|
|
|
next_per_commit_point, changed);
|
2017-04-01 12:58:30 +02:00
|
|
|
tal_free(tmpctx);
|
2017-06-20 07:50:03 +02:00
|
|
|
return msg;
|
|
|
|
}
|
2017-04-01 12:58:30 +02:00
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* We come back here once master has acked the revoke_and_ack we received */
|
|
|
|
static struct io_plan *accepted_revocation(struct io_conn *conn,
|
|
|
|
struct peer *peer)
|
|
|
|
{
|
2017-04-01 12:58:30 +02:00
|
|
|
start_commit_timer(peer);
|
2017-06-20 07:50:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 12:58:30 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn,
|
|
|
|
struct peer *peer,
|
|
|
|
const u8 *msg)
|
2017-04-01 12:58:30 +02:00
|
|
|
{
|
|
|
|
struct sha256 old_commit_secret;
|
|
|
|
struct privkey privkey;
|
|
|
|
struct channel_id channel_id;
|
|
|
|
struct pubkey per_commit_point, next_per_commit;
|
2017-06-20 07:41:03 +02:00
|
|
|
const struct htlc **changed_htlcs = tal_arr(msg, const struct htlc *, 0);
|
2017-04-01 12:58:30 +02:00
|
|
|
|
|
|
|
if (!fromwire_revoke_and_ack(msg, NULL, &channel_id, &old_commit_secret,
|
|
|
|
&next_per_commit)) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad revoke_and_ack %s", tal_hex(msg, msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2017-06-06 01:48:10 +02:00
|
|
|
* A receiving node MUST check that `per_commitment_secret` generates
|
|
|
|
* the previous `per_commitment_point`, and MUST fail if it does
|
2017-04-01 12:58:30 +02:00
|
|
|
* not.
|
|
|
|
*/
|
|
|
|
memcpy(&privkey, &old_commit_secret, sizeof(privkey));
|
|
|
|
if (!pubkey_from_privkey(&privkey, &per_commit_point)) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad privkey %s",
|
|
|
|
type_to_string(msg, struct privkey, &privkey));
|
|
|
|
}
|
|
|
|
if (!pubkey_eq(&per_commit_point, &peer->old_per_commit[REMOTE])) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Wrong privkey %s for %s",
|
|
|
|
type_to_string(msg, struct privkey, &privkey),
|
|
|
|
type_to_string(msg, struct pubkey,
|
|
|
|
&peer->old_per_commit[REMOTE]));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We start timer even if this returns false: we might have delayed
|
|
|
|
* commit because we were waiting for this! */
|
2017-06-20 07:41:03 +02:00
|
|
|
if (channel_rcvd_revoke_and_ack(peer->channel, &changed_htlcs))
|
2017-04-01 12:58:30 +02:00
|
|
|
status_trace("Commits outstanding after recv revoke_and_ack");
|
|
|
|
else
|
|
|
|
status_trace("No commits outstanding after recv revoke_and_ack");
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* Tell master about things this locks in, wait for response */
|
|
|
|
msg = got_revoke_msg(msg, peer->commit_index[REMOTE],
|
2017-06-20 07:55:03 +02:00
|
|
|
&old_commit_secret, &next_per_commit,
|
|
|
|
changed_htlcs);
|
2017-06-20 07:50:03 +02:00
|
|
|
master_sync_reply(peer, take(msg),
|
|
|
|
WIRE_CHANNEL_GOT_REVOKE_REPLY,
|
|
|
|
handle_reply_wake_peer);
|
|
|
|
|
2017-06-20 07:51:03 +02:00
|
|
|
peer->commit_index[REMOTE]++;
|
|
|
|
peer->old_per_commit[REMOTE] = peer->current_per_commit[REMOTE];
|
|
|
|
peer->current_per_commit[REMOTE] = next_per_commit;
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* And peer waits for reply. */
|
|
|
|
return io_wait(conn, peer, accepted_revocation, peer);
|
2017-04-01 12:58:30 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_fulfill_htlc(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *msg)
|
2017-04-01 13:01:13 +02:00
|
|
|
{
|
|
|
|
struct channel_id channel_id;
|
|
|
|
u64 id;
|
|
|
|
struct preimage preimage;
|
|
|
|
enum channel_remove_err e;
|
|
|
|
|
|
|
|
if (!fromwire_update_fulfill_htlc(msg, NULL, &channel_id,
|
|
|
|
&id, &preimage)) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fulfill_htlc %s", tal_hex(msg, msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
e = channel_fulfill_htlc(peer->channel, LOCAL, id, &preimage);
|
|
|
|
switch (e) {
|
|
|
|
case CHANNEL_ERR_REMOVE_OK:
|
2017-06-20 07:50:03 +02:00
|
|
|
/* FIXME: We could send preimages to master immediately. */
|
2017-04-01 13:01:13 +02:00
|
|
|
start_commit_timer(peer);
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 13:01:13 +02:00
|
|
|
/* These shouldn't happen, because any offered HTLC (which would give
|
|
|
|
* us the preimage) should have timed out long before. If we
|
|
|
|
* were to get preimages from other sources, this could happen. */
|
|
|
|
case CHANNEL_ERR_NO_SUCH_ID:
|
|
|
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
|
|
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
|
|
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
|
|
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fulfill_htlc: failed to fulfill %"
|
|
|
|
PRIu64 " error %u", id, e);
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_fail_htlc(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *msg)
|
2017-04-01 13:01:13 +02:00
|
|
|
{
|
|
|
|
struct channel_id channel_id;
|
|
|
|
u64 id;
|
|
|
|
enum channel_remove_err e;
|
|
|
|
u8 *reason;
|
2017-06-20 07:50:03 +02:00
|
|
|
struct htlc *htlc;
|
2017-04-01 13:01:13 +02:00
|
|
|
|
|
|
|
if (!fromwire_update_fail_htlc(msg, msg, NULL,
|
|
|
|
&channel_id, &id, &reason)) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fulfill_htlc %s", tal_hex(msg, msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
e = channel_fail_htlc(peer->channel, LOCAL, id);
|
|
|
|
switch (e) {
|
|
|
|
case CHANNEL_ERR_REMOVE_OK:
|
2017-06-20 07:50:03 +02:00
|
|
|
/* Save reason for when we tell master. */
|
|
|
|
htlc = channel_get_htlc(peer->channel, LOCAL, id);
|
|
|
|
htlc->fail = tal_steal(htlc, reason);
|
2017-04-01 13:01:13 +02:00
|
|
|
start_commit_timer(peer);
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 13:01:13 +02:00
|
|
|
case CHANNEL_ERR_NO_SUCH_ID:
|
|
|
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
|
|
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
|
|
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
|
|
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fail_htlc: failed to remove %"
|
|
|
|
PRIu64 " error %u", id, e);
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_peer_fail_malformed_htlc(struct io_conn *conn,
|
|
|
|
struct peer *peer,
|
|
|
|
const u8 *msg)
|
2017-05-02 07:26:29 +02:00
|
|
|
{
|
|
|
|
struct channel_id channel_id;
|
|
|
|
u64 id;
|
|
|
|
enum channel_remove_err e;
|
|
|
|
struct sha256 sha256_of_onion;
|
2017-06-20 07:50:03 +02:00
|
|
|
u16 failure_code;
|
|
|
|
struct htlc *htlc;
|
|
|
|
u8 *fail;
|
2017-05-02 07:26:29 +02:00
|
|
|
|
|
|
|
if (!fromwire_update_fail_malformed_htlc(msg, NULL, &channel_id, &id,
|
2017-06-20 07:50:03 +02:00
|
|
|
&sha256_of_onion,
|
|
|
|
&failure_code)) {
|
2017-05-02 07:26:29 +02:00
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fail_malformed_htlc %s",
|
|
|
|
tal_hex(msg, msg));
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:50:03 +02:00
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A receiving node MUST fail the channel if the `BADONION` bit in
|
|
|
|
* `failure_code` is not set for `update_fail_malformed_htlc`.
|
|
|
|
*/
|
|
|
|
if (!(failure_code & BADONION)) {
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fail_malformed_htlc failure code %u",
|
|
|
|
failure_code);
|
|
|
|
}
|
|
|
|
|
2017-05-02 07:26:29 +02:00
|
|
|
e = channel_fail_htlc(peer->channel, LOCAL, id);
|
|
|
|
switch (e) {
|
|
|
|
case CHANNEL_ERR_REMOVE_OK:
|
2017-06-20 07:50:03 +02:00
|
|
|
htlc = channel_get_htlc(peer->channel, LOCAL, id);
|
|
|
|
/* FIXME: Do this! */
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* A receiving node MAY check the `sha256_of_onion`
|
|
|
|
* in `update_fail_malformed_htlc` and MAY retry or choose an
|
|
|
|
* alternate error response if it does not match the onion it
|
|
|
|
* sent.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* Otherwise, a receiving node which has an outgoing HTLC
|
|
|
|
* canceled by `update_fail_malformed_htlc` MUST return an
|
|
|
|
* error in the `update_fail_htlc` sent to the link which
|
|
|
|
* originally sent the HTLC using the `failure_code` given and
|
|
|
|
* setting the data to `sha256_of_onion`.
|
|
|
|
*/
|
|
|
|
fail = tal_arr(htlc, u8, 0);
|
|
|
|
towire_u16(&fail, failure_code);
|
|
|
|
towire_sha256(&fail, &sha256_of_onion);
|
|
|
|
/* FIXME: Make htlc->fail a u8 *! */
|
|
|
|
htlc->fail = fail;
|
2017-05-02 07:26:29 +02:00
|
|
|
start_commit_timer(peer);
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-05-02 07:26:29 +02:00
|
|
|
case CHANNEL_ERR_NO_SUCH_ID:
|
|
|
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
|
|
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
|
|
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
|
|
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad update_fail_malformed_htlc: failed to remove %"
|
|
|
|
PRIu64 " error %u", id, e);
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_ping(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *msg)
|
2017-04-12 18:10:10 +02:00
|
|
|
{
|
|
|
|
u8 *pong;
|
|
|
|
|
|
|
|
if (!check_ping_make_pong(peer, msg, &pong))
|
|
|
|
peer_failed(io_conn_fd(peer->peer_conn),
|
|
|
|
&peer->pcs.cs,
|
|
|
|
&peer->channel_id,
|
|
|
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
|
|
|
"Bad ping");
|
2017-04-12 18:10:10 +02:00
|
|
|
|
|
|
|
status_trace("Got ping, sending %s", pong ?
|
|
|
|
wire_type_name(fromwire_peektype(pong))
|
|
|
|
: "nothing");
|
|
|
|
|
2017-04-12 18:10:10 +02:00
|
|
|
if (pong)
|
|
|
|
msg_enqueue(&peer->peer_out, take(pong));
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-12 18:10:10 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 07:44:03 +02:00
|
|
|
static struct io_plan *handle_pong(struct io_conn *conn,
|
|
|
|
struct peer *peer, const u8 *pong)
|
2017-04-12 18:10:10 +02:00
|
|
|
{
|
|
|
|
u8 *ignored;
|
|
|
|
|
|
|
|
status_trace("Got pong!");
|
|
|
|
if (!fromwire_pong(pong, pong, NULL, &ignored))
|
|
|
|
status_failed(WIRE_CHANNEL_PEER_READ_FAILED, "Bad pong");
|
|
|
|
|
|
|
|
if (!peer->num_pings_outstanding)
|
|
|
|
status_failed(WIRE_CHANNEL_PEER_READ_FAILED, "Unexpected pong");
|
|
|
|
|
|
|
|
peer->num_pings_outstanding--;
|
|
|
|
daemon_conn_send(&peer->master,
|
|
|
|
take(towire_channel_ping_reply(pong, tal_len(pong))));
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-12 18:10:10 +02:00
|
|
|
}
|
|
|
|
|
2017-04-01 12:26:07 +02:00
|
|
|
static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
|
|
|
{
|
|
|
|
enum wire_type type = fromwire_peektype(msg);
|
2017-04-04 13:31:54 +02:00
|
|
|
status_trace("peer_in %s", wire_type_name(type));
|
2017-04-01 12:26:07 +02:00
|
|
|
|
|
|
|
/* Must get funding_locked before almost anything. */
|
|
|
|
if (!peer->funding_locked[REMOTE]) {
|
2017-06-20 07:44:03 +02:00
|
|
|
/* We can get gossip before funding, too */
|
2017-04-01 12:26:07 +02:00
|
|
|
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);
|
2017-03-11 21:49:52 +01:00
|
|
|
}
|
2017-04-01 12:26:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case WIRE_FUNDING_LOCKED:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_funding_locked(conn, peer, msg);
|
2017-04-01 12:26:07 +02:00
|
|
|
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_announcement_signatures(conn, peer, msg);
|
2017-04-01 12:26:07 +02:00
|
|
|
case WIRE_CHANNEL_ANNOUNCEMENT:
|
|
|
|
case WIRE_CHANNEL_UPDATE:
|
|
|
|
case WIRE_NODE_ANNOUNCEMENT:
|
|
|
|
/* Forward to gossip daemon */
|
2017-03-10 15:11:54 +01:00
|
|
|
daemon_conn_send(&peer->gossip_client, msg);
|
2017-06-20 07:44:03 +02:00
|
|
|
return peer_read_message(conn, &peer->pcs, peer_in);
|
2017-04-01 12:26:07 +02:00
|
|
|
case WIRE_UPDATE_ADD_HTLC:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_add_htlc(conn, peer, msg);
|
2017-04-01 12:28:39 +02:00
|
|
|
case WIRE_COMMITMENT_SIGNED:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_commit_sig(conn, peer, msg);
|
2017-04-01 12:58:30 +02:00
|
|
|
case WIRE_REVOKE_AND_ACK:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_revoke_and_ack(conn, peer, msg);
|
2017-04-01 13:01:13 +02:00
|
|
|
case WIRE_UPDATE_FULFILL_HTLC:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_fulfill_htlc(conn, peer, msg);
|
2017-04-01 13:01:13 +02:00
|
|
|
case WIRE_UPDATE_FAIL_HTLC:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_fail_htlc(conn, peer, msg);
|
2017-05-02 07:26:29 +02:00
|
|
|
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_peer_fail_malformed_htlc(conn, peer, msg);
|
2017-04-12 18:10:10 +02:00
|
|
|
case WIRE_PING:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_ping(conn, peer, msg);
|
2017-04-12 18:10:10 +02:00
|
|
|
case WIRE_PONG:
|
2017-06-20 07:44:03 +02:00
|
|
|
return handle_pong(conn, peer, msg);
|
2017-04-12 18:10:10 +02:00
|
|
|
|
2017-04-01 12:26:07 +02:00
|
|
|
case WIRE_INIT:
|
|
|
|
case WIRE_ERROR:
|
|
|
|
case WIRE_OPEN_CHANNEL:
|
|
|
|
case WIRE_ACCEPT_CHANNEL:
|
|
|
|
case WIRE_FUNDING_CREATED:
|
|
|
|
case WIRE_FUNDING_SIGNED:
|
2017-06-20 07:40:03 +02:00
|
|
|
case WIRE_CHANNEL_REESTABLISH:
|
2017-04-01 12:26:07 +02:00
|
|
|
goto badmessage;
|
|
|
|
|
|
|
|
case WIRE_SHUTDOWN:
|
|
|
|
case WIRE_CLOSING_SIGNED:
|
|
|
|
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));
|
2017-03-10 15:11:54 +01:00
|
|
|
}
|
2017-03-07 02:26:12 +01:00
|
|
|
|
2017-04-01 12:26:07 +02:00
|
|
|
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));
|
2017-03-07 02:26:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct io_plan *setup_peer_conn(struct io_conn *conn, struct peer *peer)
|
|
|
|
{
|
|
|
|
return io_duplex(conn, peer_read_message(conn, &peer->pcs, peer_in),
|
|
|
|
peer_out(conn, peer));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void peer_conn_broken(struct io_conn *conn, struct peer *peer)
|
|
|
|
{
|
2017-05-24 12:10:06 +02:00
|
|
|
/* If we have signatures, send an update to say we're disabled. */
|
|
|
|
if (peer->have_sigs[LOCAL] && peer->have_sigs[REMOTE]) {
|
|
|
|
send_channel_update(peer, true);
|
|
|
|
|
|
|
|
/* Make sure gossipd actually gets this message before dying */
|
|
|
|
daemon_conn_sync_flush(&peer->gossip_client);
|
|
|
|
}
|
2017-03-07 02:26:12 +01:00
|
|
|
status_failed(WIRE_CHANNEL_PEER_READ_FAILED,
|
|
|
|
"peer connection broken: %s", strerror(errno));
|
|
|
|
}
|
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
/* We do this synchronously. */
|
|
|
|
static void init_channel(struct peer *peer)
|
2017-03-07 02:26:12 +01:00
|
|
|
{
|
|
|
|
struct privkey seed;
|
|
|
|
struct basepoints points[NUM_SIDES];
|
|
|
|
u64 funding_satoshi, push_msat;
|
|
|
|
u16 funding_txout;
|
2017-03-29 12:58:15 +02:00
|
|
|
struct pubkey funding_pubkey[NUM_SIDES];
|
2017-03-07 02:26:12 +01:00
|
|
|
struct sha256_double funding_txid;
|
|
|
|
bool am_funder;
|
2017-05-24 12:10:17 +02:00
|
|
|
u8 *funding_signed;
|
2017-06-20 08:00:03 +02:00
|
|
|
u8 *msg;
|
2017-03-07 02:26:12 +01:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
msg = wire_sync_read(peer, REQ_FD);
|
2017-05-24 12:10:17 +02:00
|
|
|
if (!fromwire_channel_init(msg, msg, NULL,
|
2017-03-07 02:26:12 +01:00
|
|
|
&funding_txid, &funding_txout,
|
|
|
|
&peer->conf[LOCAL], &peer->conf[REMOTE],
|
|
|
|
&peer->their_commit_sig,
|
|
|
|
&peer->pcs.cs,
|
2017-03-29 12:58:15 +02:00
|
|
|
&funding_pubkey[REMOTE],
|
2017-03-07 02:26:12 +01:00
|
|
|
&points[REMOTE].revocation,
|
|
|
|
&points[REMOTE].payment,
|
|
|
|
&points[REMOTE].delayed_payment,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->old_per_commit[REMOTE],
|
2017-03-07 02:26:12 +01:00
|
|
|
&am_funder,
|
2017-05-01 18:25:20 +02:00
|
|
|
&peer->fee_base,
|
|
|
|
&peer->fee_per_satoshi,
|
|
|
|
&funding_satoshi, &push_msat,
|
2017-03-11 17:16:17 +01:00
|
|
|
&seed,
|
|
|
|
&peer->node_ids[LOCAL],
|
2017-04-01 12:28:39 +02:00
|
|
|
&peer->node_ids[REMOTE],
|
2017-05-01 18:25:20 +02:00
|
|
|
&peer->commit_msec,
|
2017-05-24 12:10:17 +02:00
|
|
|
&peer->cltv_delta,
|
|
|
|
&funding_signed))
|
2017-05-23 13:57:04 +02:00
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "Init: %s",
|
2017-03-07 02:26:12 +01:00
|
|
|
tal_hex(msg, msg));
|
|
|
|
|
2017-04-12 08:10:15 +02:00
|
|
|
/* channel_id is set from funding txout */
|
|
|
|
derive_channel_id(&peer->channel_id, &funding_txid, funding_txout);
|
|
|
|
|
2017-03-07 02:26:12 +01:00
|
|
|
/* We derive everything from the one secret seed. */
|
2017-03-29 12:58:15 +02:00
|
|
|
derive_basepoints(&seed, &funding_pubkey[LOCAL], &points[LOCAL],
|
2017-03-07 02:26:12 +01:00
|
|
|
&peer->our_secrets, &peer->shaseed,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->old_per_commit[LOCAL],
|
|
|
|
peer->commit_index[LOCAL]);
|
|
|
|
status_trace("First per_commit_point = %s",
|
|
|
|
type_to_string(trc, struct pubkey,
|
|
|
|
&peer->old_per_commit[LOCAL]));
|
2017-03-07 02:26:12 +01:00
|
|
|
|
|
|
|
peer->channel = new_channel(peer, &funding_txid, funding_txout,
|
2017-05-01 18:25:20 +02:00
|
|
|
funding_satoshi, push_msat, peer->fee_base,
|
2017-03-07 02:26:12 +01:00
|
|
|
&peer->conf[LOCAL], &peer->conf[REMOTE],
|
|
|
|
&points[LOCAL], &points[REMOTE],
|
2017-03-29 12:58:15 +02:00
|
|
|
&funding_pubkey[LOCAL],
|
|
|
|
&funding_pubkey[REMOTE],
|
2017-03-07 02:26:12 +01:00
|
|
|
am_funder ? LOCAL : REMOTE);
|
|
|
|
|
2017-03-22 16:46:48 +01:00
|
|
|
peer->channel_direction = get_channel_direction(
|
|
|
|
&peer->node_ids[LOCAL], &peer->node_ids[REMOTE]);
|
|
|
|
|
2017-03-07 02:26:12 +01:00
|
|
|
/* OK, now we can process peer messages. */
|
2017-04-01 12:26:07 +02:00
|
|
|
peer->peer_conn = io_new_conn(peer, PEER_FD, setup_peer_conn, peer);
|
|
|
|
io_set_finish(peer->peer_conn, peer_conn_broken, peer);
|
2017-05-24 12:10:17 +02:00
|
|
|
|
|
|
|
/* If we have a funding_signed message, we send that immediately */
|
|
|
|
if (tal_len(funding_signed) != 0)
|
|
|
|
msg_enqueue(&peer->peer_out, take(funding_signed));
|
2017-06-20 08:00:03 +02:00
|
|
|
|
|
|
|
tal_free(msg);
|
2017-03-19 21:32:44 +01:00
|
|
|
}
|
|
|
|
|
2017-03-29 13:01:15 +02:00
|
|
|
static void handle_funding_locked(struct peer *peer, const u8 *msg)
|
|
|
|
{
|
|
|
|
if (!fromwire_channel_funding_locked(msg, NULL,
|
|
|
|
&peer->short_channel_ids[LOCAL]))
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "%s", tal_hex(msg, msg));
|
|
|
|
|
2017-04-01 12:58:30 +02:00
|
|
|
next_per_commit_point(&peer->shaseed, NULL,
|
|
|
|
&peer->current_per_commit[LOCAL],
|
2017-04-01 12:58:30 +02:00
|
|
|
peer->commit_index[LOCAL]++);
|
2017-04-01 12:58:30 +02:00
|
|
|
|
2017-03-29 13:01:15 +02:00
|
|
|
msg = towire_funding_locked(peer,
|
|
|
|
&peer->channel_id,
|
2017-04-01 12:58:30 +02:00
|
|
|
&peer->current_per_commit[LOCAL]);
|
2017-03-29 13:01:15 +02:00
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
|
|
|
peer->funding_locked[LOCAL] = true;
|
|
|
|
|
|
|
|
if (peer->funding_locked[REMOTE]) {
|
|
|
|
daemon_conn_send(&peer->master,
|
|
|
|
take(towire_channel_normal_operation(peer)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_funding_announce_depth(struct peer *peer, const u8 *msg)
|
|
|
|
{
|
|
|
|
status_trace("Exchanging announcement signatures.");
|
|
|
|
send_announcement_signatures(peer);
|
2017-04-04 13:24:47 +02:00
|
|
|
|
|
|
|
/* Only send the announcement and update if the other end gave
|
|
|
|
* us its sig */
|
|
|
|
if (peer->have_sigs[REMOTE]) {
|
|
|
|
send_channel_announcement(peer);
|
|
|
|
send_channel_update(peer, false);
|
2017-05-07 01:59:48 +02:00
|
|
|
/* Tell the master that we just announced the channel,
|
|
|
|
* so it may announce the node */
|
|
|
|
daemon_conn_send(&peer->master, take(towire_channel_announced(msg)));
|
2017-04-04 13:24:47 +02:00
|
|
|
}
|
2017-03-29 13:01:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
|
|
|
|
{
|
|
|
|
u8 *msg;
|
2017-06-06 01:49:10 +02:00
|
|
|
u32 cltv_expiry;
|
|
|
|
u64 amount_msat;
|
2017-03-29 13:01:15 +02:00
|
|
|
struct sha256 payment_hash;
|
2017-04-01 12:58:30 +02:00
|
|
|
u8 onion_routing_packet[TOTAL_PACKET_SIZE];
|
2017-04-27 08:08:50 +02:00
|
|
|
enum channel_add_err e;
|
2017-03-29 13:01:15 +02:00
|
|
|
enum onion_type failcode;
|
|
|
|
/* Subtle: must be tal_arr since we marshal using tal_len() */
|
|
|
|
const char *failmsg;
|
|
|
|
|
|
|
|
if (!peer->funding_locked[LOCAL] || !peer->funding_locked[REMOTE])
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "funding not locked");
|
|
|
|
|
|
|
|
if (!fromwire_channel_offer_htlc(inmsg, NULL, &amount_msat,
|
|
|
|
&cltv_expiry, &payment_hash,
|
|
|
|
onion_routing_packet))
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
|
|
|
"bad offer_htlc message %s",
|
|
|
|
tal_hex(inmsg, inmsg));
|
|
|
|
|
2017-04-27 08:08:50 +02:00
|
|
|
e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id,
|
|
|
|
amount_msat, cltv_expiry, &payment_hash,
|
|
|
|
onion_routing_packet);
|
|
|
|
status_trace("Adding HTLC %"PRIu64" gave %i", peer->htlc_id, e);
|
|
|
|
|
|
|
|
switch (e) {
|
2017-03-29 13:01:15 +02:00
|
|
|
case CHANNEL_ERR_ADD_OK:
|
|
|
|
/* Tell the peer. */
|
|
|
|
msg = towire_update_add_htlc(peer, &peer->channel_id,
|
|
|
|
peer->htlc_id, amount_msat,
|
2017-06-06 01:49:10 +02:00
|
|
|
&payment_hash, cltv_expiry,
|
2017-03-29 13:01:15 +02:00
|
|
|
onion_routing_packet);
|
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
|
|
|
peer->funding_locked[LOCAL] = true;
|
|
|
|
start_commit_timer(peer);
|
|
|
|
/* Tell the master. */
|
|
|
|
msg = towire_channel_offer_htlc_reply(inmsg, peer->htlc_id,
|
|
|
|
0, NULL);
|
|
|
|
daemon_conn_send(&peer->master, take(msg));
|
|
|
|
peer->htlc_id++;
|
|
|
|
return;
|
|
|
|
case CHANNEL_ERR_INVALID_EXPIRY:
|
|
|
|
failcode = WIRE_INCORRECT_CLTV_EXPIRY;
|
|
|
|
failmsg = tal_fmt(inmsg, "Invalid cltv_expiry %u", cltv_expiry);
|
|
|
|
goto failed;
|
|
|
|
case CHANNEL_ERR_DUPLICATE:
|
|
|
|
case CHANNEL_ERR_DUPLICATE_ID_DIFFERENT:
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
|
|
|
"Duplicate HTLC %"PRIu64, peer->htlc_id);
|
|
|
|
|
|
|
|
/* FIXME: Fuzz the boundaries a bit to avoid probing? */
|
|
|
|
case CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED:
|
|
|
|
/* FIXME: We should advertise this? */
|
|
|
|
failcode = WIRE_TEMPORARY_CHANNEL_FAILURE;
|
|
|
|
failmsg = tal_fmt(inmsg, "Maximum value exceeded");
|
|
|
|
goto failed;
|
|
|
|
case CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED:
|
|
|
|
failcode = WIRE_TEMPORARY_CHANNEL_FAILURE;
|
|
|
|
failmsg = tal_fmt(inmsg, "Capacity exceeded");
|
|
|
|
goto failed;
|
|
|
|
case CHANNEL_ERR_HTLC_BELOW_MINIMUM:
|
|
|
|
failcode = WIRE_AMOUNT_BELOW_MINIMUM;
|
|
|
|
failmsg = tal_fmt(inmsg, "HTLC too small (%u minimum)",
|
|
|
|
htlc_minimum_msat(peer->channel, REMOTE));
|
|
|
|
goto failed;
|
|
|
|
case CHANNEL_ERR_TOO_MANY_HTLCS:
|
|
|
|
failcode = WIRE_TEMPORARY_CHANNEL_FAILURE;
|
|
|
|
failmsg = tal_fmt(inmsg, "Too many HTLCs");
|
|
|
|
goto failed;
|
|
|
|
}
|
|
|
|
/* Shouldn't return anything else! */
|
|
|
|
abort();
|
|
|
|
|
|
|
|
failed:
|
|
|
|
msg = towire_channel_offer_htlc_reply(inmsg, 0, failcode, (u8*)failmsg);
|
|
|
|
daemon_conn_send(&peer->master, take(msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_preimage(struct peer *peer, const u8 *inmsg)
|
|
|
|
{
|
|
|
|
u8 *msg;
|
|
|
|
u64 id;
|
|
|
|
struct preimage preimage;
|
|
|
|
|
|
|
|
if (!fromwire_channel_fulfill_htlc(inmsg, NULL, &id, &preimage))
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
|
|
|
"Invalid channel_fulfill_htlc");
|
|
|
|
|
|
|
|
switch (channel_fulfill_htlc(peer->channel, REMOTE, id, &preimage)) {
|
|
|
|
case CHANNEL_ERR_REMOVE_OK:
|
|
|
|
msg = towire_update_fulfill_htlc(peer, &peer->channel_id,
|
|
|
|
id, &preimage);
|
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
|
|
|
start_commit_timer(peer);
|
|
|
|
return;
|
|
|
|
/* These shouldn't happen, because any offered HTLC (which would give
|
|
|
|
* us the preimage) should have timed out long before. If we
|
|
|
|
* were to get preimages from other sources, this could happen. */
|
|
|
|
case CHANNEL_ERR_NO_SUCH_ID:
|
|
|
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
|
|
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
|
|
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
|
|
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
|
|
|
"HTLC %"PRIu64" preimage failed", id);
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_fail(struct peer *peer, const u8 *inmsg)
|
|
|
|
{
|
|
|
|
u8 *msg;
|
|
|
|
u64 id;
|
|
|
|
u8 *errpkt;
|
2017-04-01 13:01:13 +02:00
|
|
|
enum channel_remove_err e;
|
2017-03-29 13:01:15 +02:00
|
|
|
|
|
|
|
if (!fromwire_channel_fail_htlc(inmsg, inmsg, NULL, &id, &errpkt))
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
|
|
|
"Invalid channel_fail_htlc");
|
|
|
|
|
2017-04-01 13:01:13 +02:00
|
|
|
e = channel_fail_htlc(peer->channel, REMOTE, id);
|
|
|
|
switch (e) {
|
2017-03-29 13:01:15 +02:00
|
|
|
case CHANNEL_ERR_REMOVE_OK:
|
|
|
|
msg = towire_update_fail_htlc(peer, &peer->channel_id,
|
|
|
|
id, errpkt);
|
|
|
|
msg_enqueue(&peer->peer_out, take(msg));
|
|
|
|
start_commit_timer(peer);
|
|
|
|
return;
|
|
|
|
/* These shouldn't happen, because any offered HTLC (which would give
|
|
|
|
* us the preimage) should have timed out long before. If we
|
|
|
|
* were to get preimages from other sources, this could happen. */
|
|
|
|
case CHANNEL_ERR_NO_SUCH_ID:
|
|
|
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
|
|
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
|
|
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
|
|
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND,
|
2017-04-01 13:01:13 +02:00
|
|
|
"HTLC %"PRIu64" removal failed: %i", id, e);
|
2017-03-29 13:01:15 +02:00
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2017-04-12 18:10:10 +02:00
|
|
|
static void handle_ping_cmd(struct peer *peer, const u8 *inmsg)
|
|
|
|
{
|
|
|
|
u16 num_pong_bytes, ping_len;
|
|
|
|
u8 *ping;
|
|
|
|
|
|
|
|
if (!fromwire_channel_ping(inmsg, NULL, &num_pong_bytes, &ping_len))
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "Bad channel_ping");
|
|
|
|
|
|
|
|
ping = make_ping(peer, num_pong_bytes, ping_len);
|
|
|
|
if (tal_len(ping) > 65535)
|
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "Oversize channel_ping");
|
|
|
|
|
|
|
|
msg_enqueue(&peer->peer_out, take(ping));
|
|
|
|
|
|
|
|
status_trace("sending ping expecting %sresponse",
|
|
|
|
num_pong_bytes >= 65532 ? "no " : "");
|
|
|
|
|
|
|
|
/* BOLT #1:
|
|
|
|
*
|
|
|
|
* if `num_pong_bytes` is less than 65532 it MUST respond by sending a
|
|
|
|
* `pong` message with `byteslen` equal to `num_pong_bytes`, otherwise
|
|
|
|
* it MUST ignore the `ping`.
|
|
|
|
*/
|
|
|
|
if (num_pong_bytes >= 65532)
|
|
|
|
daemon_conn_send(&peer->master,
|
|
|
|
take(towire_channel_ping_reply(peer, 0)));
|
|
|
|
else
|
|
|
|
peer->num_pings_outstanding++;
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:32:44 +01:00
|
|
|
static struct io_plan *req_in(struct io_conn *conn, struct daemon_conn *master)
|
|
|
|
{
|
|
|
|
struct peer *peer = container_of(master, struct peer, master);
|
2017-06-20 08:00:03 +02:00
|
|
|
enum channel_wire_type t = fromwire_peektype(master->msg_in);
|
2017-03-19 21:32:44 +01:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
/* Waiting for something specific? Defer others. */
|
|
|
|
if (peer->handle_master_reply) {
|
|
|
|
void (*handle)(struct peer *peer, const u8 *msg);
|
2017-03-29 13:01:15 +02:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
if (t != peer->master_reply_type) {
|
|
|
|
msg_enqueue(&peer->master_deferred,
|
|
|
|
take(master->msg_in));
|
|
|
|
master->msg_in = NULL;
|
|
|
|
goto out_next;
|
|
|
|
}
|
2017-06-20 07:49:03 +02:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
/* Just in case it resets this. */
|
|
|
|
handle = peer->handle_master_reply;
|
|
|
|
peer->handle_master_reply = NULL;
|
2017-06-20 07:49:03 +02:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
handle(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
}
|
2017-06-20 07:49:03 +02:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
switch (t) {
|
|
|
|
case WIRE_CHANNEL_FUNDING_LOCKED:
|
|
|
|
handle_funding_locked(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
case WIRE_CHANNEL_FUNDING_ANNOUNCE_DEPTH:
|
|
|
|
handle_funding_announce_depth(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
case WIRE_CHANNEL_OFFER_HTLC:
|
|
|
|
handle_offer_htlc(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
case WIRE_CHANNEL_FULFILL_HTLC:
|
|
|
|
handle_preimage(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
case WIRE_CHANNEL_FAIL_HTLC:
|
|
|
|
handle_fail(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
case WIRE_CHANNEL_PING:
|
|
|
|
handle_ping_cmd(peer, master->msg_in);
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
case WIRE_CHANNEL_BAD_COMMAND:
|
|
|
|
case WIRE_CHANNEL_HSM_FAILED:
|
|
|
|
case WIRE_CHANNEL_CRYPTO_FAILED:
|
|
|
|
case WIRE_CHANNEL_GOSSIP_BAD_MESSAGE:
|
|
|
|
case WIRE_CHANNEL_INTERNAL_ERROR:
|
|
|
|
case WIRE_CHANNEL_PEER_WRITE_FAILED:
|
|
|
|
case WIRE_CHANNEL_PEER_READ_FAILED:
|
|
|
|
case WIRE_CHANNEL_NORMAL_OPERATION:
|
|
|
|
case WIRE_CHANNEL_INIT:
|
|
|
|
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
|
|
|
|
case WIRE_CHANNEL_PING_REPLY:
|
|
|
|
case WIRE_CHANNEL_PEER_BAD_MESSAGE:
|
|
|
|
case WIRE_CHANNEL_ANNOUNCED:
|
|
|
|
case WIRE_CHANNEL_SENDING_COMMITSIG:
|
|
|
|
case WIRE_CHANNEL_GOT_COMMITSIG:
|
|
|
|
case WIRE_CHANNEL_GOT_REVOKE:
|
|
|
|
case WIRE_CHANNEL_SENDING_COMMITSIG_REPLY:
|
|
|
|
case WIRE_CHANNEL_GOT_COMMITSIG_REPLY:
|
|
|
|
case WIRE_CHANNEL_GOT_REVOKE_REPLY:
|
|
|
|
case WIRE_CHANNEL_GOT_FUNDING_LOCKED:
|
|
|
|
break;
|
2017-03-29 13:01:15 +02:00
|
|
|
}
|
2017-06-20 08:00:03 +02:00
|
|
|
status_failed(WIRE_CHANNEL_BAD_COMMAND, "%u %s", t,
|
|
|
|
channel_wire_type_name(t));
|
2017-03-19 21:32:44 +01:00
|
|
|
|
2017-03-29 13:01:15 +02:00
|
|
|
out:
|
2017-06-20 07:49:03 +02:00
|
|
|
/* In case we've now processed reply, process packet backlog. */
|
|
|
|
if (!peer->handle_master_reply) {
|
|
|
|
const u8 *msg = msg_dequeue(&peer->master_deferred);
|
|
|
|
if (msg) {
|
|
|
|
/* Free old packet exactly like daemon_conn_read_next */
|
|
|
|
master->msg_in = tal_free(master->msg_in);
|
|
|
|
master->msg_in = cast_const(u8 *, tal_steal(master,msg));
|
|
|
|
return req_in(conn, master);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out_next:
|
2017-03-19 21:32:44 +01:00
|
|
|
return daemon_conn_read_next(conn, master);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef TESTING
|
2017-06-06 05:08:42 +02:00
|
|
|
static void master_gone(struct io_conn *unused, struct daemon_conn *dc)
|
|
|
|
{
|
|
|
|
/* Can't tell master, it's gone. */
|
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gossip_gone(struct io_conn *unused, struct daemon_conn *dc)
|
|
|
|
{
|
|
|
|
status_failed(WIRE_CHANNEL_GOSSIP_BAD_MESSAGE,
|
|
|
|
"Gossip connection closed");
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:32:44 +01:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
struct peer *peer = tal(NULL, struct peer);
|
2017-04-12 08:11:15 +02:00
|
|
|
int i;
|
2017-03-19 21:32:44 +01:00
|
|
|
|
|
|
|
if (argc == 2 && streq(argv[1], "--version")) {
|
|
|
|
printf("%s\n", version());
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
subdaemon_debug(argc, argv);
|
|
|
|
|
|
|
|
/* We handle write returning errors! */
|
|
|
|
signal(SIGCHLD, SIG_IGN);
|
|
|
|
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
|
|
|
| SECP256K1_CONTEXT_SIGN);
|
|
|
|
|
2017-06-06 05:08:42 +02:00
|
|
|
daemon_conn_init(peer, &peer->master, REQ_FD, req_in, master_gone);
|
2017-06-20 08:00:03 +02:00
|
|
|
status_setup_async(&peer->master);
|
|
|
|
|
2017-03-29 13:01:15 +02:00
|
|
|
peer->htlc_id = 0;
|
2017-04-12 18:10:10 +02:00
|
|
|
peer->num_pings_outstanding = 0;
|
2017-04-01 12:28:39 +02:00
|
|
|
timers_init(&peer->timers, time_mono());
|
|
|
|
peer->commit_timer = NULL;
|
2017-04-01 12:58:30 +02:00
|
|
|
peer->commit_index[LOCAL] = peer->commit_index[REMOTE] = 0;
|
2017-04-04 13:24:47 +02:00
|
|
|
peer->have_sigs[LOCAL] = peer->have_sigs[REMOTE] = false;
|
2017-06-20 07:49:03 +02:00
|
|
|
peer->handle_master_reply = NULL;
|
2017-06-20 07:50:03 +02:00
|
|
|
peer->master_reply_type = 0;
|
2017-06-20 07:49:03 +02:00
|
|
|
msg_queue_init(&peer->master_deferred, peer);
|
2017-06-20 08:00:03 +02:00
|
|
|
msg_queue_init(&peer->peer_out, peer);
|
2017-04-12 08:11:15 +02:00
|
|
|
|
|
|
|
/* We send these to HSM to get real signatures; don't have valgrind
|
|
|
|
* complain. */
|
|
|
|
for (i = 0; i < NUM_SIDES; i++) {
|
|
|
|
memset(&peer->announcement_node_sigs[i], 0,
|
|
|
|
sizeof(peer->announcement_node_sigs[i]));
|
|
|
|
memset(&peer->announcement_bitcoin_sigs[i], 0,
|
|
|
|
sizeof(peer->announcement_bitcoin_sigs[i]));
|
|
|
|
}
|
|
|
|
|
2017-03-19 21:32:44 +01:00
|
|
|
daemon_conn_init(peer, &peer->gossip_client, GOSSIP_FD,
|
2017-06-06 05:08:42 +02:00
|
|
|
gossip_client_recv, gossip_gone);
|
2017-03-19 21:32:44 +01:00
|
|
|
|
|
|
|
init_peer_crypto_state(peer, &peer->pcs);
|
|
|
|
peer->funding_locked[LOCAL] = peer->funding_locked[REMOTE] = false;
|
2017-03-07 02:26:12 +01:00
|
|
|
|
2017-06-20 08:00:03 +02:00
|
|
|
/* Read init_channel message sync. */
|
|
|
|
init_channel(peer);
|
|
|
|
|
2017-04-01 12:28:39 +02:00
|
|
|
for (;;) {
|
|
|
|
struct timer *expired = NULL;
|
|
|
|
io_loop(&peer->timers, &expired);
|
|
|
|
|
|
|
|
if (!expired)
|
|
|
|
break;
|
|
|
|
timer_expired(peer, expired);
|
|
|
|
}
|
|
|
|
|
2017-03-07 02:26:12 +01:00
|
|
|
tal_free(peer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* TESTING */
|