mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 20:09:18 +01:00
gossipd: pass remote private channel update to ld
and stash in the database. Rusty: I added the bad gossip message so we would see unknown updates in CI, and made sure we don't send our own generated updates to lightningd. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
c1beb4b745
commit
8e897746e2
14 changed files with 198 additions and 12 deletions
|
@ -600,7 +600,7 @@ static void apply_update(struct daemon *daemon,
|
|||
take(update);
|
||||
}
|
||||
|
||||
msg = handle_channel_update(daemon->rstate, update, &chan->nodes[direction]->id, NULL, true);
|
||||
msg = handle_channel_update(daemon->rstate, update, NULL, NULL, true);
|
||||
if (msg)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"%s: rejected local channel update %s: %s",
|
||||
|
|
|
@ -1206,6 +1206,7 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT_REPLY:
|
||||
case WIRE_GOSSIPD_GET_ADDRS_REPLY:
|
||||
case WIRE_GOSSIPD_GOT_LOCAL_CHANNEL_UPDATE:
|
||||
case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -136,3 +136,16 @@ msgdata,gossipd_used_local_channel_update,scid,short_channel_id,
|
|||
# Tell gossipd we have verified a new public IP by the remote_addr feature
|
||||
msgtype,gossipd_discovered_ip,3009
|
||||
msgdata,gossipd_discovered_ip,discovered_ip,wireaddr,
|
||||
|
||||
subtype,remote_priv_update
|
||||
subtypedata,remote_priv_update,source_node,node_id,
|
||||
subtypedata,remote_priv_update,scid,short_channel_id,
|
||||
subtypedata,remote_priv_update,fee_base,u32,
|
||||
subtypedata,remote_priv_update,fee_ppm,u32,
|
||||
subtypedata,remote_priv_update,cltv_delta,u16,
|
||||
subtypedata,remote_priv_update,htlc_minimum_msat,amount_msat,
|
||||
subtypedata,remote_priv_update,htlc_maximum_msat,amount_msat,
|
||||
|
||||
# Tell lightningd we received channel update info for a local channel
|
||||
msgtype,gossipd_remote_channel_update,3010
|
||||
msgdata,gossipd_remote_channel_update,update,remote_priv_update,
|
||||
|
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <bitcoin/script.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/daemon_conn.h>
|
||||
#include <common/gossip_store.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/pseudorand.h>
|
||||
|
@ -1347,9 +1348,32 @@ static bool is_chan_dying(struct routing_state *rstate,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void tell_lightningd_private_update(struct routing_state *rstate,
|
||||
const struct node_id *source_peer,
|
||||
struct short_channel_id scid,
|
||||
u32 fee_base_msat,
|
||||
u32 fee_ppm,
|
||||
u16 cltv_delta,
|
||||
struct amount_msat htlc_minimum,
|
||||
struct amount_msat htlc_maximum)
|
||||
{
|
||||
struct remote_priv_update remote_update;
|
||||
u8* msg;
|
||||
remote_update.source_node = *source_peer;
|
||||
remote_update.scid = scid;
|
||||
remote_update.fee_base = fee_base_msat;
|
||||
remote_update.fee_ppm = fee_ppm;
|
||||
remote_update.cltv_delta = cltv_delta;
|
||||
remote_update.htlc_minimum_msat = htlc_minimum;
|
||||
remote_update.htlc_maximum_msat = htlc_maximum;
|
||||
msg = towire_gossipd_remote_channel_update(NULL, &remote_update);
|
||||
daemon_conn_send(rstate->daemon->master, take(msg));
|
||||
}
|
||||
|
||||
bool routing_add_channel_update(struct routing_state *rstate,
|
||||
const u8 *update TAKES,
|
||||
u32 index,
|
||||
/* NULL if it's us */
|
||||
const struct node_id *source_peer,
|
||||
bool ignore_timestamp,
|
||||
bool force_spam_flag,
|
||||
|
@ -1398,6 +1422,16 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||
/* Maybe announcement was waiting for this update? */
|
||||
uc = get_unupdated_channel(rstate, &short_channel_id);
|
||||
if (!uc) {
|
||||
if (index)
|
||||
return false;
|
||||
/* Allow ld to process a private channel update */
|
||||
if (source_peer) {
|
||||
tell_lightningd_private_update(rstate, source_peer,
|
||||
short_channel_id, fee_base_msat,
|
||||
fee_proportional_millionths,
|
||||
expiry, htlc_minimum,
|
||||
htlc_maximum);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
sat = uc->sat;
|
||||
|
@ -1535,6 +1569,14 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||
hc->bcast.index = index;
|
||||
hc->rgraph.index = index;
|
||||
}
|
||||
if (source_peer) {
|
||||
/* give lightningd the channel's inbound info to store to db */
|
||||
tell_lightningd_private_update(rstate, source_peer,
|
||||
short_channel_id, fee_base_msat,
|
||||
fee_proportional_millionths,
|
||||
expiry, htlc_minimum,
|
||||
htlc_maximum);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2340,4 +2382,3 @@ void routing_channel_spent(struct routing_state *rstate,
|
|||
type_to_string(msg, struct short_channel_id, &chan->scid));
|
||||
remember_chan_dying(rstate, &chan->scid, deadline, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED,
|
|||
const struct half_chan *hc UNNEEDED,
|
||||
const u8 *cupdate UNNEEDED)
|
||||
{ fprintf(stderr, "cupdate_different called!\n"); abort(); }
|
||||
/* Generated stub for daemon_conn_send */
|
||||
void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); }
|
||||
/* Generated stub for gossip_store_add */
|
||||
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
||||
u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED,
|
||||
|
@ -133,6 +136,9 @@ void status_fmt(enum log_level level UNNEEDED,
|
|||
const char *fmt UNNEEDED, ...)
|
||||
|
||||
{ fprintf(stderr, "status_fmt called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipd_remote_channel_update */
|
||||
u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); }
|
||||
/* AUTOGENERATED MOCKS END */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
|
@ -30,6 +30,9 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED,
|
|||
const struct half_chan *hc UNNEEDED,
|
||||
const u8 *cupdate UNNEEDED)
|
||||
{ fprintf(stderr, "cupdate_different called!\n"); abort(); }
|
||||
/* Generated stub for daemon_conn_send */
|
||||
void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); }
|
||||
/* Generated stub for gossip_store_add */
|
||||
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
||||
u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED,
|
||||
|
@ -99,6 +102,9 @@ void status_fmt(enum log_level level UNNEEDED,
|
|||
const char *fmt UNNEEDED, ...)
|
||||
|
||||
{ fprintf(stderr, "status_fmt called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipd_remote_channel_update */
|
||||
u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); }
|
||||
/* Generated stub for towire_warningfmt */
|
||||
u8 *towire_warningfmt(const tal_t *ctx UNNEEDED,
|
||||
const struct channel_id *channel UNNEEDED,
|
||||
|
|
|
@ -264,6 +264,7 @@ struct channel *new_unsaved_channel(struct peer *peer,
|
|||
= CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE;
|
||||
channel->shutdown_wrong_funding = NULL;
|
||||
channel->closing_feerate_range = NULL;
|
||||
channel->private_update = NULL;
|
||||
channel->channel_update = NULL;
|
||||
channel->alias[LOCAL] = channel->alias[REMOTE] = NULL;
|
||||
|
||||
|
@ -427,7 +428,9 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||
u16 lease_chan_max_ppt,
|
||||
struct amount_msat htlc_minimum_msat,
|
||||
struct amount_msat htlc_maximum_msat,
|
||||
bool ignore_fee_limits)
|
||||
bool ignore_fee_limits,
|
||||
/* NULL or stolen */
|
||||
struct remote_priv_update *private_update STEALS)
|
||||
{
|
||||
struct channel *channel = tal(peer->ld, struct channel);
|
||||
struct amount_msat htlc_min, htlc_max;
|
||||
|
@ -553,6 +556,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||
channel->lease_commit_sig = tal_steal(channel, lease_commit_sig);
|
||||
channel->lease_chan_max_msat = lease_chan_max_msat;
|
||||
channel->lease_chan_max_ppt = lease_chan_max_ppt;
|
||||
channel->private_update = tal_steal(channel, private_update);
|
||||
channel->blockheight_states = dup_height_states(channel, height_states);
|
||||
channel->channel_update = NULL;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <common/scb_wiregen.h>
|
||||
#include <common/tx_roles.h>
|
||||
#include <common/utils.h>
|
||||
#include <gossipd/gossipd_wiregen.h>
|
||||
#include <lightningd/channel_state.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
|
@ -297,6 +298,10 @@ struct channel {
|
|||
/* Lease commited max part per thousandth channel fee (ppm * 1000) */
|
||||
u16 lease_chan_max_ppt;
|
||||
|
||||
/* Private channel incoming fee rates, cltv delta min/max htlc from
|
||||
* peer. Used to generate route hints, blinded paths. */
|
||||
struct remote_priv_update *private_update;
|
||||
|
||||
/* Latest channel_update, for use in error messages. */
|
||||
u8 *channel_update;
|
||||
|
||||
|
@ -383,7 +388,9 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||
u16 lease_chan_max_ppt,
|
||||
struct amount_msat htlc_minimum_msat,
|
||||
struct amount_msat htlc_maximum_msat,
|
||||
bool ignore_fee_limits);
|
||||
bool ignore_fee_limits,
|
||||
/* NULL or stolen */
|
||||
struct remote_priv_update *private_update STEALS);
|
||||
|
||||
/* new_inflight - Create a new channel_inflight for a channel */
|
||||
struct channel_inflight *new_inflight(struct channel *channel,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <common/json_command.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <gossipd/gossipd_wiregen.h>
|
||||
#include <hsmd/permissions.h>
|
||||
|
@ -172,6 +173,57 @@ const u8 *get_channel_update(struct channel *channel)
|
|||
return channel->channel_update;
|
||||
}
|
||||
|
||||
static void set_channel_remote_update(struct lightningd *ld,
|
||||
struct channel *channel,
|
||||
struct remote_priv_update* update TAKES)
|
||||
{
|
||||
struct short_channel_id *scid;
|
||||
|
||||
scid = channel->scid;
|
||||
if (!scid)
|
||||
scid = channel->alias[LOCAL];
|
||||
|
||||
if (!node_id_eq(&update->source_node, &channel->peer->id)) {
|
||||
log_unusual(ld->log, "Bad gossip order: %s sent us a channel update for a "
|
||||
"channel owned by %s (%s)",
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&update->source_node),
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&channel->peer->id),
|
||||
type_to_string(tmpctx, struct short_channel_id, scid));
|
||||
if (taken(update))
|
||||
tal_free(update);
|
||||
return;
|
||||
}
|
||||
log_debug(ld->log, "updating channel %s with private inbound settings",
|
||||
type_to_string(tmpctx, struct short_channel_id, scid));
|
||||
tal_free(channel->private_update);
|
||||
channel->private_update = tal_dup(channel,
|
||||
struct remote_priv_update, update);
|
||||
if (taken(update))
|
||||
tal_free(update);
|
||||
wallet_channel_save(ld->wallet, channel);
|
||||
}
|
||||
|
||||
static void handle_private_update_data(struct lightningd *ld, const u8 *msg)
|
||||
{
|
||||
struct channel *channel;
|
||||
struct remote_priv_update *update;
|
||||
|
||||
update = tal(tmpctx, struct remote_priv_update);
|
||||
if (!fromwire_gossipd_remote_channel_update(msg, update))
|
||||
fatal("Gossip gave bad GOSSIPD_REMOTE_CHANNEL_UPDATE %s",
|
||||
tal_hex(msg, msg));
|
||||
channel = any_channel_by_scid(ld, &update->scid, true);
|
||||
if (!channel) {
|
||||
log_unusual(ld->log, "could not find channel for peer's "
|
||||
"private channel update");
|
||||
return;
|
||||
}
|
||||
|
||||
set_channel_remote_update(ld, channel, update);
|
||||
}
|
||||
|
||||
static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
||||
{
|
||||
enum gossipd_wire t = fromwire_peektype(msg);
|
||||
|
@ -213,6 +265,11 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||
case WIRE_GOSSIPD_GOT_LOCAL_CHANNEL_UPDATE:
|
||||
handle_local_channel_update(gossip->ld, msg);
|
||||
break;
|
||||
case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE:
|
||||
/* Please stash in database for us! */
|
||||
handle_private_update_data(gossip->ld, msg);
|
||||
tal_free(msg);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -232,7 +232,8 @@ wallet_commit_channel(struct lightningd *ld,
|
|||
0, NULL, 0, 0, /* No leases on v1s */
|
||||
ld->config.htlc_minimum_msat,
|
||||
ld->config.htlc_maximum_msat,
|
||||
ld->config.ignore_fee_limits);
|
||||
ld->config.ignore_fee_limits,
|
||||
NULL);
|
||||
|
||||
/* Now we finally put it in the database. */
|
||||
wallet_channel_insert(ld->wallet, channel);
|
||||
|
@ -1486,7 +1487,8 @@ static struct channel *stub_chan(struct command *cmd,
|
|||
0, NULL, 0, 0, /* No leases on v1s */
|
||||
ld->config.htlc_minimum_msat,
|
||||
ld->config.htlc_maximum_msat,
|
||||
false);
|
||||
false,
|
||||
NULL);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJ
|
|||
|
||||
# Topology wants to decode node_announcement, and peer_wiregen which
|
||||
# pulls in some of bitcoin/.
|
||||
plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
|
||||
plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o common/gossmods_listpeerchannels.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
|
||||
|
||||
plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
|
||||
|
||||
|
|
|
@ -176,7 +176,9 @@ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED,
|
|||
u16 lease_chan_max_ppt UNNEEDED,
|
||||
struct amount_msat htlc_minimum_msat UNNEEDED,
|
||||
struct amount_msat htlc_maximum_msat UNNEEDED,
|
||||
bool ignore_fee_limits UNNEEDED)
|
||||
bool ignore_fee_limits UNNEEDED,
|
||||
/* NULL or stolen */
|
||||
struct remote_priv_update* remote_update STEALS UNNEEDED)
|
||||
{ fprintf(stderr, "new_channel called!\n"); abort(); }
|
||||
/* Generated stub for new_coin_wallet_deposit */
|
||||
struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
|
||||
|
|
|
@ -1904,7 +1904,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
|
|||
7777, 22,
|
||||
AMOUNT_MSAT(0),
|
||||
AMOUNT_MSAT(-1ULL),
|
||||
false);
|
||||
false,
|
||||
NULL);
|
||||
db_begin_transaction(w->db);
|
||||
CHECK(!wallet_err);
|
||||
wallet_channel_insert(w, chan);
|
||||
|
|
|
@ -1514,6 +1514,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||
u32 lease_chan_max_msat;
|
||||
u16 lease_chan_max_ppt;
|
||||
bool ignore_fee_limits;
|
||||
struct remote_priv_update *remote_update;
|
||||
|
||||
peer_dbid = db_col_u64(stmt, "peer_id");
|
||||
peer = find_peer_by_dbid(w->ld, peer_dbid);
|
||||
|
@ -1678,6 +1679,27 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||
last_sig = NULL;
|
||||
}
|
||||
|
||||
if (!db_col_is_null(stmt, "remote_cltv_expiry_delta")) {
|
||||
remote_update = tal(NULL, struct remote_priv_update);
|
||||
remote_update->source_node = peer->id;
|
||||
if (scid)
|
||||
remote_update->scid = *scid;
|
||||
else
|
||||
remote_update->scid = *alias[LOCAL];
|
||||
remote_update->fee_base = db_col_int(stmt, "remote_feerate_base");
|
||||
remote_update->fee_ppm = db_col_int(stmt, "remote_feerate_ppm");
|
||||
remote_update->cltv_delta = db_col_int(stmt, "remote_cltv_expiry_delta");
|
||||
remote_update->htlc_minimum_msat = db_col_amount_msat(stmt, "remote_htlc_minimum_msat");
|
||||
remote_update->htlc_maximum_msat = db_col_amount_msat(stmt, "remote_htlc_maximum_msat");
|
||||
} else {
|
||||
remote_update = NULL;
|
||||
db_col_ignore(stmt, "remote_feerate_base");
|
||||
db_col_ignore(stmt, "remote_feerate_ppm");
|
||||
db_col_ignore(stmt, "remote_cltv_expiry_delta");
|
||||
db_col_ignore(stmt, "remote_htlc_minimum_msat");
|
||||
db_col_ignore(stmt, "remote_htlc_maximum_msat");
|
||||
}
|
||||
|
||||
chan = new_channel(peer, db_col_u64(stmt, "id"),
|
||||
&wshachain,
|
||||
channel_state_in_db(db_col_int(stmt, "state")),
|
||||
|
@ -1737,7 +1759,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||
lease_chan_max_ppt,
|
||||
htlc_minimum_msat,
|
||||
htlc_maximum_msat,
|
||||
ignore_fee_limits);
|
||||
ignore_fee_limits,
|
||||
remote_update);
|
||||
|
||||
if (!wallet_channel_load_inflights(w, chan)) {
|
||||
tal_free(chan);
|
||||
|
@ -1925,6 +1948,11 @@ static bool wallet_channels_load_active(struct wallet *w)
|
|||
", alias_local"
|
||||
", alias_remote"
|
||||
", ignore_fee_limits"
|
||||
", remote_feerate_base"
|
||||
", remote_feerate_ppm"
|
||||
", remote_cltv_expiry_delta"
|
||||
", remote_htlc_minimum_msat"
|
||||
", remote_htlc_maximum_msat"
|
||||
" FROM channels"
|
||||
" WHERE state != ?;")); //? 0
|
||||
db_bind_int(stmt, CLOSED);
|
||||
|
@ -2238,8 +2266,13 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
|
|||
" htlc_maximum_msat=?," // 43
|
||||
" alias_local=?," // 44
|
||||
" alias_remote=?," // 45
|
||||
" ignore_fee_limits=?" // 46
|
||||
" WHERE id=?")); // 47
|
||||
" ignore_fee_limits=?," // 46
|
||||
" remote_feerate_base=?," // 47
|
||||
" remote_feerate_ppm=?," // 48
|
||||
" remote_cltv_expiry_delta=?," // 49
|
||||
" remote_htlc_minimum_msat=?," // 50
|
||||
" remote_htlc_maximum_msat=?" // 51
|
||||
" WHERE id=?")); // 52
|
||||
db_bind_u64(stmt, chan->their_shachain.id);
|
||||
if (chan->scid)
|
||||
db_bind_short_channel_id(stmt, chan->scid);
|
||||
|
@ -2321,6 +2354,19 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
|
|||
db_bind_null(stmt);
|
||||
|
||||
db_bind_int(stmt, chan->ignore_fee_limits);
|
||||
if (chan->private_update) {
|
||||
db_bind_int(stmt, chan->private_update->fee_base);
|
||||
db_bind_int(stmt, chan->private_update->fee_ppm);
|
||||
db_bind_int(stmt, chan->private_update->cltv_delta);
|
||||
db_bind_amount_msat(stmt, &chan->private_update->htlc_minimum_msat);
|
||||
db_bind_amount_msat(stmt, &chan->private_update->htlc_maximum_msat);
|
||||
} else {
|
||||
db_bind_null(stmt);
|
||||
db_bind_null(stmt);
|
||||
db_bind_null(stmt);
|
||||
db_bind_null(stmt);
|
||||
db_bind_null(stmt);
|
||||
}
|
||||
db_bind_u64(stmt, chan->dbid);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue