Browse Source

channel: object to track channel state.

This object is basically the embodyment of BOLT #2.  Each HTLC already
knows its own state; this moves them between states and keeps them
consistent.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
4a7418e3db
  1. 4
      lightningd/Makefile
  2. 592
      lightningd/channel.c
  3. 353
      lightningd/channel.h
  4. 501
      lightningd/test/run-channel.c
  5. 1
      type_to_string.h

4
lightningd/Makefile

@ -27,11 +27,13 @@ LIGHTNINGD_OLD_OBJS := $(LIGHTNINGD_OLD_SRC:.c=.o)
LIGHTNINGD_OLD_HEADERS := $(LIGHTNINGD_OLD_SRC:.c=.h)
LIGHTNINGD_OLD_LIB_SRC := \
daemon/htlc_state.c
daemon/htlc_state.c \
daemon/pseudorand.c
LIGHTNINGD_OLD_LIB_OBJS := $(LIGHTNINGD_OLD_LIB_SRC:.c=.o)
LIGHTNINGD_OLD_LIB_HEADERS := $(LIGHTNINGD_OLD_LIB_SRC:.c=.h)
LIGHTNINGD_LIB_SRC := \
lightningd/channel.c \
lightningd/channel_config.c \
lightningd/commit_tx.c \
lightningd/cryptomsg.c \

592
lightningd/channel.c

