mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-03 13:14:22 +01:00
htlcs: add flag to 'fail immediately'
If we're over the dust limit, we fail it immediatey *after* commiting it, but we need a way to signal this throughout the lifecycle, so we add it to htlc_in struct and persist it through to the database. If it's supposed to be failed, we fail after the commit cycle is completed.
This commit is contained in:
committed by
Christian Decker
parent
208b161226
commit
42e40c1ced
@@ -738,7 +738,11 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
|
||||
#endif
|
||||
add_err = channel_add_htlc(peer->channel, REMOTE, id, amount,
|
||||
cltv_expiry, &payment_hash,
|
||||
onion_routing_packet, blinding, &htlc, NULL);
|
||||
onion_routing_packet, blinding, &htlc, NULL,
|
||||
/* We don't immediately fail incoming htlcs,
|
||||
* instead we wait and fail them after
|
||||
* they've been committed */
|
||||
false);
|
||||
if (add_err != CHANNEL_ERR_ADD_OK)
|
||||
peer_failed_warn(peer->pps, &peer->channel_id,
|
||||
"Bad peer_add_htlc: %s",
|
||||
@@ -1468,6 +1472,7 @@ static void marshall_htlc_info(const tal_t *ctx,
|
||||
ecdh(a.blinding, &a.blinding_ss);
|
||||
} else
|
||||
a.blinding = NULL;
|
||||
a.fail_immediate = htlc->fail_immediate;
|
||||
tal_arr_expand(added, a);
|
||||
} else if (htlc->state == RCVD_REMOVE_COMMIT) {
|
||||
if (htlc->r) {
|
||||
@@ -3299,7 +3304,8 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
|
||||
|
||||
e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id,
|
||||
amount, cltv_expiry, &payment_hash,
|
||||
onion_routing_packet, take(blinding), NULL, &htlc_fee);
|
||||
onion_routing_packet, take(blinding), NULL,
|
||||
&htlc_fee, true);
|
||||
status_debug("Adding HTLC %"PRIu64" amount=%s cltv=%u gave %s",
|
||||
peer->htlc_id,
|
||||
type_to_string(tmpctx, struct amount_msat, &amount),
|
||||
|
||||
@@ -28,6 +28,9 @@ struct htlc {
|
||||
|
||||
/* Blinding (optional). */
|
||||
struct pubkey *blinding;
|
||||
|
||||
/* Should we immediately fail this htlc? */
|
||||
bool fail_immediate;
|
||||
};
|
||||
|
||||
static inline bool htlc_has(const struct htlc *h, int flag)
|
||||
|
||||
@@ -493,7 +493,8 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||
const struct pubkey *blinding TAKES,
|
||||
struct htlc **htlcp,
|
||||
bool enforce_aggregate_limits,
|
||||
struct amount_sat *htlc_fee)
|
||||
struct amount_sat *htlc_fee,
|
||||
bool err_immediate_failures)
|
||||
{
|
||||
struct htlc *htlc, *old;
|
||||
struct amount_msat msat_in_htlcs, committed_msat, adding_msat, removing_msat;
|
||||
@@ -508,6 +509,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||
htlc->id = id;
|
||||
htlc->amount = amount;
|
||||
htlc->state = state;
|
||||
htlc->fail_immediate = false;
|
||||
|
||||
htlc->rhash = *payment_hash;
|
||||
if (blinding)
|
||||
@@ -768,7 +770,8 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
|
||||
const u8 routing[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)],
|
||||
const struct pubkey *blinding TAKES,
|
||||
struct htlc **htlcp,
|
||||
struct amount_sat *htlc_fee)
|
||||
struct amount_sat *htlc_fee,
|
||||
bool err_immediate_failures)
|
||||
{
|
||||
enum htlc_state state;
|
||||
|
||||
@@ -786,7 +789,7 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
|
||||
|
||||
return add_htlc(channel, state, id, amount, cltv_expiry,
|
||||
payment_hash, routing, blinding,
|
||||
htlcp, true, htlc_fee);
|
||||
htlcp, true, htlc_fee, err_immediate_failures);
|
||||
}
|
||||
|
||||
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id)
|
||||
@@ -1392,7 +1395,7 @@ bool channel_force_htlcs(struct channel *channel,
|
||||
&htlcs[i]->payment_hash,
|
||||
htlcs[i]->onion_routing_packet,
|
||||
htlcs[i]->blinding,
|
||||
&htlc, false, NULL);
|
||||
&htlc, false, NULL, false);
|
||||
if (e != CHANNEL_ERR_ADD_OK) {
|
||||
status_broken("%s HTLC %"PRIu64" failed error %u",
|
||||
htlc_state_owner(htlcs[i]->state) == LOCAL
|
||||
|
||||
@@ -103,6 +103,10 @@ u32 actual_feerate(const struct channel *channel,
|
||||
* @routing: routing information (copied)
|
||||
* @blinding: optional blinding information for this HTLC.
|
||||
* @htlcp: optional pointer for resulting htlc: filled in if and only if CHANNEL_ERR_NONE.
|
||||
* @err_immediate_failures: in some cases (dusty htlcs) we want to immediately
|
||||
* fail the htlc; for peer incoming don't want to
|
||||
* error, but rather mark it as failed and fail after
|
||||
* it's been committed to (so set this to false)
|
||||
*
|
||||
* If this returns CHANNEL_ERR_NONE, the fee htlc was added and
|
||||
* the output amounts adjusted accordingly. Otherwise nothing
|
||||
@@ -117,7 +121,8 @@ enum channel_add_err channel_add_htlc(struct channel *channel,
|
||||
const u8 routing[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)],
|
||||
const struct pubkey *blinding TAKES,
|
||||
struct htlc **htlcp,
|
||||
struct amount_sat *htlc_fee);
|
||||
struct amount_sat *htlc_fee,
|
||||
bool err_immediate_failures);
|
||||
|
||||
/**
|
||||
* channel_get_htlc: find an HTLC
|
||||
|
||||
@@ -165,7 +165,7 @@ static const struct htlc **include_htlcs(struct channel *channel, enum side side
|
||||
memset(&preimage, i, sizeof(preimage));
|
||||
sha256(&hash, &preimage, sizeof(preimage));
|
||||
e = channel_add_htlc(channel, sender, i, msatoshi, 500+i, &hash,
|
||||
dummy_routing, NULL, NULL, NULL);
|
||||
dummy_routing, NULL, NULL, NULL, true);
|
||||
assert(e == CHANNEL_ERR_ADD_OK);
|
||||
htlcs[i] = channel_get_htlc(channel, sender, i);
|
||||
}
|
||||
@@ -257,7 +257,7 @@ static void send_and_fulfill_htlc(struct channel *channel,
|
||||
sha256(&rhash, &r, sizeof(r));
|
||||
|
||||
assert(channel_add_htlc(channel, sender, 1337, msatoshi, 900, &rhash,
|
||||
dummy_routing, NULL, NULL, NULL)
|
||||
dummy_routing, NULL, NULL, NULL, true)
|
||||
== CHANNEL_ERR_ADD_OK);
|
||||
|
||||
changed_htlcs = tal_arr(channel, const struct htlc *, 0);
|
||||
|
||||
@@ -78,6 +78,7 @@ void towire_added_htlc(u8 **pptr, const struct added_htlc *added)
|
||||
towire_secret(pptr, &added->blinding_ss);
|
||||
} else
|
||||
towire_bool(pptr, false);
|
||||
towire_bool(pptr, added->fail_immediate);
|
||||
}
|
||||
|
||||
void towire_existing_htlc(u8 **pptr, const struct existing_htlc *existing)
|
||||
@@ -171,6 +172,7 @@ void fromwire_added_htlc(const u8 **cursor, size_t *max,
|
||||
fromwire_secret(cursor, max, &added->blinding_ss);
|
||||
} else
|
||||
added->blinding = NULL;
|
||||
added->fail_immediate = fromwire_bool(cursor, max);
|
||||
}
|
||||
|
||||
struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx,
|
||||
|
||||
@@ -15,6 +15,7 @@ struct added_htlc {
|
||||
struct sha256 payment_hash;
|
||||
u32 cltv_expiry;
|
||||
u8 onion_routing_packet[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)];
|
||||
bool fail_immediate;
|
||||
|
||||
/* If this is non-NULL, secret is the resulting shared secret */
|
||||
struct pubkey *blinding;
|
||||
|
||||
@@ -130,7 +130,8 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
|
||||
const struct secret *shared_secret TAKES,
|
||||
const struct pubkey *blinding TAKES,
|
||||
const struct secret *blinding_ss,
|
||||
const u8 *onion_routing_packet)
|
||||
const u8 *onion_routing_packet,
|
||||
bool fail_immediate)
|
||||
{
|
||||
struct htlc_in *hin = tal(ctx, struct htlc_in);
|
||||
|
||||
@@ -141,6 +142,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
|
||||
hin->cltv_expiry = cltv_expiry;
|
||||
hin->payment_hash = *payment_hash;
|
||||
hin->status = NULL;
|
||||
hin->fail_immediate = fail_immediate;
|
||||
if (shared_secret)
|
||||
hin->shared_secret = tal_dup(hin, struct secret, shared_secret);
|
||||
else
|
||||
|
||||
@@ -52,6 +52,8 @@ struct htlc_in {
|
||||
struct secret blinding_ss;
|
||||
/* true if we supplied the preimage */
|
||||
bool *we_filled;
|
||||
/* true if we immediately fail the htlc (too much dust) */
|
||||
bool fail_immediate;
|
||||
|
||||
/* A simple text annotation shown in `listpeers` */
|
||||
char *status;
|
||||
@@ -154,7 +156,8 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
|
||||
const struct secret *shared_secret TAKES,
|
||||
const struct pubkey *blinding TAKES,
|
||||
const struct secret *blinding_ss,
|
||||
const u8 *onion_routing_packet);
|
||||
const u8 *onion_routing_packet,
|
||||
bool fail_immediate);
|
||||
|
||||
/* You need to set the ID, then connect_htlc_out this! */
|
||||
struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||
|
||||
@@ -1171,6 +1171,13 @@ static bool peer_accepted_htlc(const tal_t *ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hin->fail_immediate && htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION)) {
|
||||
log_debug(channel->log, "failing immediately, as requested");
|
||||
/* Failing the htlc, typically done because of htlc dust */
|
||||
*failmsg = towire_temporary_node_failure(ctx);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!replay && !htlc_in_update_state(channel, hin, RCVD_ADD_ACK_REVOCATION)) {
|
||||
*failmsg = towire_temporary_node_failure(ctx);
|
||||
goto fail;
|
||||
@@ -1863,7 +1870,8 @@ static bool channel_added_their_htlc(struct channel *channel,
|
||||
added->cltv_expiry, &added->payment_hash,
|
||||
op ? &shared_secret : NULL,
|
||||
added->blinding, &added->blinding_ss,
|
||||
added->onion_routing_packet);
|
||||
added->onion_routing_packet,
|
||||
added->fail_immediate);
|
||||
|
||||
/* Save an incoming htlc to the wallet */
|
||||
wallet_htlc_save_in(ld->wallet, channel, hin);
|
||||
|
||||
@@ -2317,8 +2317,9 @@ void wallet_htlc_save_in(struct wallet *wallet,
|
||||
" shared_secret,"
|
||||
" routing_onion,"
|
||||
" received_time,"
|
||||
" min_commit_num) VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
" min_commit_num, "
|
||||
" fail_immediate) VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
|
||||
db_bind_u64(stmt, 0, chan->dbid);
|
||||
db_bind_u64(stmt, 1, in->key.id);
|
||||
@@ -2345,6 +2346,8 @@ void wallet_htlc_save_in(struct wallet *wallet,
|
||||
db_bind_u64(stmt, 11, min_unsigned(chan->next_index[LOCAL]-1,
|
||||
chan->next_index[REMOTE]-1));
|
||||
|
||||
db_bind_int(stmt, 12, in->fail_immediate);
|
||||
|
||||
db_exec_prepared_v2(stmt);
|
||||
in->dbid = db_last_insert_id_v2(take(stmt));
|
||||
}
|
||||
@@ -2555,6 +2558,8 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
|
||||
} else
|
||||
in->we_filled = NULL;
|
||||
|
||||
in->fail_immediate = db_column_int(stmt, 14);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -2683,6 +2688,7 @@ bool wallet_htlcs_load_in_for_channel(struct wallet *wallet,
|
||||
", shared_secret"
|
||||
", received_time"
|
||||
", we_filled"
|
||||
", fail_immediate"
|
||||
" FROM channel_htlcs"
|
||||
" WHERE direction= ?"
|
||||
" AND channel_id= ?"
|
||||
|
||||
Reference in New Issue
Block a user