liquidity-ads: persist channel blockheight states to disk

Adds new tables to database, backfills, basically copies the fee_rates
state machine for channeld.
This commit is contained in:
niftynei
2021-06-22 13:25:59 -05:00
committed by neil saitug
parent a396c341cf
commit 265f960cfe
72 changed files with 1414 additions and 441 deletions

164
common/blockheight_states.c Normal file
View File

@@ -0,0 +1,164 @@
#include <ccan/array_size/array_size.h>
#include <ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
#include <common/blockheight_states.h>
#include <common/fee_states.h>
#include <common/type_to_string.h>
#include <wire/wire.h>
struct height_states *new_height_states(const tal_t *ctx,
enum side opener,
const u32 *blockheight)
{
struct height_states *states = tal(ctx, struct height_states);
/* Set to NULL except terminal value */
for (size_t i = 0; i < ARRAY_SIZE(states->height); i++)
states->height[i] = NULL;
if (blockheight)
/* We reuse fee states! */
states->height[last_fee_state(opener)]
= tal_dup(states, u32, blockheight);
return states;
}
u32 get_blockheight(const struct height_states *height_states,
enum side opener,
enum side side)
{
/* The first non-NULL blockheight committed to this side is current */
/* We use the same states as update_fee */
for (enum htlc_state i = first_fee_state(opener);
i <= last_fee_state(opener);
i++) {
if (!height_states->height[i])
continue;
if (!(htlc_state_flags(i) & HTLC_FLAG(side, HTLC_F_COMMITTED)))
continue;
return *height_states->height[i];
}
/* Some blockheight should always be set! */
abort();
}
void start_height_update(struct height_states *height_states,
enum side opener,
u32 blockheight)
{
/* Same as the feerate states */
enum htlc_state start = first_fee_state(opener);
/* BOLT #2:
* Unlike an HTLC, `update_fee` is never closed but simply replaced.
*/
if (height_states->height[start] == NULL)
height_states->height[start] = tal(height_states, u32);
*height_states->height[start] = blockheight;
}
/* Are blockheights all agreed by both sides? */
bool blockheight_changes_done(const struct height_states *height_states,
bool ignore_uncommitted)
{
size_t num_blockheights = 0;
for (size_t i = 0; i < ARRAY_SIZE(height_states->height); i++) {
if (ignore_uncommitted
&& (i == RCVD_ADD_HTLC || i == SENT_ADD_HTLC))
continue;
num_blockheights += (height_states->height[i] != NULL);
}
return num_blockheights == 1;
}
bool inc_height_state(struct height_states *height_states,
enum htlc_state hstate)
{
/* These only advance through ADDING states. */
assert(htlc_state_flags(hstate) & HTLC_ADDING);
if (!height_states->height[hstate])
return false;
/* FIXME: We can never clash, except at final state unless someone
* has violated protocol (eg, send two revoke_and_ack back-to-back) */
tal_free(height_states->height[hstate+1]);
height_states->height[hstate+1] = height_states->height[hstate];
height_states->height[hstate] = NULL;
return true;
}
struct height_states *dup_height_states(const tal_t *ctx,
const struct height_states *states TAKES)
{
struct height_states *n;
if (taken(states))
return cast_const(struct height_states *,
tal_steal(ctx, states));
n = tal_dup(ctx, struct height_states, states);
for (size_t i = 0; i < ARRAY_SIZE(n->height); i++) {
if (n->height[i])
n->height[i] = tal_dup(n, u32, n->height[i]);
}
return n;
}
/* FIXME: we don't know opener inside fromwire_height_states, so can't do
* this there :( */
bool height_states_valid(const struct height_states *states, enum side opener)
{
/* We use the same states as update fee */
return states->height[last_fee_state(opener)] != NULL;
}
void towire_height_states(u8 **pptr, const struct height_states *states)
{
for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) {
/* We don't send uncommitted feestates */
if (!(htlc_state_flags(i) & (HTLC_REMOTE_F_COMMITTED
| HTLC_LOCAL_F_COMMITTED))
|| states->height[i] == NULL) {
towire_bool(pptr, false);
continue;
}
towire_bool(pptr, true);
towire_u32(pptr, *states->height[i]);
}
}
struct height_states *fromwire_height_states(const tal_t *ctx, const u8 **cursor, size_t *max)
{
struct height_states *states = tal(ctx, struct height_states);
for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) {
if (fromwire_bool(cursor, max)) {
states->height[i] = tal(states, u32);
*states->height[i] = fromwire_u32(cursor, max);
} else {
states->height[i] = NULL;
}
}
if (!*cursor)
return tal_free(states);
return states;
}
static const char *fmt_height_states(const tal_t *ctx,
const struct height_states *states)
{
char *ret = tal_strdup(ctx, "{");
for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) {
if (states->height[i] != NULL)
tal_append_fmt(&ret, " %s:%u",
htlc_state_name(i),
*states->height[i]);
}
tal_append_fmt(&ret, " }");
return ret;
}
REGISTER_TYPE_TO_STRING(height_states, fmt_height_states);

