mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
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>
This commit is contained in:
parent
409fef582d
commit
cf7c399cc5
@ -20,6 +20,33 @@ void channel_set_owner(struct channel *channel, struct subd *owner)
|
|||||||
|
|
||||||
static void destroy_channel(struct channel *channel)
|
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. */
|
/* Free any old owner still hanging around. */
|
||||||
channel_set_owner(channel, NULL);
|
channel_set_owner(channel, NULL);
|
||||||
|
|
||||||
@ -112,6 +139,15 @@ struct channel *peer_active_channel(struct peer *peer)
|
|||||||
return NULL;
|
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,
|
void channel_set_state(struct channel *channel,
|
||||||
enum peer_state old_state,
|
enum peer_state old_state,
|
||||||
enum peer_state state)
|
enum peer_state state)
|
||||||
|
@ -116,6 +116,9 @@ struct peer *channel2peer(const struct channel *channel);
|
|||||||
/* Find a channel which is not onchain, if any */
|
/* Find a channel which is not onchain, if any */
|
||||||
struct channel *peer_active_channel(struct peer *peer);
|
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)
|
static inline bool channel_can_add_htlc(const struct channel *channel)
|
||||||
{
|
{
|
||||||
return channel->state == CHANNELD_NORMAL;
|
return channel->state == CHANNELD_NORMAL;
|
||||||
|
@ -13,18 +13,18 @@ size_t hash_htlc_key(const struct htlc_key *k)
|
|||||||
{
|
{
|
||||||
struct siphash24_ctx ctx;
|
struct siphash24_ctx ctx;
|
||||||
siphash24_init(&ctx, siphash_seed());
|
siphash24_init(&ctx, siphash_seed());
|
||||||
/* peer doesn't move while in this hash, so we just hash pointer. */
|
/* channel doesn't move while in this hash, so we just hash pointer. */
|
||||||
siphash24_update(&ctx, &k->peer, sizeof(k->peer));
|
siphash24_update(&ctx, &k->channel, sizeof(k->channel));
|
||||||
siphash24_u64(&ctx, k->id);
|
siphash24_u64(&ctx, k->id);
|
||||||
|
|
||||||
return siphash24_done(&ctx);
|
return siphash24_done(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct htlc_in *find_htlc_in(const struct htlc_in_map *map,
|
struct htlc_in *find_htlc_in(const struct htlc_in_map *map,
|
||||||
const struct peer *peer,
|
const struct channel *channel,
|
||||||
u64 htlc_id)
|
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);
|
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,
|
struct htlc_out *find_htlc_out(const struct htlc_out_map *map,
|
||||||
const struct peer *peer,
|
const struct channel *channel,
|
||||||
u64 htlc_id)
|
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);
|
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 htlc_in *new_htlc_in(const tal_t *ctx,
|
||||||
struct peer *peer, u64 id,
|
struct channel *channel, u64 id,
|
||||||
u64 msatoshi, u32 cltv_expiry,
|
u64 msatoshi, u32 cltv_expiry,
|
||||||
const struct sha256 *payment_hash,
|
const struct sha256 *payment_hash,
|
||||||
const struct secret *shared_secret,
|
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);
|
struct htlc_in *hin = tal(ctx, struct htlc_in);
|
||||||
|
|
||||||
hin->dbid = 0;
|
hin->dbid = 0;
|
||||||
hin->key.peer = peer;
|
hin->key.channel = channel;
|
||||||
hin->key.id = id;
|
hin->key.id = id;
|
||||||
hin->msatoshi = msatoshi;
|
hin->msatoshi = msatoshi;
|
||||||
hin->cltv_expiry = cltv_expiry;
|
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! */
|
/* You need to set the ID, then connect_htlc_out this! */
|
||||||
struct htlc_out *new_htlc_out(const tal_t *ctx,
|
struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||||
struct peer *peer,
|
struct channel *channel,
|
||||||
u64 msatoshi, u32 cltv_expiry,
|
u64 msatoshi, u32 cltv_expiry,
|
||||||
const struct sha256 *payment_hash,
|
const struct sha256 *payment_hash,
|
||||||
const u8 *onion_routing_packet,
|
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 */
|
/* Mark this as an as of now unsaved HTLC */
|
||||||
hout->dbid = 0;
|
hout->dbid = 0;
|
||||||
|
|
||||||
hout->key.peer = peer;
|
hout->key.channel = channel;
|
||||||
hout->key.id = HTLC_INVALID_ID;
|
hout->key.id = HTLC_INVALID_ID;
|
||||||
hout->msatoshi = msatoshi;
|
hout->msatoshi = msatoshi;
|
||||||
hout->cltv_expiry = cltv_expiry;
|
hout->cltv_expiry = cltv_expiry;
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#include <common/sphinx.h>
|
#include <common/sphinx.h>
|
||||||
#include <wire/gen_onion_wire.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 htlc_key {
|
||||||
struct peer *peer;
|
struct channel *channel;
|
||||||
u64 id;
|
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)
|
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,
|
static inline bool htlc_out_eq(const struct htlc_out *out,
|
||||||
const struct htlc_key *k)
|
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);
|
htlc_out_map);
|
||||||
|
|
||||||
struct htlc_in *find_htlc_in(const struct htlc_in_map *map,
|
struct htlc_in *find_htlc_in(const struct htlc_in_map *map,
|
||||||
const struct peer *peer,
|
const struct channel *channel,
|
||||||
u64 htlc_id);
|
u64 htlc_id);
|
||||||
|
|
||||||
struct htlc_out *find_htlc_out(const struct htlc_out_map *map,
|
struct htlc_out *find_htlc_out(const struct htlc_out_map *map,
|
||||||
const struct peer *peer,
|
const struct channel *channel,
|
||||||
u64 htlc_id);
|
u64 htlc_id);
|
||||||
|
|
||||||
/* You still need to connect_htlc_in this! */
|
/* You still need to connect_htlc_in this! */
|
||||||
struct htlc_in *new_htlc_in(const tal_t *ctx,
|
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,
|
u64 msatoshi, u32 cltv_expiry,
|
||||||
const struct sha256 *payment_hash,
|
const struct sha256 *payment_hash,
|
||||||
const struct secret *shared_secret,
|
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! */
|
/* You need to set the ID, then connect_htlc_out this! */
|
||||||
struct htlc_out *new_htlc_out(const tal_t *ctx,
|
struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||||
struct peer *peer,
|
struct channel *channel,
|
||||||
u64 msatoshi, u32 cltv_expiry,
|
u64 msatoshi, u32 cltv_expiry,
|
||||||
const struct sha256 *payment_hash,
|
const struct sha256 *payment_hash,
|
||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
|
@ -395,7 +395,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
tal_count(path_secrets),
|
tal_count(path_secrets),
|
||||||
hout->failuremsg);
|
hout->failuremsg);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
log_info(hout->key.peer->log,
|
log_info(hout->key.channel->log,
|
||||||
"htlc %"PRIu64" failed with bad reply (%s)",
|
"htlc %"PRIu64" failed with bad reply (%s)",
|
||||||
hout->key.id,
|
hout->key.id,
|
||||||
tal_hex(ltmp, hout->failuremsg));
|
tal_hex(ltmp, hout->failuremsg));
|
||||||
@ -403,7 +403,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
fail = NULL;
|
fail = NULL;
|
||||||
failcode = WIRE_PERMANENT_NODE_FAILURE;
|
failcode = WIRE_PERMANENT_NODE_FAILURE;
|
||||||
/* Select a channel to mark unroutable by random */
|
/* 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,
|
ld->gossip,
|
||||||
payment->route_channels);
|
payment->route_channels);
|
||||||
/* Can now retry; we selected a channel to mark
|
/* 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;
|
report_to_gossipd = false;
|
||||||
} else {
|
} else {
|
||||||
failcode = fromwire_peektype(reply->msg);
|
failcode = fromwire_peektype(reply->msg);
|
||||||
log_info(hout->key.peer->log,
|
log_info(hout->key.channel->log,
|
||||||
"htlc %"PRIu64" "
|
"htlc %"PRIu64" "
|
||||||
"failed from %ith node "
|
"failed from %ith node "
|
||||||
"with code 0x%04x (%s)",
|
"with code 0x%04x (%s)",
|
||||||
@ -455,7 +455,6 @@ static bool send_payment(struct command *cmd,
|
|||||||
const struct sha256 *rhash,
|
const struct sha256 *rhash,
|
||||||
const struct route_hop *route)
|
const struct route_hop *route)
|
||||||
{
|
{
|
||||||
struct peer *peer;
|
|
||||||
const u8 *onion;
|
const u8 *onion;
|
||||||
u8 sessionkey[32];
|
u8 sessionkey[32];
|
||||||
unsigned int base_expiry;
|
unsigned int base_expiry;
|
||||||
@ -471,6 +470,7 @@ static bool send_payment(struct command *cmd,
|
|||||||
struct htlc_out *hout;
|
struct htlc_out *hout;
|
||||||
struct short_channel_id *channels;
|
struct short_channel_id *channels;
|
||||||
struct routing_failure *fail;
|
struct routing_failure *fail;
|
||||||
|
struct channel *channel;
|
||||||
|
|
||||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||||
base_expiry = get_block_height(cmd->ld->topology) + 1;
|
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");
|
log_add(cmd->ld->log, "... retrying");
|
||||||
}
|
}
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, &ids[0]);
|
channel = active_channel_by_id(cmd->ld, &ids[0]);
|
||||||
if (!peer) {
|
if (!channel) {
|
||||||
/* Report routing failure to gossipd */
|
/* Report routing failure to gossipd */
|
||||||
fail = immediate_routing_failure(cmd, cmd->ld,
|
fail = immediate_routing_failure(cmd, cmd->ld,
|
||||||
WIRE_UNKNOWN_NEXT_PEER,
|
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",
|
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %u",
|
||||||
route[0].amount, n_hops, route[n_hops-1].amount);
|
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,
|
base_expiry + route[0].delay,
|
||||||
rhash, onion, NULL, &hout);
|
rhash, onion, NULL, &hout);
|
||||||
if (failcode) {
|
if (failcode) {
|
||||||
|
@ -96,32 +96,6 @@ static void peer_set_owner(struct peer *peer, struct subd *owner)
|
|||||||
|
|
||||||
static void destroy_peer(struct peer *peer)
|
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);
|
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);
|
for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
|
||||||
hin;
|
hin;
|
||||||
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
||||||
if (hin->key.peer != channel2peer(channel))
|
if (hin->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* BOLT #5:
|
/* 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);
|
for (hout = htlc_out_map_first(&ld->htlcs_out, &outi);
|
||||||
hout;
|
hout;
|
||||||
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||||
if (channel && hout->key.peer != channel2peer(channel))
|
if (channel && hout->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
tal_free(hout);
|
tal_free(hout);
|
||||||
deleted = true;
|
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);
|
for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
|
||||||
hin;
|
hin;
|
||||||
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
||||||
if (channel && hin->key.peer != channel2peer(channel))
|
if (channel && hin->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
tal_free(hin);
|
tal_free(hin);
|
||||||
deleted = true;
|
deleted = true;
|
||||||
|
@ -22,12 +22,11 @@
|
|||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <wire/gen_onion_wire.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,
|
enum htlc_state oldstate, enum htlc_state newstate,
|
||||||
u64 htlc_id, const char *dir)
|
u64 htlc_id, const char *dir)
|
||||||
{
|
{
|
||||||
enum htlc_state expected = oldstate + 1;
|
enum htlc_state expected = oldstate + 1;
|
||||||
struct channel *channel = peer2channel(peer);
|
|
||||||
|
|
||||||
/* We never get told about RCVD_REMOVE_HTLC, so skip over that
|
/* We never get told about RCVD_REMOVE_HTLC, so skip over that
|
||||||
* (we initialize in SENT_ADD_HTLC / RCVD_ADD_COMMIT, so those
|
* (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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug(peer->log, "HTLC %s %"PRIu64" %s->%s",
|
log_debug(channel->log, "HTLC %s %"PRIu64" %s->%s",
|
||||||
dir, htlc_id,
|
dir, htlc_id,
|
||||||
htlc_state_name(oldstate), htlc_state_name(newstate));
|
htlc_state_name(oldstate), htlc_state_name(newstate));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool htlc_in_update_state(struct peer *peer,
|
static bool htlc_in_update_state(struct channel *channel,
|
||||||
struct htlc_in *hin,
|
struct htlc_in *hin,
|
||||||
enum htlc_state newstate)
|
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;
|
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;
|
hin->hstate = newstate;
|
||||||
htlc_in_check(hin, __func__);
|
htlc_in_check(hin, __func__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool htlc_out_update_state(struct peer *peer,
|
static bool htlc_out_update_state(struct channel *channel,
|
||||||
struct htlc_out *hout,
|
struct htlc_out *hout,
|
||||||
enum htlc_state newstate)
|
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;
|
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;
|
hout->hstate = newstate;
|
||||||
htlc_out_check(hout, __func__);
|
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));
|
memset(&hin->failoutchannel, 0, sizeof(hin->failoutchannel));
|
||||||
|
|
||||||
/* We update state now to signal it's in progress, for persistence. */
|
/* 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. */
|
/* Tell peer, if we can. */
|
||||||
if (!peer2channel(hin->key.peer)->owner)
|
if (!hin->key.channel->owner)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
subd_send_msg(peer2channel(hin->key.peer)->owner,
|
subd_send_msg(hin->key.channel->owner,
|
||||||
take(towire_channel_fail_htlc(hin,
|
take(towire_channel_fail_htlc(hin,
|
||||||
hin->key.id,
|
hin->key.id,
|
||||||
hin->failuremsg,
|
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,
|
static void local_fail_htlc(struct htlc_in *hin, enum onion_type failcode,
|
||||||
const struct short_channel_id *out_channel)
|
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));
|
hin->key.id, failcode, onion_type_name(failcode));
|
||||||
|
|
||||||
fail_in_htlc(hin, failcode, NULL, out_channel);
|
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);
|
assert(hout->failcode || hout->failuremsg);
|
||||||
if (hout->in) {
|
if (hout->in) {
|
||||||
fail_in_htlc(hout->in, hout->failcode, hout->failuremsg,
|
fail_in_htlc(hout->in, hout->failcode, hout->failuremsg,
|
||||||
peer2channel(hout->key.peer)->scid);
|
hout->key.channel->scid);
|
||||||
} else {
|
} 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)
|
if (amt_in_htlc - fee >= amt_to_forward)
|
||||||
return true;
|
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,
|
" %"PRIu64" in, %"PRIu64" out, fee reqd %"PRIu64,
|
||||||
hin->key.id, amt_in_htlc, amt_to_forward, fee);
|
hin->key.id, amt_in_htlc, amt_to_forward, fee);
|
||||||
return false;
|
return false;
|
||||||
@ -185,7 +187,7 @@ static bool check_cltv(struct htlc_in *hin,
|
|||||||
{
|
{
|
||||||
if (cltv_expiry - delta >= outgoing_cltv_value)
|
if (cltv_expiry - delta >= outgoing_cltv_value)
|
||||||
return true;
|
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",
|
" %u in, %u out, delta reqd %u",
|
||||||
hin->key.id, cltv_expiry, outgoing_cltv_value, delta);
|
hin->key.id, cltv_expiry, outgoing_cltv_value, delta);
|
||||||
return false;
|
return false;
|
||||||
@ -199,21 +201,21 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
|
|||||||
htlc_in_check(hin, __func__);
|
htlc_in_check(hin, __func__);
|
||||||
|
|
||||||
/* We update state now to signal it's in progress, for persistence. */
|
/* 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
|
/* No owner? We'll either send to channeld in peer_htlcs, or
|
||||||
* onchaind in onchaind_tell_fulfill. */
|
* onchaind in onchaind_tell_fulfill. */
|
||||||
if (!peer2channel(hin->key.peer)->owner) {
|
if (!hin->key.channel->owner) {
|
||||||
log_debug(hin->key.peer->log, "HTLC fulfilled, but no owner.");
|
log_debug(hin->key.channel->log, "HTLC fulfilled, but no owner.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer_on_chain(hin->key.peer)) {
|
if (channel_on_chain(hin->key.channel)) {
|
||||||
msg = towire_onchain_known_preimage(hin, preimage);
|
msg = towire_onchain_known_preimage(hin, preimage);
|
||||||
} else {
|
} else {
|
||||||
msg = towire_channel_fulfill_htlc(hin, hin->key.id, preimage);
|
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,
|
static void handle_localpay(struct htlc_in *hin,
|
||||||
@ -224,7 +226,7 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
{
|
{
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
const struct invoice *invoice;
|
const struct invoice *invoice;
|
||||||
struct lightningd *ld = hin->key.peer->ld;
|
struct lightningd *ld = hin->key.channel->peer->ld;
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
@ -284,7 +286,7 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
*/
|
*/
|
||||||
if (get_block_height(ld->topology) + ld->config.cltv_final
|
if (get_block_height(ld->topology) + ld->config.cltv_final
|
||||||
> cltv_expiry) {
|
> cltv_expiry) {
|
||||||
log_debug(hin->key.peer->log,
|
log_debug(hin->key.channel->log,
|
||||||
"Expiry cltv too soon %u < %u + %u",
|
"Expiry cltv too soon %u < %u + %u",
|
||||||
cltv_expiry,
|
cltv_expiry,
|
||||||
get_block_height(ld->topology),
|
get_block_height(ld->topology),
|
||||||
@ -314,7 +316,7 @@ fail:
|
|||||||
*/
|
*/
|
||||||
static void hout_subd_died(struct htlc_out *hout)
|
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",
|
"Failing HTLC %"PRIu64" due to peer death",
|
||||||
hout->key.id);
|
hout->key.id);
|
||||||
|
|
||||||
@ -329,6 +331,7 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds,
|
|||||||
{
|
{
|
||||||
u16 failure_code;
|
u16 failure_code;
|
||||||
u8 *failurestr;
|
u8 *failurestr;
|
||||||
|
struct lightningd *ld = subd->ld;
|
||||||
|
|
||||||
if (!fromwire_channel_offer_htlc_reply(msg, msg, NULL,
|
if (!fromwire_channel_offer_htlc_reply(msg, msg, NULL,
|
||||||
&hout->key.id,
|
&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),
|
onion_type_name(failure_code),
|
||||||
(int)tal_len(failurestr),
|
(int)tal_len(failurestr),
|
||||||
(const char *)failurestr);
|
(const char *)failurestr);
|
||||||
payment_failed(hout->key.peer->ld, hout, localfail);
|
payment_failed(ld, hout, localfail);
|
||||||
} else
|
} else
|
||||||
local_fail_htlc(hout->in, failure_code,
|
local_fail_htlc(hout->in, failure_code,
|
||||||
peer2channel(hout->key.peer)->scid);
|
hout->key.channel->scid);
|
||||||
/* Prevent hout from being failed twice. */
|
/* Prevent hout from being failed twice. */
|
||||||
tal_del_destructor(hout, hout_subd_died);
|
tal_del_destructor(hout, hout_subd_died);
|
||||||
tal_free(hout);
|
tal_free(hout);
|
||||||
return;
|
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) {
|
|| hout->key.id == HTLC_INVALID_ID) {
|
||||||
channel_internal_error(subd->channel,
|
channel_internal_error(subd->channel,
|
||||||
"Bad offer_htlc_reply HTLC id %"PRIu64
|
"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. */
|
/* 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 struct sha256 *payment_hash,
|
||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
struct htlc_out **houtp)
|
struct htlc_out **houtp)
|
||||||
{
|
{
|
||||||
struct htlc_out *hout;
|
struct htlc_out *hout;
|
||||||
struct channel *channel = peer2channel(out);
|
|
||||||
u8 *msg;
|
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)",
|
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;
|
return WIRE_UNKNOWN_NEXT_PEER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->owner) {
|
if (!out->owner) {
|
||||||
log_info(out->log, "Attempt to send HTLC but unowned (%s)",
|
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;
|
return WIRE_TEMPORARY_CHANNEL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make peer's daemon own it, catch if it dies. */
|
/* 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);
|
payment_hash, onion_routing_packet, in);
|
||||||
tal_add_destructor(hout, hout_subd_died);
|
tal_add_destructor(hout, hout_subd_died);
|
||||||
|
|
||||||
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
|
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
|
||||||
onion_routing_packet);
|
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)
|
if (houtp)
|
||||||
*houtp = hout;
|
*houtp = hout;
|
||||||
@ -419,11 +421,11 @@ static void forward_htlc(struct htlc_in *hin,
|
|||||||
{
|
{
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
u64 fee;
|
u64 fee;
|
||||||
struct lightningd *ld = hin->key.peer->ld;
|
struct lightningd *ld = hin->key.channel->peer->ld;
|
||||||
struct peer *next = peer_by_id(ld, next_hop);
|
struct channel *next = active_channel_by_id(ld, next_hop);
|
||||||
|
|
||||||
/* Unknown peer, or peer not ready. */
|
/* Unknown peer, or peer not ready. */
|
||||||
if (!next || !peer2channel(next)->scid) {
|
if (!next || !next->scid) {
|
||||||
local_fail_htlc(hin, WIRE_UNKNOWN_NEXT_PEER, NULL);
|
local_fail_htlc(hin, WIRE_UNKNOWN_NEXT_PEER, NULL);
|
||||||
return;
|
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.
|
/* 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. */
|
* But never offer an expired HTLC; that's dumb. */
|
||||||
if (get_block_height(next->ld->topology) >= outgoing_cltv_value) {
|
if (get_block_height(ld->topology) >= outgoing_cltv_value) {
|
||||||
log_debug(hin->key.peer->log,
|
log_debug(hin->key.channel->log,
|
||||||
"Expiry cltv %u too close to current %u",
|
"Expiry cltv %u too close to current %u",
|
||||||
outgoing_cltv_value,
|
outgoing_cltv_value,
|
||||||
get_block_height(next->ld->topology));
|
get_block_height(ld->topology));
|
||||||
failcode = WIRE_EXPIRY_TOO_SOON;
|
failcode = WIRE_EXPIRY_TOO_SOON;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -476,13 +478,13 @@ static void forward_htlc(struct htlc_in *hin,
|
|||||||
*
|
*
|
||||||
* 1. type: 21 (`expiry_too_far`)
|
* 1. type: 21 (`expiry_too_far`)
|
||||||
*/
|
*/
|
||||||
if (get_block_height(next->ld->topology)
|
if (get_block_height(ld->topology)
|
||||||
+ next->ld->config.max_htlc_expiry < outgoing_cltv_value) {
|
+ ld->config.max_htlc_expiry < outgoing_cltv_value) {
|
||||||
log_debug(hin->key.peer->log,
|
log_debug(hin->key.channel->log,
|
||||||
"Expiry cltv %u too far from current %u + max %u",
|
"Expiry cltv %u too far from current %u + max %u",
|
||||||
outgoing_cltv_value,
|
outgoing_cltv_value,
|
||||||
get_block_height(next->ld->topology),
|
get_block_height(ld->topology),
|
||||||
next->ld->config.max_htlc_expiry);
|
ld->config.max_htlc_expiry);
|
||||||
failcode = WIRE_EXPIRY_TOO_FAR;
|
failcode = WIRE_EXPIRY_TOO_FAR;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -494,7 +496,7 @@ static void forward_htlc(struct htlc_in *hin,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
local_fail_htlc(hin, failcode, peer2channel(next)->scid);
|
local_fail_htlc(hin, failcode, next->scid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary information, while we resolve the next hop */
|
/* 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);
|
const tal_t *tmpctx = tal_tmpctx(peer);
|
||||||
struct channel *channel = peer2channel(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) {
|
if (!hin) {
|
||||||
channel_internal_error(channel,
|
channel_internal_error(channel,
|
||||||
"peer_got_revoke unknown htlc %"PRIu64, id);
|
"peer_got_revoke unknown htlc %"PRIu64, id);
|
||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
@ -673,7 +675,7 @@ static bool peer_fulfilled_our_htlc(struct channel *channel,
|
|||||||
struct htlc_out *hout;
|
struct htlc_out *hout;
|
||||||
struct peer *peer = channel2peer(channel);
|
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) {
|
if (!hout) {
|
||||||
channel_internal_error(channel,
|
channel_internal_error(channel,
|
||||||
"fulfilled_our_htlc unknown htlc %"PRIu64,
|
"fulfilled_our_htlc unknown htlc %"PRIu64,
|
||||||
@ -681,7 +683,7 @@ static bool peer_fulfilled_our_htlc(struct channel *channel,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!htlc_out_update_state(peer, hout, RCVD_REMOVE_COMMIT))
|
if (!htlc_out_update_state(channel, hout, RCVD_REMOVE_COMMIT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fulfill_our_htlc_out(peer, hout, &fulfilled->payment_preimage);
|
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);
|
for (hout = htlc_out_map_first(&ld->htlcs_out, &outi);
|
||||||
hout;
|
hout;
|
||||||
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||||
if (hout->key.peer != channel2peer(channel))
|
if (hout->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!structeq(&hout->payment_hash, &payment_hash))
|
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 htlc_out *hout;
|
||||||
struct peer *peer = channel2peer(channel);
|
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) {
|
if (!hout) {
|
||||||
channel_internal_error(channel,
|
channel_internal_error(channel,
|
||||||
"failed_our_htlc unknown htlc %"PRIu64,
|
"failed_our_htlc unknown htlc %"PRIu64,
|
||||||
@ -732,7 +734,7 @@ static bool peer_failed_our_htlc(struct channel *channel,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!htlc_out_update_state(peer, hout, RCVD_REMOVE_COMMIT))
|
if (!htlc_out_update_state(channel, hout, RCVD_REMOVE_COMMIT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
hout->failcode = failed->malformed;
|
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)) {
|
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||||
struct ripemd160 hash;
|
struct ripemd160 hash;
|
||||||
|
|
||||||
if (hout->key.peer != channel2peer(channel))
|
if (hout->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ripemd160(&hash,
|
ripemd160(&hash,
|
||||||
@ -789,11 +791,11 @@ void onchain_failed_our_htlc(const struct channel *channel,
|
|||||||
char *localfail = tal_fmt(channel, "%s: %s",
|
char *localfail = tal_fmt(channel, "%s: %s",
|
||||||
onion_type_name(WIRE_PERMANENT_CHANNEL_FAILURE),
|
onion_type_name(WIRE_PERMANENT_CHANNEL_FAILURE),
|
||||||
why);
|
why);
|
||||||
payment_failed(hout->key.peer->ld, hout, localfail);
|
payment_failed(hout->key.channel->peer->ld, hout, localfail);
|
||||||
tal_free(localfail);
|
tal_free(localfail);
|
||||||
} else
|
} else
|
||||||
local_fail_htlc(hout->in, WIRE_PERMANENT_CHANNEL_FAILURE,
|
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)
|
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 htlc_in *hin;
|
||||||
struct channel *channel = peer2channel(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) {
|
if (!hin) {
|
||||||
channel_internal_error(channel, "Can't find in HTLC %"PRIu64, id);
|
channel_internal_error(channel, "Can't find in HTLC %"PRIu64, id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!htlc_in_update_state(peer, hin, newstate))
|
if (!htlc_in_update_state(channel, hin, newstate))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (newstate == SENT_REMOVE_ACK_REVOCATION)
|
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 htlc_out *hout;
|
||||||
struct channel *channel = peer2channel(peer);
|
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) {
|
if (!hout) {
|
||||||
channel_internal_error(channel, "Can't find out HTLC %"PRIu64, id);
|
channel_internal_error(channel, "Can't find out HTLC %"PRIu64, id);
|
||||||
return false;
|
return false;
|
||||||
@ -882,7 +884,7 @@ static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
|
|||||||
&hout->payment_hash);
|
&hout->payment_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!htlc_out_update_state(peer, hout, newstate))
|
if (!htlc_out_update_state(channel, hout, newstate))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* First transition into commitment; now it outlives peer. */
|
/* 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*
|
/* This stays around even if we fail it immediately: it *is*
|
||||||
* part of the current commitment. */
|
* 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,
|
added->cltv_expiry, &added->payment_hash,
|
||||||
shared_secret, added->onion_routing_packet);
|
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. */
|
/* These are all errors before finding next hop. */
|
||||||
assert(!(failcodes[i] & UPDATE));
|
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);
|
local_fail_htlc(hin, failcodes[i], NULL);
|
||||||
}
|
}
|
||||||
wallet_channel_save(ld->wallet, channel);
|
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_out_map_iter outi;
|
||||||
struct htlc_in *hin;
|
struct htlc_in *hin;
|
||||||
struct htlc_out *hout;
|
struct htlc_out *hout;
|
||||||
|
struct channel *channel = peer2channel(peer);
|
||||||
|
struct lightningd *ld = channel->peer->ld;
|
||||||
|
|
||||||
*htlcs = tal_arr(ctx, struct added_htlc, 0);
|
*htlcs = tal_arr(ctx, struct added_htlc, 0);
|
||||||
*htlc_states = tal_arr(ctx, enum htlc_state, 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_htlcs = tal_arr(ctx, const struct failed_htlc *, 0);
|
||||||
*failed_sides = tal_arr(ctx, enum side, 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;
|
||||||
hin = htlc_in_map_next(&peer->ld->htlcs_in, &ini)) {
|
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
||||||
if (hin->key.peer != peer)
|
if (hin->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
add_htlc(htlcs, htlc_states,
|
add_htlc(htlcs, htlc_states,
|
||||||
@ -1383,10 +1387,10 @@ void peer_htlcs(const tal_t *ctx,
|
|||||||
fulfilled_htlcs, fulfilled_sides);
|
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;
|
||||||
hout = htlc_out_map_next(&peer->ld->htlcs_out, &outi)) {
|
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||||
if (hout->key.peer != peer)
|
if (hout->key.channel != channel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
add_htlc(htlcs, htlc_states,
|
add_htlc(htlcs, htlc_states,
|
||||||
@ -1454,14 +1458,14 @@ void notify_new_block(struct lightningd *ld, u32 height)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Peer on chain already? */
|
/* Peer on chain already? */
|
||||||
if (peer_on_chain(hout->key.peer))
|
if (channel_on_chain(hout->key.channel))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Peer already failed, or we hit it? */
|
/* Peer already failed, or we hit it? */
|
||||||
if (peer2channel(hout->key.peer)->error)
|
if (hout->key.channel->error)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
channel_fail_permanent(peer2channel(hout->key.peer),
|
channel_fail_permanent(hout->key.channel,
|
||||||
"Offered HTLC %"PRIu64
|
"Offered HTLC %"PRIu64
|
||||||
" %s cltv %u hit deadline",
|
" %s cltv %u hit deadline",
|
||||||
hout->key.id,
|
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);
|
for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
|
||||||
hin;
|
hin;
|
||||||
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
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... */
|
/* Not fulfilled? If overdue, that's their problem... */
|
||||||
if (!hin->preimage)
|
if (!hin->preimage)
|
||||||
|
@ -35,7 +35,7 @@ void peer_got_revoke(struct channel *channel, const u8 *msg);
|
|||||||
void update_per_commit_point(struct peer *peer,
|
void update_per_commit_point(struct peer *peer,
|
||||||
const struct pubkey *per_commitment_point);
|
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 struct sha256 *payment_hash,
|
||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
|
@ -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(&out.payment_hash, 'A', sizeof(struct sha256));
|
||||||
memset(&payment_key, 'B', sizeof(payment_key));
|
memset(&payment_key, 'B', sizeof(payment_key));
|
||||||
in.key.id = 42;
|
in.key.id = 42;
|
||||||
in.key.peer = peer;
|
in.key.channel = chan;
|
||||||
in.msatoshi = 42;
|
in.msatoshi = 42;
|
||||||
|
|
||||||
out.in = ∈
|
out.in = ∈
|
||||||
out.key.id = 1337;
|
out.key.id = 1337;
|
||||||
out.key.peer = peer;
|
out.key.channel = chan;
|
||||||
out.msatoshi = 41;
|
out.msatoshi = 41;
|
||||||
|
|
||||||
/* Store the htlc_in */
|
/* Store the htlc_in */
|
||||||
|
@ -1053,13 +1053,13 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
|
|||||||
db_exec_prepared(wallet->db, stmt);
|
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)
|
sqlite3_stmt *stmt, struct htlc_in *in)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
in->dbid = sqlite3_column_int64(stmt, 0);
|
in->dbid = sqlite3_column_int64(stmt, 0);
|
||||||
in->key.id = sqlite3_column_int64(stmt, 1);
|
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->msatoshi = sqlite3_column_int64(stmt, 2);
|
||||||
in->cltv_expiry = sqlite3_column_int(stmt, 3);
|
in->cltv_expiry = sqlite3_column_int(stmt, 3);
|
||||||
in->hstate = sqlite3_column_int(stmt, 4);
|
in->hstate = sqlite3_column_int(stmt, 4);
|
||||||
@ -1087,13 +1087,13 @@ static bool wallet_stmt2htlc_in(const struct channel *channel,
|
|||||||
|
|
||||||
return ok;
|
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)
|
sqlite3_stmt *stmt, struct htlc_out *out)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
out->dbid = sqlite3_column_int64(stmt, 0);
|
out->dbid = sqlite3_column_int64(stmt, 0);
|
||||||
out->key.id = sqlite3_column_int64(stmt, 1);
|
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->msatoshi = sqlite3_column_int64(stmt, 2);
|
||||||
out->cltv_expiry = sqlite3_column_int(stmt, 3);
|
out->cltv_expiry = sqlite3_column_int(stmt, 3);
|
||||||
out->hstate = sqlite3_column_int(stmt, 4);
|
out->hstate = sqlite3_column_int(stmt, 4);
|
||||||
|
@ -18,6 +18,7 @@ struct invoices;
|
|||||||
struct channel;
|
struct channel;
|
||||||
struct lightningd;
|
struct lightningd;
|
||||||
struct oneshot;
|
struct oneshot;
|
||||||
|
struct peer;
|
||||||
struct pubkey;
|
struct pubkey;
|
||||||
struct timers;
|
struct timers;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user