diff --git a/lightningd/channel.c b/lightningd/channel.c index abdf8b388..3ff244782 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -20,6 +20,33 @@ void channel_set_owner(struct channel *channel, struct subd *owner) static void destroy_channel(struct channel *channel) { + /* 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; + struct lightningd *ld = channel->peer->ld; + + for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); + hout; + hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { + if (hout->key.channel != channel) + continue; + fatal("Freeing channel %s has hout %s", + channel_state_name(channel), + htlc_state_name(hout->hstate)); + } + + for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); + hin; + hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { + if (hin->key.channel != channel) + continue; + fatal("Freeing channel %s has hin %s", + channel_state_name(channel), + htlc_state_name(hin->hstate)); + } + /* Free any old owner still hanging around. */ channel_set_owner(channel, NULL); @@ -112,6 +139,15 @@ struct channel *peer_active_channel(struct peer *peer) return NULL; } +struct channel *active_channel_by_id(struct lightningd *ld, + const struct pubkey *id) +{ + struct peer *peer = peer_by_id(ld, id); + if (!peer) + return NULL; + return peer_active_channel(peer); +} + void channel_set_state(struct channel *channel, enum peer_state old_state, enum peer_state state) diff --git a/lightningd/channel.h b/lightningd/channel.h index c03f563bf..84bec888f 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -116,6 +116,9 @@ struct peer *channel2peer(const struct channel *channel); /* Find a channel which is not onchain, if any */ struct channel *peer_active_channel(struct peer *peer); +struct channel *active_channel_by_id(struct lightningd *ld, + const struct pubkey *id); + static inline bool channel_can_add_htlc(const struct channel *channel) { return channel->state == CHANNELD_NORMAL; diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index ca6ecc72a..38fd7bd4a 100644 --- a/lightningd/htlc_end.c +++ b/lightningd/htlc_end.c @@ -13,18 +13,18 @@ size_t hash_htlc_key(const struct htlc_key *k) { struct siphash24_ctx ctx; siphash24_init(&ctx, siphash_seed()); - /* peer doesn't move while in this hash, so we just hash pointer. */ - siphash24_update(&ctx, &k->peer, sizeof(k->peer)); + /* channel doesn't move while in this hash, so we just hash pointer. */ + siphash24_update(&ctx, &k->channel, sizeof(k->channel)); siphash24_u64(&ctx, k->id); return siphash24_done(&ctx); } struct htlc_in *find_htlc_in(const struct htlc_in_map *map, - const struct peer *peer, + const struct channel *channel, u64 htlc_id) { - const struct htlc_key key = { (struct peer *)peer, htlc_id }; + const struct htlc_key key = { (struct channel *)channel, htlc_id }; return htlc_in_map_get(map, &key); } @@ -40,10 +40,10 @@ void connect_htlc_in(struct htlc_in_map *map, struct htlc_in *hend) } struct htlc_out *find_htlc_out(const struct htlc_out_map *map, - const struct peer *peer, + const struct channel *channel, u64 htlc_id) { - const struct htlc_key key = { (struct peer *)peer, htlc_id }; + const struct htlc_key key = { (struct channel *)channel, htlc_id }; return htlc_out_map_get(map, &key); } @@ -91,7 +91,7 @@ struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr) } struct htlc_in *new_htlc_in(const tal_t *ctx, - struct peer *peer, u64 id, + struct channel *channel, u64 id, u64 msatoshi, u32 cltv_expiry, const struct sha256 *payment_hash, const struct secret *shared_secret, @@ -100,7 +100,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx, struct htlc_in *hin = tal(ctx, struct htlc_in); hin->dbid = 0; - hin->key.peer = peer; + hin->key.channel = channel; hin->key.id = id; hin->msatoshi = msatoshi; hin->cltv_expiry = cltv_expiry; @@ -131,7 +131,7 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout, /* You need to set the ID, then connect_htlc_out this! */ struct htlc_out *new_htlc_out(const tal_t *ctx, - struct peer *peer, + struct channel *channel, u64 msatoshi, u32 cltv_expiry, const struct sha256 *payment_hash, const u8 *onion_routing_packet, @@ -142,7 +142,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx, /* Mark this as an as of now unsaved HTLC */ hout->dbid = 0; - hout->key.peer = peer; + hout->key.channel = channel; hout->key.id = HTLC_INVALID_ID; hout->msatoshi = msatoshi; hout->cltv_expiry = cltv_expiry; diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 1d2a8c9c7..a95ed4f2a 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -7,9 +7,9 @@ #include #include -/* We look up HTLCs by peer & id */ +/* We look up HTLCs by channel & id */ struct htlc_key { - struct peer *peer; + struct channel *channel; u64 id; }; @@ -91,13 +91,13 @@ size_t hash_htlc_key(const struct htlc_key *htlc_key); static inline bool htlc_in_eq(const struct htlc_in *in, const struct htlc_key *k) { - return in->key.peer == k->peer && in->key.id == k->id; + return in->key.channel == k->channel && in->key.id == k->id; } static inline bool htlc_out_eq(const struct htlc_out *out, const struct htlc_key *k) { - return out->key.peer == k->peer && out->key.id == k->id; + return out->key.channel == k->channel && out->key.id == k->id; } @@ -108,16 +108,16 @@ HTABLE_DEFINE_TYPE(struct htlc_out, keyof_htlc_out, hash_htlc_key, htlc_out_eq, htlc_out_map); struct htlc_in *find_htlc_in(const struct htlc_in_map *map, - const struct peer *peer, + const struct channel *channel, u64 htlc_id); struct htlc_out *find_htlc_out(const struct htlc_out_map *map, - const struct peer *peer, + const struct channel *channel, u64 htlc_id); /* You still need to connect_htlc_in this! */ struct htlc_in *new_htlc_in(const tal_t *ctx, - struct peer *peer, u64 id, + struct channel *channel, u64 id, u64 msatoshi, u32 cltv_expiry, const struct sha256 *payment_hash, const struct secret *shared_secret, @@ -125,7 +125,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx, /* You need to set the ID, then connect_htlc_out this! */ struct htlc_out *new_htlc_out(const tal_t *ctx, - struct peer *peer, + struct channel *channel, u64 msatoshi, u32 cltv_expiry, const struct sha256 *payment_hash, const u8 *onion_routing_packet, diff --git a/lightningd/pay.c b/lightningd/pay.c index 6bed5650a..06e1bbb8a 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -395,7 +395,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, tal_count(path_secrets), hout->failuremsg); if (!reply) { - log_info(hout->key.peer->log, + log_info(hout->key.channel->log, "htlc %"PRIu64" failed with bad reply (%s)", hout->key.id, tal_hex(ltmp, hout->failuremsg)); @@ -403,7 +403,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, fail = NULL; failcode = WIRE_PERMANENT_NODE_FAILURE; /* Select a channel to mark unroutable by random */ - random_mark_channel_unroutable(hout->key.peer->log, + random_mark_channel_unroutable(hout->key.channel->log, ld->gossip, payment->route_channels); /* Can now retry; we selected a channel to mark @@ -414,7 +414,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, report_to_gossipd = false; } else { failcode = fromwire_peektype(reply->msg); - log_info(hout->key.peer->log, + log_info(hout->key.channel->log, "htlc %"PRIu64" " "failed from %ith node " "with code 0x%04x (%s)", @@ -455,7 +455,6 @@ static bool send_payment(struct command *cmd, const struct sha256 *rhash, const struct route_hop *route) { - struct peer *peer; const u8 *onion; u8 sessionkey[32]; unsigned int base_expiry; @@ -471,6 +470,7 @@ static bool send_payment(struct command *cmd, struct htlc_out *hout; struct short_channel_id *channels; struct routing_failure *fail; + struct channel *channel; /* Expiry for HTLCs is absolute. And add one to give some margin. */ base_expiry = get_block_height(cmd->ld->topology) + 1; @@ -534,8 +534,8 @@ static bool send_payment(struct command *cmd, log_add(cmd->ld->log, "... retrying"); } - peer = peer_by_id(cmd->ld, &ids[0]); - if (!peer) { + channel = active_channel_by_id(cmd->ld, &ids[0]); + if (!channel) { /* Report routing failure to gossipd */ fail = immediate_routing_failure(cmd, cmd->ld, WIRE_UNKNOWN_NEXT_PEER, @@ -559,7 +559,7 @@ static bool send_payment(struct command *cmd, log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %u", route[0].amount, n_hops, route[n_hops-1].amount); - failcode = send_htlc_out(peer, route[0].amount, + failcode = send_htlc_out(channel, route[0].amount, base_expiry + route[0].delay, rhash, onion, NULL, &hout); if (failcode) { diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 951f13aef..98d7b15c2 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -96,32 +96,6 @@ static void peer_set_owner(struct peer *peer, struct subd *owner) static void destroy_peer(struct peer *peer) { - /* 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", - channel_state_name(peer2channel(peer)), - 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", - channel_state_name(peer2channel(peer)), - htlc_state_name(hin->hstate)); - } - list_del_from(&peer->ld->peers, &peer->list); } @@ -887,7 +861,7 @@ static void onchaind_tell_fulfill(struct channel *channel) for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); hin; hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { - if (hin->key.peer != channel2peer(channel)) + if (hin->key.channel != channel) continue; /* BOLT #5: @@ -1098,7 +1072,7 @@ void free_htlcs(struct lightningd *ld, const struct channel *channel) for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); hout; hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { - if (channel && hout->key.peer != channel2peer(channel)) + if (channel && hout->key.channel != channel) continue; tal_free(hout); deleted = true; @@ -1107,7 +1081,7 @@ void free_htlcs(struct lightningd *ld, const struct channel *channel) for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); hin; hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { - if (channel && hin->key.peer != channel2peer(channel)) + if (channel && hin->key.channel != channel) continue; tal_free(hin); deleted = true; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index d345c2894..16b89df3d 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -22,12 +22,11 @@ #include #include -static bool state_update_ok(struct peer *peer, +static bool state_update_ok(struct channel *channel, enum htlc_state oldstate, enum htlc_state newstate, u64 htlc_id, const char *dir) { enum htlc_state expected = oldstate + 1; - struct channel *channel = peer2channel(peer); /* We never get told about RCVD_REMOVE_HTLC, so skip over that * (we initialize in SENT_ADD_HTLC / RCVD_ADD_COMMIT, so those @@ -44,34 +43,37 @@ static bool state_update_ok(struct peer *peer, return false; } - log_debug(peer->log, "HTLC %s %"PRIu64" %s->%s", + log_debug(channel->log, "HTLC %s %"PRIu64" %s->%s", dir, htlc_id, htlc_state_name(oldstate), htlc_state_name(newstate)); return true; } -static bool htlc_in_update_state(struct peer *peer, +static bool htlc_in_update_state(struct channel *channel, struct htlc_in *hin, enum htlc_state newstate) { - if (!state_update_ok(peer, hin->hstate, newstate, hin->key.id, "in")) + if (!state_update_ok(channel, hin->hstate, newstate, hin->key.id, "in")) return false; - wallet_htlc_update(peer->ld->wallet, hin->dbid, newstate, hin->preimage); + wallet_htlc_update(channel->peer->ld->wallet, + hin->dbid, newstate, hin->preimage); hin->hstate = newstate; htlc_in_check(hin, __func__); return true; } -static bool htlc_out_update_state(struct peer *peer, +static bool htlc_out_update_state(struct channel *channel, struct htlc_out *hout, enum htlc_state newstate) { - if (!state_update_ok(peer, hout->hstate, newstate, hout->key.id, "out")) + if (!state_update_ok(channel, hout->hstate, newstate, hout->key.id, + "out")) return false; - wallet_htlc_update(peer->ld->wallet, hout->dbid, newstate, NULL); + wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate, + NULL); hout->hstate = newstate; htlc_out_check(hout, __func__); @@ -97,13 +99,13 @@ static void fail_in_htlc(struct htlc_in *hin, memset(&hin->failoutchannel, 0, sizeof(hin->failoutchannel)); /* We update state now to signal it's in progress, for persistence. */ - htlc_in_update_state(hin->key.peer, hin, SENT_REMOVE_HTLC); + htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC); /* Tell peer, if we can. */ - if (!peer2channel(hin->key.peer)->owner) + if (!hin->key.channel->owner) return; - subd_send_msg(peer2channel(hin->key.peer)->owner, + subd_send_msg(hin->key.channel->owner, take(towire_channel_fail_htlc(hin, hin->key.id, hin->failuremsg, @@ -115,7 +117,7 @@ static void fail_in_htlc(struct htlc_in *hin, static void local_fail_htlc(struct htlc_in *hin, enum onion_type failcode, const struct short_channel_id *out_channel) { - log_info(hin->key.peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)", + log_info(hin->key.channel->log, "failed htlc %"PRIu64" code 0x%04x (%s)", hin->key.id, failcode, onion_type_name(failcode)); fail_in_htlc(hin, failcode, NULL, out_channel); @@ -128,9 +130,9 @@ static void fail_out_htlc(struct htlc_out *hout, const char *localfail) assert(hout->failcode || hout->failuremsg); if (hout->in) { fail_in_htlc(hout->in, hout->failcode, hout->failuremsg, - peer2channel(hout->key.peer)->scid); + hout->key.channel->scid); } else { - payment_failed(hout->key.peer->ld, hout, localfail); + payment_failed(hout->key.channel->peer->ld, hout, localfail); } } @@ -156,7 +158,7 @@ static bool check_amount(struct htlc_in *hin, { if (amt_in_htlc - fee >= amt_to_forward) return true; - log_debug(hin->key.peer->ld->log, "HTLC %"PRIu64" incorrect amount:" + log_debug(hin->key.channel->log, "HTLC %"PRIu64" incorrect amount:" " %"PRIu64" in, %"PRIu64" out, fee reqd %"PRIu64, hin->key.id, amt_in_htlc, amt_to_forward, fee); return false; @@ -185,7 +187,7 @@ static bool check_cltv(struct htlc_in *hin, { if (cltv_expiry - delta >= outgoing_cltv_value) return true; - log_debug(hin->key.peer->ld->log, "HTLC %"PRIu64" incorrect CLTV:" + log_debug(hin->key.channel->log, "HTLC %"PRIu64" incorrect CLTV:" " %u in, %u out, delta reqd %u", hin->key.id, cltv_expiry, outgoing_cltv_value, delta); return false; @@ -199,21 +201,21 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage) htlc_in_check(hin, __func__); /* We update state now to signal it's in progress, for persistence. */ - htlc_in_update_state(hin->key.peer, hin, SENT_REMOVE_HTLC); + htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC); /* No owner? We'll either send to channeld in peer_htlcs, or * onchaind in onchaind_tell_fulfill. */ - if (!peer2channel(hin->key.peer)->owner) { - log_debug(hin->key.peer->log, "HTLC fulfilled, but no owner."); + if (!hin->key.channel->owner) { + log_debug(hin->key.channel->log, "HTLC fulfilled, but no owner."); return; } - if (peer_on_chain(hin->key.peer)) { + if (channel_on_chain(hin->key.channel)) { msg = towire_onchain_known_preimage(hin, preimage); } else { msg = towire_channel_fulfill_htlc(hin, hin->key.id, preimage); } - subd_send_msg(peer2channel(hin->key.peer)->owner, take(msg)); + subd_send_msg(hin->key.channel->owner, take(msg)); } static void handle_localpay(struct htlc_in *hin, @@ -224,7 +226,7 @@ static void handle_localpay(struct htlc_in *hin, { enum onion_type failcode; const struct invoice *invoice; - struct lightningd *ld = hin->key.peer->ld; + struct lightningd *ld = hin->key.channel->peer->ld; /* BOLT #4: * @@ -284,7 +286,7 @@ static void handle_localpay(struct htlc_in *hin, */ if (get_block_height(ld->topology) + ld->config.cltv_final > cltv_expiry) { - log_debug(hin->key.peer->log, + log_debug(hin->key.channel->log, "Expiry cltv too soon %u < %u + %u", cltv_expiry, get_block_height(ld->topology), @@ -314,7 +316,7 @@ fail: */ static void hout_subd_died(struct htlc_out *hout) { - log_debug(hout->key.peer->log, + log_debug(hout->key.channel->log, "Failing HTLC %"PRIu64" due to peer death", hout->key.id); @@ -329,6 +331,7 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds, { u16 failure_code; u8 *failurestr; + struct lightningd *ld = subd->ld; if (!fromwire_channel_offer_htlc_reply(msg, msg, NULL, &hout->key.id, @@ -347,17 +350,17 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds, onion_type_name(failure_code), (int)tal_len(failurestr), (const char *)failurestr); - payment_failed(hout->key.peer->ld, hout, localfail); + payment_failed(ld, hout, localfail); } else local_fail_htlc(hout->in, failure_code, - peer2channel(hout->key.peer)->scid); + hout->key.channel->scid); /* Prevent hout from being failed twice. */ tal_del_destructor(hout, hout_subd_died); tal_free(hout); return; } - if (find_htlc_out(&subd->ld->htlcs_out, hout->key.peer, hout->key.id) + if (find_htlc_out(&subd->ld->htlcs_out, hout->key.channel, hout->key.id) || hout->key.id == HTLC_INVALID_ID) { channel_internal_error(subd->channel, "Bad offer_htlc_reply HTLC id %"PRIu64 @@ -373,36 +376,35 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds, /* When channeld includes it in commitment, we'll make it persistent. */ } -enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv, +enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv, const struct sha256 *payment_hash, const u8 *onion_routing_packet, struct htlc_in *in, struct htlc_out **houtp) { struct htlc_out *hout; - struct channel *channel = peer2channel(out); u8 *msg; - if (!peer_can_add_htlc(out)) { + if (!channel_can_add_htlc(out)) { log_info(out->log, "Attempt to send HTLC but not ready (%s)", - peer_state_name(channel->state)); + channel_state_name(out)); return WIRE_UNKNOWN_NEXT_PEER; } - if (!channel->owner) { + if (!out->owner) { log_info(out->log, "Attempt to send HTLC but unowned (%s)", - peer_state_name(channel->state)); + channel_state_name(out)); return WIRE_TEMPORARY_CHANNEL_FAILURE; } /* Make peer's daemon own it, catch if it dies. */ - hout = new_htlc_out(channel->owner, out, amount, cltv, + hout = new_htlc_out(out->owner, out, amount, cltv, payment_hash, onion_routing_packet, in); tal_add_destructor(hout, hout_subd_died); msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash, onion_routing_packet); - subd_req(out->ld, channel->owner, take(msg), -1, 0, rcvd_htlc_reply, hout); + subd_req(out->peer->ld, out->owner, take(msg), -1, 0, rcvd_htlc_reply, hout); if (houtp) *houtp = hout; @@ -419,11 +421,11 @@ static void forward_htlc(struct htlc_in *hin, { enum onion_type failcode; u64 fee; - struct lightningd *ld = hin->key.peer->ld; - struct peer *next = peer_by_id(ld, next_hop); + struct lightningd *ld = hin->key.channel->peer->ld; + struct channel *next = active_channel_by_id(ld, next_hop); /* Unknown peer, or peer not ready. */ - if (!next || !peer2channel(next)->scid) { + if (!next || !next->scid) { local_fail_htlc(hin, WIRE_UNKNOWN_NEXT_PEER, NULL); return; } @@ -461,11 +463,11 @@ static void forward_htlc(struct htlc_in *hin, */ /* In our case, G = 1, so we need to expire it one after it's expiration. * But never offer an expired HTLC; that's dumb. */ - if (get_block_height(next->ld->topology) >= outgoing_cltv_value) { - log_debug(hin->key.peer->log, + if (get_block_height(ld->topology) >= outgoing_cltv_value) { + log_debug(hin->key.channel->log, "Expiry cltv %u too close to current %u", outgoing_cltv_value, - get_block_height(next->ld->topology)); + get_block_height(ld->topology)); failcode = WIRE_EXPIRY_TOO_SOON; goto fail; } @@ -476,13 +478,13 @@ static void forward_htlc(struct htlc_in *hin, * * 1. type: 21 (`expiry_too_far`) */ - if (get_block_height(next->ld->topology) - + next->ld->config.max_htlc_expiry < outgoing_cltv_value) { - log_debug(hin->key.peer->log, + if (get_block_height(ld->topology) + + ld->config.max_htlc_expiry < outgoing_cltv_value) { + log_debug(hin->key.channel->log, "Expiry cltv %u too far from current %u + max %u", outgoing_cltv_value, - get_block_height(next->ld->topology), - next->ld->config.max_htlc_expiry); + get_block_height(ld->topology), + ld->config.max_htlc_expiry); failcode = WIRE_EXPIRY_TOO_FAR; goto fail; } @@ -494,7 +496,7 @@ static void forward_htlc(struct htlc_in *hin, return; fail: - local_fail_htlc(hin, failcode, peer2channel(next)->scid); + local_fail_htlc(hin, failcode, next->scid); } /* Temporary information, while we resolve the next hop */ @@ -555,14 +557,14 @@ static bool peer_accepted_htlc(struct peer *peer, const tal_t *tmpctx = tal_tmpctx(peer); struct channel *channel = peer2channel(peer); - hin = find_htlc_in(&peer->ld->htlcs_in, peer, id); + hin = find_htlc_in(&peer->ld->htlcs_in, channel, id); if (!hin) { channel_internal_error(channel, "peer_got_revoke unknown htlc %"PRIu64, id); return false; } - if (!htlc_in_update_state(peer, hin, RCVD_ADD_ACK_REVOCATION)) + if (!htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION)) return false; /* BOLT #2: @@ -673,7 +675,7 @@ static bool peer_fulfilled_our_htlc(struct channel *channel, struct htlc_out *hout; struct peer *peer = channel2peer(channel); - hout = find_htlc_out(&peer->ld->htlcs_out, peer, fulfilled->id); + hout = find_htlc_out(&peer->ld->htlcs_out, channel, fulfilled->id); if (!hout) { channel_internal_error(channel, "fulfilled_our_htlc unknown htlc %"PRIu64, @@ -681,7 +683,7 @@ static bool peer_fulfilled_our_htlc(struct channel *channel, return false; } - if (!htlc_out_update_state(peer, hout, RCVD_REMOVE_COMMIT)) + if (!htlc_out_update_state(channel, hout, RCVD_REMOVE_COMMIT)) return false; fulfill_our_htlc_out(peer, hout, &fulfilled->payment_preimage); @@ -702,7 +704,7 @@ void onchain_fulfilled_htlc(struct channel *channel, for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); hout; hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { - if (hout->key.peer != channel2peer(channel)) + if (hout->key.channel != channel) continue; if (!structeq(&hout->payment_hash, &payment_hash)) @@ -724,7 +726,7 @@ static bool peer_failed_our_htlc(struct channel *channel, struct htlc_out *hout; struct peer *peer = channel2peer(channel); - hout = find_htlc_out(&peer->ld->htlcs_out, peer, failed->id); + hout = find_htlc_out(&peer->ld->htlcs_out, channel, failed->id); if (!hout) { channel_internal_error(channel, "failed_our_htlc unknown htlc %"PRIu64, @@ -732,7 +734,7 @@ static bool peer_failed_our_htlc(struct channel *channel, return false; } - if (!htlc_out_update_state(peer, hout, RCVD_REMOVE_COMMIT)) + if (!htlc_out_update_state(channel, hout, RCVD_REMOVE_COMMIT)) return false; hout->failcode = failed->malformed; @@ -762,7 +764,7 @@ struct htlc_out *find_htlc_out_by_ripemd(const struct channel *channel, hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { struct ripemd160 hash; - if (hout->key.peer != channel2peer(channel)) + if (hout->key.channel != channel) continue; ripemd160(&hash, @@ -789,11 +791,11 @@ void onchain_failed_our_htlc(const struct channel *channel, char *localfail = tal_fmt(channel, "%s: %s", onion_type_name(WIRE_PERMANENT_CHANNEL_FAILURE), why); - payment_failed(hout->key.peer->ld, hout, localfail); + payment_failed(hout->key.channel->peer->ld, hout, localfail); tal_free(localfail); } else local_fail_htlc(hout->in, WIRE_PERMANENT_CHANNEL_FAILURE, - peer2channel(hout->key.peer)->scid); + hout->key.channel->scid); } static void remove_htlc_in(struct peer *peer, struct htlc_in *hin) @@ -847,13 +849,13 @@ static bool update_in_htlc(struct peer *peer, u64 id, enum htlc_state newstate) struct htlc_in *hin; struct channel *channel = peer2channel(peer); - hin = find_htlc_in(&peer->ld->htlcs_in, peer, id); + hin = find_htlc_in(&peer->ld->htlcs_in, channel, id); if (!hin) { channel_internal_error(channel, "Can't find in HTLC %"PRIu64, id); return false; } - if (!htlc_in_update_state(peer, hin, newstate)) + if (!htlc_in_update_state(channel, hin, newstate)) return false; if (newstate == SENT_REMOVE_ACK_REVOCATION) @@ -867,7 +869,7 @@ static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate) struct htlc_out *hout; struct channel *channel = peer2channel(peer); - hout = find_htlc_out(&peer->ld->htlcs_out, peer, id); + hout = find_htlc_out(&peer->ld->htlcs_out, channel, id); if (!hout) { channel_internal_error(channel, "Can't find out HTLC %"PRIu64, id); return false; @@ -882,7 +884,7 @@ static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate) &hout->payment_hash); } - if (!htlc_out_update_state(peer, hout, newstate)) + if (!htlc_out_update_state(channel, hout, newstate)) return false; /* First transition into commitment; now it outlives peer. */ @@ -1034,7 +1036,7 @@ static bool channel_added_their_htlc(struct channel *channel, /* This stays around even if we fail it immediately: it *is* * part of the current commitment. */ - hin = new_htlc_in(channel, channel2peer(channel), added->id, added->amount_msat, + hin = new_htlc_in(channel, channel, added->id, added->amount_msat, added->cltv_expiry, &added->payment_hash, shared_secret, added->onion_routing_packet); @@ -1271,7 +1273,7 @@ void peer_got_revoke(struct channel *channel, const u8 *msg) /* These are all errors before finding next hop. */ assert(!(failcodes[i] & UPDATE)); - hin = find_htlc_in(&ld->htlcs_in, channel2peer(channel), changed[i].id); + hin = find_htlc_in(&ld->htlcs_in, channel, changed[i].id); local_fail_htlc(hin, failcodes[i], NULL); } wallet_channel_save(ld->wallet, channel); @@ -1356,6 +1358,8 @@ void peer_htlcs(const tal_t *ctx, struct htlc_out_map_iter outi; struct htlc_in *hin; struct htlc_out *hout; + struct channel *channel = peer2channel(peer); + struct lightningd *ld = channel->peer->ld; *htlcs = tal_arr(ctx, struct added_htlc, 0); *htlc_states = tal_arr(ctx, enum htlc_state, 0); @@ -1364,10 +1368,10 @@ void peer_htlcs(const tal_t *ctx, *failed_htlcs = tal_arr(ctx, const struct failed_htlc *, 0); *failed_sides = tal_arr(ctx, enum side, 0); - for (hin = htlc_in_map_first(&peer->ld->htlcs_in, &ini); + for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); hin; - hin = htlc_in_map_next(&peer->ld->htlcs_in, &ini)) { - if (hin->key.peer != peer) + hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { + if (hin->key.channel != channel) continue; add_htlc(htlcs, htlc_states, @@ -1383,10 +1387,10 @@ void peer_htlcs(const tal_t *ctx, fulfilled_htlcs, fulfilled_sides); } - for (hout = htlc_out_map_first(&peer->ld->htlcs_out, &outi); + for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); hout; - hout = htlc_out_map_next(&peer->ld->htlcs_out, &outi)) { - if (hout->key.peer != peer) + hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { + if (hout->key.channel != channel) continue; add_htlc(htlcs, htlc_states, @@ -1454,14 +1458,14 @@ void notify_new_block(struct lightningd *ld, u32 height) continue; /* Peer on chain already? */ - if (peer_on_chain(hout->key.peer)) + if (channel_on_chain(hout->key.channel)) continue; /* Peer already failed, or we hit it? */ - if (peer2channel(hout->key.peer)->error) + if (hout->key.channel->error) continue; - channel_fail_permanent(peer2channel(hout->key.peer), + channel_fail_permanent(hout->key.channel, "Offered HTLC %"PRIu64 " %s cltv %u hit deadline", hout->key.id, @@ -1489,7 +1493,7 @@ void notify_new_block(struct lightningd *ld, u32 height) for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); hin; hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { - struct channel *channel = peer2channel(hin->key.peer); + struct channel *channel = hin->key.channel; /* Not fulfilled? If overdue, that's their problem... */ if (!hin->preimage) diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index 70ebf76d6..47724a5cf 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -35,7 +35,7 @@ void peer_got_revoke(struct channel *channel, const u8 *msg); void update_per_commit_point(struct peer *peer, const struct pubkey *per_commitment_point); -enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv, +enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv, const struct sha256 *payment_hash, const u8 *onion_routing_packet, struct htlc_in *in, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 6cac1a1ed..bfb7b85b0 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1015,12 +1015,12 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) memset(&out.payment_hash, 'A', sizeof(struct sha256)); memset(&payment_key, 'B', sizeof(payment_key)); in.key.id = 42; - in.key.peer = peer; + in.key.channel = chan; in.msatoshi = 42; out.in = ∈ out.key.id = 1337; - out.key.peer = peer; + out.key.channel = chan; out.msatoshi = 41; /* Store the htlc_in */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 6b7d98ff6..7e18de02f 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1053,13 +1053,13 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, db_exec_prepared(wallet->db, stmt); } -static bool wallet_stmt2htlc_in(const struct channel *channel, +static bool wallet_stmt2htlc_in(struct channel *channel, sqlite3_stmt *stmt, struct htlc_in *in) { bool ok = true; in->dbid = sqlite3_column_int64(stmt, 0); in->key.id = sqlite3_column_int64(stmt, 1); - in->key.peer = channel2peer(channel); + in->key.channel = channel; in->msatoshi = sqlite3_column_int64(stmt, 2); in->cltv_expiry = sqlite3_column_int(stmt, 3); in->hstate = sqlite3_column_int(stmt, 4); @@ -1087,13 +1087,13 @@ static bool wallet_stmt2htlc_in(const struct channel *channel, return ok; } -static bool wallet_stmt2htlc_out(const struct channel *channel, +static bool wallet_stmt2htlc_out(struct channel *channel, sqlite3_stmt *stmt, struct htlc_out *out) { bool ok = true; out->dbid = sqlite3_column_int64(stmt, 0); out->key.id = sqlite3_column_int64(stmt, 1); - out->key.peer = channel2peer(channel); + out->key.channel = channel; out->msatoshi = sqlite3_column_int64(stmt, 2); out->cltv_expiry = sqlite3_column_int(stmt, 3); out->hstate = sqlite3_column_int(stmt, 4); diff --git a/wallet/wallet.h b/wallet/wallet.h index 9d37fcc4d..0fadfc58a 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -18,6 +18,7 @@ struct invoices; struct channel; struct lightningd; struct oneshot; +struct peer; struct pubkey; struct timers;