Browse Source

lightningd: rename htlc_in and htlc_out failuremsg fields to failonion.

This is clearer, especially when we also deal with raw not-yet-onion-wrapped
failure messages.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
b84b4b4695
  1. 32
      lightningd/htlc_end.c
  2. 4
      lightningd/htlc_end.h
  3. 20
      lightningd/pay.c
  4. 50
      lightningd/peer_htlcs.c
  5. 3
      wallet/db.c
  6. 18
      wallet/wallet.c
  7. 6
      wallet/wallet.h

32
lightningd/htlc_end.c

@ -98,11 +98,11 @@ struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr)
else if (htlc_state_owner(hin->hstate) != REMOTE)
return corrupt(abortstr, "invalid state %s",
htlc_state_name(hin->hstate));
else if (hin->failuremsg && hin->preimage)
return corrupt(abortstr, "Both failuremsg and succeeded");
else if (hin->failonion && hin->preimage)
return corrupt(abortstr, "Both failonion and succeeded");
else if (hin->failcode != 0 && hin->preimage)
return corrupt(abortstr, "Both failcode and succeeded");
else if (hin->failuremsg && (hin->failcode & BADONION))
else if (hin->failonion && (hin->failcode & BADONION))
return corrupt(abortstr, "Both failed and malformed");
/* Can't have a resolution while still being added. */
@ -110,13 +110,13 @@ struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr)
&& hin->hstate <= RCVD_ADD_ACK_REVOCATION) {
if (hin->preimage)
return corrupt(abortstr, "Still adding, has preimage");
if (hin->failuremsg)
if (hin->failonion)
return corrupt(abortstr, "Still adding, has failmsg");
if (hin->failcode)
return corrupt(abortstr, "Still adding, has failcode");
} else if (hin->hstate >= SENT_REMOVE_HTLC
&& hin->hstate <= SENT_REMOVE_ACK_REVOCATION) {
if (!hin->preimage && !hin->failuremsg && !hin->failcode)
if (!hin->preimage && !hin->failonion && !hin->failcode)
return corrupt(abortstr, "Removing, no resolution");
} else
return corrupt(abortstr, "Bad state %s",
@ -149,7 +149,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
hin->hstate = RCVD_ADD_COMMIT;
hin->failcode = 0;
hin->failuremsg = NULL;
hin->failonion = NULL;
hin->preimage = NULL;
hin->received_time = time_now();
@ -163,7 +163,7 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
if (htlc_state_owner(hout->hstate) != LOCAL)
return corrupt(abortstr, "invalid state %s",
htlc_state_name(hout->hstate));
else if (hout->failuremsg && hout->preimage)
else if (hout->failonion && hout->preimage)
return corrupt(abortstr, "Both failed and succeeded");
if (hout->am_origin && hout->in)
@ -185,7 +185,7 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
return corrupt(abortstr, "Input hash != output hash");
/* If output is resolved, input must be resolved same
* way (or not resolved yet). */
if (hout->failuremsg) {
if (hout->failonion) {
if (hout->in->failcode)
return corrupt(abortstr,
"Output failmsg, input failcode");
@ -193,16 +193,16 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
return corrupt(abortstr,
"Output failmsg, input preimage");
} else if (hout->failcode) {
if (hout->in->failuremsg)
if (hout->in->failonion)
return corrupt(abortstr,
"Output failcode, input failmsg");
"Output failcode, input failonion");
if (hout->in->preimage)
return corrupt(abortstr,
"Output failcode, input preimage");
} else if (hout->preimage) {
if (hout->in->failuremsg)
if (hout->in->failonion)
return corrupt(abortstr,
"Output preimage, input failmsg");
"Output preimage, input failonion");
if (hout->in->failcode)
return corrupt(abortstr,
"Output preimage, input failcode");
@ -210,7 +210,7 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
if (hout->in->preimage)
return corrupt(abortstr,
"Output unresolved, input preimage");
if (hout->in->failuremsg)
if (hout->in->failonion)
return corrupt(abortstr,
"Output unresovled, input failmsg");
if (hout->in->failcode)
@ -224,13 +224,13 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
&& hout->hstate <= SENT_ADD_ACK_REVOCATION) {
if (hout->preimage)
return corrupt(abortstr, "Still adding, has preimage");
if (hout->failuremsg)
if (hout->failonion)
return corrupt(abortstr, "Still adding, has failmsg");
if (hout->failcode)
return corrupt(abortstr, "Still adding, has failcode");
} else if (hout->hstate >= RCVD_REMOVE_HTLC
&& hout->hstate <= RCVD_REMOVE_ACK_REVOCATION) {
if (!hout->preimage && !hout->failuremsg && !hout->failcode)
if (!hout->preimage && !hout->failonion && !hout->failcode)
return corrupt(abortstr, "Removing, no resolution");
} else
return corrupt(abortstr, "Bad state %s",
@ -286,7 +286,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
hout->hstate = SENT_ADD_HTLC;
hout->failcode = 0;
hout->failuremsg = NULL;
hout->failonion = NULL;
hout->preimage = NULL;
hout->am_origin = am_origin;

4
lightningd/htlc_end.h

@ -40,7 +40,7 @@ struct htlc_in {
enum onion_type failcode;
/* For a remote error. */
const struct onionreply *failuremsg;
const struct onionreply *failonion;
/* If failcode & UPDATE, this is the channel which failed. */
struct short_channel_id failoutchannel;
@ -72,7 +72,7 @@ struct htlc_out {
enum onion_type failcode;
/* For a remote error. */
const struct onionreply *failuremsg;
const struct onionreply *failonion;
/* If we fulfilled, here's the preimage. */
/* FIXME: This is basically unused, except as a bool! */

20
lightningd/pay.c

@ -538,7 +538,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
{
struct wallet_payment *payment;
struct routing_failure* fail = NULL;
const char *failmsg;
const char *failstr;
errcode_t pay_errcode;
payment = wallet_payment_by_hash(tmpctx, ld->wallet,
@ -564,7 +564,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
/* This gives more details than a generic failure message */
if (localfail) {
fail = local_routing_failure(tmpctx, ld, hout, payment);
failmsg = localfail;
failstr = localfail;
pay_errcode = PAY_TRY_OTHER_ROUTE;
} else if (payment->path_secrets == NULL) {
/* This was a payment initiated with `sendonion`, we therefore
@ -574,18 +574,18 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
pay_errcode = PAY_UNPARSEABLE_ONION;
fail = NULL;
failmsg = NULL;
failstr = NULL;
} else if (hout->failcode) {
/* Direct peer told channeld it's a malformed onion using
* update_fail_malformed_htlc. */
failmsg = "malformed onion";
failstr = "malformed onion";
fail = badonion_routing_failure(tmpctx, ld, payment,
hout->failcode);
pay_errcode = PAY_UNPARSEABLE_ONION;
} else {
/* Must be normal remote fail with an onion-wrapped error. */
assert(!hout->failcode);
failmsg = "reply from remote";
failstr = "reply from remote";
/* Try to parse reply. */
struct secret *path_secrets = payment->path_secrets;
u8 *reply;
@ -593,12 +593,12 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
reply = unwrap_onionreply(tmpctx, path_secrets,
tal_count(path_secrets),
hout->failuremsg, &origin_index);
hout->failonion, &origin_index);
if (!reply) {
log_info(hout->key.channel->log,
"htlc %"PRIu64" failed with bad reply (%s)",
hout->key.id,
tal_hex(tmpctx, hout->failuremsg));
tal_hex(tmpctx, hout->failonion->contents));
/* Cannot record failure. */
fail = NULL;
pay_errcode = PAY_UNPARSEABLE_ONION;
@ -629,18 +629,18 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
wallet_payment_set_failinfo(ld->wallet,
&hout->payment_hash,
hout->partid,
fail ? NULL : hout->failuremsg,
fail ? NULL : hout->failonion,
pay_errcode == PAY_DESTINATION_PERM_FAIL,
fail ? fail->erring_index : -1,
fail ? fail->failcode : 0,
fail ? fail->erring_node : NULL,
fail ? fail->erring_channel : NULL,
NULL,
failmsg,
failstr,
fail ? fail->channel_dir : 0);
tell_waiters_failed(ld, &hout->payment_hash, payment, pay_errcode,
hout->failuremsg, fail, failmsg);
hout->failonion, fail, failstr);
}
/* Wait for a payment. If cmd is deleted, then wait_payment()

50
lightningd/peer_htlcs.c

@ -74,7 +74,7 @@ static bool htlc_in_update_state(struct channel *channel,
wallet_htlc_update(channel->peer->ld->wallet,
hin->dbid, newstate, hin->preimage,
hin->failcode, hin->failuremsg);
hin->failcode, hin->failonion);
hin->hstate = newstate;
return true;
@ -89,7 +89,7 @@ static bool htlc_out_update_state(struct channel *channel,
return false;
wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate,
hout->preimage, hout->failcode, hout->failuremsg);
hout->preimage, hout->failcode, hout->failonion);
hout->hstate = newstate;
return true;
@ -97,16 +97,16 @@ static bool htlc_out_update_state(struct channel *channel,
static void fail_in_htlc(struct htlc_in *hin,
enum onion_type failcode,
const struct onionreply *failuremsg,
const struct onionreply *failonion,
const struct short_channel_id *out_channelid)
{
struct failed_htlc failed_htlc;
assert(!hin->preimage);
assert(failcode || failuremsg);
assert(failcode || failonion);
hin->failcode = failcode;
if (failuremsg)
hin->failuremsg = dup_onionreply(hin, failuremsg);
if (failonion)
hin->failonion = dup_onionreply(hin, failonion);
/* We need this set, since we send it to channeld. */
if (hin->failcode & UPDATE)
@ -126,7 +126,7 @@ static void fail_in_htlc(struct htlc_in *hin,
failed_htlc.id = hin->key.id;
failed_htlc.failcode = hin->failcode;
failed_htlc.failreason = hin->failuremsg;
failed_htlc.failreason = hin->failonion;
if (failed_htlc.failcode & UPDATE)
failed_htlc.scid = &hin->failoutchannel;
else
@ -158,12 +158,12 @@ void fail_htlc(struct htlc_in *hin, enum onion_type failcode)
static void fail_out_htlc(struct htlc_out *hout, const char *localfail)
{
htlc_out_check(hout, __func__);
assert(hout->failcode || hout->failuremsg);
assert(hout->failcode || hout->failonion);
if (hout->am_origin) {
payment_failed(hout->key.channel->peer->ld, hout, localfail);
} else if (hout->in) {
fail_in_htlc(hout->in, hout->failcode, hout->failuremsg,
fail_in_htlc(hout->in, hout->failcode, hout->failonion,
hout->key.channel->scid);
}
}
@ -999,7 +999,7 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
htlc_out_check(hout, __func__);
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, hout->failcode, hout->failuremsg);
hout->preimage, hout->failcode, hout->failonion);
/* Update channel stats */
wallet_channel_stats_incr_out_fulfilled(ld->wallet,
channel->dbid,
@ -1055,7 +1055,7 @@ void onchain_fulfilled_htlc(struct channel *channel,
/* It's possible that we failed some and succeeded one,
* if we got multiple errors. */
if (hout->failcode != 0 || hout->failuremsg)
if (hout->failcode != 0 || hout->failonion)
continue;
if (!sha256_eq(&hout->payment_hash, &payment_hash))
@ -1093,9 +1093,9 @@ static bool peer_failed_our_htlc(struct channel *channel,
hout->failcode = failed->failcode;
if (!failed->failcode)
hout->failuremsg = dup_onionreply(hout, failed->failreason);
hout->failonion = dup_onionreply(hout, failed->failreason);
else
hout->failuremsg = NULL;
hout->failonion = NULL;
log_debug(channel->log, "Our HTLC %"PRIu64" failed (%u)", failed->id,
hout->failcode);
@ -1121,7 +1121,7 @@ void onchain_failed_our_htlc(const struct channel *channel,
return;
/* Don't fail twice (or if already succeeded)! */
if (hout->failuremsg || hout->failcode || hout->preimage)
if (hout->failonion || hout->failcode || hout->preimage)
return;
hout->failcode = WIRE_PERMANENT_CHANNEL_FAILURE;
@ -1130,7 +1130,7 @@ void onchain_failed_our_htlc(const struct channel *channel,
hout->hstate = RCVD_REMOVE_HTLC;
htlc_out_check(hout, __func__);
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate,
hout->preimage, hout->failcode, hout->failuremsg);
hout->preimage, hout->failcode, hout->failonion);
if (hout->am_origin) {
assert(why != NULL);
@ -1152,7 +1152,7 @@ void onchain_failed_our_htlc(const struct channel *channel,
static void remove_htlc_in(struct channel *channel, struct htlc_in *hin)
{
htlc_in_check(hin, __func__);
assert(hin->failuremsg || hin->preimage || hin->failcode);
assert(hin->failonion || hin->preimage || hin->failcode);
log_debug(channel->log, "Removing in HTLC %"PRIu64" state %s %s",
hin->key.id, htlc_state_name(hin->hstate),
@ -1189,7 +1189,7 @@ static void remove_htlc_in(struct channel *channel, struct htlc_in *hin)
static void remove_htlc_out(struct channel *channel, struct htlc_out *hout)
{
htlc_out_check(hout, __func__);
assert(hout->failuremsg || hout->preimage || hout->failcode);
assert(hout->failonion || hout->preimage || hout->failcode);
log_debug(channel->log, "Removing out HTLC %"PRIu64" state %s %s",
hout->key.id, htlc_state_name(hout->hstate),
hout->preimage ? "FULFILLED"
@ -1809,7 +1809,7 @@ static void add_fulfill(u64 id, enum side side,
static void add_fail(u64 id, enum side side,
enum onion_type failcode,
const struct short_channel_id *failing_channel,
const struct onionreply *failuremsg,
const struct onionreply *failonion,
const struct failed_htlc ***failed_htlcs,
enum side **failed_sides)
{
@ -1825,8 +1825,8 @@ static void add_fail(u64 id, enum side side,
} else
newf->scid = NULL;
if (failuremsg)
newf->failreason = dup_onionreply(newf, failuremsg);
if (failonion)
newf->failreason = dup_onionreply(newf, failonion);
else
newf->failreason = NULL;
@ -1868,10 +1868,10 @@ void peer_htlcs(const tal_t *ctx,
hin->cltv_expiry, hin->onion_routing_packet,
hin->hstate);
if (hin->failuremsg || hin->failcode)
if (hin->failonion || hin->failcode)
add_fail(hin->key.id, REMOTE, hin->failcode,
&hin->failoutchannel,
hin->failuremsg, failed_htlcs, failed_sides);
hin->failonion, failed_htlcs, failed_sides);
if (hin->preimage)
add_fulfill(hin->key.id, REMOTE, hin->preimage,
fulfilled_htlcs, fulfilled_sides);
@ -1888,10 +1888,10 @@ void peer_htlcs(const tal_t *ctx,
hout->cltv_expiry, hout->onion_routing_packet,
hout->hstate);
if (hout->failuremsg || hout->failcode)
if (hout->failonion || hout->failcode)
add_fail(hout->key.id, LOCAL, hout->failcode,
hout->key.channel->scid,
hout->failuremsg, failed_htlcs, failed_sides);
hout->failonion, failed_htlcs, failed_sides);
if (hout->preimage)
add_fulfill(hout->key.id, LOCAL, hout->preimage,
fulfilled_htlcs, fulfilled_sides);
@ -2073,7 +2073,7 @@ static void fixup_hout(struct lightningd *ld, struct htlc_out *hout)
return;
/* Failed ones (only happens after db fixed!) OK. */
if (hout->failcode || hout->failuremsg)
if (hout->failcode || hout->failonion)
return;
/* payment_preimage for HTLC in *was* stored, so look for that. */

3
wallet/db.c

@ -127,7 +127,8 @@ static struct migration dbmigrations[] = {
" payment_hash BLOB,"
" payment_key BLOB,"
" routing_onion BLOB,"
" failuremsg BLOB,"
" failuremsg BLOB," /* Note: This is in fact the failure onionreply,
* but renaming columns is hard! */
" malformed_onion INTEGER,"
" hstate INTEGER,"
" shared_secret BLOB,"

18
wallet/wallet.c

@ -1759,7 +1759,7 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state,
const struct preimage *payment_key,
enum onion_type failcode,
const struct onionreply *failuremsg)
const struct onionreply *failonion)
{
struct db_stmt *stmt;
@ -1780,8 +1780,8 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
db_bind_null(stmt, 1);
db_bind_int(stmt, 2, failcode);
if (failuremsg)
db_bind_onionreply(stmt, 3, failuremsg);
if (failonion)
db_bind_onionreply(stmt, 3, failonion);
else
db_bind_null(stmt, 3);
@ -1813,9 +1813,9 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
sizeof(in->onion_routing_packet));
if (db_column_is_null(stmt, 8))
in->failuremsg = NULL;
in->failonion = NULL;
else
in->failuremsg = db_column_onionreply(in, stmt, 8);
in->failonion = db_column_onionreply(in, stmt, 8);
in->failcode = db_column_int(stmt, 9);
if (db_column_is_null(stmt, 11)) {
@ -1869,9 +1869,9 @@ static bool wallet_stmt2htlc_out(struct wallet *wallet,
sizeof(out->onion_routing_packet));
if (db_column_is_null(stmt, 8))
out->failuremsg = NULL;
out->failonion = NULL;
else
out->failuremsg = db_column_onionreply(out, stmt, 8);
out->failonion = db_column_onionreply(out, stmt, 8);
out->failcode = db_column_int_or_default(stmt, 9, 0);
out->in = NULL;
@ -1911,7 +1911,7 @@ static void fixup_hin(struct wallet *wallet, struct htlc_in *hin)
if (hin->failcode & UPDATE)
hin->failcode = WIRE_TEMPORARY_NODE_FAILURE;
/* We didn't used to save failcore, failuremsg... */
/* We didn't used to save failcore, failonion... */
#ifdef COMPAT_V061
/* We care about HTLCs being removed only, not those being added. */
if (hin->hstate < SENT_REMOVE_HTLC)
@ -1922,7 +1922,7 @@ static void fixup_hin(struct wallet *wallet, struct htlc_in *hin)
return;
/* Failed ones (only happens after db fixed!) OK. */
if (hin->failcode || hin->failuremsg)
if (hin->failcode || hin->failonion)
return;
hin->failcode = WIRE_TEMPORARY_NODE_FAILURE;

6
wallet/wallet.h

@ -582,17 +582,17 @@ void wallet_htlc_save_out(struct wallet *wallet,
* @payment_key: the `payment_key` which hashes to the `payment_hash`,
* or NULL if unknown.
* @failcode: the current failure code, or 0.
* @failuremsg: the current failure message (from peer), or NULL.
* @failonion: the current failure message (from peer), or NULL.
*
* Used to update the state of an HTLC, either a `struct htlc_in` or a
* `struct htlc_out` and optionally set the `payment_key` should the
* HTLC have been settled, or `failcode`/`failuremsg` if failed.
* HTLC have been settled, or `failcode`/`failonion` if failed.
*/
void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
const enum htlc_state new_state,
const struct preimage *payment_key,
enum onion_type failcode,
const struct onionreply *failuremsg);
const struct onionreply *failonion);
/**
* wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB.

Loading…
Cancel
Save