Browse Source

htlc: keep channel pointer, not peer pointer.

And move the no-remaining-htlcs check from the peer destructor to the
channel destructor.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
cf7c399cc5
  1. 36
      lightningd/channel.c
  2. 3
      lightningd/channel.h
  3. 20
      lightningd/htlc_end.c
  4. 16
      lightningd/htlc_end.h
  5. 14
      lightningd/pay.c
  6. 32
      lightningd/peer_control.c
  7. 152
      lightningd/peer_htlcs.c
  8. 2
      lightningd/peer_htlcs.h
  9. 4
      wallet/test/run-wallet.c
  10. 8
      wallet/wallet.c
  11. 1
      wallet/wallet.h

36
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)

3
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;

20
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;

16
lightningd/htlc_end.h

@ -7,9 +7,9 @@
#include <common/sphinx.h>
#include <wire/gen_onion_wire.h>
/* 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,

14
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) {

32
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;

152
lightningd/peer_htlcs.c

@ -22,12 +22,11 @@
#include <wallet/wallet.h>
#include <wire/gen_onion_wire.h>
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)

2
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,

4
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 = &in;
out.key.id = 1337;
out.key.peer = peer;
out.key.channel = chan;
out.msatoshi = 41;
/* Store the htlc_in */

8
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);

1
wallet/wallet.h

@ -18,6 +18,7 @@ struct invoices;
struct channel;
struct lightningd;
struct oneshot;
struct peer;
struct pubkey;
struct timers;

Loading…
Cancel
Save