mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
channel: remove htlcs array.
We could put it back later for debugging, but we should be using the global state not this array. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7cd9272ba9
commit
19be4dbfe6
146
daemon/channel.c
146
daemon/channel.c
@ -1,5 +1,6 @@
|
||||
#include "channel.h"
|
||||
#include "htlc.h"
|
||||
#include "remove_dust.h"
|
||||
#include <assert.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
@ -36,17 +37,6 @@ static uint64_t calculate_fee_msat(size_t num_nondust_htlcs,
|
||||
return fee_by_feerate(bytes, fee_rate) * 1000;
|
||||
}
|
||||
|
||||
/* Total, in millisatoshi. */
|
||||
static uint64_t htlcs_total(struct htlc **htlcs)
|
||||
{
|
||||
size_t i, n = tal_count(htlcs);
|
||||
uint64_t total = 0;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
total += htlcs[i]->msatoshis;
|
||||
return total;
|
||||
}
|
||||
|
||||
/* Pay this much fee, if possible. Return amount unpaid. */
|
||||
static uint64_t pay_fee(struct channel_oneside *side, uint64_t fee_msat)
|
||||
{
|
||||
@ -103,11 +93,10 @@ static bool change_funding(uint64_t anchor_satoshis,
|
||||
size_t num_nondust_htlcs)
|
||||
{
|
||||
uint64_t fee_msat;
|
||||
uint64_t htlcs_total;
|
||||
|
||||
assert(a->pay_msat + a->fee_msat
|
||||
+ b->pay_msat + b->fee_msat
|
||||
+ htlcs_total(a->htlcs) + htlcs_total(b->htlcs)
|
||||
== anchor_satoshis * 1000);
|
||||
htlcs_total = anchor_satoshis * 1000
|
||||
- (a->pay_msat + a->fee_msat + b->pay_msat + b->fee_msat);
|
||||
|
||||
fee_msat = calculate_fee_msat(num_nondust_htlcs, fee_rate);
|
||||
|
||||
@ -121,10 +110,9 @@ static bool change_funding(uint64_t anchor_satoshis,
|
||||
a->pay_msat -= htlc_msat;
|
||||
recalculate_fees(a, b, fee_msat);
|
||||
|
||||
assert(a->pay_msat + a->fee_msat
|
||||
+ b->pay_msat + b->fee_msat
|
||||
+ htlcs_total(a->htlcs) + htlcs_total(b->htlcs) + htlc_msat
|
||||
== anchor_satoshis * 1000);
|
||||
htlcs_total += htlc_msat;
|
||||
assert(htlcs_total == anchor_satoshis * 1000
|
||||
- (a->pay_msat + a->fee_msat + b->pay_msat + b->fee_msat));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -139,7 +127,7 @@ struct channel_state *initial_cstate(const tal_t *ctx,
|
||||
|
||||
cstate->fee_rate = fee_rate;
|
||||
cstate->anchor = anchor_satoshis;
|
||||
cstate->changes = 0;
|
||||
cstate->num_nondust = 0;
|
||||
|
||||
/* Anchor must fit in 32 bit. */
|
||||
if (anchor_satoshis >= (1ULL << 32) / 1000)
|
||||
@ -153,8 +141,7 @@ struct channel_state *initial_cstate(const tal_t *ctx,
|
||||
fundee = &cstate->side[!funding];
|
||||
|
||||
/* Neither side has HTLCs. */
|
||||
funder->htlcs = tal_arr(cstate, struct htlc *, 0);
|
||||
fundee->htlcs = tal_arr(cstate, struct htlc *, 0);
|
||||
funder->num_htlcs = fundee->num_htlcs = 0;
|
||||
|
||||
/* Initially, all goes back to funder. */
|
||||
funder->pay_msat = anchor_satoshis * 1000 - fee_msat;
|
||||
@ -168,37 +155,13 @@ struct channel_state *initial_cstate(const tal_t *ctx,
|
||||
return cstate;
|
||||
}
|
||||
|
||||
/* Dust is defined as an output < 546*minRelayTxFee/1000.
|
||||
* minRelayTxFee defaults to 1000 satoshi. */
|
||||
bool is_dust_amount(uint64_t satoshis)
|
||||
{
|
||||
return satoshis < 546;
|
||||
}
|
||||
|
||||
static size_t count_nondust_htlcs(struct htlc **htlcs)
|
||||
{
|
||||
size_t i, n = tal_count(htlcs), nondust = 0;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (!is_dust_amount(htlcs[i]->msatoshis / 1000))
|
||||
nondust++;
|
||||
return nondust;
|
||||
}
|
||||
|
||||
static size_t total_nondust_htlcs(const struct channel_state *cstate)
|
||||
{
|
||||
return count_nondust_htlcs(cstate->side[OURS].htlcs)
|
||||
+ count_nondust_htlcs(cstate->side[THEIRS].htlcs);
|
||||
}
|
||||
|
||||
void adjust_fee(struct channel_state *cstate, uint32_t fee_rate)
|
||||
{
|
||||
uint64_t fee_msat;
|
||||
|
||||
fee_msat = calculate_fee_msat(total_nondust_htlcs(cstate), fee_rate);
|
||||
fee_msat = calculate_fee_msat(cstate->num_nondust, fee_rate);
|
||||
|
||||
recalculate_fees(&cstate->side[OURS], &cstate->side[THEIRS], fee_msat);
|
||||
cstate->changes++;
|
||||
}
|
||||
|
||||
bool force_fee(struct channel_state *cstate, uint64_t fee)
|
||||
@ -207,42 +170,29 @@ bool force_fee(struct channel_state *cstate, uint64_t fee)
|
||||
if (fee > 0xFFFFFFFFFFFFFFFFULL / 1000)
|
||||
return false;
|
||||
recalculate_fees(&cstate->side[OURS], &cstate->side[THEIRS], fee * 1000);
|
||||
cstate->changes++;
|
||||
return cstate->side[OURS].fee_msat + cstate->side[THEIRS].fee_msat == fee * 1000;
|
||||
}
|
||||
|
||||
/* Add a HTLC to @creator if it can afford it. */
|
||||
bool cstate_add_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side)
|
||||
bool cstate_add_htlc(struct channel_state *cstate, const struct htlc *htlc)
|
||||
{
|
||||
size_t n, nondust;
|
||||
size_t nondust;
|
||||
struct channel_oneside *creator, *recipient;
|
||||
|
||||
assert(htlc_channel_side(htlc) == side);
|
||||
creator = &cstate->side[side];
|
||||
recipient = &cstate->side[!side];
|
||||
|
||||
for (n = 0; n < tal_count(creator->htlcs); n++)
|
||||
assert(creator->htlcs[n] != htlc);
|
||||
creator = &cstate->side[htlc_channel_side(htlc)];
|
||||
recipient = &cstate->side[!htlc_channel_side(htlc)];
|
||||
|
||||
/* Remember to count the new one in total txsize if not dust! */
|
||||
nondust = total_nondust_htlcs(cstate);
|
||||
if (!is_dust_amount(htlc->msatoshis / 1000))
|
||||
nondust = cstate->num_nondust;
|
||||
if (!is_dust(htlc->msatoshis / 1000))
|
||||
nondust++;
|
||||
|
||||
if (!change_funding(cstate->anchor, cstate->fee_rate,
|
||||
htlc->msatoshis, creator, recipient, nondust))
|
||||
return false;
|
||||
|
||||
n = tal_count(creator->htlcs);
|
||||
tal_resize(&creator->htlcs, n+1);
|
||||
|
||||
creator->htlcs[n] = htlc;
|
||||
memcheck(&creator->htlcs[n]->msatoshis,
|
||||
sizeof(creator->htlcs[n]->msatoshis));
|
||||
memcheck(&creator->htlcs[n]->rhash, sizeof(creator->htlcs[n]->rhash));
|
||||
cstate->changes++;
|
||||
cstate->num_nondust = nondust;
|
||||
creator->num_htlcs++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -250,14 +200,13 @@ bool cstate_add_htlc(struct channel_state *cstate,
|
||||
static void remove_htlc(struct channel_state *cstate,
|
||||
enum channel_side creator,
|
||||
enum channel_side beneficiary,
|
||||
struct htlc *htlc)
|
||||
const struct htlc *htlc)
|
||||
{
|
||||
size_t nondust;
|
||||
size_t i, n = tal_count(cstate->side[creator].htlcs);
|
||||
|
||||
/* Remember to remove this one in total txsize if not dust! */
|
||||
nondust = total_nondust_htlcs(cstate);
|
||||
if (!is_dust_amount(htlc->msatoshis / 1000)) {
|
||||
nondust = cstate->num_nondust;
|
||||
if (!is_dust(htlc->msatoshis / 1000)) {
|
||||
assert(nondust > 0);
|
||||
nondust--;
|
||||
}
|
||||
@ -270,58 +219,25 @@ static void remove_htlc(struct channel_state *cstate,
|
||||
abort();
|
||||
|
||||
/* Actually remove the HTLC. */
|
||||
for (i = 0; i < tal_count(cstate->side[creator].htlcs); i++) {
|
||||
if (cstate->side[creator].htlcs[i] == htlc) {
|
||||
memmove(cstate->side[creator].htlcs + i,
|
||||
cstate->side[creator].htlcs + i + 1,
|
||||
(n - i - 1) * sizeof(htlc));
|
||||
tal_resize(&cstate->side[creator].htlcs, n-1);
|
||||
cstate->changes++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
assert(cstate->side[creator].num_htlcs > 0);
|
||||
cstate->side[creator].num_htlcs--;
|
||||
cstate->num_nondust = nondust;
|
||||
}
|
||||
|
||||
void cstate_fail_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side)
|
||||
void cstate_fail_htlc(struct channel_state *cstate, const struct htlc *htlc)
|
||||
{
|
||||
assert(htlc_channel_side(htlc) == side);
|
||||
remove_htlc(cstate, side, side, htlc);
|
||||
remove_htlc(cstate, htlc_channel_side(htlc), htlc_channel_side(htlc),
|
||||
htlc);
|
||||
}
|
||||
|
||||
void cstate_fulfill_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side)
|
||||
void cstate_fulfill_htlc(struct channel_state *cstate, const struct htlc *htlc)
|
||||
{
|
||||
assert(htlc_channel_side(htlc) == side);
|
||||
remove_htlc(cstate, side, !side, htlc);
|
||||
}
|
||||
|
||||
struct htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
||||
uint64_t id,
|
||||
enum channel_side side)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
||||
if (cstate->side[side].htlcs[i]->id == id)
|
||||
return cstate->side[side].htlcs[i];
|
||||
}
|
||||
return NULL;
|
||||
remove_htlc(cstate, htlc_channel_side(htlc), !htlc_channel_side(htlc),
|
||||
htlc);
|
||||
}
|
||||
|
||||
struct channel_state *copy_cstate(const tal_t *ctx,
|
||||
const struct channel_state *cstate)
|
||||
{
|
||||
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs->side); i++) {
|
||||
cs->side[i].htlcs = tal_dup_arr(cs, struct htlc *,
|
||||
cs->side[i].htlcs,
|
||||
tal_count(cs->side[i].htlcs), 0);
|
||||
}
|
||||
return cs;
|
||||
return tal_dup(ctx, struct channel_state, cstate);
|
||||
}
|
||||
|
@ -6,12 +6,13 @@
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct htlc;
|
||||
|
||||
struct channel_oneside {
|
||||
/* Payment and fee is in millisatoshi. */
|
||||
uint32_t pay_msat, fee_msat;
|
||||
/* Use tal_count to get the number */
|
||||
/* FIXME: Use htlc_map, but needs permute changes. */
|
||||
struct htlc **htlcs;
|
||||
/* Number of HTLCs (required for limiting total number) */
|
||||
unsigned int num_htlcs;
|
||||
};
|
||||
|
||||
enum channel_side {
|
||||
@ -26,8 +27,8 @@ struct channel_state {
|
||||
uint64_t anchor;
|
||||
/* Satoshis per 1000 bytes. */
|
||||
uint32_t fee_rate;
|
||||
/* Generation counter (incremented on every change) */
|
||||
uint32_t changes;
|
||||
/* Number of non-dust htlcs (to calculate txsize) */
|
||||
unsigned int num_nondust;
|
||||
struct channel_oneside side[2];
|
||||
};
|
||||
|
||||
@ -57,41 +58,31 @@ struct channel_state *copy_cstate(const tal_t *ctx,
|
||||
* cstate_add_htlc: append an HTLC to cstate if it can afford it
|
||||
* @cstate: The channel state
|
||||
* @htlc: the htlc pointer.
|
||||
* @side: OURS or THEIRS
|
||||
*
|
||||
* If that direction can't afford the HTLC (or still owes its half of the fees),
|
||||
* this will return false and leave @cstate unchanged. Otherwise
|
||||
* cstate->side[dir].htlcs will have the HTLC appended, and pay_msat and
|
||||
* this will return false and leave @cstate unchanged. Otherwise, pay_msat and
|
||||
* fee_msat are adjusted accordingly; true is returned.
|
||||
*/
|
||||
bool cstate_add_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side);
|
||||
bool cstate_add_htlc(struct channel_state *cstate, const struct htlc *htlc);
|
||||
/**
|
||||
* cstate_fail_htlc: remove an HTLC, funds to the side which offered it.
|
||||
* @cstate: The channel state
|
||||
* @htlc: the htlc in cstate->side[dir].htlcs[].
|
||||
* @side: OURS or THEIRS
|
||||
* @htlc: the htlc to remove.
|
||||
*
|
||||
* This will remove the @index'th entry in cstate->side[dir].htlcs[], and credit
|
||||
* the value of the HTLC (back) to cstate->side[dir].
|
||||
*/
|
||||
void cstate_fail_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side);
|
||||
void cstate_fail_htlc(struct channel_state *cstate, const struct htlc *htlc);
|
||||
|
||||
/**
|
||||
* cstate_fulfill_htlc: remove an HTLC, funds to side which accepted it.
|
||||
* @cstate: The channel state
|
||||
* @htlc: the htlc in cstate->side[dir].htlcs[].
|
||||
* @side: OURS or THEIRS
|
||||
* @htlc: the htlc to remove
|
||||
*
|
||||
* This will remove the @index'th entry in cstate->side[dir].htlcs[], and credit
|
||||
* the value of the HTLC to cstate->side[!dir].
|
||||
*/
|
||||
void cstate_fulfill_htlc(struct channel_state *cstate,
|
||||
struct htlc *htlc,
|
||||
enum channel_side side);
|
||||
void cstate_fulfill_htlc(struct channel_state *cstate, const struct htlc *htlc);
|
||||
|
||||
/**
|
||||
* adjust_fee: Change fee rate.
|
||||
@ -111,18 +102,6 @@ void adjust_fee(struct channel_state *cstate, uint32_t fee_rate);
|
||||
*/
|
||||
bool force_fee(struct channel_state *cstate, uint64_t fee);
|
||||
|
||||
/**
|
||||
* cstate_htlc_by_id: find an HTLC on this side of the channel by ID.
|
||||
* @cstate: The channel state
|
||||
* @id: id for HTLC.
|
||||
* @side: OURS or THEIRS
|
||||
*
|
||||
* Returns a pointer into cstate->side[@side].htlcs, or NULL.
|
||||
*/
|
||||
struct htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
||||
uint64_t id,
|
||||
enum channel_side side);
|
||||
|
||||
/**
|
||||
* fee_for_feerate: calculate the fee (in satoshi) for a given fee_rate.
|
||||
* @txsize: transaction size in bytes.
|
||||
@ -130,13 +109,4 @@ struct htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
||||
*/
|
||||
uint64_t fee_by_feerate(size_t txsize, uint32_t fee_rate);
|
||||
|
||||
/**
|
||||
* is_dust_amount: is an output of this value considered dust?
|
||||
* @satoshis: number of satoshis.
|
||||
*
|
||||
* Transactions with dust outputs will not be relayed by the bitcoin
|
||||
* network. It's not an exact definition, unfortunately.
|
||||
*/
|
||||
bool is_dust_amount(uint64_t satoshis);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_CHANNEL_H */
|
||||
|
@ -375,7 +375,7 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt, struct htlc **h)
|
||||
* A node MUST NOT add a HTLC if it would result in it
|
||||
* offering more than 300 HTLCs in the remote commitment transaction.
|
||||
*/
|
||||
if (tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs) == 300)
|
||||
if (peer->remote.staging_cstate->side[THEIRS].num_htlcs == 300)
|
||||
return pkt_err(peer, "Too many HTLCs");
|
||||
|
||||
/* BOLT #2:
|
||||
@ -403,19 +403,20 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt, struct htlc **h)
|
||||
static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
|
||||
struct htlc **local_htlc)
|
||||
{
|
||||
*local_htlc = htlc_get(&peer->htlcs, id, LOCAL);
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* A node MUST check that `id` corresponds to an HTLC in its
|
||||
* current commitment transaction, and MUST fail the
|
||||
* connection if it does not.
|
||||
*/
|
||||
if (!cstate_htlc_by_id(peer->local.commit->cstate, id, OURS))
|
||||
if (!(*local_htlc))
|
||||
return pkt_err(peer, "Did not find HTLC %"PRIu64, id);
|
||||
|
||||
/* They must not fail/fulfill twice, so it should be in staging, too. */
|
||||
*local_htlc = cstate_htlc_by_id(peer->local.staging_cstate, id, OURS);
|
||||
if (!*local_htlc)
|
||||
return pkt_err(peer, "Already removed HTLC %"PRIu64, id);
|
||||
if ((*local_htlc)->state != SENT_ADD_ACK_REVOCATION)
|
||||
return pkt_err(peer, "HTLC %"PRIu64" state %s", id,
|
||||
htlc_state_name((*local_htlc)->state));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "permute_tx.h"
|
||||
#include "protobuf_convert.h"
|
||||
#include "pseudorand.h"
|
||||
#include "remove_dust.h"
|
||||
#include "routing.h"
|
||||
#include "secrets.h"
|
||||
#include "state.h"
|
||||
@ -131,7 +132,7 @@ static const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer)
|
||||
|
||||
/* FIXME: Fail gracefully in these cases (not worth collecting) */
|
||||
if (fee > commit->output[p2wsh_out].amount
|
||||
|| is_dust_amount(commit->output[p2wsh_out].amount - fee))
|
||||
|| is_dust(commit->output[p2wsh_out].amount - fee))
|
||||
fatal("Amount of %"PRIu64" won't cover fee %"PRIu64,
|
||||
commit->output[p2wsh_out].amount, fee);
|
||||
|
||||
@ -223,8 +224,6 @@ static bool peer_uncommitted_changes(const struct peer *peer)
|
||||
|
||||
static void remote_changes_pending(struct peer *peer)
|
||||
{
|
||||
log_debug(peer->log, "remote_changes_pending: changes=%u",
|
||||
peer->remote.staging_cstate->changes);
|
||||
if (!peer->commit_timer) {
|
||||
log_debug(peer->log, "remote_changes_pending: adding timer");
|
||||
peer->commit_timer = new_reltimer(peer->dstate, peer,
|
||||
@ -547,12 +546,12 @@ static void adjust_cstate_side(struct channel_state *cstate,
|
||||
|
||||
if (old_committed && !new_committed) {
|
||||
if (h->r)
|
||||
cstate_fulfill_htlc(cstate, h, htlc_channel_side(h));
|
||||
cstate_fulfill_htlc(cstate, h);
|
||||
else
|
||||
cstate_fail_htlc(cstate, h, htlc_channel_side(h));
|
||||
cstate_fail_htlc(cstate, h);
|
||||
} else if (!old_committed && new_committed) {
|
||||
/* FIXME: This can happen; see BOLT */
|
||||
if (!cstate_add_htlc(cstate, h, htlc_channel_side(h)))
|
||||
if (!cstate_add_htlc(cstate, h))
|
||||
fatal("Could not afford htlc");
|
||||
}
|
||||
}
|
||||
@ -839,7 +838,7 @@ static Pkt *handle_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
|
||||
* "Fee Calculation" ). A node SHOULD fail the connection if
|
||||
* this occurs.
|
||||
*/
|
||||
if (!cstate_add_htlc(peer->local.staging_cstate, htlc, THEIRS)) {
|
||||
if (!cstate_add_htlc(peer->local.staging_cstate, htlc)) {
|
||||
tal_free(htlc);
|
||||
return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
|
||||
" in our commitment tx",
|
||||
@ -857,7 +856,7 @@ static Pkt *handle_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cstate_fail_htlc(peer->local.staging_cstate, htlc, OURS);
|
||||
cstate_fail_htlc(peer->local.staging_cstate, htlc);
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
@ -885,7 +884,7 @@ static Pkt *handle_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
|
||||
* ... and the receiving node MUST add the HTLC fulfill/fail
|
||||
* to the unacked changeset for its local commitment.
|
||||
*/
|
||||
cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS);
|
||||
cstate_fulfill_htlc(peer->local.staging_cstate, htlc);
|
||||
htlc_changestate(htlc, SENT_ADD_ACK_REVOCATION, RCVD_REMOVE_HTLC);
|
||||
return NULL;
|
||||
}
|
||||
@ -1204,7 +1203,7 @@ static const struct bitcoin_tx *htlc_fulfill_tx(const struct peer *peer,
|
||||
peer->dstate->config.closing_fee_rate);
|
||||
|
||||
/* FIXME: Fail gracefully in these cases (not worth collecting) */
|
||||
if (fee > satoshis || is_dust_amount(satoshis - fee))
|
||||
if (fee > satoshis || is_dust(satoshis - fee))
|
||||
fatal("HTLC fulfill amount of %"PRIu64" won't cover fee %"PRIu64,
|
||||
satoshis, fee);
|
||||
|
||||
@ -1234,9 +1233,7 @@ static bool command_htlc_fail(struct peer *peer, struct htlc *htlc)
|
||||
* The sending node MUST add the HTLC fulfill/fail to the
|
||||
* unacked changeset for its remote commitment
|
||||
*/
|
||||
assert(cstate_htlc_by_id(peer->remote.staging_cstate, htlc->id, THEIRS)
|
||||
== htlc);
|
||||
cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
||||
cstate_fail_htlc(peer->remote.staging_cstate, htlc);
|
||||
|
||||
htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC);
|
||||
|
||||
@ -1285,9 +1282,7 @@ static bool command_htlc_fulfill(struct peer *peer, struct htlc *htlc)
|
||||
* The sending node MUST add the HTLC fulfill/fail to the
|
||||
* unacked changeset for its remote commitment
|
||||
*/
|
||||
assert(cstate_htlc_by_id(peer->remote.staging_cstate, htlc->id, THEIRS)
|
||||
== htlc);
|
||||
cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
||||
cstate_fulfill_htlc(peer->remote.staging_cstate, htlc);
|
||||
|
||||
htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC);
|
||||
|
||||
@ -1329,7 +1324,7 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis,
|
||||
* A node MUST NOT add a HTLC if it would result in it
|
||||
* offering more than 300 HTLCs in the remote commitment transaction.
|
||||
*/
|
||||
if (tal_count(peer->remote.staging_cstate->side[OURS].htlcs) == 300) {
|
||||
if (peer->remote.staging_cstate->side[OURS].num_htlcs == 300) {
|
||||
log_unusual(peer->log, "add_htlc: fail: already at limit");
|
||||
return NULL;
|
||||
}
|
||||
@ -1352,7 +1347,7 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis,
|
||||
* the remote commitment transaction at the current `fee_rate`
|
||||
*/
|
||||
cstate = copy_cstate(peer, peer->remote.staging_cstate);
|
||||
if (!cstate_add_htlc(cstate, htlc, OURS)) {
|
||||
if (!cstate_add_htlc(cstate, htlc)) {
|
||||
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
||||
" milli-satoshis in their commit tx",
|
||||
msatoshis);
|
||||
@ -1361,7 +1356,7 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis,
|
||||
tal_free(cstate);
|
||||
|
||||
cstate = copy_cstate(peer, peer->local.staging_cstate);
|
||||
if (!cstate_add_htlc(cstate, htlc, OURS)) {
|
||||
if (!cstate_add_htlc(cstate, htlc)) {
|
||||
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
||||
" milli-satoshis in our commit tx",
|
||||
msatoshis);
|
||||
@ -1374,7 +1369,7 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis,
|
||||
* The sending node MUST add the HTLC addition to the unacked
|
||||
* changeset for its remote commitment
|
||||
*/
|
||||
if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS))
|
||||
if (!cstate_add_htlc(peer->remote.staging_cstate, htlc))
|
||||
fatal("Could not add HTLC?");
|
||||
|
||||
remote_changes_pending(peer);
|
||||
@ -1538,11 +1533,12 @@ static void do_commit(struct peer *peer, struct command *jsoncmd)
|
||||
ci->cstate, REMOTE);
|
||||
bitcoin_txid(ci->tx, &ci->txid);
|
||||
|
||||
log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs",
|
||||
log_debug(peer->log, "Signing tx for %u/%u msatoshis, %u/%u htlcs (%u non-dust)",
|
||||
ci->cstate->side[OURS].pay_msat,
|
||||
ci->cstate->side[THEIRS].pay_msat,
|
||||
tal_count(ci->cstate->side[OURS].htlcs),
|
||||
tal_count(ci->cstate->side[THEIRS].htlcs));
|
||||
ci->cstate->side[OURS].num_htlcs,
|
||||
ci->cstate->side[THEIRS].num_htlcs,
|
||||
ci->cstate->num_nondust);
|
||||
log_add_struct(peer->log, " (txid %s)", struct sha256_double, &ci->txid);
|
||||
|
||||
ci->sig = tal(ci, struct bitcoin_signature);
|
||||
@ -1963,18 +1959,23 @@ const struct json_command connect_command = {
|
||||
};
|
||||
|
||||
/* Have any of our HTLCs passed their deadline? */
|
||||
static bool any_deadline_past(struct peer *peer,
|
||||
const struct channel_state *cstate)
|
||||
static bool any_deadline_past(struct peer *peer)
|
||||
{
|
||||
size_t i;
|
||||
u32 height = get_block_height(peer->dstate);
|
||||
struct htlc **htlcs = cstate->side[OURS].htlcs;
|
||||
struct htlc_map_iter it;
|
||||
struct htlc *h;
|
||||
|
||||
for (i = 0; i < tal_count(htlcs); i++) {
|
||||
if (height >= htlcs[i]->deadline) {
|
||||
for (h = htlc_map_first(&peer->htlcs, &it);
|
||||
h;
|
||||
h = htlc_map_next(&peer->htlcs, &it)) {
|
||||
if (htlc_is_dead(h))
|
||||
continue;
|
||||
if (htlc_owner(h) != LOCAL)
|
||||
continue;
|
||||
if (height >= h->deadline) {
|
||||
log_unusual_struct(peer->log,
|
||||
"HTLC %s deadline has passed",
|
||||
struct htlc, htlcs[i]);
|
||||
struct htlc, h);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1983,26 +1984,28 @@ static bool any_deadline_past(struct peer *peer,
|
||||
|
||||
static void check_htlc_expiry(struct peer *peer)
|
||||
{
|
||||
size_t i;
|
||||
u32 height = get_block_height(peer->dstate);
|
||||
struct htlc_map_iter it;
|
||||
struct htlc *h;
|
||||
|
||||
again:
|
||||
/* Check their currently still-existing htlcs for expiry:
|
||||
* We eliminate them from staging as we go. */
|
||||
for (i = 0; i < tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs); i++) {
|
||||
struct htlc *htlc = peer->remote.staging_cstate->side[THEIRS].htlcs[i];
|
||||
/* Check their currently still-existing htlcs for expiry */
|
||||
for (h = htlc_map_first(&peer->htlcs, &it);
|
||||
h;
|
||||
h = htlc_map_next(&peer->htlcs, &it)) {
|
||||
assert(!abs_locktime_is_seconds(&h->expiry));
|
||||
|
||||
assert(!abs_locktime_is_seconds(&htlc->expiry));
|
||||
/* Only their consider HTLCs which are completely locked in. */
|
||||
if (h->state != RCVD_ADD_ACK_REVOCATION)
|
||||
continue;
|
||||
|
||||
/* We give it an extra block, to avoid the worst of the
|
||||
* inter-node timing issues. */
|
||||
if (height <= abs_locktime_to_blocks(&htlc->expiry))
|
||||
if (height <= abs_locktime_to_blocks(&h->expiry))
|
||||
continue;
|
||||
|
||||
/* This can fail only if we're in an error state. */
|
||||
if (!command_htlc_fail(peer, htlc))
|
||||
if (!command_htlc_fail(peer, h))
|
||||
return;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
@ -2019,10 +2022,7 @@ again:
|
||||
if (!state_is_normal(peer->state))
|
||||
return;
|
||||
|
||||
if (any_deadline_past(peer, peer->remote.staging_cstate)
|
||||
|| any_deadline_past(peer, peer->local.staging_cstate)
|
||||
|| any_deadline_past(peer, peer->remote.commit->cstate)
|
||||
|| any_deadline_past(peer, peer->local.commit->cstate)) {
|
||||
if (any_deadline_past(peer)) {
|
||||
set_peer_state(peer, STATE_ERR_BREAKDOWN, __func__);
|
||||
peer_breakdown(peer);
|
||||
}
|
||||
@ -2191,7 +2191,7 @@ static const struct bitcoin_tx *htlc_timeout_tx(const struct peer *peer,
|
||||
peer->dstate->config.closing_fee_rate);
|
||||
|
||||
/* FIXME: Fail gracefully in these cases (not worth collecting) */
|
||||
if (fee > satoshis || is_dust_amount(satoshis - fee))
|
||||
if (fee > satoshis || is_dust(satoshis - fee))
|
||||
fatal("HTLC refund amount of %"PRIu64" won't cover fee %"PRIu64,
|
||||
satoshis, fee);
|
||||
|
||||
@ -2735,7 +2735,7 @@ static void resolve_their_steal(struct peer *peer,
|
||||
fee = peer->dstate->config.closing_fee_rate
|
||||
* (measure_tx_cost(steal_tx) + wsize) / 1000;
|
||||
|
||||
if (fee > input_total || is_dust_amount(input_total - fee)) {
|
||||
if (fee > input_total || is_dust(input_total - fee)) {
|
||||
log_unusual(peer->log, "Not worth stealing tiny amount %"PRIu64,
|
||||
input_total);
|
||||
/* Consider them all resolved by steal tx. */
|
||||
|
@ -9,8 +9,15 @@ void remove_dust(struct bitcoin_tx *tx, int *map);
|
||||
/* Less than this is dust. */
|
||||
#define DUST_THRESHOLD 546
|
||||
|
||||
static inline bool is_dust(u64 amount)
|
||||
/**
|
||||
* is_dust: is an output of this value considered dust?
|
||||
* @satoshis: number of satoshis.
|
||||
*
|
||||
* Transactions with dust outputs will not be relayed by the bitcoin
|
||||
* network. It's not an exact definition, unfortunately.
|
||||
*/
|
||||
static inline bool is_dust(u64 satoshis)
|
||||
{
|
||||
return amount < DUST_THRESHOLD;
|
||||
return satoshis < DUST_THRESHOLD;
|
||||
}
|
||||
#endif /* LIGHTNING_REMOVE_DUST_H */
|
||||
|
Loading…
Reference in New Issue
Block a user