View File

@@ -0,0 +1,79 @@
#ifndef LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H
#define LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H
#include "config.h"
#include <ccan/tal/tal.h>
#include <common/htlc.h>
struct height_states {
/* Current blockheight: goes through same
* state machine as feestate addition.
*
* We need to know if there's an actual change pending though (even if
* it's a "change" to an idential feerate!) so we use pointers.
*/
u32 *height[HTLC_STATE_INVALID];
};
/**
* new_height_states: Initialize a height_states structure as at
* open-of-channel.
* @ctx: the tal ctx to allocate off
* @opener: which side opened the channel
* (and thus, proposes blockheight updates).
* @blockheight: the initial blockheight (if any).
*/
struct height_states *new_height_states(const tal_t *ctx,
enum side opener,
const u32 *blockheight);
/**
* get_blockheight: Get the current blockheight
* @height_states: the blockheight state machine
* @opener: which side opened the channel
* (and thus, proposes blockheight updates).
* @side: which side to get the blockheight for
*/
u32 get_blockheight(const struct height_states *height_states,
enum side opener,
enum side side);
/**
* start_height_update: feed a new blockheight update into state machine.
* @height_states: the height state machine
* @opener: which side opened the channel (and thus, proposes
* blockheight updates).
* @blockheight: the new blockheight.
*/
void start_height_update(struct height_states *height_states,
enum side opener,
u32 blockheight);
/**
* inc_height_state: move this blockheight to the next state.
* @height_states: the blockheight state machine
* @hstate: state
*
* Moves height_states[hstate] to height_states[hstate+1], if not NULL.
* Returns true if it wasn't NULL.
*/
bool inc_height_state(struct height_states *height_states,
enum htlc_state hstate);
/* Are blockheights all agreed by both sides? */
bool blockheight_changes_done(const struct height_states *height_states,
bool ignore_uncommitted);
/* Duplicate a set of height states */
struct height_states *dup_height_states(const tal_t *ctx,
const struct height_states *states TAKES);
/* Marshal and unmarshal */
void towire_height_states(u8 **pptr, const struct height_states *height_states);
/* FIXME: You must check that height_states_valid! */
struct height_states *fromwire_height_states(const tal_t *ctx,
const u8 **cursor, size_t *max);
/**
* is this height_state struct valid for this side?
*/
bool height_states_valid(const struct height_states *states, enum side opener);
#endif /* LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H */

View File