@ -0,0 +1,592 @@
#include "channel.h"
#include "commit_tx.h"
#include "type_to_string.h"
#include <assert.h>
#include <bitcoin/preimage.h>
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/structeq/structeq.h>
#include <ccan/tal/str/str.h>
#include <daemon/htlc.h>
#include <inttypes.h>
#include <lightningd/channel_config.h>
#include <lightningd/key_derive.h>
#include <status.h>
#include <string.h>
static void htlc_arr_append(const struct htlc ***arr, const struct htlc *htlc)
{
size_t n;
if (!arr)
return;
n = tal_count(*arr);
tal_resize(arr, n+1);
(*arr)[n] = htlc;
}
/* What does adding the HTLC do to the balance for this side */
static s64 balance_adding_htlc(const struct htlc *htlc, enum side side)
{
if (htlc_owner(htlc) == side)
return -htlc->msatoshi;
return 0;
}
/* What does removing the HTLC do to the balance for this side */
static s64 balance_removing_htlc(const struct htlc *htlc, enum side side)
{
enum side paid_to;
/* Fulfilled HTLCs are paid to recipient, otherwise returns to owner */
if (htlc->r)
paid_to = !htlc_owner(htlc);
else
paid_to = htlc_owner(htlc);
if (side == paid_to)
return htlc->msatoshi;
return 0;
}
/* Returns up to three arrays:
* committed: HTLCs currently committed.
* pending_removal: HTLCs pending removal (subset of committed)
* pending_addition: HTLCs pending addition (no overlap with committed)
*/
static void gather_htlcs(const tal_t *ctx,
const struct channel *channel,
enum side side,
const struct htlc ***committed,
const struct htlc ***pending_removal,
const struct htlc ***pending_addition)
{
struct htlc_map_iter it;
const struct htlc *htlc;
const int committed_flag = HTLC_FLAG(side, HTLC_F_COMMITTED);
const int pending_flag = HTLC_FLAG(side, HTLC_F_PENDING);
*committed = tal_arr(ctx, const struct htlc *, 0);
if (pending_removal)
*pending_removal = tal_arr(ctx, const struct htlc *, 0);
if (pending_addition)
*pending_addition = tal_arr(ctx, const struct htlc *, 0);
for (htlc = htlc_map_first(&channel->htlcs, &it);
htlc;
htlc = htlc_map_next(&channel->htlcs, &it)) {
if (htlc_has(htlc, committed_flag)) {
htlc_arr_append(committed, htlc);
if (htlc_has(htlc, pending_flag))
htlc_arr_append(pending_removal, htlc);
} else if (htlc_has(htlc, pending_flag))
htlc_arr_append(pending_addition, htlc);
}
}
static u64 total_offered_msatoshis(const struct htlc **htlcs, enum side side)
{
size_t i;
u64 total = 0;
for (i = 0; i < tal_count(htlcs); i++) {
if (htlc_owner(htlcs[i]) == side)
total += htlcs[i]->msatoshi;
}
return total;
}
static void destroy_htlc_map(struct channel *channel)
{
htlc_map_clear(&channel->htlcs);
}
struct channel *new_channel(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
u64 push_msat,
u32 feerate_per_kw,
const struct channel_config *local,
const struct channel_config *remote,
const struct pubkey *local_revocation_basepoint,
const struct pubkey *remote_revocation_basepoint,
const struct pubkey *local_payment_basepoint,
const struct pubkey *remote_payment_basepoint,
const struct pubkey *local_delayed_payment_basepoint,
const struct pubkey *remote_delayed_payment_basepoint,
enum side funder)
{
struct channel *channel = tal(ctx, struct channel);
channel->funding_txid = *funding_txid;
channel->funding_txout = funding_txout;
if (funding_satoshis > UINT64_MAX / 1000)
return tal_free(channel);
channel->funding_msat = funding_satoshis * 1000;
if (push_msat > channel->funding_msat)
return tal_free(channel);
channel->funder = funder;
channel->config[LOCAL] = local;
channel->config[REMOTE] = remote;
htlc_map_init(&channel->htlcs);
channel->view[LOCAL].feerate_per_kw
= channel->view[REMOTE].feerate_per_kw
= feerate_per_kw;
channel->view[funder].owed_msat[funder]
= channel->view[!funder].owed_msat[funder]
= channel->funding_msat - push_msat;
channel->view[funder].owed_msat[!funder]
= channel->view[!funder].owed_msat[!funder]
= push_msat;
channel->view[LOCAL].commitment_number
= channel->view[REMOTE].commitment_number
= 0;
channel->revocation_basepoint[LOCAL] = *local_revocation_basepoint;
channel->revocation_basepoint[REMOTE] = *remote_revocation_basepoint;
channel->payment_basepoint[LOCAL] = *local_payment_basepoint;
channel->payment_basepoint[REMOTE] = *remote_payment_basepoint;
channel->delayed_payment_basepoint[LOCAL]
= *local_delayed_payment_basepoint;
channel->delayed_payment_basepoint[REMOTE]
= *remote_delayed_payment_basepoint;
channel->commitment_number_obscurer
= commit_number_obscurer(&channel->payment_basepoint[funder],
&channel->payment_basepoint[!funder]);
tal_add_destructor(channel, destroy_htlc_map);
return channel;
}
/* FIXME: We could cache this. */
struct bitcoin_tx *channel_tx(const tal_t *ctx,
const struct channel *channel,
const struct pubkey *per_commitment_point,
const struct htlc ***htlcmap,
enum side side)
{
struct bitcoin_tx *tx;
const struct htlc **committed;
/* Payment keys for @side and !@side */
struct pubkey side_payment_key, other_payment_key;
/* Delayed payment key for @side */
struct pubkey side_delayed_payment_key;
/* Revocation payment key for @side */
struct pubkey side_revocation_key;
if (!derive_simple_key(&channel->payment_basepoint[side],
per_commitment_point,
&side_payment_key))
return NULL;
if (!derive_simple_key(&channel->payment_basepoint[!side],
per_commitment_point,
&other_payment_key))
return NULL;
if (!derive_simple_key(&channel->delayed_payment_basepoint[side],
per_commitment_point,
&side_delayed_payment_key))
return NULL;
if (!derive_revocation_key(&channel->revocation_basepoint[side],
per_commitment_point,
&side_revocation_key))
return NULL;
/* Figure out what @side will already be committed to. */
gather_htlcs(ctx, channel, side, &committed, NULL, NULL);
tx = commit_tx(ctx, &channel->funding_txid,
channel->funding_txout,
channel->funding_msat / 1000,
channel->funder,
to_self_delay(channel, side),
&side_revocation_key,
&side_delayed_payment_key,
&side_payment_key,
&other_payment_key,
channel->view[side].feerate_per_kw,
dust_limit_satoshis(channel, side),
channel->view[side].owed_msat[side],
channel->view[side].owed_msat[!side],
committed,
htlcmap,
channel->view[side].commitment_number
^ channel->commitment_number_obscurer,
side);
tal_free(committed);
return tx;
}
struct channel *copy_channel(const tal_t *ctx, const struct channel *old)
{
struct channel *new = tal_dup(ctx, struct channel, old);
htlc_map_copy(&new->htlcs, &old->htlcs);
return new;
}
enum channel_add_err channel_add_htlc(struct channel *channel,
enum side sender,
u64 id,
u64 msatoshi,
u32 expiry,
const struct sha256 *payment_hash,
const u8 routing[1254])
{
const tal_t *tmpctx = tal_tmpctx(channel);
struct htlc *htlc, *old;
s64 msat_in_htlcs, fee_msat, balance_msat;
enum side recipient = !sender;
const struct htlc **committed, **adding, **removing;
enum channel_add_err e;
const struct channel_view *view;
size_t i;
htlc = tal(tmpctx, struct htlc);
if (sender == LOCAL)
htlc->state = SENT_ADD_HTLC;
else
htlc->state = RCVD_ADD_HTLC;
htlc->id = id;
htlc->msatoshi = msatoshi;
if (!blocks_to_abs_locktime(expiry, &htlc->expiry))
return CHANNEL_ERR_INVALID_EXPIRY;
htlc->rhash = *payment_hash;
htlc->r = NULL;
/* BOLT #2:
*
* 1. type: 128 (`update_add_htlc`)
* 2. data:
* * [8:channel-id]
* * [8:id]
* * [4:amount-msat]
* * [4:cltv-expiry]
* * [32:payment-hash]
* * [1254:onion-routing-packet]
*/
htlc->routing = tal_dup_arr(htlc, u8, routing, 1254, 0);
/* FIXME: check expiry etc. against config. */
/* FIXME: set deadline */
old = htlc_get(&channel->htlcs, htlc->id, htlc_owner(htlc));
if (old) {
if (old->state != htlc->state
|| old->msatoshi != htlc->msatoshi
|| old->expiry.locktime != htlc->expiry.locktime
|| !structeq(&old->rhash, &htlc->rhash))
e = CHANNEL_ERR_DUPLICATE_ID_DIFFERENT;
else
e = CHANNEL_ERR_DUPLICATE;
goto out;
}
/* We're always considering the recipient's view of the channel here */
view = &channel->view[recipient];
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if it receives an
* `amount-sat` equal to zero, below its own `htlc-minimum-msat`,
* or...
*/
if (htlc->msatoshi == 0) {
e = CHANNEL_ERR_HTLC_BELOW_MINIMUM;
goto out;
}
if (htlc->msatoshi < htlc_minimum_msat(channel, recipient)) {
e = CHANNEL_ERR_HTLC_BELOW_MINIMUM;
goto out;
}
/* Figure out what receiver will already be committed to. */
gather_htlcs(tmpctx, channel, recipient, &committed, &removing, &adding);
htlc_arr_append(&adding, htlc);
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if a sending node
* adds more than its `max-accepted-htlcs` HTLCs to its local
* commitment transaction */
if (tal_count(committed) - tal_count(removing) + tal_count(adding)
> max_accepted_htlcs(channel, recipient)) {
e = CHANNEL_ERR_TOO_MANY_HTLCS;
goto out;
}
msat_in_htlcs = total_offered_msatoshis(committed, htlc_owner(htlc))
- total_offered_msatoshis(removing, htlc_owner(htlc))
+ total_offered_msatoshis(adding, htlc_owner(htlc));
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if a sending node
* adds more than `max-htlc-value-in-flight-msat` in HTLCs to
* its local commitment transaction. */
if (msat_in_htlcs > max_htlc_value_in_flight_msat(channel, recipient)) {
e = CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
goto out;
}
/* BOLT #2:
*
* or which the sending node cannot afford at the current `fee-rate`
* while maintaining its channel reserve.
*/
if (channel->funder == htlc_owner(htlc)) {
u64 feerate = view->feerate_per_kw;
u64 dust = dust_limit_satoshis(channel, recipient);
size_t untrimmed;
assert(feerate >= 1);
assert(dust >= 1);
untrimmed = commit_tx_num_untrimmed(committed, feerate, dust,
recipient)
+ commit_tx_num_untrimmed(adding, feerate, dust,
recipient)
- commit_tx_num_untrimmed(removing, feerate, dust,
recipient);
fee_msat = commit_tx_base_fee(feerate, untrimmed);
} else
fee_msat = 0;
assert(fee_msat >= 0);
/* Figure out what balance sender would have after applying all
* pending changes. */
balance_msat = view->owed_msat[sender];
assert(balance_msat >= 0);
for (i = 0; i < tal_count(removing); i++)
balance_msat += balance_removing_htlc(removing[i], sender);
assert(balance_msat >= 0);
for (i = 0; i < tal_count(adding); i++)
balance_msat += balance_adding_htlc(adding[i], sender);
assert(balance_msat >= 0);
/* This is a little subtle:
*
* The change is being applied to the receiver but it will
* come back to the sender after revoke_and_ack. So the check
* here is that the balance to the sender doesn't go below the
* sender's reserve. */
if (balance_msat - fee_msat < (s64)channel_reserve_msat(channel, sender)) {
e = CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
goto out;
}
htlc_map_add(&channel->htlcs, tal_steal(channel, htlc));
e = CHANNEL_ERR_ADD_OK;
out:
tal_free(tmpctx);
return e;
}
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id)
{
return htlc_get(&channel->htlcs, id, sender);
}
enum channel_remove_err channel_fulfill_htlc(struct channel *channel,
enum side sender,
u64 id,
const struct preimage *preimage)
{
struct sha256 hash;
struct htlc *htlc;
/* Fulfill is done by !creator of HTLC */
htlc = channel_get_htlc(channel, !sender, id);
if (!htlc)
return CHANNEL_ERR_NO_SUCH_ID;
if (htlc->r)
return CHANNEL_ERR_ALREADY_FULFILLED;
sha256(&hash, preimage, sizeof(*preimage));
/* BOLT #2:
*
* A receiving node MUST check that the `payment-preimage` value in
* `update-fulfill_htlc` SHA256 hashes to the corresponding HTLC
* `payment-hash`, and MUST fail the channel if it does not.
*/
if (!structeq(&hash, &htlc->rhash))
return CHANNEL_ERR_BAD_PREIMAGE;
htlc->r = tal_dup(htlc, struct preimage, preimage);
/* BOLT #2:
*
* A receiving node MUST check that `id` corresponds to an HTLC in its
* current commitment transaction, and MUST fail the channel if it
* does not.
*/
if (!htlc_has(htlc, HTLC_FLAG(!htlc_owner(htlc), HTLC_F_COMMITTED))) {
status_trace("channel_fulfill_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_UNCOMMITTED;
}
/* We enforce a stricter check, forcing state machine to be linear,
* based on: */
/* BOLT #2:
*
* A node MUST NOT send `update_fulfill_htlc` until an HTLC is
* irrevocably committed in both sides' commitment transactions.
*/
if (htlc->state == SENT_ADD_ACK_REVOCATION)
htlc->state = RCVD_REMOVE_HTLC;
else if (htlc->state == RCVD_ADD_ACK_REVOCATION)
htlc->state = SENT_REMOVE_HTLC;
else {
status_trace("channel_fulfill_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_NOT_IRREVOCABLE;
}
return CHANNEL_ERR_REMOVE_OK;
}
static void htlc_incstate(struct channel *channel,
struct htlc *htlc,
enum side sidechanged)
{
int preflags, postflags;
const int committed_f = HTLC_FLAG(sidechanged, HTLC_F_COMMITTED);
status_trace("htlc %"PRIu64": %s->%s", htlc->id,
htlc_state_name(htlc->state),
htlc_state_name(htlc->state+1));
preflags = htlc_state_flags(htlc->state);
postflags = htlc_state_flags(htlc->state + 1);
/* You can't change sides. */
assert((preflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER))
== (postflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER)));
htlc->state++;
/* If we've added or removed, adjust balances. */
if (!(preflags & committed_f) && (postflags & committed_f)) {
status_trace("htlc added %s: local %+"PRIi64" remote %+"PRIi64,
side_to_str(sidechanged),
balance_adding_htlc(htlc, LOCAL),
balance_adding_htlc(htlc, REMOTE));
channel->view[sidechanged].owed_msat[LOCAL]
+= balance_adding_htlc(htlc, LOCAL);
channel->view[sidechanged].owed_msat[REMOTE]
+= balance_adding_htlc(htlc, REMOTE);
} else if ((preflags & committed_f) && !(postflags & committed_f)) {
status_trace("htlc removed %s: local %+"PRIi64" remote %+"PRIi64,
side_to_str(sidechanged),
balance_removing_htlc(htlc, LOCAL),
balance_removing_htlc(htlc, REMOTE));
channel->view[sidechanged].owed_msat[LOCAL]
+= balance_removing_htlc(htlc, LOCAL);
channel->view[sidechanged].owed_msat[REMOTE]
+= balance_removing_htlc(htlc, REMOTE);
}
}
/* FIXME: Commit to storage when this happens. */
static bool change_htlcs(struct channel *channel,
enum side sidechanged,
const enum htlc_state *htlc_states,
size_t n_hstates)
{
struct htlc_map_iter it;
struct htlc *h;
bool changed = false;
size_t i;
for (h = htlc_map_first(&channel->htlcs, &it);
h;
h = htlc_map_next(&channel->htlcs, &it)) {
for (i = 0; i < n_hstates; i++) {
if (h->state == htlc_states[i]) {
htlc_incstate(channel, h, sidechanged);
changed = true;
}
}
}
return changed;
}
/* FIXME: Handle fee changes too. */
bool channel_sent_commit(struct channel *channel)
{
const enum htlc_state states[] = { SENT_ADD_HTLC,
SENT_REMOVE_REVOCATION,
SENT_ADD_REVOCATION,
SENT_REMOVE_HTLC };
status_trace("sent commit");
return change_htlcs(channel, REMOTE, states, ARRAY_SIZE(states));
}
bool channel_rcvd_revoke_and_ack(struct channel *channel)
{
const enum htlc_state states[] = { SENT_ADD_COMMIT,
SENT_REMOVE_ACK_COMMIT,
SENT_ADD_ACK_COMMIT,
SENT_REMOVE_COMMIT };
status_trace("received revoke_and_ack");
return change_htlcs(channel, LOCAL, states, ARRAY_SIZE(states));
}
/* FIXME: We can actually merge these two... */
bool channel_rcvd_commit(struct channel *channel)
{
const enum htlc_state states[] = { RCVD_ADD_REVOCATION,
RCVD_REMOVE_HTLC,
RCVD_ADD_HTLC,
RCVD_REMOVE_REVOCATION };
status_trace("received commit");
return change_htlcs(channel, LOCAL, states, ARRAY_SIZE(states));
}
bool channel_sent_revoke_and_ack(struct channel *channel)
{
const enum htlc_state states[] = { RCVD_ADD_ACK_COMMIT,
RCVD_REMOVE_COMMIT,
RCVD_ADD_COMMIT,
RCVD_REMOVE_ACK_COMMIT };
status_trace("sent revoke_and_ack");
return change_htlcs(channel, REMOTE, states, ARRAY_SIZE(states));
}
static char *fmt_channel_view(const tal_t *ctx, const struct channel_view *view)
{
return tal_fmt(ctx, "{ feerate_per_kw=%"PRIu64","
" owed_local=%"PRIu64","
" owed_remote=%"PRIu64" }",
view->feerate_per_kw,
view->owed_msat[LOCAL],
view->owed_msat[REMOTE]);
}
static char *fmt_channel(const tal_t *ctx, const struct channel *channel)
{
return tal_fmt(ctx, "{ funding_msat=%"PRIu64","
" funder=%s,"
" local=%s,"
" remote=%s }",
channel->funding_msat,
side_to_str(channel->funder),
fmt_channel_view(ctx, &channel->view[LOCAL]),
fmt_channel_view(ctx, &channel->view[REMOTE]));
}
REGISTER_TYPE_TO_STRING(channel, fmt_channel);

