Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .msggen.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,21 @@
"ListconfigsConfigsConfSource": {
"cmdline": 0
},
"ListforwardsForwardsFailureReason": {
"channel_failed_permanent": 11,
"cltv_expiry_too_far": 8,
"cltv_expiry_too_soon": 7,
"cltv_incorrect": 6,
"dust_limit": 2,
"fee_insufficient": 5,
"htlc_above_maximum": 4,
"htlc_below_minimum": 3,
"insufficient_outgoing_liquidity": 0,
"invalid_onion": 12,
"outgoing_peer_offline": 10,
"too_many_htlcs": 1,
"unknown_next_peer": 9
},
"ListforwardsForwardsStatus": {
"failed": 3,
"local_failed": 2,
Expand Down Expand Up @@ -3066,6 +3081,7 @@
"ListForwards.forwards[].created_index": 12,
"ListForwards.forwards[].failcode": 15,
"ListForwards.forwards[].failreason": 16,
"ListForwards.forwards[].failure_reason": 17,
"ListForwards.forwards[].fee_msat": 7,
"ListForwards.forwards[].in_channel": 1,
"ListForwards.forwards[].in_htlc_id": 10,
Expand Down Expand Up @@ -11156,6 +11172,10 @@
"added": "pre-v0.10.1",
"deprecated": null
},
"ListForwards.forwards[].failure_reason": {
"added": "pre-v0.10.1",
"deprecated": null
},
"ListForwards.forwards[].fee_msat": {
"added": "pre-v0.10.1",
"deprecated": null
Expand Down
12 changes: 10 additions & 2 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <channeld/watchtower.h>
#include <common/billboard.h>
#include <common/ecdh_hsmd.h>
#include <common/forward_failure_reason.h>
#include <common/interactivetx.h>
#include <common/key_derive.h>
#include <common/memleak.h>
Expand Down Expand Up @@ -6373,6 +6374,7 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
enum channel_add_err e;
const u8 *failwiremsg;
const char *failstr;
enum forward_failure_reason reason = FORWARD_FAIL_UNKNOWN;
struct amount_sat htlc_fee;
struct pubkey *path_key;
struct tlv_field *extra_tlvs;
Expand Down Expand Up @@ -6435,13 +6437,14 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
start_commit_timer(peer);
/* Tell the master. */
msg = towire_channeld_offer_htlc_reply(NULL, peer->htlc_id,
0, "");
0, "", FORWARD_FAIL_UNKNOWN);
wire_sync_write(MASTER_FD, take(msg));
peer->htlc_id++;
return;
case CHANNEL_ERR_INVALID_EXPIRY:
failwiremsg = towire_incorrect_cltv_expiry(inmsg, cltv_expiry, NULL);
failstr = tal_fmt(inmsg, "Invalid cltv_expiry %u", cltv_expiry);
reason = FORWARD_FAIL_CLTV_INCORRECT;
goto failed;
case CHANNEL_ERR_DUPLICATE:
case CHANNEL_ERR_DUPLICATE_ID_DIFFERENT:
Expand All @@ -6451,21 +6454,25 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
case CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED:
failwiremsg = towire_required_node_feature_missing(inmsg);
failstr = "Mini mode: maximum value exceeded";
reason = FORWARD_FAIL_HTLC_ABOVE_MAXIMUM;
goto failed;
/* FIXME: Fuzz the boundaries a bit to avoid probing? */
case CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED:
failwiremsg = towire_temporary_channel_failure(inmsg, NULL);
failstr = tal_fmt(inmsg, "Capacity exceeded - HTLC fee: %s", fmt_amount_sat(inmsg, htlc_fee));
reason = FORWARD_FAIL_INSUFFICIENT_OUTGOING_LIQUIDITY;
goto failed;
case CHANNEL_ERR_HTLC_BELOW_MINIMUM:
failwiremsg = towire_amount_below_minimum(inmsg, amount, NULL);
failstr = tal_fmt(inmsg, "HTLC too small (%s minimum)",
fmt_amount_msat(tmpctx,
peer->channel->config[REMOTE].htlc_minimum));
reason = FORWARD_FAIL_HTLC_BELOW_MINIMUM;
goto failed;
case CHANNEL_ERR_TOO_MANY_HTLCS:
failwiremsg = towire_temporary_channel_failure(inmsg, NULL);
failstr = "Too many HTLCs";
reason = FORWARD_FAIL_TOO_MANY_HTLCS;
goto failed;
case CHANNEL_ERR_DUST_FAILURE:
/* BOLT-919 #2:
Expand All @@ -6476,14 +6483,15 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
*/
failwiremsg = towire_temporary_channel_failure(inmsg, NULL);
failstr = "HTLC too dusty, allowed dust limit reached";
reason = FORWARD_FAIL_DUST_LIMIT;
goto failed;
}
/* Shouldn't return anything else! */
abort();

failed:
/* lightningd appends update to this for us */
msg = towire_channeld_offer_htlc_reply(NULL, 0, failwiremsg, failstr);
msg = towire_channeld_offer_htlc_reply(NULL, 0, failwiremsg, failstr, reason);
wire_sync_write(MASTER_FD, take(msg));
}