@@ -6,6 +6,7 @@
#include <ccan/array_size/array_size.h>
#include <ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
#include <common/blockheight_states.h>
#include <common/features.h>
#include <common/fee_states.h>
#include <common/initial_channel.h>
@@ -21,6 +22,7 @@ struct channel *new_initial_channel(const tal_t *ctx,
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
u32 minimum_depth,
const struct height_states *height_states TAKES,
u32 lease_expiry,
struct amount_sat funding,
struct amount_msat local_msatoshi,
@@ -58,6 +60,13 @@ struct channel *new_initial_channel(const tal_t *ctx,
/* takes() if necessary */
channel->fee_states = dup_fee_states(channel, fee_states);
/* takes() if necessary */
if (!height_states)
channel->blockheight_states = NULL;
else
channel->blockheight_states
= dup_height_states(channel, height_states);
channel->view[LOCAL].owed[LOCAL]
= channel->view[REMOTE].owed[LOCAL]
= local_msatoshi;
@@ -108,8 +117,11 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
if (channel->lease_expiry == 0)
csv_lock = 1;
else
/* FIXME: */
csv_lock = 1;
/* For the initial commitment, starts max lease */
csv_lock = channel->lease_expiry
- get_blockheight(channel->blockheight_states,
channel->opener,
side);
*wscript = bitcoin_redeem_2of2(ctx,
&channel->funding_pubkey[side],

View File

@@ -62,6 +62,10 @@ struct channel {
/* Fee changes, some which may be in transit */
struct fee_states *fee_states;
/* Blockheight changes, some which may be in transit
* (option_will_fund)*/
struct height_states *blockheight_states;
/* What it looks like to each side. */
struct channel_view view[NUM_SIDES];
@@ -82,7 +86,8 @@ struct channel {
* @funding_txid: The commitment transaction id.
* @funding_txout: The commitment transaction output number.
* @minimum_depth: The minimum confirmations needed for funding transaction.
* @lease_expiry: Block the lease expires
* @height_states: The blockheight update states.
* @lease_expiry: Block the lease expires.
* @funding_satoshis: The commitment transaction amount.
* @local_msatoshi: The amount for the local side (remainder goes to remote)
* @fee_states: The fee update states.
@@ -103,6 +108,7 @@ struct channel *new_initial_channel(const tal_t *ctx,
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
u32 minimum_depth,
const struct height_states *height_states TAKES,
u32 lease_expiry,
struct amount_sat funding,
struct amount_msat local_msatoshi,

View File

@@ -80,4 +80,4 @@ bool fromwire_status_peer_error(const tal_t *ctx, const void *p, struct channel_
fromwire_u8_array(&cursor, &plen, *error_for_them, len);
return cursor != NULL;
}
// SHA256STAMP:9eae5e1735b52e459db2548ff73399a8cb503ddbf72defc5bfa4022f3682ffd5
// SHA256STAMP:db80a04b587e0918ef55f7e82519f7ff86620c5ec4fd845452214059c1cdbd41

View File

@@ -34,4 +34,4 @@ bool fromwire_status_peer_error(const tal_t *ctx, const void *p, struct channel_
#endif /* LIGHTNING_COMMON_PEER_STATUS_WIREGEN_H */
// SHA256STAMP:9eae5e1735b52e459db2548ff73399a8cb503ddbf72defc5bfa4022f3682ffd5
// SHA256STAMP:db80a04b587e0918ef55f7e82519f7ff86620c5ec4fd845452214059c1cdbd41

View File

@@ -214,4 +214,4 @@ bool fromwire_status_version(const tal_t *ctx, const void *p, wirestring **versi
*version = fromwire_wirestring(ctx, &cursor, &plen);
return cursor != NULL;
}
// SHA256STAMP:676725f967cd09851ed0d872ed58ed058fa9de7d95acca7169e0262e7d0b2c64
// SHA256STAMP:6f868de7019bd204be0d90618a044c20ec1170430e3196674040ddb7f7278e80

View File

@@ -58,4 +58,4 @@ bool fromwire_status_version(const tal_t *ctx, const void *p, wirestring **versi
#endif /* LIGHTNING_COMMON_STATUS_WIREGEN_H */
// SHA256STAMP:676725f967cd09851ed0d872ed58ed058fa9de7d95acca7169e0262e7d0b2c64
// SHA256STAMP:6f868de7019bd204be0d90618a044c20ec1170430e3196674040ddb7f7278e80

View File

@@ -37,6 +37,7 @@ union printable_types {
const struct amount_msat *amount_msat;
const struct amount_sat *amount_sat;
const struct fee_states *fee_states;
const struct height_states *height_states;
const char *charp_;
const struct wally_psbt *wally_psbt;
const struct wally_tx *wally_tx;