diff --git a/lightningd/channel.c b/lightningd/channel.c index 10f388672..ff68376ee 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -306,6 +307,48 @@ struct channel *new_unsaved_channel(struct peer *peer, return channel; } +/* + * The maximum msat that this node could possibly accept for an htlc. + * It's the default htlc_maximum_msat in channel_updates, if none is + * explicitly set (and the cap on what can be set!). + * + * We advertize the maximum value possible, defined as the smaller + * of the remote's maximum in-flight HTLC or the total channel + * capacity the reserve we have to keep. + * FIXME: does this need fuzz? + */ +static struct amount_msat htlc_max_possible_send(const struct channel *channel) +{ + struct amount_sat lower_bound; + struct amount_msat lower_bound_msat; + + /* These shouldn't fail */ + if (!amount_sat_sub(&lower_bound, channel->funding_sats, + channel->channel_info.their_config.channel_reserve)) { + log_broken(channel->log, "%s: their reserve %s > funding %s!", + __func__, + type_to_string(tmpctx, struct amount_sat, + &channel->funding_sats), + type_to_string(tmpctx, struct amount_sat, + &channel->channel_info.their_config.channel_reserve)); + return AMOUNT_MSAT(0); + } + + if (!amount_sat_to_msat(&lower_bound_msat, lower_bound)) { + log_broken(channel->log, "%s: impossible size channel %s!", + __func__, + type_to_string(tmpctx, struct amount_sat, + &lower_bound)); + return AMOUNT_MSAT(0); + } + + if (amount_msat_less(channel->channel_info.their_config.max_htlc_value_in_flight, + lower_bound_msat)) + lower_bound_msat = channel->channel_info.their_config.max_htlc_value_in_flight; + + return lower_bound_msat; +} + struct channel *new_channel(struct peer *peer, u64 dbid, /* NULL or stolen */ struct wallet_shachain *their_shachain, @@ -366,9 +409,11 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, u32 lease_chan_max_msat, - u16 lease_chan_max_ppt) + u16 lease_chan_max_ppt, + struct amount_msat htlc_maximum_msat) { struct channel *channel = tal(peer->ld, struct channel); + struct amount_msat htlc_max; assert(dbid != 0); channel->peer = peer; @@ -464,6 +509,14 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->blockheight_states = dup_height_states(channel, height_states); channel->channel_update = NULL; + /* DB migration, for example, sets this to bignum; correct + * here */ + htlc_max = htlc_max_possible_send(channel); + if (amount_msat_less(htlc_max, htlc_maximum_msat)) + channel->htlc_maximum_msat = htlc_max; + else + channel->htlc_maximum_msat = htlc_maximum_msat; + list_add_tail(&peer->channels, &channel->list); channel->rr_number = peer->ld->rr_counter++; tal_add_destructor(channel, destroy_channel); diff --git a/lightningd/channel.h b/lightningd/channel.h index 091346f2c..98953fbe7 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -196,8 +196,12 @@ struct channel { * peer via option_data_loss_protect? */ const struct pubkey *future_per_commitment_point; + /* Max htlc amount allowed in channel. */ + struct amount_msat htlc_maximum_msat; + /* Feerate per channel */ u32 feerate_base, feerate_ppm; + /* But allow these feerates up until this time. */ struct timeabs old_feerate_timeout; u32 old_feerate_base, old_feerate_ppm; @@ -309,7 +313,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, u32 lease_chan_max_msat, - u16 lease_chan_max_ppt); + u16 lease_chan_max_ppt, + struct amount_msat htlc_maximum_msat); /* new_inflight - Create a new channel_inflight for a channel */ struct channel_inflight * diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 4c91a43f2..be576e75a 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -209,7 +209,8 @@ wallet_commit_channel(struct lightningd *ld, NULL, take(new_height_states(NULL, uc->fc ? LOCAL : REMOTE, &lease_start_blockheight)), - 0, NULL, 0, 0); /* No leases on v1s */ + 0, NULL, 0, 0, /* No leases on v1s */ + AMOUNT_MSAT(-1ULL)); /* No htlc_maximum_msat */ /* Now we finally put it in the database. */ wallet_channel_insert(ld->wallet, channel); diff --git a/wallet/db.c b/wallet/db.c index 3225579eb..09721db2c 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -869,6 +869,8 @@ static struct migration dbmigrations[] = { NULL}, {SQL("ALTER TABLE channel_htlcs ADD fees_msat BIGINT DEFAULT 0"), NULL}, {SQL("ALTER TABLE channel_funding_inflights ADD lease_fee BIGINT DEFAULT 0"), NULL}, + /* Default is too big; we set to max after loading */ + {SQL("ALTER TABLE channels ADD htlc_maximum_msat BIGINT DEFAULT 2100000000000000"), NULL}, }; /** diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 5c28d58f6..c1ce3a94b 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1597,7 +1597,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) &lease_blockheight_start), 100, lease_commit_sig, - 7777, 22); + 7777, 22, + AMOUNT_MSAT(-1ULL)); db_begin_transaction(w->db); CHECK(!wallet_err); wallet_channel_insert(w, chan); diff --git a/wallet/wallet.c b/wallet/wallet.c index fa44b869c..7cc5676f0 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1263,7 +1263,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm struct pubkey local_funding_pubkey; struct pubkey *future_per_commitment_point; struct amount_sat funding_sat, our_funding_sat; - struct amount_msat push_msat, our_msat, msat_to_us_min, msat_to_us_max; + struct amount_msat push_msat, our_msat, msat_to_us_min, msat_to_us_max, htlc_maximum_msat; struct channel_type *type; secp256k1_ecdsa_signature *lease_commit_sig; u32 lease_chan_max_msat; @@ -1403,6 +1403,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_col_amount_msat(stmt, "msatoshi_local", &our_msat); db_col_amount_msat(stmt, "msatoshi_to_us_min", &msat_to_us_min); db_col_amount_msat(stmt, "msatoshi_to_us_max", &msat_to_us_max); + db_col_amount_msat(stmt, "htlc_maximum_msat", &htlc_maximum_msat); if (!db_col_is_null(stmt, "lease_commit_sig")) { lease_commit_sig = tal(w, secp256k1_ecdsa_signature); @@ -1478,7 +1479,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_col_int(stmt, "lease_expiry"), lease_commit_sig, lease_chan_max_msat, - lease_chan_max_ppt); + lease_chan_max_ppt, + htlc_maximum_msat); if (!wallet_channel_load_inflights(w, chan)) { tal_free(chan); @@ -1572,6 +1574,7 @@ static bool wallet_channels_load_active(struct wallet *w) ", lease_commit_sig" ", lease_chan_max_msat" ", lease_chan_max_ppt" + ", htlc_maximum_msat" " FROM channels" " WHERE state != ?;")); //? 0 db_bind_int(stmt, 0, CLOSED); @@ -1851,8 +1854,9 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) " lease_expiry=?," // 38 " lease_commit_sig=?," // 39 " lease_chan_max_msat=?," // 40 - " lease_chan_max_ppt=?" // 41 - " WHERE id=?")); // 42 + " lease_chan_max_ppt=?," // 41 + " htlc_maximum_msat=?" // 42 + " WHERE id=?")); // 43 db_bind_u64(stmt, 0, chan->their_shachain.id); if (chan->scid) db_bind_short_channel_id(stmt, 1, chan->scid); @@ -1915,7 +1919,8 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_null(stmt, 40); db_bind_null(stmt, 41); } - db_bind_u64(stmt, 42, chan->dbid); + db_bind_amount_msat(stmt, 42, &chan->htlc_maximum_msat); + db_bind_u64(stmt, 43, chan->dbid); db_exec_prepared_v2(take(stmt)); wallet_channel_config_save(w, &chan->channel_info.their_config);