353
lightningd/channel.h

@ -0,0 +1,353 @@
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_H
#define LIGHTNING_LIGHTNINGD_CHANNEL_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <bitcoin/shadouble.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <daemon/htlc.h>
#include <lightningd/channel_config.h>
#include <stdbool.h>
struct signature;
/* View from each side */
struct channel_view {
/* Current feerate in satoshis per 1000 weight. */
u64 feerate_per_kw;
/* What commitment number are we up to */
u64 commitment_number;
/* How much is owed to each side (includes pending changes) */
u64 owed_msat[NUM_SIDES];
};
struct channel {
/* Funding txid and output. */
struct sha256_double funding_txid;
unsigned int funding_txout;
/* Millisatoshis in from commitment tx */
u64 funding_msat;
/* Who is paying fees. */
enum side funder;
/* Limits and settings on this channel. */
const struct channel_config *config[NUM_SIDES];
/* Basepoints for deriving keys. */
struct pubkey revocation_basepoint[NUM_SIDES];
struct pubkey payment_basepoint[NUM_SIDES];
struct pubkey delayed_payment_basepoint[NUM_SIDES];
/* Mask for obscuring the encoding of the commitment number. */
u64 commitment_number_obscurer;
/* All live HTLCs for this channel */
struct htlc_map htlcs;
/* What it looks like to each side. */
struct channel_view view[NUM_SIDES];
};
/* Some requirements are self-specified (eg. my dust limit), others
* are force upon the other side (eg. minimum htlc you can add).
*
* These values are also universally in msatsoshi. These avoid
* confusion: use them! */
/* BOLT #2:
*
* `dust-limit-satoshis` is the threshold below which output should be
* generated for this node's commitment or HTLC transaction */
static inline u64 dust_limit_satoshis(const struct channel *channel,
enum side side)
{
return channel->config[side]->dust_limit_satoshis;
}
/* BOLT #2:
*
* `max-htlc-value-in-inflight-msat` is a cap on total value of
* outstanding HTLCs, which allows a node to limit its exposure to
* HTLCs */
static inline u64 max_htlc_value_in_flight_msat(const struct channel *channel,
enum side recipient)
{
return channel->config[recipient]->max_htlc_value_in_flight_msat;
}
/* BOLT #2:
*
* similarly `max-accepted-htlcs` limits the number of outstanding
* HTLCs the other node can offer. */
static inline u16 max_accepted_htlcs(const struct channel *channel,
enum side recipient)
{
return channel->config[recipient]->max_accepted_htlcs;
}
/* BOLT #2:
*
* `channel-reserve-satoshis` is the minimum amount that the other
* node is to keep as a direct payment. */
static inline u64 channel_reserve_msat(const struct channel *channel,
enum side side)
{
return channel->config[!side]->channel_reserve_satoshis * 1000;
}
/* BOLT #2:
*
* `htlc-minimum-msat` indicates the smallest value HTLC this node will accept.
*/
static inline u32 htlc_minimum_msat(const struct channel *channel,
enum side recipient)
{
return channel->config[recipient]->htlc_minimum_msat;
}
/* BOLT #2:
*
* `to-self-delay` is the number of blocks that the other nodes
* to-self outputs must be delayed, using `OP_CHECKSEQUENCEVERIFY`
* delays */
static inline u16 to_self_delay(const struct channel *channel, enum side side)
{
return channel->config[!side]->to_self_delay;
}
/**
* new_channel: Given initial fees and funding, what is initial state?
* @ctx: tal context to allocate return value from.
* @funding_txid: The commitment transaction id.
* @funding_txout: The commitment transaction output number.
* @funding_satoshis: The commitment transaction amount.
* @funding_satoshis: The commitment transaction amount.
* @push_msat: The amount the initator gives to the other side.
* @feerate_per_kw: feerate per kiloweight (satoshis)
* @local: local channel configuration
* @remote: remote channel configuration
* @local_revocation_basepoint: local basepoint for revocations.
* @remote_revocation_basepoint: remote basepoint for revocations.
* @local_payment_basepoint: local basepoint for payments.
* @remote_payment_basepoint: remote basepoint for payments.
* @local_delayed_payment_basepoint: local basepoint for delayed payments.
* @remote_delayed_payment_basepoint: remote basepoint for delayed payments.
* @funder: which side initiated it.
*
* Returns state, or NULL if malformed.
*/
struct channel *new_channel(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
u64 push_msat,
u32 feerate_per_kw,
const struct channel_config *local,
const struct channel_config *remote,
const struct pubkey *local_revocation_basepoint,
const struct pubkey *remote_revocation_basepoint,
const struct pubkey *local_payment_basepoint,
const struct pubkey *remote_payment_basepoint,
const struct pubkey *local_delayed_payment_basepoint,
const struct pubkey *remote_delayed_payment_basepoint,
enum side funder);
/**
* channel_tx: Get the current commitment transaction for the channel.
* @ctx: tal context to allocate return value from.
* @channel: The channel to evaluate
* @per_commitment_point: Per-commitment point to determine keys
* @htlc_map: Pointer to htlcs for each tx output (allocated off @ctx) or NULL.
* @side: which side to get the commitment transaction for
*
* Returns the unsigned commitment transaction for the committed state
* for @side and fills in @htlc_map (if not NULL), or NULL on key
* derivation failure.
*/
struct bitcoin_tx *channel_tx(const tal_t *ctx,
const struct channel *channel,
const struct pubkey *per_commitment_point,
const struct htlc ***htlcmap,
enum side side);
/**
* actual_feerate: what is the actual feerate for the local side.
* @channel: The channel state
* @theirsig: The other side's signature
*
* The fee calculated on a commitment transaction is a worst-case
* approximation. It's also possible that the desired feerate is not
* met, because the initiator sets it while the other side is adding many
* htlcs.
*
* This is the fee rate we actually care about, if we're going to check
* whether it's actually too low.
*/
uint32_t actual_feerate(const struct channel *channel,
const struct signature *theirsig);
/**
* copy_channel: Make a deep copy of channel
* @ctx: tal context to allocate return value from.
* @channel: channel to copy.
*/
struct channel *copy_channel(const tal_t *ctx, const struct channel *channel);
enum channel_add_err {
/* All OK! */
CHANNEL_ERR_ADD_OK,
/* Bad expiry value */
CHANNEL_ERR_INVALID_EXPIRY,
/* Not really a failure, if expected: it's an exact duplicate. */
CHANNEL_ERR_DUPLICATE,
/* Same ID, but otherwise different. */
CHANNEL_ERR_DUPLICATE_ID_DIFFERENT,
/* Would exceed the specified max_htlc_value_in_flight_msat */
CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED,
/* Can't afford it */
CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED,
/* HTLC is below htlc_minimum_msat */
CHANNEL_ERR_HTLC_BELOW_MINIMUM,
/* HTLC would push past max_accepted_htlcs */
CHANNEL_ERR_TOO_MANY_HTLCS,
};
/**
* channel_add_htlc: append an HTLC to channel if it can afford it
* @channel: The channel
* @offerer: the side offering the HTLC (to the other side).
* @id: unique HTLC id.
* @msatoshi: amount in millisatoshi.
* @expiry: block number when HTLC can no longer be redeemed.
* @payment_hash: hash whose preimage can redeem HTLC.
* @routing: routing information (copied)
*
* If this returns CHANNEL_ERR_NONE, the fee htlc was added and
* the output amounts adjusted accordingly. Otherwise nothing
* is changed.
*/
enum channel_add_err channel_add_htlc(struct channel *channel,
enum side sender,
u64 id,
u64 msatoshi,
u32 expiry,
const struct sha256 *payment_hash,
const u8 routing[1254]);
/**
* channel_get_htlc: find an HTLC
* @channel: The channel
* @offerer: the side offering the HTLC.
* @id: unique HTLC id.
*/
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id);
enum channel_remove_err {
/* All OK! */
CHANNEL_ERR_REMOVE_OK,
/* No such HTLC. */
CHANNEL_ERR_NO_SUCH_ID,
/* Already have fulfilled it */
CHANNEL_ERR_ALREADY_FULFILLED,
/* Preimage doesn't hash to value. */
CHANNEL_ERR_BAD_PREIMAGE,
/* HTLC is not committed */
CHANNEL_ERR_HTLC_UNCOMMITTED,
/* HTLC is not committed and prior revoked on both sides */
CHANNEL_ERR_HTLC_NOT_IRREVOCABLE
};
/**
* channel_fail_htlc: remove an HTLC, funds to the side which offered it.
* @channel: The channel state
* @sender: the side fulfilling the HTLC (opposite to side which sent it)
* @id: unique HTLC id.
*
* This will remove the htlc and credit the value of the HTLC (back)
* to its offerer.
*/
enum channel_remove_err channel_fail_htlc(struct channel *channel,
enum side sender, u64 id);
/**
* channel_fulfill_htlc: remove an HTLC, funds to side which accepted it.
* @channel: The channel state
* @sender: the side fulfilling the HTLC (opposite to side which sent it)
* @id: unique HTLC id.
*
* If the htlc exists, is not already fulfilled, the preimage is correct and
* HTLC committed at the recipient, this will add a pending change to
* remove the htlc and give the value of the HTLC to its recipient,
* and return CHANNEL_ERR_FULFILL_OK. Otherwise, it will return another error.
*/
enum channel_remove_err channel_fulfill_htlc(struct channel *channel,
enum side sender,
u64 id,
const struct preimage *preimage);
/**
* approx_max_feerate: what's the we (initiator) could raise fee rate to?
* @channel: The channel state
*
* This is not exact! To check if their offer is valid, use can_afford_feerate.
*/
u64 approx_max_feerate(const struct channel *channel);
/**
* can_afford_feerate: could the initiator pay for the fee at fee_rate?
* @channel: The channel state
* @feerate_per_kw: the new fee rate proposed
*/
bool can_afford_feerate(const struct channel *channel, u64 feerate_per_kw);
/**
* adjust_fee: Change fee rate.
* @channel: The channel state
* @feerate_per_kw: fee in satoshi per 1000 bytes.
* @side: which side to adjust.
*/
void adjust_fee(struct channel *channel, u64 feerate_per_kw, enum side side);
/**
* force_fee: Change fees to a specific value.
* @channel: The channel state
* @fee: fee in satoshi.
*
* This is used for the close transaction, which specifies an exact fee.
* If the fee cannot be paid in full, this return false (but cstate will
* still be altered).
*/
bool force_fee(struct channel *channel, u64 fee);
/**
* channel_sent_commit: commit all remote outstanding changes.
* @channel: the channel
*
* This is where we commit to pending changes we've added; returns true if
* anything changed. */
bool channel_sent_commit(struct channel *channel);
/**
* channel_rcvd_revoke_and_ack: accept ack on remote committed changes.
* @channel: the channel
*
* This is where we commit to pending changes we've added; returns true if
* anything changed. */
bool channel_rcvd_revoke_and_ack(struct channel *channel);
/**
* channel_rcvd_commit: commit all local outstanding changes.
* @channel: the channel
*
* This is where we commit to pending changes we've added; returns true if
* anything changed. */
bool channel_rcvd_commit(struct channel *channel);
/**
* channel_sent_revoke_and_ack: sent ack on local committed changes.
* @channel: the channel
*
* This is where we commit to pending changes we've added; returns true if
* anything changed. */
bool channel_sent_revoke_and_ack(struct channel *channel);
#endif /* LIGHTNING_DAEMON_CHANNEL_H */

