mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 23:54:22 +01:00
daemon: use htlc pointers everywhere.
No more copies! I tried changing the cstate->side[].htlcs to htlc_map rather than a simple pointer array, but we rely on those array indices heavily for permutation mapping, and it turned into a major rewrite (especially for the steal case). Eventually, we're going to want to reconstruct the commit info for older commit txs rather than keeping all the permutation and per-commit-info HTLC information in memory, so we can do the work then. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static bool add_htlc(struct bitcoin_tx *tx, size_t n,
|
static bool add_htlc(struct bitcoin_tx *tx, size_t n,
|
||||||
const struct channel_htlc *h,
|
const struct htlc *h,
|
||||||
const struct pubkey *ourkey,
|
const struct pubkey *ourkey,
|
||||||
const struct pubkey *theirkey,
|
const struct pubkey *theirkey,
|
||||||
const struct sha256 *rhash,
|
const struct sha256 *rhash,
|
||||||
@@ -96,7 +96,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
|||||||
|
|
||||||
/* HTLCs this side sent. */
|
/* HTLCs this side sent. */
|
||||||
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
||||||
if (!add_htlc(tx, num, &cstate->side[side].htlcs[i],
|
if (!add_htlc(tx, num, cstate->side[side].htlcs[i],
|
||||||
self, other, rhash, locktime,
|
self, other, rhash, locktime,
|
||||||
bitcoin_redeem_htlc_send))
|
bitcoin_redeem_htlc_send))
|
||||||
return tal_free(tx);
|
return tal_free(tx);
|
||||||
@@ -104,7 +104,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
|||||||
}
|
}
|
||||||
/* HTLCs this side has received. */
|
/* HTLCs this side has received. */
|
||||||
for (i = 0; i < tal_count(cstate->side[!side].htlcs); i++) {
|
for (i = 0; i < tal_count(cstate->side[!side].htlcs); i++) {
|
||||||
if (!add_htlc(tx, num, &cstate->side[!side].htlcs[i],
|
if (!add_htlc(tx, num, cstate->side[!side].htlcs[i],
|
||||||
self, other, rhash, locktime,
|
self, other, rhash, locktime,
|
||||||
bitcoin_redeem_htlc_recv))
|
bitcoin_redeem_htlc_recv))
|
||||||
return tal_free(tx);
|
return tal_free(tx);
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ static uint64_t calculate_fee_msat(size_t num_nondust_htlcs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Total, in millisatoshi. */
|
/* Total, in millisatoshi. */
|
||||||
static uint64_t htlcs_total(const struct channel_htlc *htlcs)
|
static uint64_t htlcs_total(struct htlc **htlcs)
|
||||||
{
|
{
|
||||||
size_t i, n = tal_count(htlcs);
|
size_t i, n = tal_count(htlcs);
|
||||||
uint64_t total = 0;
|
uint64_t total = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
total += htlcs[i].msatoshis;
|
total += htlcs[i]->msatoshis;
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,8 +152,8 @@ struct channel_state *initial_cstate(const tal_t *ctx,
|
|||||||
fundee = &cstate->side[!funding];
|
fundee = &cstate->side[!funding];
|
||||||
|
|
||||||
/* Neither side has HTLCs. */
|
/* Neither side has HTLCs. */
|
||||||
funder->htlcs = tal_arr(cstate, struct channel_htlc, 0);
|
funder->htlcs = tal_arr(cstate, struct htlc *, 0);
|
||||||
fundee->htlcs = tal_arr(cstate, struct channel_htlc, 0);
|
fundee->htlcs = tal_arr(cstate, struct htlc *, 0);
|
||||||
|
|
||||||
/* Initially, all goes back to funder. */
|
/* Initially, all goes back to funder. */
|
||||||
funder->pay_msat = anchor_satoshis * 1000 - fee_msat;
|
funder->pay_msat = anchor_satoshis * 1000 - fee_msat;
|
||||||
@@ -174,12 +174,12 @@ bool is_dust_amount(uint64_t satoshis)
|
|||||||
return satoshis < 546;
|
return satoshis < 546;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t count_nondust_htlcs(const struct channel_htlc *htlcs)
|
static size_t count_nondust_htlcs(struct htlc **htlcs)
|
||||||
{
|
{
|
||||||
size_t i, n = tal_count(htlcs), nondust = 0;
|
size_t i, n = tal_count(htlcs), nondust = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
if (!is_dust_amount(htlcs[i].msatoshis / 1000))
|
if (!is_dust_amount(htlcs[i]->msatoshis / 1000))
|
||||||
nondust++;
|
nondust++;
|
||||||
return nondust;
|
return nondust;
|
||||||
}
|
}
|
||||||
@@ -211,13 +211,8 @@ bool force_fee(struct channel_state *cstate, uint64_t fee)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add a HTLC to @creator if it can afford it. */
|
/* Add a HTLC to @creator if it can afford it. */
|
||||||
struct channel_htlc *cstate_add_htlc(struct channel_state *cstate,
|
bool cstate_add_htlc(struct channel_state *cstate,
|
||||||
u32 msatoshis,
|
struct htlc *htlc,
|
||||||
const struct abs_locktime *expiry,
|
|
||||||
const struct sha256 *rhash,
|
|
||||||
uint64_t id,
|
|
||||||
const u8 *routing,
|
|
||||||
size_t routing_len,
|
|
||||||
enum channel_side side)
|
enum channel_side side)
|
||||||
{
|
{
|
||||||
size_t n, nondust;
|
size_t n, nondust;
|
||||||
@@ -228,42 +223,32 @@ struct channel_htlc *cstate_add_htlc(struct channel_state *cstate,
|
|||||||
|
|
||||||
/* Remember to count the new one in total txsize if not dust! */
|
/* Remember to count the new one in total txsize if not dust! */
|
||||||
nondust = total_nondust_htlcs(cstate);
|
nondust = total_nondust_htlcs(cstate);
|
||||||
if (!is_dust_amount(msatoshis / 1000))
|
if (!is_dust_amount(htlc->msatoshis / 1000))
|
||||||
nondust++;
|
nondust++;
|
||||||
|
|
||||||
if (!change_funding(cstate->anchor, cstate->fee_rate,
|
if (!change_funding(cstate->anchor, cstate->fee_rate,
|
||||||
msatoshis, creator, recipient, nondust))
|
htlc->msatoshis, creator, recipient, nondust))
|
||||||
return NULL;
|
return false;
|
||||||
|
|
||||||
n = tal_count(creator->htlcs);
|
n = tal_count(creator->htlcs);
|
||||||
tal_resize(&creator->htlcs, n+1);
|
tal_resize(&creator->htlcs, n+1);
|
||||||
|
|
||||||
creator->htlcs[n].msatoshis = msatoshis;
|
creator->htlcs[n] = htlc;
|
||||||
creator->htlcs[n].expiry = *expiry;
|
memcheck(&creator->htlcs[n]->msatoshis,
|
||||||
creator->htlcs[n].rhash = *rhash;
|
sizeof(creator->htlcs[n]->msatoshis));
|
||||||
creator->htlcs[n].id = id;
|
memcheck(&creator->htlcs[n]->rhash, sizeof(creator->htlcs[n]->rhash));
|
||||||
creator->htlcs[n].routing = tal_dup_arr(cstate, u8, routing,
|
|
||||||
routing_len, 0);
|
|
||||||
memcheck(&creator->htlcs[n].msatoshis,
|
|
||||||
sizeof(creator->htlcs[n].msatoshis));
|
|
||||||
memcheck(&creator->htlcs[n].rhash, sizeof(creator->htlcs[n].rhash));
|
|
||||||
cstate->changes++;
|
cstate->changes++;
|
||||||
return &creator->htlcs[n];
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove htlc from creator, credit it to beneficiary. */
|
/* Remove htlc from creator, credit it to beneficiary. */
|
||||||
static void remove_htlc(struct channel_state *cstate,
|
static void remove_htlc(struct channel_state *cstate,
|
||||||
enum channel_side creator,
|
enum channel_side creator,
|
||||||
enum channel_side beneficiary,
|
enum channel_side beneficiary,
|
||||||
struct channel_htlc *htlc)
|
struct htlc *htlc)
|
||||||
{
|
{
|
||||||
size_t nondust;
|
size_t nondust;
|
||||||
size_t n = tal_count(cstate->side[creator].htlcs);
|
size_t i, n = tal_count(cstate->side[creator].htlcs);
|
||||||
const struct channel_htlc *end;
|
|
||||||
|
|
||||||
end = cstate->side[creator].htlcs + n;
|
|
||||||
|
|
||||||
assert(htlc >= cstate->side[creator].htlcs && htlc < end);
|
|
||||||
|
|
||||||
/* Remember to remove this one in total txsize if not dust! */
|
/* Remember to remove this one in total txsize if not dust! */
|
||||||
nondust = total_nondust_htlcs(cstate);
|
nondust = total_nondust_htlcs(cstate);
|
||||||
@@ -280,48 +265,55 @@ static void remove_htlc(struct channel_state *cstate,
|
|||||||
abort();
|
abort();
|
||||||
|
|
||||||
/* Actually remove the HTLC. */
|
/* Actually remove the HTLC. */
|
||||||
tal_free(htlc->routing);
|
for (i = 0; i < tal_count(cstate->side[creator].htlcs); i++) {
|
||||||
memmove(htlc, htlc + 1, (end - htlc - 1) * sizeof(*htlc));
|
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);
|
tal_resize(&cstate->side[creator].htlcs, n-1);
|
||||||
cstate->changes++;
|
cstate->changes++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cstate_fail_htlc(struct channel_state *cstate,
|
void cstate_fail_htlc(struct channel_state *cstate,
|
||||||
struct channel_htlc *htlc,
|
struct htlc *htlc,
|
||||||
enum channel_side side)
|
enum channel_side side)
|
||||||
{
|
{
|
||||||
remove_htlc(cstate, side, side, htlc);
|
remove_htlc(cstate, side, side, htlc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cstate_fulfill_htlc(struct channel_state *cstate,
|
void cstate_fulfill_htlc(struct channel_state *cstate,
|
||||||
struct channel_htlc *htlc,
|
struct htlc *htlc,
|
||||||
enum channel_side side)
|
enum channel_side side)
|
||||||
{
|
{
|
||||||
remove_htlc(cstate, side, !side, htlc);
|
remove_htlc(cstate, side, !side, htlc);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cstate_find_htlc(const struct channel_state *cstate,
|
struct htlc *cstate_find_htlc(const struct channel_state *cstate,
|
||||||
const struct sha256 *rhash,
|
const struct sha256 *rhash,
|
||||||
enum channel_side side)
|
enum channel_side side)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
||||||
if (structeq(&cstate->side[side].htlcs[i].rhash, rhash))
|
if (structeq(&cstate->side[side].htlcs[i]->rhash, rhash))
|
||||||
return i;
|
return cstate->side[side].htlcs[i];
|
||||||
}
|
}
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct channel_htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
struct htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
||||||
uint64_t id,
|
uint64_t id,
|
||||||
enum channel_side side)
|
enum channel_side side)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
||||||
if (cstate->side[side].htlcs[i].id == id)
|
if (cstate->side[side].htlcs[i]->id == id)
|
||||||
return &cstate->side[side].htlcs[i];
|
return cstate->side[side].htlcs[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -330,19 +322,12 @@ struct channel_state *copy_cstate(const tal_t *ctx,
|
|||||||
const struct channel_state *cstate)
|
const struct channel_state *cstate)
|
||||||
{
|
{
|
||||||
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
|
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
|
||||||
size_t i, j;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cs->side); i++) {
|
for (i = 0; i < ARRAY_SIZE(cs->side); i++) {
|
||||||
cs->side[i].htlcs = tal_dup_arr(cs, struct channel_htlc,
|
cs->side[i].htlcs = tal_dup_arr(cs, struct htlc *,
|
||||||
cs->side[i].htlcs,
|
cs->side[i].htlcs,
|
||||||
tal_count(cs->side[i].htlcs), 0);
|
tal_count(cs->side[i].htlcs), 0);
|
||||||
for (j = 0; j < tal_count(cs->side[i].htlcs); j++) {
|
|
||||||
struct channel_htlc *h = &cs->side[i].htlcs[j];
|
|
||||||
h->routing = tal_dup_arr(cs, u8,
|
|
||||||
h->routing,
|
|
||||||
tal_count(h->routing),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,17 @@
|
|||||||
#define LIGHTNING_DAEMON_CHANNEL_H
|
#define LIGHTNING_DAEMON_CHANNEL_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "bitcoin/locktime.h"
|
#include "bitcoin/locktime.h"
|
||||||
|
#include "htlc.h"
|
||||||
#include <ccan/crypto/sha256/sha256.h>
|
#include <ccan/crypto/sha256/sha256.h>
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct channel_htlc {
|
|
||||||
u64 id;
|
|
||||||
u64 msatoshis;
|
|
||||||
struct abs_locktime expiry;
|
|
||||||
struct sha256 rhash;
|
|
||||||
const u8 *routing;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct channel_oneside {
|
struct channel_oneside {
|
||||||
/* Payment and fee is in millisatoshi. */
|
/* Payment and fee is in millisatoshi. */
|
||||||
uint32_t pay_msat, fee_msat;
|
uint32_t pay_msat, fee_msat;
|
||||||
/* Use tal_count to get the number */
|
/* Use tal_count to get the number */
|
||||||
struct channel_htlc *htlcs;
|
/* FIXME: Use htlc_map, but needs permute changes. */
|
||||||
|
struct htlc **htlcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum channel_side {
|
enum channel_side {
|
||||||
@@ -63,27 +57,16 @@ struct channel_state *copy_cstate(const tal_t *ctx,
|
|||||||
/**
|
/**
|
||||||
* cstate_add_htlc: append an HTLC to cstate if it can afford it
|
* cstate_add_htlc: append an HTLC to cstate if it can afford it
|
||||||
* @cstate: The channel state
|
* @cstate: The channel state
|
||||||
* @msatoshis: Millisatoshi going into a HTLC
|
* @htlc: the htlc pointer.
|
||||||
* @expiry: time it expires
|
|
||||||
* @rhash: hash of redeem secret
|
|
||||||
* @id: 64-bit ID for htlc
|
|
||||||
* @routing: onion routing blob
|
|
||||||
* @routing_len: onion routing blob length
|
|
||||||
* @side: OURS or THEIRS
|
* @side: OURS or THEIRS
|
||||||
*
|
*
|
||||||
* If that direction can't afford the HTLC (or still owes its half of the fees),
|
* If that direction can't afford the HTLC (or still owes its half of the fees),
|
||||||
* this will return NULL and leave @cstate unchanged. Otherwise
|
* this will return false and leave @cstate unchanged. Otherwise
|
||||||
* cstate->side[dir].htlcs will have the HTLC appended, and pay_msat and
|
* cstate->side[dir].htlcs will have the HTLC appended, and pay_msat and
|
||||||
* fee_msat are adjusted accordingly; &cstate->side[dir].htlcs[<last>]
|
* fee_msat are adjusted accordingly; true is returned.
|
||||||
* is returned.
|
|
||||||
*/
|
*/
|
||||||
struct channel_htlc *cstate_add_htlc(struct channel_state *cstate,
|
bool cstate_add_htlc(struct channel_state *cstate,
|
||||||
u32 msatoshis,
|
struct htlc *htlc,
|
||||||
const struct abs_locktime *expiry,
|
|
||||||
const struct sha256 *rhash,
|
|
||||||
uint64_t id,
|
|
||||||
const u8 *routing,
|
|
||||||
size_t routing_len,
|
|
||||||
enum channel_side side);
|
enum channel_side side);
|
||||||
/**
|
/**
|
||||||
* cstate_fail_htlc: remove an HTLC, funds to the side which offered it.
|
* cstate_fail_htlc: remove an HTLC, funds to the side which offered it.
|
||||||
@@ -95,7 +78,7 @@ struct channel_htlc *cstate_add_htlc(struct channel_state *cstate,
|
|||||||
* the value of the HTLC (back) to cstate->side[dir].
|
* the value of the HTLC (back) to cstate->side[dir].
|
||||||
*/
|
*/
|
||||||
void cstate_fail_htlc(struct channel_state *cstate,
|
void cstate_fail_htlc(struct channel_state *cstate,
|
||||||
struct channel_htlc *htlc,
|
struct htlc *htlc,
|
||||||
enum channel_side side);
|
enum channel_side side);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,7 +91,7 @@ void cstate_fail_htlc(struct channel_state *cstate,
|
|||||||
* the value of the HTLC to cstate->side[!dir].
|
* the value of the HTLC to cstate->side[!dir].
|
||||||
*/
|
*/
|
||||||
void cstate_fulfill_htlc(struct channel_state *cstate,
|
void cstate_fulfill_htlc(struct channel_state *cstate,
|
||||||
struct channel_htlc *htlc,
|
struct htlc *htlc,
|
||||||
enum channel_side side);
|
enum channel_side side);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,9 +118,9 @@ bool force_fee(struct channel_state *cstate, uint64_t fee);
|
|||||||
* @rhash: hash of redeem secret
|
* @rhash: hash of redeem secret
|
||||||
* @side: OURS or THEIRS
|
* @side: OURS or THEIRS
|
||||||
*
|
*
|
||||||
* Returns a number < tal_count(cstate->side[dir].htlcs), or -1 on fail.
|
* Returns the HTLC, or NULL on fail.
|
||||||
*/
|
*/
|
||||||
size_t cstate_find_htlc(const struct channel_state *cstate,
|
struct htlc *cstate_find_htlc(const struct channel_state *cstate,
|
||||||
const struct sha256 *rhash,
|
const struct sha256 *rhash,
|
||||||
enum channel_side side);
|
enum channel_side side);
|
||||||
|
|
||||||
@@ -149,7 +132,7 @@ size_t cstate_find_htlc(const struct channel_state *cstate,
|
|||||||
*
|
*
|
||||||
* Returns a pointer into cstate->side[@side].htlcs, or NULL.
|
* Returns a pointer into cstate->side[@side].htlcs, or NULL.
|
||||||
*/
|
*/
|
||||||
struct channel_htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
struct htlc *cstate_htlc_by_id(const struct channel_state *cstate,
|
||||||
uint64_t id,
|
uint64_t id,
|
||||||
enum channel_side side);
|
enum channel_side side);
|
||||||
|
|
||||||
|
|||||||
116
daemon/packets.c
116
daemon/packets.c
@@ -4,6 +4,7 @@
|
|||||||
#include "commit_tx.h"
|
#include "commit_tx.h"
|
||||||
#include "controlled_time.h"
|
#include "controlled_time.h"
|
||||||
#include "cryptopkt.h"
|
#include "cryptopkt.h"
|
||||||
|
#include "htlc.h"
|
||||||
#include "lightningd.h"
|
#include "lightningd.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "names.h"
|
#include "names.h"
|
||||||
@@ -168,29 +169,23 @@ void queue_pkt_open_complete(struct peer *peer)
|
|||||||
queue_pkt(peer, PKT__PKT_OPEN_COMPLETE, o);
|
queue_pkt(peer, PKT__PKT_OPEN_COMPLETE, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_pkt_htlc_add(struct peer *peer,
|
void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc)
|
||||||
u64 id,
|
|
||||||
u64 msatoshis,
|
|
||||||
const struct sha256 *rhash,
|
|
||||||
u32 expiry,
|
|
||||||
const u8 *route)
|
|
||||||
{
|
{
|
||||||
UpdateAddHtlc *u = tal(peer, UpdateAddHtlc);
|
UpdateAddHtlc *u = tal(peer, UpdateAddHtlc);
|
||||||
union htlc_staging stage;
|
union htlc_staging stage;
|
||||||
struct abs_locktime locktime;
|
|
||||||
struct channel_htlc *htlc;
|
|
||||||
|
|
||||||
update_add_htlc__init(u);
|
update_add_htlc__init(u);
|
||||||
|
|
||||||
u->id = id;
|
u->id = htlc->id;
|
||||||
u->amount_msat = msatoshis;
|
u->amount_msat = htlc->msatoshis;
|
||||||
u->r_hash = sha256_to_proto(u, rhash);
|
u->r_hash = sha256_to_proto(u, &htlc->rhash);
|
||||||
if (!blocks_to_abs_locktime(expiry, &locktime))
|
u->expiry = abs_locktime_to_proto(u, &htlc->expiry);
|
||||||
fatal("Invalid locktime?");
|
|
||||||
u->expiry = abs_locktime_to_proto(u, &locktime);
|
|
||||||
u->route = tal(u, Routing);
|
u->route = tal(u, Routing);
|
||||||
routing__init(u->route);
|
routing__init(u->route);
|
||||||
u->route->info.data = tal_dup_arr(u, u8, route, tal_count(route), 0);
|
u->route->info.data = tal_dup_arr(u, u8,
|
||||||
|
htlc->routing,
|
||||||
|
tal_count(htlc->routing),
|
||||||
|
0);
|
||||||
u->route->info.len = tal_count(u->route->info.data);
|
u->route->info.len = tal_count(u->route->info.data);
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
@@ -198,16 +193,11 @@ void queue_pkt_htlc_add(struct peer *peer,
|
|||||||
* The sending node MUST add the HTLC addition to the unacked
|
* The sending node MUST add the HTLC addition to the unacked
|
||||||
* changeset for its remote commitment
|
* changeset for its remote commitment
|
||||||
*/
|
*/
|
||||||
htlc = cstate_add_htlc(peer->remote.staging_cstate,
|
if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS))
|
||||||
msatoshis, &locktime, rhash, id,
|
|
||||||
route, tal_count(route), OURS);
|
|
||||||
if (!htlc)
|
|
||||||
fatal("Could not add HTLC?");
|
fatal("Could not add HTLC?");
|
||||||
|
|
||||||
stage.add.add = HTLC_ADD;
|
stage.add.add = HTLC_ADD;
|
||||||
/* FIXME: This assumes stage's lifetime >= htlc, since we copy
|
stage.add.htlc = htlc;
|
||||||
* htlc.route pointer. Why not just make stage.add.htlc a ptr? */
|
|
||||||
stage.add.htlc = *htlc;
|
|
||||||
add_unacked(&peer->remote, &stage);
|
add_unacked(&peer->remote, &stage);
|
||||||
|
|
||||||
remote_changes_pending(peer);
|
remote_changes_pending(peer);
|
||||||
@@ -215,14 +205,14 @@ void queue_pkt_htlc_add(struct peer *peer,
|
|||||||
queue_pkt(peer, PKT__PKT_UPDATE_ADD_HTLC, u);
|
queue_pkt(peer, PKT__PKT_UPDATE_ADD_HTLC, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_pkt_htlc_fulfill(struct peer *peer, u64 id, const struct rval *r)
|
void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc,
|
||||||
|
const struct rval *r)
|
||||||
{
|
{
|
||||||
UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc);
|
UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc);
|
||||||
struct channel_htlc *htlc;
|
|
||||||
union htlc_staging stage;
|
union htlc_staging stage;
|
||||||
|
|
||||||
update_fulfill_htlc__init(f);
|
update_fulfill_htlc__init(f);
|
||||||
f->id = id;
|
f->id = htlc->id;
|
||||||
f->r = rval_to_proto(f, r);
|
f->r = rval_to_proto(f, r);
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
@@ -230,12 +220,12 @@ void queue_pkt_htlc_fulfill(struct peer *peer, u64 id, const struct rval *r)
|
|||||||
* The sending node MUST add the HTLC fulfill/fail to the
|
* The sending node MUST add the HTLC fulfill/fail to the
|
||||||
* unacked changeset for its remote commitment
|
* unacked changeset for its remote commitment
|
||||||
*/
|
*/
|
||||||
htlc = cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS);
|
assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS)
|
||||||
assert(htlc);
|
== htlc);
|
||||||
cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
||||||
|
|
||||||
stage.fulfill.fulfill = HTLC_FULFILL;
|
stage.fulfill.fulfill = HTLC_FULFILL;
|
||||||
stage.fulfill.id = f->id;
|
stage.fulfill.htlc = htlc;
|
||||||
stage.fulfill.r = *r;
|
stage.fulfill.r = *r;
|
||||||
add_unacked(&peer->remote, &stage);
|
add_unacked(&peer->remote, &stage);
|
||||||
|
|
||||||
@@ -244,14 +234,13 @@ void queue_pkt_htlc_fulfill(struct peer *peer, u64 id, const struct rval *r)
|
|||||||
queue_pkt(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f);
|
queue_pkt(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_pkt_htlc_fail(struct peer *peer, u64 id)
|
void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc)
|
||||||
{
|
{
|
||||||
UpdateFailHtlc *f = tal(peer, UpdateFailHtlc);
|
UpdateFailHtlc *f = tal(peer, UpdateFailHtlc);
|
||||||
struct channel_htlc *htlc;
|
|
||||||
union htlc_staging stage;
|
union htlc_staging stage;
|
||||||
|
|
||||||
update_fail_htlc__init(f);
|
update_fail_htlc__init(f);
|
||||||
f->id = id;
|
f->id = htlc->id;
|
||||||
|
|
||||||
/* FIXME: reason! */
|
/* FIXME: reason! */
|
||||||
f->reason = tal(f, FailReason);
|
f->reason = tal(f, FailReason);
|
||||||
@@ -262,12 +251,12 @@ void queue_pkt_htlc_fail(struct peer *peer, u64 id)
|
|||||||
* The sending node MUST add the HTLC fulfill/fail to the
|
* The sending node MUST add the HTLC fulfill/fail to the
|
||||||
* unacked changeset for its remote commitment
|
* unacked changeset for its remote commitment
|
||||||
*/
|
*/
|
||||||
htlc = cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS);
|
assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS)
|
||||||
assert(htlc);
|
== htlc);
|
||||||
cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS);
|
||||||
|
|
||||||
stage.fail.fail = HTLC_FAIL;
|
stage.fail.fail = HTLC_FAIL;
|
||||||
stage.fail.id = f->id;
|
stage.fail.htlc = htlc;
|
||||||
add_unacked(&peer->remote, &stage);
|
add_unacked(&peer->remote, &stage);
|
||||||
|
|
||||||
remote_changes_pending(peer);
|
remote_changes_pending(peer);
|
||||||
@@ -338,41 +327,38 @@ static void apply_changeset(struct peer *peer,
|
|||||||
size_t num_changes)
|
size_t num_changes)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
struct channel_htlc *htlc;
|
struct htlc *htlc;
|
||||||
|
|
||||||
for (i = 0; i < num_changes; i++) {
|
for (i = 0; i < num_changes; i++) {
|
||||||
switch (changes[i].type) {
|
switch (changes[i].type) {
|
||||||
case HTLC_ADD:
|
case HTLC_ADD:
|
||||||
htlc = cstate_htlc_by_id(which->staging_cstate,
|
htlc = cstate_htlc_by_id(which->staging_cstate,
|
||||||
changes[i].add.htlc.id, side);
|
changes[i].add.htlc->id, side);
|
||||||
if (htlc)
|
if (htlc)
|
||||||
fatal("Can't add duplicate HTLC id %"PRIu64,
|
fatal("Can't add duplicate HTLC id %"PRIu64,
|
||||||
changes[i].add.htlc.id);
|
changes[i].add.htlc->id);
|
||||||
if (!cstate_add_htlc(which->staging_cstate,
|
if (!cstate_add_htlc(which->staging_cstate,
|
||||||
changes[i].add.htlc.msatoshis,
|
changes[i].add.htlc,
|
||||||
&changes[i].add.htlc.expiry,
|
|
||||||
&changes[i].add.htlc.rhash,
|
|
||||||
changes[i].add.htlc.id,
|
|
||||||
changes[i].add.htlc.routing,
|
|
||||||
tal_count(changes[i].add.htlc.routing),
|
|
||||||
side))
|
side))
|
||||||
fatal("Adding HTLC to %s failed",
|
fatal("Adding HTLC to %s failed",
|
||||||
side == OURS ? "ours" : "theirs");
|
side == OURS ? "ours" : "theirs");
|
||||||
continue;
|
continue;
|
||||||
case HTLC_FAIL:
|
case HTLC_FAIL:
|
||||||
htlc = cstate_htlc_by_id(which->staging_cstate,
|
htlc = cstate_htlc_by_id(which->staging_cstate,
|
||||||
changes[i].fail.id, !side);
|
changes[i].fail.htlc->id,
|
||||||
|
!side);
|
||||||
if (!htlc)
|
if (!htlc)
|
||||||
fatal("Can't fail non-exisent HTLC id %"PRIu64,
|
fatal("Can't fail non-exisent HTLC id %"PRIu64,
|
||||||
changes[i].fail.id);
|
changes[i].fail.htlc->id);
|
||||||
cstate_fail_htlc(which->staging_cstate, htlc, !side);
|
cstate_fail_htlc(which->staging_cstate, htlc, !side);
|
||||||
continue;
|
continue;
|
||||||
case HTLC_FULFILL:
|
case HTLC_FULFILL:
|
||||||
htlc = cstate_htlc_by_id(which->staging_cstate,
|
htlc = cstate_htlc_by_id(which->staging_cstate,
|
||||||
changes[i].fulfill.id, !side);
|
changes[i].fulfill.htlc->id,
|
||||||
|
!side);
|
||||||
if (!htlc)
|
if (!htlc)
|
||||||
fatal("Can't fulfill non-exisent HTLC id %"PRIu64,
|
fatal("Can't fulfill non-exisent HTLC id %"PRIu64,
|
||||||
changes[i].fulfill.id);
|
changes[i].fulfill.htlc->id);
|
||||||
cstate_fulfill_htlc(which->staging_cstate, htlc, !side);
|
cstate_fulfill_htlc(which->staging_cstate, htlc, !side);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -613,7 +599,7 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
|
|||||||
const UpdateAddHtlc *u = pkt->update_add_htlc;
|
const UpdateAddHtlc *u = pkt->update_add_htlc;
|
||||||
struct sha256 rhash;
|
struct sha256 rhash;
|
||||||
struct abs_locktime expiry;
|
struct abs_locktime expiry;
|
||||||
struct channel_htlc *htlc;
|
struct htlc *htlc;
|
||||||
union htlc_staging stage;
|
union htlc_staging stage;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
@@ -647,22 +633,15 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
|
|||||||
/* Note that it's not *our* problem if they do this, it's
|
/* Note that it's not *our* problem if they do this, it's
|
||||||
* theirs (future confusion). Nonetheless, we detect and
|
* theirs (future confusion). Nonetheless, we detect and
|
||||||
* error for them. */
|
* error for them. */
|
||||||
if (cstate_htlc_by_id(peer->remote.staging_cstate, u->id, THEIRS)
|
if (htlc_map_get(&peer->remote.htlcs, u->id))
|
||||||
|| cstate_htlc_by_id(peer->remote.commit->cstate, u->id, THEIRS)) {
|
|
||||||
return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);
|
return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);
|
||||||
}
|
|
||||||
|
|
||||||
if (cstate_htlc_by_id(peer->local.staging_cstate, u->id, THEIRS)
|
|
||||||
|| cstate_htlc_by_id(peer->local.commit->cstate, u->id, THEIRS)) {
|
|
||||||
return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* ...and the receiving node MUST add the HTLC addition to the
|
* ...and the receiving node MUST add the HTLC addition to the
|
||||||
* unacked changeset for its local commitment. */
|
* unacked changeset for its local commitment. */
|
||||||
htlc = cstate_add_htlc(peer->local.staging_cstate,
|
htlc = peer_new_htlc(peer, u->id, u->amount_msat, &rhash,
|
||||||
u->amount_msat, &expiry, &rhash, u->id,
|
abs_locktime_to_blocks(&expiry),
|
||||||
u->route->info.data, u->route->info.len,
|
u->route->info.data, u->route->info.len,
|
||||||
THEIRS);
|
THEIRS);
|
||||||
|
|
||||||
@@ -677,13 +656,15 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
|
|||||||
/* FIXME: This is wrong! We may have already added more txs to
|
/* FIXME: This is wrong! We may have already added more txs to
|
||||||
* them.staging_cstate, driving that fee up.
|
* them.staging_cstate, driving that fee up.
|
||||||
* We should check against the last version they acknowledged. */
|
* We should check against the last version they acknowledged. */
|
||||||
if (!htlc)
|
if (!cstate_add_htlc(peer->local.staging_cstate, htlc, THEIRS)) {
|
||||||
|
tal_free(htlc);
|
||||||
return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
|
return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
|
||||||
" in your commitment tx",
|
" in your commitment tx",
|
||||||
u->amount_msat);
|
u->amount_msat);
|
||||||
|
}
|
||||||
|
|
||||||
stage.add.add = HTLC_ADD;
|
stage.add.add = HTLC_ADD;
|
||||||
stage.add.htlc = *htlc;
|
stage.add.htlc = htlc;
|
||||||
add_unacked(&peer->local, &stage);
|
add_unacked(&peer->local, &stage);
|
||||||
|
|
||||||
/* FIXME: Fees must be sufficient. */
|
/* FIXME: Fees must be sufficient. */
|
||||||
@@ -691,18 +672,15 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
|
static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
|
||||||
struct channel_htlc **local_htlc)
|
struct htlc **local_htlc)
|
||||||
{
|
{
|
||||||
struct channel_htlc *htlc;
|
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* A node MUST check that `id` corresponds to an HTLC in its
|
* A node MUST check that `id` corresponds to an HTLC in its
|
||||||
* current commitment transaction, and MUST fail the
|
* current commitment transaction, and MUST fail the
|
||||||
* connection if it does not.
|
* connection if it does not.
|
||||||
*/
|
*/
|
||||||
htlc = cstate_htlc_by_id(peer->local.commit->cstate, id, OURS);
|
if (!cstate_htlc_by_id(peer->local.commit->cstate, id, OURS))
|
||||||
if (!htlc)
|
|
||||||
return pkt_err(peer, "Did not find HTLC %"PRIu64, id);
|
return pkt_err(peer, "Did not find HTLC %"PRIu64, id);
|
||||||
|
|
||||||
/* They must not fail/fulfill twice, so it should be in staging, too. */
|
/* They must not fail/fulfill twice, so it should be in staging, too. */
|
||||||
@@ -716,7 +694,7 @@ static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
|
|||||||
Pkt *accept_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
|
Pkt *accept_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
|
||||||
{
|
{
|
||||||
const UpdateFailHtlc *f = pkt->update_fail_htlc;
|
const UpdateFailHtlc *f = pkt->update_fail_htlc;
|
||||||
struct channel_htlc *htlc;
|
struct htlc *htlc;
|
||||||
Pkt *err;
|
Pkt *err;
|
||||||
union htlc_staging stage;
|
union htlc_staging stage;
|
||||||
|
|
||||||
@@ -734,7 +712,7 @@ Pkt *accept_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
|
|||||||
* to the unacked changeset for its local commitment.
|
* to the unacked changeset for its local commitment.
|
||||||
*/
|
*/
|
||||||
stage.fail.fail = HTLC_FAIL;
|
stage.fail.fail = HTLC_FAIL;
|
||||||
stage.fail.id = f->id;
|
stage.fail.htlc = htlc;
|
||||||
add_unacked(&peer->local, &stage);
|
add_unacked(&peer->local, &stage);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -742,7 +720,7 @@ Pkt *accept_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
|
|||||||
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
|
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
|
||||||
{
|
{
|
||||||
const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
|
const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
|
||||||
struct channel_htlc *htlc;
|
struct htlc *htlc;
|
||||||
struct sha256 rhash;
|
struct sha256 rhash;
|
||||||
struct rval r;
|
struct rval r;
|
||||||
Pkt *err;
|
Pkt *err;
|
||||||
@@ -767,7 +745,7 @@ Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
|
|||||||
cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS);
|
cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS);
|
||||||
|
|
||||||
stage.fulfill.fulfill = HTLC_FULFILL;
|
stage.fulfill.fulfill = HTLC_FULFILL;
|
||||||
stage.fulfill.id = f->id;
|
stage.fulfill.htlc = htlc;
|
||||||
stage.fulfill.r = r;
|
stage.fulfill.r = r;
|
||||||
add_unacked(&peer->local, &stage);
|
add_unacked(&peer->local, &stage);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
155
daemon/peer.c
155
daemon/peer.c
@@ -535,23 +535,23 @@ static void state_event(struct peer *peer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Reason! */
|
/* FIXME: Reason! */
|
||||||
static bool command_htlc_fail(struct peer *peer, u64 id)
|
static bool command_htlc_fail(struct peer *peer, struct htlc *htlc)
|
||||||
{
|
{
|
||||||
if (!state_can_remove_htlc(peer->state))
|
if (!state_can_remove_htlc(peer->state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
queue_pkt_htlc_fail(peer, id);
|
queue_pkt_htlc_fail(peer, htlc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool command_htlc_fulfill(struct peer *peer,
|
static bool command_htlc_fulfill(struct peer *peer,
|
||||||
u64 id,
|
struct htlc *htlc,
|
||||||
const struct rval *r)
|
const struct rval *r)
|
||||||
{
|
{
|
||||||
if (!state_can_remove_htlc(peer->state))
|
if (!state_can_remove_htlc(peer->state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
queue_pkt_htlc_fulfill(peer, id, r);
|
queue_pkt_htlc_fulfill(peer, htlc, r);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,6 +562,7 @@ static bool command_htlc_add(struct peer *peer, u64 msatoshis,
|
|||||||
{
|
{
|
||||||
struct channel_state *cstate;
|
struct channel_state *cstate;
|
||||||
struct abs_locktime locktime;
|
struct abs_locktime locktime;
|
||||||
|
struct htlc *htlc;
|
||||||
|
|
||||||
if (!blocks_to_abs_locktime(expiry, &locktime)) {
|
if (!blocks_to_abs_locktime(expiry, &locktime)) {
|
||||||
log_unusual(peer->log, "add_htlc: fail: bad expiry %u", expiry);
|
log_unusual(peer->log, "add_htlc: fail: bad expiry %u", expiry);
|
||||||
@@ -580,6 +581,7 @@ static bool command_htlc_add(struct peer *peer, u64 msatoshis,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: This is wrong: constraint on remote is sufficient. */
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* A node MUST NOT add a HTLC if it would result in it
|
* A node MUST NOT add a HTLC if it would result in it
|
||||||
@@ -597,37 +599,38 @@ static bool command_htlc_add(struct peer *peer, u64 msatoshis,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htlc = peer_new_htlc(peer, peer->htlc_id_counter,
|
||||||
|
msatoshis, rhash, expiry, route, tal_count(route),
|
||||||
|
OURS);
|
||||||
|
|
||||||
|
/* FIXME: BOLT is not correct here: we should say IFF we cannot
|
||||||
|
* afford it in remote at its own current proposed fee-rate. */
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* A node MUST NOT offer `amount_msat` it cannot pay for in
|
* A node MUST NOT offer `amount_msat` it cannot pay for in
|
||||||
* both commitment transactions at the current `fee_rate`
|
* both commitment transactions at the current `fee_rate`
|
||||||
*/
|
*/
|
||||||
cstate = copy_cstate(peer, peer->remote.staging_cstate);
|
cstate = copy_cstate(peer, peer->remote.staging_cstate);
|
||||||
if (!cstate_add_htlc(cstate, msatoshis,
|
if (!cstate_add_htlc(cstate, htlc, OURS)) {
|
||||||
&locktime, rhash, peer->htlc_id_counter,
|
|
||||||
route, tal_count(route),
|
|
||||||
OURS)) {
|
|
||||||
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
||||||
" milli-satoshis in their commit tx",
|
" milli-satoshis in their commit tx",
|
||||||
msatoshis);
|
msatoshis);
|
||||||
|
tal_free(htlc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tal_free(cstate);
|
tal_free(cstate);
|
||||||
|
|
||||||
cstate = copy_cstate(peer, peer->local.staging_cstate);
|
cstate = copy_cstate(peer, peer->local.staging_cstate);
|
||||||
if (!cstate_add_htlc(cstate, msatoshis,
|
if (!cstate_add_htlc(cstate, htlc, OURS)) {
|
||||||
&locktime, rhash, peer->htlc_id_counter,
|
|
||||||
route, tal_count(route),
|
|
||||||
OURS)) {
|
|
||||||
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
log_unusual(peer->log, "add_htlc: fail: Cannot afford %"PRIu64
|
||||||
" milli-satoshis in our commit tx",
|
" milli-satoshis in our commit tx",
|
||||||
msatoshis);
|
msatoshis);
|
||||||
|
tal_free(htlc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tal_free(cstate);
|
tal_free(cstate);
|
||||||
|
|
||||||
queue_pkt_htlc_add(peer, peer->htlc_id_counter,
|
queue_pkt_htlc_add(peer, htlc);
|
||||||
msatoshis, rhash, expiry, route);
|
|
||||||
|
|
||||||
/* Make sure we never offer the same one twice. */
|
/* Make sure we never offer the same one twice. */
|
||||||
peer->htlc_id_counter++;
|
peer->htlc_id_counter++;
|
||||||
@@ -841,6 +844,9 @@ static struct peer *new_peer(struct lightningd_state *dstate,
|
|||||||
peer->local.commit = peer->remote.commit = NULL;
|
peer->local.commit = peer->remote.commit = NULL;
|
||||||
peer->local.staging_cstate = peer->remote.staging_cstate = NULL;
|
peer->local.staging_cstate = peer->remote.staging_cstate = NULL;
|
||||||
|
|
||||||
|
htlc_map_init(&peer->local.htlcs);
|
||||||
|
htlc_map_init(&peer->remote.htlcs);
|
||||||
|
|
||||||
/* FIXME: Attach IO logging for this peer. */
|
/* FIXME: Attach IO logging for this peer. */
|
||||||
tal_add_destructor(peer, destroy_peer);
|
tal_add_destructor(peer, destroy_peer);
|
||||||
|
|
||||||
@@ -860,6 +866,41 @@ static struct peer *new_peer(struct lightningd_state *dstate,
|
|||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void htlc_destroy(struct htlc *htlc)
|
||||||
|
{
|
||||||
|
if (!htlc_map_del(&htlc->peer->local.htlcs, htlc)
|
||||||
|
&& !htlc_map_del(&htlc->peer->remote.htlcs, htlc))
|
||||||
|
fatal("Could not find htlc to destroy");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct htlc *peer_new_htlc(struct peer *peer,
|
||||||
|
u64 id,
|
||||||
|
u64 msatoshis,
|
||||||
|
const struct sha256 *rhash,
|
||||||
|
u32 expiry,
|
||||||
|
const u8 *route,
|
||||||
|
size_t routelen,
|
||||||
|
enum channel_side side)
|
||||||
|
{
|
||||||
|
struct htlc *h = tal(peer, struct htlc);
|
||||||
|
h->peer = peer;
|
||||||
|
h->id = id;
|
||||||
|
h->msatoshis = msatoshis;
|
||||||
|
h->rhash = *rhash;
|
||||||
|
if (!blocks_to_abs_locktime(expiry, &h->expiry))
|
||||||
|
fatal("Invalid HTLC expiry %u", expiry);
|
||||||
|
h->routing = tal_dup_arr(h, u8, route, routelen, 0);
|
||||||
|
if (side == OURS)
|
||||||
|
htlc_map_add(&peer->local.htlcs, h);
|
||||||
|
else {
|
||||||
|
assert(side == THEIRS);
|
||||||
|
htlc_map_add(&peer->remote.htlcs, h);
|
||||||
|
}
|
||||||
|
tal_add_destructor(h, htlc_destroy);
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
static struct io_plan *peer_connected_out(struct io_conn *conn,
|
static struct io_plan *peer_connected_out(struct io_conn *conn,
|
||||||
struct lightningd_state *dstate,
|
struct lightningd_state *dstate,
|
||||||
struct json_connecting *connect)
|
struct json_connecting *connect)
|
||||||
@@ -1066,7 +1107,7 @@ again:
|
|||||||
/* Check their currently still-existing htlcs for expiry:
|
/* Check their currently still-existing htlcs for expiry:
|
||||||
* We eliminate them from staging as we go. */
|
* We eliminate them from staging as we go. */
|
||||||
for (i = 0; i < tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs); i++) {
|
for (i = 0; i < tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs); i++) {
|
||||||
struct channel_htlc *htlc = &peer->remote.staging_cstate->side[THEIRS].htlcs[i];
|
struct htlc *htlc = peer->remote.staging_cstate->side[THEIRS].htlcs[i];
|
||||||
|
|
||||||
assert(!abs_locktime_is_seconds(&htlc->expiry));
|
assert(!abs_locktime_is_seconds(&htlc->expiry));
|
||||||
|
|
||||||
@@ -1076,7 +1117,7 @@ again:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* This can fail only if we're in an error state. */
|
/* This can fail only if we're in an error state. */
|
||||||
if (!command_htlc_fail(peer, htlc->id))
|
if (!command_htlc_fail(peer, htlc))
|
||||||
return;
|
return;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
@@ -1166,8 +1207,7 @@ static bool is_mutual_close(const struct peer *peer,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct channel_htlc *htlc_by_index(const struct commit_info *ci,
|
static struct htlc *htlc_by_index(const struct commit_info *ci, size_t index)
|
||||||
size_t index)
|
|
||||||
{
|
{
|
||||||
if (ci->map[index] == -1)
|
if (ci->map[index] == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1177,13 +1217,10 @@ static struct channel_htlc *htlc_by_index(const struct commit_info *ci,
|
|||||||
index -= 2;
|
index -= 2;
|
||||||
|
|
||||||
if (index < tal_count(ci->cstate->side[OURS].htlcs))
|
if (index < tal_count(ci->cstate->side[OURS].htlcs))
|
||||||
return cast_const(struct channel_htlc *,
|
return ci->cstate->side[OURS].htlcs[index];
|
||||||
ci->cstate->side[OURS].htlcs)
|
|
||||||
+ index;
|
|
||||||
index -= tal_count(ci->cstate->side[OURS].htlcs);
|
index -= tal_count(ci->cstate->side[OURS].htlcs);
|
||||||
assert(index < tal_count(ci->cstate->side[THEIRS].htlcs));
|
assert(index < tal_count(ci->cstate->side[THEIRS].htlcs));
|
||||||
return cast_const(struct channel_htlc *, ci->cstate->side[THEIRS].htlcs)
|
return ci->cstate->side[THEIRS].htlcs[index];
|
||||||
+ index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool htlc_is_ours(const struct commit_info *ci, size_t index)
|
static bool htlc_is_ours(const struct commit_info *ci, size_t index)
|
||||||
@@ -1200,7 +1237,7 @@ static const struct bitcoin_tx *htlc_timeout_tx(const struct peer *peer,
|
|||||||
unsigned int i)
|
unsigned int i)
|
||||||
{
|
{
|
||||||
u8 *wscript;
|
u8 *wscript;
|
||||||
struct channel_htlc *htlc;
|
struct htlc *htlc;
|
||||||
struct bitcoin_tx *tx = bitcoin_tx(peer, 1, 1);
|
struct bitcoin_tx *tx = bitcoin_tx(peer, 1, 1);
|
||||||
struct bitcoin_signature sig;
|
struct bitcoin_signature sig;
|
||||||
u64 fee, satoshis;
|
u64 fee, satoshis;
|
||||||
@@ -1360,7 +1397,7 @@ static void resolve_cheating(struct peer *peer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 2; i < tal_count(ci->map); i++) {
|
for (i = 2; i < tal_count(ci->map); i++) {
|
||||||
struct channel_htlc *h;
|
struct htlc *h;
|
||||||
|
|
||||||
if (ci->map[i] == -1)
|
if (ci->map[i] == -1)
|
||||||
continue;
|
continue;
|
||||||
@@ -1420,7 +1457,7 @@ static void our_htlc_spent(struct peer *peer,
|
|||||||
size_t input_num,
|
size_t input_num,
|
||||||
ptrint_t *pi)
|
ptrint_t *pi)
|
||||||
{
|
{
|
||||||
struct channel_htlc *h;
|
struct htlc *h;
|
||||||
struct sha256 sha;
|
struct sha256 sha;
|
||||||
struct rval preimage;
|
struct rval preimage;
|
||||||
size_t i = ptr2int(pi);
|
size_t i = ptr2int(pi);
|
||||||
@@ -1475,7 +1512,7 @@ static void our_htlc_depth(struct peer *peer,
|
|||||||
bool our_commit,
|
bool our_commit,
|
||||||
size_t i)
|
size_t i)
|
||||||
{
|
{
|
||||||
struct channel_htlc *h;
|
struct htlc *h;
|
||||||
u32 height;
|
u32 height;
|
||||||
|
|
||||||
/* Must be in a block. */
|
/* Must be in a block. */
|
||||||
@@ -1584,7 +1621,7 @@ static void their_htlc_depth(struct peer *peer,
|
|||||||
ptrint_t *pi)
|
ptrint_t *pi)
|
||||||
{
|
{
|
||||||
u32 height;
|
u32 height;
|
||||||
struct channel_htlc *h;
|
struct htlc *h;
|
||||||
size_t i = ptr2int(pi);
|
size_t i = ptr2int(pi);
|
||||||
|
|
||||||
/* Must be in a block. */
|
/* Must be in a block. */
|
||||||
@@ -2253,7 +2290,7 @@ static const char *owner_name(enum channel_side side)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void route_htlc_onwards(struct peer *peer,
|
static void route_htlc_onwards(struct peer *peer,
|
||||||
const struct channel_htlc *htlc,
|
const struct htlc *htlc,
|
||||||
u64 msatoshis,
|
u64 msatoshis,
|
||||||
const BitcoinPubkey *pb_id,
|
const BitcoinPubkey *pb_id,
|
||||||
const u8 *rest_of_route)
|
const u8 *rest_of_route)
|
||||||
@@ -2261,7 +2298,7 @@ static void route_htlc_onwards(struct peer *peer,
|
|||||||
/* FIXME: implement */
|
/* FIXME: implement */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
static void their_htlc_added(struct peer *peer, struct htlc *htlc)
|
||||||
{
|
{
|
||||||
RouteStep *step;
|
RouteStep *step;
|
||||||
const u8 *rest_of_route;
|
const u8 *rest_of_route;
|
||||||
@@ -2269,7 +2306,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
|
|
||||||
if (abs_locktime_is_seconds(&htlc->expiry)) {
|
if (abs_locktime_is_seconds(&htlc->expiry)) {
|
||||||
log_unusual(peer->log, "HTLC %"PRIu64" is in seconds", htlc->id);
|
log_unusual(peer->log, "HTLC %"PRIu64" is in seconds", htlc->id);
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2278,7 +2315,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:"
|
log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:"
|
||||||
" block %u",
|
" block %u",
|
||||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2287,7 +2324,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too far:"
|
log_unusual(peer->log, "HTLC %"PRIu64" expires too far:"
|
||||||
" block %u",
|
" block %u",
|
||||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2296,7 +2333,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
if (!step) {
|
if (!step) {
|
||||||
log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64,
|
log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64,
|
||||||
htlc->id);
|
htlc->id);
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2309,7 +2346,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
log_add_struct(peer->log, " rhash=%s",
|
log_add_struct(peer->log, " rhash=%s",
|
||||||
struct sha256, &htlc->rhash);
|
struct sha256, &htlc->rhash);
|
||||||
if (unlikely(!peer->dstate->dev_never_routefail))
|
if (unlikely(!peer->dstate->dev_never_routefail))
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
goto free_rest;
|
goto free_rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2319,13 +2356,13 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
htlc->id,
|
htlc->id,
|
||||||
htlc->msatoshis,
|
htlc->msatoshis,
|
||||||
payment->msatoshis);
|
payment->msatoshis);
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info(peer->log, "Immediately resolving HTLC %"PRIu64,
|
log_info(peer->log, "Immediately resolving HTLC %"PRIu64,
|
||||||
htlc->id);
|
htlc->id);
|
||||||
command_htlc_fulfill(peer, htlc->id, &payment->r);
|
command_htlc_fulfill(peer, htlc, &payment->r);
|
||||||
goto free_rest;
|
goto free_rest;
|
||||||
|
|
||||||
case ROUTE_STEP__NEXT_BITCOIN:
|
case ROUTE_STEP__NEXT_BITCOIN:
|
||||||
@@ -2334,7 +2371,7 @@ static void their_htlc_added(struct peer *peer, const struct channel_htlc *htlc)
|
|||||||
goto free_rest;
|
goto free_rest;
|
||||||
default:
|
default:
|
||||||
log_info(peer->log, "Unknown step type %u", step->next_case);
|
log_info(peer->log, "Unknown step type %u", step->next_case);
|
||||||
command_htlc_fail(peer, htlc->id);
|
command_htlc_fail(peer, htlc);
|
||||||
goto free_rest;
|
goto free_rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2357,7 +2394,7 @@ void peer_both_committed_to(struct peer *peer,
|
|||||||
switch (changes[i].type) {
|
switch (changes[i].type) {
|
||||||
case HTLC_ADD:
|
case HTLC_ADD:
|
||||||
type = "ADD";
|
type = "ADD";
|
||||||
htlc_id = changes[i].add.htlc.id;
|
htlc_id = changes[i].add.htlc->id;
|
||||||
owner = owner_name(side);
|
owner = owner_name(side);
|
||||||
assert(cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
assert(cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
||||||
side));
|
side));
|
||||||
@@ -2366,7 +2403,7 @@ void peer_both_committed_to(struct peer *peer,
|
|||||||
goto print;
|
goto print;
|
||||||
case HTLC_FAIL:
|
case HTLC_FAIL:
|
||||||
type = "FAIL";
|
type = "FAIL";
|
||||||
htlc_id = changes[i].fail.id;
|
htlc_id = changes[i].fail.htlc->id;
|
||||||
owner = owner_name(!side);
|
owner = owner_name(!side);
|
||||||
assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
||||||
!side));
|
!side));
|
||||||
@@ -2379,7 +2416,7 @@ void peer_both_committed_to(struct peer *peer,
|
|||||||
goto print;
|
goto print;
|
||||||
case HTLC_FULFILL:
|
case HTLC_FULFILL:
|
||||||
type = "FULFILL";
|
type = "FULFILL";
|
||||||
htlc_id = changes[i].fulfill.id;
|
htlc_id = changes[i].fulfill.htlc->id;
|
||||||
owner = owner_name(!side);
|
owner = owner_name(!side);
|
||||||
assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id,
|
||||||
!side));
|
!side));
|
||||||
@@ -2404,7 +2441,7 @@ void peer_both_committed_to(struct peer *peer,
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
switch (changes[i].type) {
|
switch (changes[i].type) {
|
||||||
case HTLC_ADD:
|
case HTLC_ADD:
|
||||||
their_htlc_added(peer, &changes[i].add.htlc);
|
their_htlc_added(peer, changes[i].add.htlc);
|
||||||
break;
|
break;
|
||||||
case HTLC_FULFILL:
|
case HTLC_FULFILL:
|
||||||
/* FIXME: resolve_one_htlc(peer, id, preimage); */
|
/* FIXME: resolve_one_htlc(peer, id, preimage); */
|
||||||
@@ -2495,11 +2532,11 @@ static void json_add_htlcs(struct json_result *response,
|
|||||||
json_array_start(response, id);
|
json_array_start(response, id);
|
||||||
for (i = 0; i < tal_count(side->htlcs); i++) {
|
for (i = 0; i < tal_count(side->htlcs); i++) {
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_u64(response, "msatoshis", side->htlcs[i].msatoshis);
|
json_add_u64(response, "msatoshis", side->htlcs[i]->msatoshis);
|
||||||
json_add_abstime(response, "expiry", &side->htlcs[i].expiry);
|
json_add_abstime(response, "expiry", &side->htlcs[i]->expiry);
|
||||||
json_add_hex(response, "rhash",
|
json_add_hex(response, "rhash",
|
||||||
&side->htlcs[i].rhash,
|
&side->htlcs[i]->rhash,
|
||||||
sizeof(side->htlcs[i].rhash));
|
sizeof(side->htlcs[i]->rhash));
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
}
|
}
|
||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
@@ -2648,12 +2685,12 @@ const struct json_command newhtlc_command = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Looks for their HTLC, but must be committed. */
|
/* Looks for their HTLC, but must be committed. */
|
||||||
static size_t find_their_committed_htlc(struct peer *peer,
|
static struct htlc *find_their_committed_htlc(struct peer *peer,
|
||||||
const struct sha256 *rhash)
|
const struct sha256 *rhash)
|
||||||
{
|
{
|
||||||
/* Must be in last committed cstate. */
|
/* Must be in last committed cstate. */
|
||||||
if (cstate_find_htlc(peer->remote.commit->cstate, rhash, THEIRS) == -1)
|
if (!cstate_find_htlc(peer->remote.commit->cstate, rhash, THEIRS))
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
return cstate_find_htlc(peer->remote.staging_cstate, rhash, THEIRS);
|
return cstate_find_htlc(peer->remote.staging_cstate, rhash, THEIRS);
|
||||||
}
|
}
|
||||||
@@ -2665,8 +2702,7 @@ static void json_fulfillhtlc(struct command *cmd,
|
|||||||
jsmntok_t *peeridtok, *rtok;
|
jsmntok_t *peeridtok, *rtok;
|
||||||
struct rval r;
|
struct rval r;
|
||||||
struct sha256 rhash;
|
struct sha256 rhash;
|
||||||
size_t i;
|
struct htlc *htlc;
|
||||||
u64 id;
|
|
||||||
|
|
||||||
if (!json_get_params(buffer, params,
|
if (!json_get_params(buffer, params,
|
||||||
"peerid", &peeridtok,
|
"peerid", &peeridtok,
|
||||||
@@ -2698,14 +2734,13 @@ static void json_fulfillhtlc(struct command *cmd,
|
|||||||
|
|
||||||
sha256(&rhash, &r, sizeof(r));
|
sha256(&rhash, &r, sizeof(r));
|
||||||
|
|
||||||
i = find_their_committed_htlc(peer, &rhash);
|
htlc = find_their_committed_htlc(peer, &rhash);
|
||||||
if (i == -1) {
|
if (!htlc) {
|
||||||
command_fail(cmd, "preimage htlc not found");
|
command_fail(cmd, "preimage htlc not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
|
if (command_htlc_fulfill(peer, htlc, &r))
|
||||||
if (command_htlc_fulfill(peer, id, &r))
|
|
||||||
command_success(cmd, null_response(cmd));
|
command_success(cmd, null_response(cmd));
|
||||||
else
|
else
|
||||||
command_fail(cmd,
|
command_fail(cmd,
|
||||||
@@ -2726,8 +2761,7 @@ static void json_failhtlc(struct command *cmd,
|
|||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
jsmntok_t *peeridtok, *rhashtok;
|
jsmntok_t *peeridtok, *rhashtok;
|
||||||
struct sha256 rhash;
|
struct sha256 rhash;
|
||||||
size_t i;
|
struct htlc *htlc;
|
||||||
u64 id;
|
|
||||||
|
|
||||||
if (!json_get_params(buffer, params,
|
if (!json_get_params(buffer, params,
|
||||||
"peerid", &peeridtok,
|
"peerid", &peeridtok,
|
||||||
@@ -2759,13 +2793,12 @@ static void json_failhtlc(struct command *cmd,
|
|||||||
|
|
||||||
/* Look in peer->remote.staging_cstate->a, as that's where we'll
|
/* Look in peer->remote.staging_cstate->a, as that's where we'll
|
||||||
* immediately remove it from: avoids double-handling. */
|
* immediately remove it from: avoids double-handling. */
|
||||||
i = find_their_committed_htlc(peer, &rhash);
|
htlc = find_their_committed_htlc(peer, &rhash);
|
||||||
if (i == -1) {
|
if (!htlc) {
|
||||||
command_fail(cmd, "htlc not found");
|
command_fail(cmd, "htlc not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
|
if (command_htlc_fail(peer, htlc))
|
||||||
if (command_htlc_fail(peer, id))
|
|
||||||
command_success(cmd, null_response(cmd));
|
command_success(cmd, null_response(cmd));
|
||||||
else
|
else
|
||||||
command_fail(cmd,
|
command_fail(cmd,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "bitcoin/script.h"
|
#include "bitcoin/script.h"
|
||||||
#include "bitcoin/shadouble.h"
|
#include "bitcoin/shadouble.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
|
#include "htlc.h"
|
||||||
#include "lightning.pb-c.h"
|
#include "lightning.pb-c.h"
|
||||||
#include "netaddr.h"
|
#include "netaddr.h"
|
||||||
#include "protobuf_convert.h"
|
#include "protobuf_convert.h"
|
||||||
@@ -24,18 +25,18 @@ enum htlc_stage_type {
|
|||||||
|
|
||||||
struct htlc_add {
|
struct htlc_add {
|
||||||
enum htlc_stage_type add;
|
enum htlc_stage_type add;
|
||||||
struct channel_htlc htlc;
|
struct htlc *htlc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct htlc_fulfill {
|
struct htlc_fulfill {
|
||||||
enum htlc_stage_type fulfill;
|
enum htlc_stage_type fulfill;
|
||||||
u64 id;
|
struct htlc *htlc;
|
||||||
struct rval r;
|
struct rval r;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct htlc_fail {
|
struct htlc_fail {
|
||||||
enum htlc_stage_type fail;
|
enum htlc_stage_type fail;
|
||||||
u64 id;
|
struct htlc *htlc;
|
||||||
};
|
};
|
||||||
|
|
||||||
union htlc_staging {
|
union htlc_staging {
|
||||||
@@ -95,6 +96,9 @@ struct peer_visible_state {
|
|||||||
|
|
||||||
/* cstate to generate next commitment tx. */
|
/* cstate to generate next commitment tx. */
|
||||||
struct channel_state *staging_cstate;
|
struct channel_state *staging_cstate;
|
||||||
|
|
||||||
|
/* HTLCs offered by this side */
|
||||||
|
struct htlc_map htlcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct out_pkt {
|
struct out_pkt {
|
||||||
@@ -240,6 +244,16 @@ void add_acked_changes(union htlc_staging **acked,
|
|||||||
void peer_both_committed_to(struct peer *peer,
|
void peer_both_committed_to(struct peer *peer,
|
||||||
const union htlc_staging *changes, enum channel_side side);
|
const union htlc_staging *changes, enum channel_side side);
|
||||||
|
|
||||||
|
/* Freeing removes from map, too */
|
||||||
|
struct htlc *peer_new_htlc(struct peer *peer,
|
||||||
|
u64 id,
|
||||||
|
u64 msatoshis,
|
||||||
|
const struct sha256 *rhash,
|
||||||
|
u32 expiry,
|
||||||
|
const u8 *route,
|
||||||
|
size_t route_len,
|
||||||
|
enum channel_side side);
|
||||||
|
|
||||||
/* Peer has recieved revocation. */
|
/* Peer has recieved revocation. */
|
||||||
void peer_update_complete(struct peer *peer);
|
void peer_update_complete(struct peer *peer);
|
||||||
|
|
||||||
|
|||||||
12
state.h
12
state.h
@@ -100,14 +100,10 @@ void queue_pkt_open(struct peer *peer, OpenChannel__AnchorOffer anchor);
|
|||||||
void queue_pkt_anchor(struct peer *peer);
|
void queue_pkt_anchor(struct peer *peer);
|
||||||
void queue_pkt_open_commit_sig(struct peer *peer);
|
void queue_pkt_open_commit_sig(struct peer *peer);
|
||||||
void queue_pkt_open_complete(struct peer *peer);
|
void queue_pkt_open_complete(struct peer *peer);
|
||||||
void queue_pkt_htlc_add(struct peer *peer,
|
void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc);
|
||||||
u64 id,
|
void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc,
|
||||||
u64 msatoshis,
|
const struct rval *r);
|
||||||
const struct sha256 *rhash,
|
void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc);
|
||||||
u32 expiry,
|
|
||||||
const u8 *route);
|
|
||||||
void queue_pkt_htlc_fulfill(struct peer *peer, u64 id, const struct rval *r);
|
|
||||||
void queue_pkt_htlc_fail(struct peer *peer, u64 id);
|
|
||||||
void queue_pkt_commit(struct peer *peer);
|
void queue_pkt_commit(struct peer *peer);
|
||||||
void queue_pkt_revocation(struct peer *peer);
|
void queue_pkt_revocation(struct peer *peer);
|
||||||
void queue_pkt_close_clearing(struct peer *peer);
|
void queue_pkt_close_clearing(struct peer *peer);
|
||||||
|
|||||||
Reference in New Issue
Block a user