Expand Down
3 changes: 3 additions & 0 deletions channeld/channeld_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ msgdata,channeld_offer_htlc_reply,id,u64,
msgdata,channeld_offer_htlc_reply,len,u16,
msgdata,channeld_offer_htlc_reply,failuremsg,u8,len
msgdata,channeld_offer_htlc_reply,failurestr,wirestring,
# enum forward_failure_reason (common/forward_failure_reason.h) - root cause
# of the failure, 0 (FORWARD_FAIL_UNKNOWN) on success or if unclassified
msgdata,channeld_offer_htlc_reply,reason,u8,

# Main daemon found out the preimage for an HTLC
#include <bitcoin/preimage.h>
Expand Down
17 changes: 17 additions & 0 deletions cln-grpc/proto/node.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cln-grpc/src/convert.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions cln-rpc/src/model.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) \
common/crypto_state.h \
common/ecdh.h \
common/errcode.h \
common/forward_failure_reason.h \
common/gossip_constants.h \
common/hash_str.h \
common/hsm_version.h \
Expand Down
77 changes: 77 additions & 0 deletions common/forward_failure_reason.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef LIGHTNING_COMMON_FORWARD_FAILURE_REASON_H
#define LIGHTNING_COMMON_FORWARD_FAILURE_REASON_H
#include "config.h"

/* This is a DB ENUM!!!, please do not change the numbering of any
* already defined elements (adding is ok) */
enum forward_failure_reason {
/* Not classified, or not applicable (not a local failure) */
FORWARD_FAIL_UNKNOWN = 0,
/* CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED: not enough spendable
* balance/reserve on the outgoing channel */
FORWARD_FAIL_INSUFFICIENT_OUTGOING_LIQUIDITY = 1,
/* CHANNEL_ERR_TOO_MANY_HTLCS */
FORWARD_FAIL_TOO_MANY_HTLCS = 2,
/* CHANNEL_ERR_DUST_FAILURE */
FORWARD_FAIL_DUST_LIMIT = 3,
/* CHANNEL_ERR_HTLC_BELOW_MINIMUM, or amount below the next hop's
* advertised htlc_minimum_msat */
FORWARD_FAIL_HTLC_BELOW_MINIMUM = 4,
/* CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED, or amount above the next
* hops advertised htlc_maximum_msat */
FORWARD_FAIL_HTLC_ABOVE_MAXIMUM = 5,
/* Forwarding fee offered was insufficient */
FORWARD_FAIL_FEE_INSUFFICIENT = 6,
/* CHANNEL_ERR_INVALID_EXPIRY, or cltv_expiry_delta check failed */
FORWARD_FAIL_CLTV_INCORRECT = 7,
/* Outgoing cltv too close to the current block height */
FORWARD_FAIL_CLTV_EXPIRY_TOO_SOON = 8,
/* Outgoing cltv beyond our configured max_htlc_cltv */
FORWARD_FAIL_CLTV_EXPIRY_TOO_FAR = 9,
/* No usable channel/peer for the requested next hop */
FORWARD_FAIL_UNKNOWN_NEXT_PEER = 10,
/* Outgoing peers subdaemon is not connected/owned */
FORWARD_FAIL_OUTGOING_PEER_OFFLINE = 11,
/* Outgoing HTLC failed permanently (onchain timeout) */
FORWARD_FAIL_CHANNEL_FAILED_PERMANENT = 12,
/* Onion could not be parsed/decoded */
FORWARD_FAIL_INVALID_ONION = 13,
};

/* Returns NULL for FORWARD_FAIL_UNKNOWN - it is never serialized */
static inline const char *forward_failure_reason_name(enum forward_failure_reason r)
{
switch (r) {
case FORWARD_FAIL_UNKNOWN:
return NULL;
case FORWARD_FAIL_INSUFFICIENT_OUTGOING_LIQUIDITY:
return "insufficient_outgoing_liquidity";
case FORWARD_FAIL_TOO_MANY_HTLCS:
return "too_many_htlcs";
case FORWARD_FAIL_DUST_LIMIT:
return "dust_limit";
case FORWARD_FAIL_HTLC_BELOW_MINIMUM:
return "htlc_below_minimum";
case FORWARD_FAIL_HTLC_ABOVE_MAXIMUM:
return "htlc_above_maximum";
case FORWARD_FAIL_FEE_INSUFFICIENT:
return "fee_insufficient";
case FORWARD_FAIL_CLTV_INCORRECT:
return "cltv_incorrect";
case FORWARD_FAIL_CLTV_EXPIRY_TOO_SOON:
return "cltv_expiry_too_soon";
case FORWARD_FAIL_CLTV_EXPIRY_TOO_FAR:
return "cltv_expiry_too_far";
case FORWARD_FAIL_UNKNOWN_NEXT_PEER:
return "unknown_next_peer";
case FORWARD_FAIL_OUTGOING_PEER_OFFLINE:
return "outgoing_peer_offline";
case FORWARD_FAIL_CHANNEL_FAILED_PERMANENT:
return "channel_failed_permanent";
case FORWARD_FAIL_INVALID_ONION:
return "invalid_onion";
}
abort();
}

#endif /* LIGHTNING_COMMON_FORWARD_FAILURE_REASON_H */
Loading
Loading