501
lightningd/test/run-channel.c

@ -0,0 +1,501 @@
#include <status.h>
#include <stdio.h>
#define status_trace(fmt , ...) \
printf(fmt "\n" , ## __VA_ARGS__)
#include "../key_derive.c"
#include "../channel.c"
#include "../commit_tx.c"
#include "../htlc_tx.c"
#include <bitcoin/preimage.h>
#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <ccan/err/err.h>
#include <ccan/str/hex/hex.h>
#include <type_to_string.h>
static struct sha256 sha256_from_hex(const char *hex)
{
struct sha256 sha256;
if (strstarts(hex, "0x"))
hex += 2;
if (!hex_decode(hex, strlen(hex), &sha256, sizeof(sha256)))
abort();
return sha256;
}
/* bitcoind loves its backwards txids! */
static struct sha256_double txid_from_hex(const char *hex)
{
struct sha256_double sha256;
struct sha256 rev = sha256_from_hex(hex);
size_t i;
for (i = 0; i < sizeof(rev); i++)
sha256.sha.u.u8[sizeof(sha256) - 1 - i] = rev.u.u8[i];
return sha256;
}
/* BOLT #3:
*
* local_feerate_per_kw: 0
* ...
* local_feerate_per_kw: 678
* ...
* local_feerate_per_kw: 679
* ...
* local_feerate_per_kw: 2168
* ...
* local_feerate_per_kw: 2169
* ...
* local_feerate_per_kw: 2294
* ...
* local_feerate_per_kw: 2295
* ...
* local_feerate_per_kw: 3872
* ...
* local_feerate_per_kw: 3873
* ...
* local_feerate_per_kw: 5149
* ...
* local_feerate_per_kw: 5150
* ...
* local_feerate_per_kw: 9651180
* ...
* local_feerate_per_kw: 9651181
* ...
* local_feerate_per_kw: 9651936
*/
static u64 feerates[] = {
0,
678,
679,
2168,
2169,
2294,
2295,
3872,
3873,
5149,
5150,
9651180,
9651181,
9651936
};
/* BOLT #3:
*
* htlc 0 direction: remote->local
* htlc 0 amount_msat: 1000000
* htlc 0 expiry: 500
* htlc 0 payment_preimage: 0000000000000000000000000000000000000000000000000000000000000000
* htlc 1 direction: remote->local
* htlc 1 amount_msat: 2000000
* htlc 1 expiry: 501
* htlc 1 payment_preimage: 0101010101010101010101010101010101010101010101010101010101010101
* htlc 2 direction: local->remote
* htlc 2 amount_msat: 2000000
* htlc 2 expiry: 502
* htlc 2 payment_preimage: 0202020202020202020202020202020202020202020202020202020202020202
* htlc 3 direction: local->remote
* htlc 3 amount_msat: 3000000
* htlc 3 expiry: 503
* htlc 3 payment_preimage: 0303030303030303030303030303030303030303030303030303030303030303
* htlc 4 direction: remote->local
* htlc 4 amount_msat: 4000000
* htlc 4 expiry: 504
* htlc 4 payment_preimage: 0404040404040404040404040404040404040404040404040404040404040404
*/
static const struct htlc **add_htlcs(struct channel *channel, enum side side)
{
int i;
const struct htlc **htlcs = tal_arr(channel, const struct htlc *, 5);
u8 *dummy_routing = tal_arr(htlcs, u8, 1254);
for (i = 0; i < 5; i++) {
struct preimage preimage;
struct sha256 hash;
enum channel_add_err e;
enum side sender;
u64 msatoshi;
switch (i) {
case 0:
sender = !side;
msatoshi = 1000000;
break;
case 1:
sender = !side;
msatoshi = 2000000;
break;
case 2:
sender = side;
msatoshi = 2000000;
break;
case 3:
sender = side;
msatoshi = 3000000;
break;
case 4:
sender = !side;
msatoshi = 4000000;
break;
}
memset(&preimage, i, sizeof(preimage));
sha256(&hash, &preimage, sizeof(preimage));
e = channel_add_htlc(channel, sender, i, msatoshi, 500+i, &hash,
dummy_routing);
assert(e == CHANNEL_ERR_ADD_OK);
htlcs[i] = channel_get_htlc(channel, sender, i);
}
tal_free(dummy_routing);
/* Now make HTLCs fully committed. */
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
channel_rcvd_commit(channel);
channel_sent_revoke_and_ack(channel);
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
return htlcs;
}
static struct pubkey pubkey_from_hex(const char *hex)
{
struct pubkey pubkey;
if (strstarts(hex, "0x"))
hex += 2;
if (!pubkey_from_hexstr(hex, strlen(hex), &pubkey))
abort();
return pubkey;
}
static void tx_must_be_eq(const struct bitcoin_tx *a,
const struct bitcoin_tx *b)
{
tal_t *tmpctx = tal_tmpctx(NULL);
u8 *lina, *linb;
size_t i, len;
lina = linearize_tx(tmpctx, a);
linb = linearize_tx(tmpctx, b);
len = tal_len(lina);
if (tal_len(linb) < len)
len = tal_len(linb);
for (i = 0; i < tal_len(lina); i++) {
if (i >= tal_len(linb))
errx(1, "Second tx is truncated:\n"
"%s\n"
"%s",
tal_hex(tmpctx, lina),
tal_hex(tmpctx, linb));
if (lina[i] != linb[i])
errx(1, "tx differ at offset %zu:\n"
"%s\n"
"%s",
i,
tal_hex(tmpctx, lina),
tal_hex(tmpctx, linb));
}
if (i != tal_len(linb))
errx(1, "First tx is truncated:\n"
"%s\n"
"%s",
tal_hex(tmpctx, lina),
tal_hex(tmpctx, linb));
tal_free(tmpctx);
}
static void send_and_fulfill_htlc(struct channel *channel,
enum side sender,
u64 msatoshi)
{
struct preimage r;
struct sha256 rhash;
u8 *dummy_routing = tal_arr(channel, u8, 1254);
memset(&r, 0, sizeof(r));
sha256(&rhash, &r, sizeof(r));
assert(channel_add_htlc(channel, sender, 1337, msatoshi, 900, &rhash,
dummy_routing) == CHANNEL_ERR_ADD_OK);
if (sender == LOCAL) {
/* Step through a complete cycle. */
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
channel_rcvd_commit(channel);
channel_sent_revoke_and_ack(channel);
assert(channel_fulfill_htlc(channel, REMOTE, 1337, &r)
== CHANNEL_ERR_REMOVE_OK);
channel_rcvd_commit(channel);
channel_sent_revoke_and_ack(channel);
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
assert(channel_get_htlc(channel, sender, 1337)->state
== RCVD_REMOVE_ACK_REVOCATION);
} else {
channel_rcvd_commit(channel);
channel_sent_revoke_and_ack(channel);
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
assert(channel_fulfill_htlc(channel, LOCAL, 1337, &r)
== CHANNEL_ERR_REMOVE_OK);
channel_sent_commit(channel);
channel_rcvd_revoke_and_ack(channel);
channel_rcvd_commit(channel);
channel_sent_revoke_and_ack(channel);
assert(channel_get_htlc(channel, sender, 1337)->state
== SENT_REMOVE_ACK_REVOCATION);
}
}
int main(void)
{
tal_t *tmpctx = tal_tmpctx(NULL);
struct sha256_double funding_txid;
/* We test from both sides. */
struct channel *lchannel, *rchannel;
u64 funding_amount_satoshi, feerate_per_kw;
unsigned int funding_output_index;
struct pubkey localkey, remotekey;
struct pubkey local_delayedkey;
struct pubkey local_revocation_key;
struct pubkey local_revocation_basepoint, local_delayed_payment_basepoint,
local_payment_basepoint, remote_payment_basepoint,
local_per_commitment_point;
struct pubkey *unknown = tal(tmpctx, struct pubkey);
struct bitcoin_tx *raw_tx, *tx;
struct channel_config *local_config = tal(tmpctx, struct channel_config);
struct channel_config *remote_config = tal(tmpctx, struct channel_config);
u64 to_local_msat, to_remote_msat;
const struct htlc **htlc_map, **htlcs;
size_t i;
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
/* BOLT #3:
*
* # Appendix C: Commitment and HTLC Transaction Test Vectors
*
* In the following:
* - we consider *local* transactions, which implies that all payments
* to *local* are delayed
* - we assume that *local* is the funder
* - private keys are displayed as 32 bytes plus a trailing 1
* (bitcoin's convention for "compressed" private keys, i.e. keys
* for which the public key is compressed)
*
* - transaction signatures are all deterministic, using
* RFC6979 (using HMAC-SHA256)
*
* We start by defining common basic parameters for each test vector:
* the HTLCs are not used for the first "simple commitment tx with no
* HTLCs" test.
*
* funding_tx_id: 8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be
* funding_output_index: 0
* funding_amount_satoshi: 10000000
*...
* local_delay: 144
* local_dust_limit_satoshi: 546
*/
funding_txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be");
funding_output_index = 0;
funding_amount_satoshi = 10000000;
remote_config->to_self_delay = 144;
local_config->dust_limit_satoshis = 546;
/* This matters only because we check if added HTLC will create new
* output, for fee considerations. */
remote_config->dust_limit_satoshis = 546;
local_config->max_htlc_value_in_flight_msat = -1ULL;
remote_config->max_htlc_value_in_flight_msat = -1ULL;
local_config->channel_reserve_satoshis = 0;
remote_config->channel_reserve_satoshis = 0;
local_config->htlc_minimum_msat = 0;
remote_config->htlc_minimum_msat = 0;
local_config->max_accepted_htlcs = 0xFFFF;
remote_config->max_accepted_htlcs = 0xFFFF;
/* BOLT #3:
*
* # From local_revocation_basepoint_secret
* INTERNAL: local_revocation_basepoint: 02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27
* # From local_delayed_payment_basepoint_secret
* INTERNAL: local_delayed_payment_basepoint: 023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1
*/
local_revocation_basepoint = pubkey_from_hex("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27");
local_delayed_payment_basepoint = pubkey_from_hex("023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1");
/* BOLT #3:
*
* local_payment_basepoint: 034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
* remote_payment_basepoint: 032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991
* # obscured commitment transaction number = 0x2bb038521914 ^ 42
*/
local_payment_basepoint = pubkey_from_hex("034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa");
remote_payment_basepoint = pubkey_from_hex("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991");
/* BOLT #3:
*
* name: simple commitment tx with no HTLCs
* to_local_msat: 7000000000
* to_remote_msat: 3000000000
* feerate_per_kw: 15000
*/
/* We put unknown in for some things; valgrind will warn if used. */
to_local_msat = 7000000000;
to_remote_msat = 3000000000;
feerate_per_kw = 15000;
lchannel = new_channel(tmpctx, &funding_txid, funding_output_index,
funding_amount_satoshi, to_remote_msat,
feerate_per_kw,
local_config,
remote_config,
&local_revocation_basepoint,
unknown,
&local_payment_basepoint,
&remote_payment_basepoint,
&local_delayed_payment_basepoint,
unknown,
LOCAL);
rchannel = new_channel(tmpctx, &funding_txid, funding_output_index,
funding_amount_satoshi, to_remote_msat,
feerate_per_kw,
remote_config,
local_config,
unknown,
&local_revocation_basepoint,
&remote_payment_basepoint,
&local_payment_basepoint,
unknown,
&local_delayed_payment_basepoint,
REMOTE);
/* BOLT #3:
*
* commitment_number: 42
*/
lchannel->view[LOCAL].commitment_number
= rchannel->view[REMOTE].commitment_number = 42;
/* BOLT #3:
*
* INTERNAL: local_per_commitment_point: 025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486
*/
local_per_commitment_point = pubkey_from_hex("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486");
/* BOLT #3:
* localkey: 030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e7
* remotekey: 0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b
* local_delayedkey: 03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c
* local_revocation_key: 0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19
*/
localkey = pubkey_from_hex("030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e7");
remotekey = pubkey_from_hex("0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b");
local_delayedkey = pubkey_from_hex("03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c");
local_revocation_key = pubkey_from_hex("0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19");
raw_tx = commit_tx(tmpctx, &funding_txid, funding_output_index,
funding_amount_satoshi,
LOCAL, remote_config->to_self_delay,
&local_revocation_key,
&local_delayedkey,
&localkey,
&remotekey,
feerate_per_kw,
local_config->dust_limit_satoshis,
to_local_msat,
to_remote_msat,
NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL);
tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
&htlc_map, LOCAL);
tx_must_be_eq(tx, raw_tx);
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
&htlc_map, REMOTE);
tx_must_be_eq(tx, raw_tx);
/* BOLT #3:
*
* name: commitment tx with all 5 htlcs untrimmed (minimum feerate)
* to_local_msat: 6988000000
* to_remote_msat: 3000000000
* local_feerate_per_kw: 0
*/
to_local_msat = 6988000000;
to_remote_msat = 3000000000;
feerate_per_kw = 0;
/* Now, BOLT doesn't adjust owed amounts the same way we do
* here: it's as if local side paid for all the HTLCs. We can
* fix this by having local side offer an HTLC, and having
* remote side accept it */
send_and_fulfill_htlc(lchannel, LOCAL, 7000000);
send_and_fulfill_htlc(rchannel, REMOTE, 7000000);
assert(lchannel->view[LOCAL].owed_msat[LOCAL]
== rchannel->view[REMOTE].owed_msat[REMOTE]);
assert(lchannel->view[REMOTE].owed_msat[REMOTE]
== rchannel->view[LOCAL].owed_msat[LOCAL]);
raw_tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
&htlc_map, LOCAL);
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
&htlc_map, REMOTE);
tx_must_be_eq(tx, raw_tx);
/* FIXME: Adjust properly! */
lchannel->view[LOCAL].feerate_per_kw = feerate_per_kw;
rchannel->view[REMOTE].feerate_per_kw = feerate_per_kw;
htlcs = add_htlcs(lchannel, LOCAL);
add_htlcs(rchannel, REMOTE);
assert(lchannel->view[LOCAL].owed_msat[LOCAL]
== rchannel->view[REMOTE].owed_msat[REMOTE]);
assert(lchannel->view[REMOTE].owed_msat[REMOTE]
== rchannel->view[LOCAL].owed_msat[LOCAL]);
for (i = 0; i < ARRAY_SIZE(feerates); i++) {
feerate_per_kw = feerates[i];
lchannel->view[LOCAL].feerate_per_kw = feerate_per_kw;
rchannel->view[REMOTE].feerate_per_kw = feerate_per_kw;
raw_tx = commit_tx(tmpctx, &funding_txid, funding_output_index,
funding_amount_satoshi,
LOCAL, remote_config->to_self_delay,
&local_revocation_key,
&local_delayedkey,
&localkey,
&remotekey,
feerate_per_kw,
local_config->dust_limit_satoshis,
to_local_msat,
to_remote_msat,
htlcs, &htlc_map,
0x2bb038521914 ^ 42, LOCAL);
tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
&htlc_map, LOCAL);
tx_must_be_eq(tx, raw_tx);
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
&htlc_map, REMOTE);
tx_must_be_eq(tx, raw_tx);
}
/* No memory leaks please */
secp256k1_context_destroy(secp256k1_ctx);
tal_free(tmpctx);
/* FIXME: Do BOLT comparison! */
return 0;
}

1
type_to_string.h

@ -22,6 +22,7 @@ union printable_types {
const struct channel_id *channel_id;
const struct privkey *privkey;
const secp256k1_ecdsa_signature *secp256k1_ecdsa_signature;
const struct channel *channel;
const char *charp_;
};

Loading…
Cancel
Save