mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 06:41:44 +01:00
struct channel_config: use amount_sat / amount_msat.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
85b8b25749
commit
b8e484b508
17 changed files with 274 additions and 224 deletions
|
@ -234,20 +234,45 @@ static const u8 *hsm_req(const tal_t *ctx, const u8 *req TAKES)
|
||||||
*/
|
*/
|
||||||
static u64 advertised_htlc_max(const struct channel *channel)
|
static u64 advertised_htlc_max(const struct channel *channel)
|
||||||
{
|
{
|
||||||
u64 lower_bound;
|
struct amount_sat cumulative_reserve, funding, lower_bound;
|
||||||
u64 cumulative_reserve_msat;
|
struct amount_msat lower_bound_msat;
|
||||||
|
|
||||||
cumulative_reserve_msat =
|
funding.satoshis = channel->funding_msat / 1000;
|
||||||
(channel->config[LOCAL].channel_reserve_satoshis +
|
|
||||||
channel->config[REMOTE].channel_reserve_satoshis) * 1000;
|
|
||||||
|
|
||||||
lower_bound = channel->config[REMOTE].max_htlc_value_in_flight_msat;
|
/* This shouldn't fail */
|
||||||
if (channel->funding_msat - cumulative_reserve_msat < lower_bound)
|
if (!amount_sat_add(&cumulative_reserve,
|
||||||
lower_bound = channel->funding_msat - cumulative_reserve_msat;
|
channel->config[LOCAL].channel_reserve,
|
||||||
|
channel->config[REMOTE].channel_reserve)) {
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"reserve overflow: local %s + remote %s",
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&channel->config[LOCAL].channel_reserve),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&channel->config[REMOTE].channel_reserve));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This shouldn't fail either */
|
||||||
|
if (!amount_sat_sub(&lower_bound, funding, cumulative_reserve)) {
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"funding %s - cumulative_reserve %s?",
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&funding),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&cumulative_reserve));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amount_sat_to_msat(&lower_bound_msat, lower_bound)) {
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"lower_bound %s invalid?",
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&lower_bound));
|
||||||
|
}
|
||||||
/* FIXME BOLT QUOTE: https://github.com/lightningnetwork/lightning-rfc/pull/512 once merged */
|
/* FIXME BOLT QUOTE: https://github.com/lightningnetwork/lightning-rfc/pull/512 once merged */
|
||||||
if (channel->chainparams->max_payment.millisatoshis < lower_bound)
|
if (amount_msat_greater(lower_bound_msat,
|
||||||
lower_bound = channel->chainparams->max_payment.millisatoshis;
|
channel->chainparams->max_payment))
|
||||||
return lower_bound;
|
lower_bound_msat = channel->chainparams->max_payment;
|
||||||
|
|
||||||
|
return lower_bound_msat.millisatoshis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and send channel_update to gossipd (and maybe peer) */
|
/* Create and send channel_update to gossipd (and maybe peer) */
|
||||||
|
@ -268,7 +293,7 @@ static void send_channel_update(struct peer *peer, int disable_flag)
|
||||||
disable_flag
|
disable_flag
|
||||||
== ROUTING_FLAGS_DISABLED,
|
== ROUTING_FLAGS_DISABLED,
|
||||||
peer->cltv_delta,
|
peer->cltv_delta,
|
||||||
peer->channel->config[REMOTE].htlc_minimum_msat,
|
peer->channel->config[REMOTE].htlc_minimum.millisatoshis,
|
||||||
peer->fee_base,
|
peer->fee_base,
|
||||||
peer->fee_per_satoshi,
|
peer->fee_per_satoshi,
|
||||||
advertised_htlc_max(peer->channel));
|
advertised_htlc_max(peer->channel));
|
||||||
|
@ -2455,8 +2480,10 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
|
||||||
goto failed;
|
goto failed;
|
||||||
case CHANNEL_ERR_HTLC_BELOW_MINIMUM:
|
case CHANNEL_ERR_HTLC_BELOW_MINIMUM:
|
||||||
failcode = WIRE_AMOUNT_BELOW_MINIMUM;
|
failcode = WIRE_AMOUNT_BELOW_MINIMUM;
|
||||||
failmsg = tal_fmt(inmsg, "HTLC too small (%"PRIu64" minimum)",
|
failmsg = tal_fmt(inmsg, "HTLC too small (%s minimum)",
|
||||||
peer->channel->config[REMOTE].htlc_minimum_msat);
|
type_to_string(tmpctx,
|
||||||
|
struct amount_msat,
|
||||||
|
&peer->channel->config[REMOTE].htlc_minimum));
|
||||||
goto failed;
|
goto failed;
|
||||||
case CHANNEL_ERR_TOO_MANY_HTLCS:
|
case CHANNEL_ERR_TOO_MANY_HTLCS:
|
||||||
failcode = WIRE_TEMPORARY_CHANNEL_FAILURE;
|
failcode = WIRE_TEMPORARY_CHANNEL_FAILURE;
|
||||||
|
|
|
@ -262,7 +262,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
|
||||||
channel->config[!side].to_self_delay,
|
channel->config[!side].to_self_delay,
|
||||||
&keyset,
|
&keyset,
|
||||||
channel->view[side].feerate_per_kw,
|
channel->view[side].feerate_per_kw,
|
||||||
channel->config[side].dust_limit_satoshis,
|
channel->config[side].dust_limit.satoshis,
|
||||||
channel->view[side].owed_msat[side],
|
channel->view[side].owed_msat[side],
|
||||||
channel->view[side].owed_msat[!side],
|
channel->view[side].owed_msat[!side],
|
||||||
committed,
|
committed,
|
||||||
|
@ -348,7 +348,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||||
if (htlc->msatoshi == 0) {
|
if (htlc->msatoshi == 0) {
|
||||||
return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
|
return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
|
||||||
}
|
}
|
||||||
if (htlc->msatoshi < channel->config[recipient].htlc_minimum_msat) {
|
if (htlc->msatoshi < channel->config[recipient].htlc_minimum.millisatoshis) {
|
||||||
return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
|
return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||||
* - SHOULD fail the channel.
|
* - SHOULD fail the channel.
|
||||||
*/
|
*/
|
||||||
if (enforce_aggregate_limits
|
if (enforce_aggregate_limits
|
||||||
&& msat_in_htlcs > channel->config[recipient].max_htlc_value_in_flight_msat) {
|
&& msat_in_htlcs > channel->config[recipient].max_htlc_value_in_flight.millisatoshis) {
|
||||||
return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
|
return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||||
*/
|
*/
|
||||||
if (channel->funder == htlc_owner(htlc)) {
|
if (channel->funder == htlc_owner(htlc)) {
|
||||||
u32 feerate = view->feerate_per_kw;
|
u32 feerate = view->feerate_per_kw;
|
||||||
u64 dust = channel->config[recipient].dust_limit_satoshis;
|
u64 dust = channel->config[recipient].dust_limit.satoshis;
|
||||||
size_t untrimmed;
|
size_t untrimmed;
|
||||||
|
|
||||||
untrimmed = commit_tx_num_untrimmed(committed, feerate, dust,
|
untrimmed = commit_tx_num_untrimmed(committed, feerate, dust,
|
||||||
|
@ -438,12 +438,13 @@ static enum channel_add_err add_htlc(struct channel *channel,
|
||||||
* here is that the balance to the sender doesn't go below the
|
* here is that the balance to the sender doesn't go below the
|
||||||
* sender's reserve. */
|
* sender's reserve. */
|
||||||
if (enforce_aggregate_limits
|
if (enforce_aggregate_limits
|
||||||
&& balance_msat - fee_msat < (s64)channel_reserve_msat(channel, sender)) {
|
&& balance_msat - fee_msat < (s64)channel->config[!sender].channel_reserve.satoshis * 1000) {
|
||||||
status_trace("balance = %"PRIu64
|
status_trace("balance = %"PRIu64
|
||||||
", fee is %"PRIu64
|
", fee is %"PRIu64
|
||||||
", reserve is %"PRIu64,
|
", reserve is %s",
|
||||||
balance_msat, fee_msat,
|
balance_msat, fee_msat,
|
||||||
channel_reserve_msat(channel, sender));
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&channel->config[!sender].channel_reserve));
|
||||||
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
|
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +698,7 @@ u32 approx_max_feerate(const struct channel *channel)
|
||||||
|
|
||||||
/* We should never go below reserve. */
|
/* We should never go below reserve. */
|
||||||
avail_msat = channel->view[!channel->funder].owed_msat[channel->funder]
|
avail_msat = channel->view[!channel->funder].owed_msat[channel->funder]
|
||||||
- channel_reserve_msat(channel, channel->funder);
|
- channel->config[!channel->funder].channel_reserve.satoshis * 1000;
|
||||||
|
|
||||||
/* We have to pay fee from onchain funds, so it's in satoshi. */
|
/* We have to pay fee from onchain funds, so it's in satoshi. */
|
||||||
return avail_msat / 1000 / weight * 1000;
|
return avail_msat / 1000 / weight * 1000;
|
||||||
|
@ -705,7 +706,7 @@ u32 approx_max_feerate(const struct channel *channel)
|
||||||
|
|
||||||
bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw)
|
bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw)
|
||||||
{
|
{
|
||||||
u64 fee_msat, dust = channel->config[!channel->funder].dust_limit_satoshis;
|
u64 fee_msat, dust = channel->config[!channel->funder].dust_limit.satoshis;
|
||||||
size_t untrimmed;
|
size_t untrimmed;
|
||||||
const struct htlc **committed, **adding, **removing;
|
const struct htlc **committed, **adding, **removing;
|
||||||
gather_htlcs(tmpctx, channel, !channel->funder,
|
gather_htlcs(tmpctx, channel, !channel->funder,
|
||||||
|
@ -730,7 +731,7 @@ bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw
|
||||||
|
|
||||||
/* How much does it think it has? Must be >= reserve + fee */
|
/* How much does it think it has? Must be >= reserve + fee */
|
||||||
return channel->view[!channel->funder].owed_msat[channel->funder]
|
return channel->view[!channel->funder].owed_msat[channel->funder]
|
||||||
>= channel_reserve_msat(channel, channel->funder) + fee_msat;
|
>= channel->config[!channel->funder].channel_reserve.satoshis * 1000 + fee_msat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw)
|
bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw)
|
||||||
|
|
|
@ -379,17 +379,17 @@ int main(void)
|
||||||
funding_amount_satoshi = 10000000;
|
funding_amount_satoshi = 10000000;
|
||||||
|
|
||||||
remote_config->to_self_delay = 144;
|
remote_config->to_self_delay = 144;
|
||||||
local_config->dust_limit_satoshis = 546;
|
local_config->dust_limit = AMOUNT_SAT(546);
|
||||||
/* This matters only because we check if added HTLC will create new
|
/* This matters only because we check if added HTLC will create new
|
||||||
* output, for fee considerations. */
|
* output, for fee considerations. */
|
||||||
remote_config->dust_limit_satoshis = 546;
|
remote_config->dust_limit = AMOUNT_SAT(546);
|
||||||
|
|
||||||
local_config->max_htlc_value_in_flight_msat = -1ULL;
|
local_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
||||||
remote_config->max_htlc_value_in_flight_msat = -1ULL;
|
remote_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
||||||
local_config->channel_reserve_satoshis = 0;
|
local_config->channel_reserve = AMOUNT_SAT(0);
|
||||||
remote_config->channel_reserve_satoshis = 0;
|
remote_config->channel_reserve = AMOUNT_SAT(0);
|
||||||
local_config->htlc_minimum_msat = 0;
|
local_config->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
remote_config->htlc_minimum_msat = 0;
|
remote_config->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
local_config->max_accepted_htlcs = 0xFFFF;
|
local_config->max_accepted_htlcs = 0xFFFF;
|
||||||
remote_config->max_accepted_htlcs = 0xFFFF;
|
remote_config->max_accepted_htlcs = 0xFFFF;
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ int main(void)
|
||||||
LOCAL, remote_config->to_self_delay,
|
LOCAL, remote_config->to_self_delay,
|
||||||
&keyset,
|
&keyset,
|
||||||
feerate_per_kw[LOCAL],
|
feerate_per_kw[LOCAL],
|
||||||
local_config->dust_limit_satoshis,
|
local_config->dust_limit.satoshis,
|
||||||
to_local_msat,
|
to_local_msat,
|
||||||
to_remote_msat,
|
to_remote_msat,
|
||||||
NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL);
|
NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL);
|
||||||
|
@ -613,7 +613,7 @@ int main(void)
|
||||||
LOCAL, remote_config->to_self_delay,
|
LOCAL, remote_config->to_self_delay,
|
||||||
&keyset,
|
&keyset,
|
||||||
feerate_per_kw[LOCAL],
|
feerate_per_kw[LOCAL],
|
||||||
local_config->dust_limit_satoshis,
|
local_config->dust_limit.satoshis,
|
||||||
to_local_msat,
|
to_local_msat,
|
||||||
to_remote_msat,
|
to_remote_msat,
|
||||||
htlcs, &htlc_map,
|
htlcs, &htlc_map,
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
void towire_channel_config(u8 **pptr, const struct channel_config *config)
|
void towire_channel_config(u8 **pptr, const struct channel_config *config)
|
||||||
{
|
{
|
||||||
towire_u64(pptr, config->dust_limit_satoshis);
|
towire_amount_sat(pptr, config->dust_limit);
|
||||||
towire_u64(pptr, config->max_htlc_value_in_flight_msat);
|
towire_amount_msat(pptr, config->max_htlc_value_in_flight);
|
||||||
towire_u64(pptr, config->channel_reserve_satoshis);
|
towire_amount_sat(pptr, config->channel_reserve);
|
||||||
towire_u32(pptr, config->htlc_minimum_msat);
|
towire_amount_msat(pptr, config->htlc_minimum);
|
||||||
towire_u16(pptr, config->to_self_delay);
|
towire_u16(pptr, config->to_self_delay);
|
||||||
towire_u16(pptr, config->max_accepted_htlcs);
|
towire_u16(pptr, config->max_accepted_htlcs);
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@ void towire_channel_config(u8 **pptr, const struct channel_config *config)
|
||||||
void fromwire_channel_config(const u8 **ptr, size_t *max,
|
void fromwire_channel_config(const u8 **ptr, size_t *max,
|
||||||
struct channel_config *config)
|
struct channel_config *config)
|
||||||
{
|
{
|
||||||
config->dust_limit_satoshis = fromwire_u64(ptr, max);
|
config->dust_limit = fromwire_amount_sat(ptr, max);
|
||||||
config->max_htlc_value_in_flight_msat = fromwire_u64(ptr, max);
|
config->max_htlc_value_in_flight = fromwire_amount_msat(ptr, max);
|
||||||
config->channel_reserve_satoshis = fromwire_u64(ptr, max);
|
config->channel_reserve = fromwire_amount_sat(ptr, max);
|
||||||
config->htlc_minimum_msat = fromwire_u32(ptr, max);
|
config->htlc_minimum = fromwire_amount_msat(ptr, max);
|
||||||
config->to_self_delay = fromwire_u16(ptr, max);
|
config->to_self_delay = fromwire_u16(ptr, max);
|
||||||
config->max_accepted_htlcs = fromwire_u16(ptr, max);
|
config->max_accepted_htlcs = fromwire_u16(ptr, max);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ccan/short_types/short_types.h>
|
#include <ccan/short_types/short_types.h>
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
|
#include <common/amount.h>
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -38,27 +39,27 @@ struct channel_config {
|
||||||
*
|
*
|
||||||
* `dust_limit_satoshis` is the threshold below which outputs should
|
* `dust_limit_satoshis` is the threshold below which outputs should
|
||||||
* not be generated for this node's commitment or HTLC transaction */
|
* not be generated for this node's commitment or HTLC transaction */
|
||||||
u64 dust_limit_satoshis;
|
struct amount_sat dust_limit;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* `max_htlc_value_in_flight_msat` is a cap on total value of
|
* `max_htlc_value_in_flight_msat` is a cap on total value of
|
||||||
* outstanding HTLCs, which allows a node to limit its exposure to
|
* outstanding HTLCs, which allows a node to limit its exposure to
|
||||||
* HTLCs */
|
* HTLCs */
|
||||||
u64 max_htlc_value_in_flight_msat;
|
struct amount_msat max_htlc_value_in_flight;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* `channel_reserve_satoshis` is the minimum amount that the other
|
* `channel_reserve_satoshis` is the minimum amount that the other
|
||||||
* node is to keep as a direct payment. */
|
* node is to keep as a direct payment. */
|
||||||
u64 channel_reserve_satoshis;
|
struct amount_sat channel_reserve;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* `htlc_minimum_msat` indicates the smallest value HTLC this node
|
* `htlc_minimum_msat` indicates the smallest value HTLC this node
|
||||||
* will accept.
|
* will accept.
|
||||||
*/
|
*/
|
||||||
u64 htlc_minimum_msat;
|
struct amount_msat htlc_minimum;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
|
|
@ -97,10 +97,10 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
|
||||||
channel->config[!side].to_self_delay,
|
channel->config[!side].to_self_delay,
|
||||||
&keyset,
|
&keyset,
|
||||||
channel->view[side].feerate_per_kw,
|
channel->view[side].feerate_per_kw,
|
||||||
channel->config[side].dust_limit_satoshis,
|
channel->config[side].dust_limit.satoshis,
|
||||||
channel->view[side].owed_msat[side],
|
channel->view[side].owed_msat[side],
|
||||||
channel->view[side].owed_msat[!side],
|
channel->view[side].owed_msat[!side],
|
||||||
channel_reserve_msat(channel, side),
|
channel->config[!side].channel_reserve.satoshis * 1000,
|
||||||
0 ^ channel->commitment_number_obscurer,
|
0 ^ channel->commitment_number_obscurer,
|
||||||
side);
|
side);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,14 +62,6 @@ struct channel {
|
||||||
const struct chainparams *chainparams;
|
const struct chainparams *chainparams;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This side's reserve is specified by the *other* side, and in satoshis:
|
|
||||||
* this is a convenience function to convert it. */
|
|
||||||
static inline u64 channel_reserve_msat(const struct channel *channel,
|
|
||||||
enum side side)
|
|
||||||
{
|
|
||||||
return channel->config[!side].channel_reserve_satoshis * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* new_initial_channel: Given initial fees and funding, what is initial state?
|
* new_initial_channel: Given initial fees and funding, what is initial state?
|
||||||
* @ctx: tal context to allocate return value from.
|
* @ctx: tal context to allocate return value from.
|
||||||
|
|
|
@ -227,7 +227,7 @@ void peer_start_closingd(struct channel *channel,
|
||||||
channel->funder,
|
channel->funder,
|
||||||
our_msatoshi / 1000, /* Rounds down */
|
our_msatoshi / 1000, /* Rounds down */
|
||||||
their_msatoshi / 1000, /* Rounds down */
|
their_msatoshi / 1000, /* Rounds down */
|
||||||
channel->our_config.dust_limit_satoshis,
|
channel->our_config.dust_limit.satoshis,
|
||||||
minfee, feelimit, startfee,
|
minfee, feelimit, startfee,
|
||||||
p2wpkh_for_keyidx(tmpctx, ld,
|
p2wpkh_for_keyidx(tmpctx, ld,
|
||||||
channel->final_key_idx),
|
channel->final_key_idx),
|
||||||
|
|
|
@ -178,11 +178,11 @@ static struct route_info **select_inchan(const tal_t *ctx,
|
||||||
msatoshi_avail = c->funding_satoshi * 1000 - c->our_msatoshi;
|
msatoshi_avail = c->funding_satoshi * 1000 - c->our_msatoshi;
|
||||||
|
|
||||||
/* Even after reserve taken into account */
|
/* Even after reserve taken into account */
|
||||||
if (c->our_config.channel_reserve_satoshis * 1000
|
if (c->our_config.channel_reserve.satoshis * 1000
|
||||||
> msatoshi_avail)
|
> msatoshi_avail)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
msatoshi_avail -= c->our_config.channel_reserve_satoshis * 1000;
|
msatoshi_avail -= c->our_config.channel_reserve.satoshis * 1000;
|
||||||
if (msatoshi_avail < capacity_needed)
|
if (msatoshi_avail < capacity_needed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -472,7 +472,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
|
||||||
channel->channel_info.their_config.to_self_delay,
|
channel->channel_info.their_config.to_self_delay,
|
||||||
channel->our_config.to_self_delay,
|
channel->our_config.to_self_delay,
|
||||||
feerate,
|
feerate,
|
||||||
channel->our_config.dust_limit_satoshis,
|
channel->our_config.dust_limit.satoshis,
|
||||||
&our_last_txid,
|
&our_last_txid,
|
||||||
p2wpkh_for_keyidx(tmpctx, ld,
|
p2wpkh_for_keyidx(tmpctx, ld,
|
||||||
channel->final_key_idx),
|
channel->final_key_idx),
|
||||||
|
|
|
@ -305,7 +305,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
||||||
&channel_info.remote_fundingkey,
|
&channel_info.remote_fundingkey,
|
||||||
&expected_txid,
|
&expected_txid,
|
||||||
&feerate,
|
&feerate,
|
||||||
&fc->uc->our_config.channel_reserve_satoshis)) {
|
&fc->uc->our_config.channel_reserve.satoshis)) {
|
||||||
log_broken(fc->uc->log,
|
log_broken(fc->uc->log,
|
||||||
"bad OPENING_FUNDER_REPLY %s",
|
"bad OPENING_FUNDER_REPLY %s",
|
||||||
tal_hex(resp, resp));
|
tal_hex(resp, resp));
|
||||||
|
@ -495,7 +495,7 @@ static void opening_fundee_finished(struct subd *openingd,
|
||||||
&channel_flags,
|
&channel_flags,
|
||||||
&feerate,
|
&feerate,
|
||||||
&funding_signed,
|
&funding_signed,
|
||||||
&uc->our_config.channel_reserve_satoshis)) {
|
&uc->our_config.channel_reserve.satoshis)) {
|
||||||
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
|
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
|
||||||
tal_hex(reply, reply));
|
tal_hex(reply, reply));
|
||||||
uncommitted_channel_disconnect(uc, "bad OPENING_FUNDEE_REPLY");
|
uncommitted_channel_disconnect(uc, "bad OPENING_FUNDEE_REPLY");
|
||||||
|
@ -644,12 +644,12 @@ new_uncommitted_channel(struct peer *peer)
|
||||||
static void channel_config(struct lightningd *ld,
|
static void channel_config(struct lightningd *ld,
|
||||||
struct channel_config *ours,
|
struct channel_config *ours,
|
||||||
u32 *max_to_self_delay,
|
u32 *max_to_self_delay,
|
||||||
u64 *min_effective_htlc_capacity_msat)
|
struct amount_msat *min_effective_htlc_capacity)
|
||||||
{
|
{
|
||||||
/* FIXME: depend on feerate. */
|
/* FIXME: depend on feerate. */
|
||||||
*max_to_self_delay = ld->config.locktime_max;
|
*max_to_self_delay = ld->config.locktime_max;
|
||||||
/* This is 1c at $1000/BTC */
|
/* This is 1c at $1000/BTC */
|
||||||
*min_effective_htlc_capacity_msat = 1000000;
|
*min_effective_htlc_capacity = AMOUNT_MSAT(1000000);
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -658,11 +658,11 @@ static void channel_config(struct lightningd *ld,
|
||||||
* - set `dust_limit_satoshis` to a sufficient value to allow
|
* - set `dust_limit_satoshis` to a sufficient value to allow
|
||||||
* commitment transactions to propagate through the Bitcoin network.
|
* commitment transactions to propagate through the Bitcoin network.
|
||||||
*/
|
*/
|
||||||
ours->dust_limit_satoshis = 546;
|
ours->dust_limit = AMOUNT_SAT(546);
|
||||||
ours->max_htlc_value_in_flight_msat = UINT64_MAX;
|
ours->max_htlc_value_in_flight = AMOUNT_MSAT(UINT64_MAX);
|
||||||
|
|
||||||
/* Don't care */
|
/* Don't care */
|
||||||
ours->htlc_minimum_msat = 0;
|
ours->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -682,7 +682,7 @@ static void channel_config(struct lightningd *ld,
|
||||||
ours->max_accepted_htlcs = 483;
|
ours->max_accepted_htlcs = 483;
|
||||||
|
|
||||||
/* This is filled in by lightning_openingd, for consistency. */
|
/* This is filled in by lightning_openingd, for consistency. */
|
||||||
ours->channel_reserve_satoshis = -1;
|
ours->channel_reserve = AMOUNT_SAT(UINT64_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int openingd_msg(struct subd *openingd,
|
static unsigned int openingd_msg(struct subd *openingd,
|
||||||
|
@ -742,7 +742,7 @@ void peer_start_openingd(struct peer *peer,
|
||||||
{
|
{
|
||||||
int hsmfd;
|
int hsmfd;
|
||||||
u32 max_to_self_delay;
|
u32 max_to_self_delay;
|
||||||
u64 min_effective_htlc_capacity_msat;
|
struct amount_msat min_effective_htlc_capacity;
|
||||||
struct uncommitted_channel *uc;
|
struct uncommitted_channel *uc;
|
||||||
const u8 *msg;
|
const u8 *msg;
|
||||||
|
|
||||||
|
@ -773,7 +773,7 @@ void peer_start_openingd(struct peer *peer,
|
||||||
|
|
||||||
channel_config(peer->ld, &uc->our_config,
|
channel_config(peer->ld, &uc->our_config,
|
||||||
&max_to_self_delay,
|
&max_to_self_delay,
|
||||||
&min_effective_htlc_capacity_msat);
|
&min_effective_htlc_capacity);
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -787,7 +787,7 @@ void peer_start_openingd(struct peer *peer,
|
||||||
&get_chainparams(peer->ld)->genesis_blockhash,
|
&get_chainparams(peer->ld)->genesis_blockhash,
|
||||||
&uc->our_config,
|
&uc->our_config,
|
||||||
max_to_self_delay,
|
max_to_self_delay,
|
||||||
min_effective_htlc_capacity_msat,
|
min_effective_htlc_capacity.millisatoshis,
|
||||||
cs, &uc->local_basepoints,
|
cs, &uc->local_basepoints,
|
||||||
&uc->local_funding_pubkey,
|
&uc->local_funding_pubkey,
|
||||||
uc->minimum_depth,
|
uc->minimum_depth,
|
||||||
|
|
|
@ -581,10 +581,10 @@ static void json_add_channel(struct lightningd *ld,
|
||||||
|
|
||||||
/* channel config */
|
/* channel config */
|
||||||
json_add_amount_sat(response,
|
json_add_amount_sat(response,
|
||||||
(struct amount_sat){channel->our_config.dust_limit_satoshis},
|
channel->our_config.dust_limit,
|
||||||
"dust_limit_satoshis", "dust_limit_msat");
|
"dust_limit_satoshis", "dust_limit_msat");
|
||||||
json_add_amount_msat(response,
|
json_add_amount_msat(response,
|
||||||
(struct amount_msat){channel->our_config.max_htlc_value_in_flight_msat},
|
channel->our_config.max_htlc_value_in_flight,
|
||||||
"max_htlc_value_in_flight_msat",
|
"max_htlc_value_in_flight_msat",
|
||||||
"max_total_htlc_in_msat");
|
"max_total_htlc_in_msat");
|
||||||
|
|
||||||
|
@ -596,23 +596,23 @@ static void json_add_channel(struct lightningd *ld,
|
||||||
* configuration `channel_reserve_satoshis` is
|
* configuration `channel_reserve_satoshis` is
|
||||||
* imposed on ours. */
|
* imposed on ours. */
|
||||||
json_add_amount_sat(response,
|
json_add_amount_sat(response,
|
||||||
(struct amount_sat){channel->our_config.channel_reserve_satoshis},
|
channel->our_config.channel_reserve,
|
||||||
"their_channel_reserve_satoshis",
|
"their_channel_reserve_satoshis",
|
||||||
"their_reserve_msat");
|
"their_reserve_msat");
|
||||||
json_add_amount_sat(response,
|
json_add_amount_sat(response,
|
||||||
(struct amount_sat){channel->channel_info.their_config.channel_reserve_satoshis},
|
channel->channel_info.their_config.channel_reserve,
|
||||||
"our_channel_reserve_satoshis",
|
"our_channel_reserve_satoshis",
|
||||||
"our_reserve_msat");
|
"our_reserve_msat");
|
||||||
/* Compute how much we can send via this channel. */
|
/* Compute how much we can send via this channel. */
|
||||||
if (!amount_msat_sub_sat(&spendable,
|
if (!amount_msat_sub_sat(&spendable,
|
||||||
(struct amount_msat){channel->our_msatoshi},
|
(struct amount_msat){channel->our_msatoshi},
|
||||||
(struct amount_sat){channel->channel_info.their_config.channel_reserve_satoshis}))
|
channel->channel_info.their_config.channel_reserve))
|
||||||
spendable = AMOUNT_MSAT(0);
|
spendable = AMOUNT_MSAT(0);
|
||||||
|
|
||||||
json_add_amount_msat(response, spendable,
|
json_add_amount_msat(response, spendable,
|
||||||
"spendable_msatoshi", "spendable_msat");
|
"spendable_msatoshi", "spendable_msat");
|
||||||
json_add_amount_msat(response,
|
json_add_amount_msat(response,
|
||||||
(struct amount_msat){channel->our_config.htlc_minimum_msat},
|
channel->our_config.htlc_minimum,
|
||||||
"htlc_minimum_msat",
|
"htlc_minimum_msat",
|
||||||
"minimum_htlc_in_msat");
|
"minimum_htlc_in_msat");
|
||||||
|
|
||||||
|
|
|
@ -1108,12 +1108,14 @@ static bool channel_added_their_htlc(struct channel *channel,
|
||||||
* - SHOULD fail the channel.
|
* - SHOULD fail the channel.
|
||||||
*/
|
*/
|
||||||
if (added->amount_msat == 0
|
if (added->amount_msat == 0
|
||||||
|| added->amount_msat < channel->our_config.htlc_minimum_msat) {
|
|| added->amount_msat < channel->our_config.htlc_minimum.millisatoshis) {
|
||||||
channel_internal_error(channel,
|
channel_internal_error(channel,
|
||||||
"trying to add HTLC msat %"PRIu64
|
"trying to add HTLC msat %"PRIu64
|
||||||
" but minimum is %"PRIu64,
|
" but minimum is %s",
|
||||||
added->amount_msat,
|
added->amount_msat,
|
||||||
channel->our_config.htlc_minimum_msat);
|
type_to_string(tmpctx,
|
||||||
|
struct amount_msat,
|
||||||
|
&channel->our_config.htlc_minimum));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -600,7 +600,7 @@ static void add_peer(struct lightningd *ld, int n, enum channel_state state,
|
||||||
/* Channel has incoming capacity n*1000 - 1 millisatoshi */
|
/* Channel has incoming capacity n*1000 - 1 millisatoshi */
|
||||||
c->funding_satoshi = n+1;
|
c->funding_satoshi = n+1;
|
||||||
c->our_msatoshi = 1;
|
c->our_msatoshi = 1;
|
||||||
c->our_config.channel_reserve_satoshis = 1;
|
c->our_config.channel_reserve.satoshis = 1;
|
||||||
list_add_tail(&peer->channels, &c->list);
|
list_add_tail(&peer->channels, &c->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct state {
|
||||||
/* Constraints on a channel they open. */
|
/* Constraints on a channel they open. */
|
||||||
u32 minimum_depth;
|
u32 minimum_depth;
|
||||||
u32 min_feerate, max_feerate;
|
u32 min_feerate, max_feerate;
|
||||||
u64 min_effective_htlc_capacity_msat;
|
struct amount_msat min_effective_htlc_capacity;
|
||||||
|
|
||||||
/* Limits on what remote config we accept. */
|
/* Limits on what remote config we accept. */
|
||||||
u32 max_to_self_delay;
|
u32 max_to_self_delay;
|
||||||
|
@ -79,7 +79,8 @@ struct state {
|
||||||
struct channel_id channel_id;
|
struct channel_id channel_id;
|
||||||
|
|
||||||
/* Funding and feerate: set by opening peer. */
|
/* Funding and feerate: set by opening peer. */
|
||||||
u64 funding_satoshis, push_msat;
|
struct amount_sat funding;
|
||||||
|
struct amount_msat push_msat;
|
||||||
u32 feerate_per_kw;
|
u32 feerate_per_kw;
|
||||||
struct bitcoin_txid funding_txid;
|
struct bitcoin_txid funding_txid;
|
||||||
u16 funding_txout;
|
u16 funding_txout;
|
||||||
|
@ -155,8 +156,8 @@ static bool check_config_bounds(struct state *state,
|
||||||
const struct channel_config *remoteconf,
|
const struct channel_config *remoteconf,
|
||||||
bool am_funder)
|
bool am_funder)
|
||||||
{
|
{
|
||||||
u64 capacity_msat;
|
struct amount_sat capacity;
|
||||||
u64 reserve_msat;
|
struct amount_sat reserve;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -185,67 +186,74 @@ static bool check_config_bounds(struct state *state,
|
||||||
/* We accumulate this into an effective bandwidth minimum. */
|
/* We accumulate this into an effective bandwidth minimum. */
|
||||||
|
|
||||||
/* Add both reserves to deduct from capacity. */
|
/* Add both reserves to deduct from capacity. */
|
||||||
if (mul_overflows_u64(remoteconf->channel_reserve_satoshis, 1000)
|
if (!amount_sat_add(&reserve,
|
||||||
|| add_overflows_u64(remoteconf->channel_reserve_satoshis * 1000,
|
remoteconf->channel_reserve,
|
||||||
state->localconf.channel_reserve_satoshis * 1000)) {
|
state->localconf.channel_reserve)) {
|
||||||
negotiation_failed(state, am_funder,
|
negotiation_failed(state, am_funder,
|
||||||
"channel_reserve_satoshis %"PRIu64
|
"channel_reserve_satoshis %s"
|
||||||
" too large",
|
" too large",
|
||||||
remoteconf->channel_reserve_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&remoteconf->channel_reserve));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
reserve_msat = remoteconf->channel_reserve_satoshis * 1000
|
|
||||||
+ state->localconf.channel_reserve_satoshis * 1000;
|
|
||||||
|
|
||||||
/* We checked this before, or it's ours. */
|
/* If reserves are larger than total sat, we fail. */
|
||||||
assert(!mul_overflows_u64(state->funding_satoshis, 1000));
|
if (!amount_sat_sub(&capacity, state->funding, reserve)) {
|
||||||
|
|
||||||
/* If reserves are larger than total msat, we fail. */
|
|
||||||
if (reserve_msat > state->funding_satoshis * 1000) {
|
|
||||||
negotiation_failed(state, am_funder,
|
negotiation_failed(state, am_funder,
|
||||||
"channel_reserve_satoshis %"PRIu64
|
"channel_reserve_satoshis %s"
|
||||||
" and %"PRIu64" too large for funding_satoshis %"PRIu64,
|
" and %s too large for funding %s",
|
||||||
remoteconf->channel_reserve_satoshis,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->localconf.channel_reserve_satoshis,
|
&remoteconf->channel_reserve),
|
||||||
state->funding_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->localconf.channel_reserve),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
capacity_msat = state->funding_satoshis * 1000 - reserve_msat;
|
|
||||||
|
|
||||||
/* If they set the max HTLC value to less than that number, it caps
|
/* If they set the max HTLC value to less than that number, it caps
|
||||||
* the channel capacity. */
|
* the channel capacity. */
|
||||||
if (remoteconf->max_htlc_value_in_flight_msat < capacity_msat)
|
if (amount_sat_greater(capacity,
|
||||||
capacity_msat = remoteconf->max_htlc_value_in_flight_msat;
|
amount_msat_to_sat_round_down(remoteconf->max_htlc_value_in_flight)))
|
||||||
|
capacity = amount_msat_to_sat_round_down(remoteconf->max_htlc_value_in_flight);
|
||||||
|
|
||||||
/* If the minimum htlc is greater than the capacity, the channel is
|
/* If the minimum htlc is greater than the capacity, the channel is
|
||||||
* useless. */
|
* useless. */
|
||||||
if (mul_overflows_u64(remoteconf->htlc_minimum_msat, 1000)
|
if (amount_msat_greater_sat(remoteconf->htlc_minimum, capacity)) {
|
||||||
|| remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat) {
|
|
||||||
negotiation_failed(state, am_funder,
|
negotiation_failed(state, am_funder,
|
||||||
"htlc_minimum_msat %"PRIu64
|
"htlc_minimum_msat %s"
|
||||||
" too large for funding_satoshis %"PRIu64
|
" too large for funding %s"
|
||||||
" capacity_msat %"PRIu64,
|
" capacity_msat %s",
|
||||||
remoteconf->htlc_minimum_msat,
|
type_to_string(tmpctx, struct amount_msat,
|
||||||
state->funding_satoshis,
|
&remoteconf->htlc_minimum),
|
||||||
capacity_msat);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&capacity));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the resulting channel doesn't meet our minimum "effective capacity"
|
/* If the resulting channel doesn't meet our minimum "effective capacity"
|
||||||
* set by lightningd, don't bother opening it. */
|
* set by lightningd, don't bother opening it. */
|
||||||
if (capacity_msat < state->min_effective_htlc_capacity_msat) {
|
if (amount_msat_greater_sat(state->min_effective_htlc_capacity,
|
||||||
|
capacity)) {
|
||||||
negotiation_failed(state, am_funder,
|
negotiation_failed(state, am_funder,
|
||||||
"channel capacity with funding %"PRIu64" msat,"
|
"channel capacity with funding %s,"
|
||||||
" reserves %"PRIu64"/%"PRIu64" msat,"
|
" reserves %s/%s,"
|
||||||
" max_htlc_value_in_flight_msat %"PRIu64
|
" max_htlc_value_in_flight_msat %s"
|
||||||
" is %"PRIu64" msat, which is below %"PRIu64" msat",
|
" is %s msat, which is below %s msat",
|
||||||
state->funding_satoshis * 1000,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
remoteconf->channel_reserve_satoshis * 1000,
|
&state->funding),
|
||||||
state->localconf.channel_reserve_satoshis * 1000,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
remoteconf->max_htlc_value_in_flight_msat,
|
&remoteconf->channel_reserve),
|
||||||
capacity_msat,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->min_effective_htlc_capacity_msat);
|
&state->localconf.channel_reserve),
|
||||||
|
type_to_string(tmpctx, struct amount_msat,
|
||||||
|
&remoteconf->max_htlc_value_in_flight),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&capacity),
|
||||||
|
type_to_string(tmpctx, struct amount_msat,
|
||||||
|
&state->min_effective_htlc_capacity));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,14 +284,15 @@ static bool check_config_bounds(struct state *state,
|
||||||
*...
|
*...
|
||||||
* - `dust_limit_satoshis` is greater than `channel_reserve_satoshis`.
|
* - `dust_limit_satoshis` is greater than `channel_reserve_satoshis`.
|
||||||
*/
|
*/
|
||||||
if (remoteconf->dust_limit_satoshis
|
if (amount_sat_greater(remoteconf->dust_limit,
|
||||||
> remoteconf->channel_reserve_satoshis) {
|
remoteconf->channel_reserve)) {
|
||||||
negotiation_failed(state, am_funder,
|
negotiation_failed(state, am_funder,
|
||||||
"dust_limit_satoshis %"PRIu64
|
"dust_limit_satoshis %s"
|
||||||
" too large for channel_reserve_satoshis %"
|
" too large for channel_reserve_satoshis %s",
|
||||||
PRIu64,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
remoteconf->dust_limit_satoshis,
|
&remoteconf->dust_limit),
|
||||||
remoteconf->channel_reserve_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&remoteconf->channel_reserve));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,8 +302,8 @@ static bool check_config_bounds(struct state *state,
|
||||||
/* We always set channel_reserve_satoshis to 1%, rounded up. */
|
/* We always set channel_reserve_satoshis to 1%, rounded up. */
|
||||||
static void set_reserve(struct state *state)
|
static void set_reserve(struct state *state)
|
||||||
{
|
{
|
||||||
state->localconf.channel_reserve_satoshis
|
state->localconf.channel_reserve.satoshis
|
||||||
= (state->funding_satoshis + 99) / 100;
|
= (state->funding.satoshis + 99) / 100;
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -303,10 +312,10 @@ static void set_reserve(struct state *state)
|
||||||
* - MUST set `channel_reserve_satoshis` greater than or equal to
|
* - MUST set `channel_reserve_satoshis` greater than or equal to
|
||||||
* `dust_limit_satoshis`.
|
* `dust_limit_satoshis`.
|
||||||
*/
|
*/
|
||||||
if (state->localconf.channel_reserve_satoshis
|
if (amount_sat_greater(state->localconf.dust_limit,
|
||||||
< state->localconf.dust_limit_satoshis)
|
state->localconf.channel_reserve))
|
||||||
state->localconf.channel_reserve_satoshis
|
state->localconf.channel_reserve
|
||||||
= state->localconf.dust_limit_satoshis;
|
= state->localconf.dust_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
|
@ -419,7 +428,8 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,
|
||||||
/*~ OK, let's fund a channel! Returns the reply for lightningd on success,
|
/*~ OK, let's fund a channel! Returns the reply for lightningd on success,
|
||||||
* or NULL if something goes wrong. */
|
* or NULL if something goes wrong. */
|
||||||
static u8 *funder_channel(struct state *state,
|
static u8 *funder_channel(struct state *state,
|
||||||
u64 change_satoshis, u32 change_keyindex,
|
struct amount_sat change,
|
||||||
|
u32 change_keyindex,
|
||||||
u8 channel_flags,
|
u8 channel_flags,
|
||||||
struct utxo **utxos TAKES,
|
struct utxo **utxos TAKES,
|
||||||
const struct ext_key *bip32_base)
|
const struct ext_key *bip32_base)
|
||||||
|
@ -449,12 +459,13 @@ static u8 *funder_channel(struct state *state,
|
||||||
*...
|
*...
|
||||||
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
|
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
|
||||||
*/
|
*/
|
||||||
if (state->funding_satoshis > state->chainparams->max_funding.satoshis)
|
if (amount_sat_greater(state->funding, state->chainparams->max_funding))
|
||||||
status_failed(STATUS_FAIL_MASTER_IO,
|
status_failed(STATUS_FAIL_MASTER_IO,
|
||||||
"funding_satoshis must be < %s, not %"PRIu64,
|
"funding_satoshis must be < %s, not %s",
|
||||||
type_to_string(tmpctx, struct amount_sat,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
&state->chainparams->max_funding),
|
&state->chainparams->max_funding),
|
||||||
state->funding_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding));
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -463,19 +474,21 @@ static u8 *funder_channel(struct state *state,
|
||||||
* - MUST set `push_msat` to equal or less than 1000 *
|
* - MUST set `push_msat` to equal or less than 1000 *
|
||||||
* `funding_satoshis`.
|
* `funding_satoshis`.
|
||||||
*/
|
*/
|
||||||
if (state->push_msat > 1000 * state->funding_satoshis)
|
if (amount_msat_greater_sat(state->push_msat, state->funding))
|
||||||
status_failed(STATUS_FAIL_MASTER_IO,
|
status_failed(STATUS_FAIL_MASTER_IO,
|
||||||
"push-msat must be < %"PRIu64,
|
"push-msat must be < %s",
|
||||||
1000 * state->funding_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding));
|
||||||
|
|
||||||
msg = towire_open_channel(NULL,
|
msg = towire_open_channel(NULL,
|
||||||
&state->chainparams->genesis_blockhash,
|
&state->chainparams->genesis_blockhash,
|
||||||
&state->channel_id,
|
&state->channel_id,
|
||||||
state->funding_satoshis, state->push_msat,
|
state->funding.satoshis,
|
||||||
state->localconf.dust_limit_satoshis,
|
state->push_msat.millisatoshis,
|
||||||
state->localconf.max_htlc_value_in_flight_msat,
|
state->localconf.dust_limit.satoshis,
|
||||||
state->localconf.channel_reserve_satoshis,
|
state->localconf.max_htlc_value_in_flight.millisatoshis,
|
||||||
state->localconf.htlc_minimum_msat,
|
state->localconf.channel_reserve.satoshis,
|
||||||
|
state->localconf.htlc_minimum.millisatoshis,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
state->localconf.to_self_delay,
|
state->localconf.to_self_delay,
|
||||||
state->localconf.max_accepted_htlcs,
|
state->localconf.max_accepted_htlcs,
|
||||||
|
@ -505,12 +518,12 @@ static u8 *funder_channel(struct state *state,
|
||||||
* valid DER-encoded compressed secp256k1 pubkeys.
|
* valid DER-encoded compressed secp256k1 pubkeys.
|
||||||
*/
|
*/
|
||||||
if (!fromwire_accept_channel(msg, &id_in,
|
if (!fromwire_accept_channel(msg, &id_in,
|
||||||
&state->remoteconf.dust_limit_satoshis,
|
&state->remoteconf.dust_limit.satoshis,
|
||||||
&state->remoteconf
|
&state->remoteconf
|
||||||
.max_htlc_value_in_flight_msat,
|
.max_htlc_value_in_flight.millisatoshis,
|
||||||
&state->remoteconf
|
&state->remoteconf
|
||||||
.channel_reserve_satoshis,
|
.channel_reserve.satoshis,
|
||||||
&state->remoteconf.htlc_minimum_msat,
|
&state->remoteconf.htlc_minimum.millisatoshis,
|
||||||
&minimum_depth,
|
&minimum_depth,
|
||||||
&state->remoteconf.to_self_delay,
|
&state->remoteconf.to_self_delay,
|
||||||
&state->remoteconf.max_accepted_htlcs,
|
&state->remoteconf.max_accepted_htlcs,
|
||||||
|
@ -564,22 +577,26 @@ static u8 *funder_channel(struct state *state,
|
||||||
* less than `dust_limit_satoshis`:
|
* less than `dust_limit_satoshis`:
|
||||||
* - MUST reject the channel.
|
* - MUST reject the channel.
|
||||||
*/
|
*/
|
||||||
if (state->remoteconf.channel_reserve_satoshis
|
if (amount_sat_greater(state->localconf.dust_limit,
|
||||||
< state->localconf.dust_limit_satoshis) {
|
state->remoteconf.channel_reserve)) {
|
||||||
negotiation_failed(state, true,
|
negotiation_failed(state, true,
|
||||||
"channel reserve %"PRIu64
|
"channel reserve %s"
|
||||||
" would be below our dust %"PRIu64,
|
" would be below our dust %s",
|
||||||
state->remoteconf.channel_reserve_satoshis,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->localconf.dust_limit_satoshis);
|
&state->remoteconf.channel_reserve),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->localconf.dust_limit));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (state->localconf.channel_reserve_satoshis
|
if (amount_sat_greater(state->remoteconf.dust_limit,
|
||||||
< state->remoteconf.dust_limit_satoshis) {
|
state->localconf.channel_reserve)) {
|
||||||
negotiation_failed(state, true,
|
negotiation_failed(state, true,
|
||||||
"dust limit %"PRIu64
|
"dust limit %s"
|
||||||
" would be above our reserve %"PRIu64,
|
" would be above our reserve %s",
|
||||||
state->remoteconf.dust_limit_satoshis,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->localconf.channel_reserve_satoshis);
|
&state->remoteconf.dust_limit),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->localconf.channel_reserve));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +605,7 @@ static u8 *funder_channel(struct state *state,
|
||||||
|
|
||||||
/*~ If lightningd told us to create change, use change index to do
|
/*~ If lightningd told us to create change, use change index to do
|
||||||
* that. */
|
* that. */
|
||||||
if (change_satoshis) {
|
if (!amount_sat_eq(change, AMOUNT_SAT(0))) {
|
||||||
changekey = tal(tmpctx, struct pubkey);
|
changekey = tal(tmpctx, struct pubkey);
|
||||||
if (!bip32_pubkey(bip32_base, changekey, change_keyindex))
|
if (!bip32_pubkey(bip32_base, changekey, change_keyindex))
|
||||||
status_failed(STATUS_FAIL_MASTER_IO,
|
status_failed(STATUS_FAIL_MASTER_IO,
|
||||||
|
@ -603,10 +620,10 @@ static u8 *funder_channel(struct state *state,
|
||||||
*/
|
*/
|
||||||
funding = funding_tx(state, &state->funding_txout,
|
funding = funding_tx(state, &state->funding_txout,
|
||||||
cast_const2(const struct utxo **, utxos),
|
cast_const2(const struct utxo **, utxos),
|
||||||
state->funding_satoshis,
|
state->funding.satoshis,
|
||||||
&state->our_funding_pubkey,
|
&state->our_funding_pubkey,
|
||||||
&their_funding_pubkey,
|
&their_funding_pubkey,
|
||||||
change_satoshis, changekey,
|
change.satoshis, changekey,
|
||||||
bip32_base);
|
bip32_base);
|
||||||
bitcoin_txid(funding, &state->funding_txid);
|
bitcoin_txid(funding, &state->funding_txid);
|
||||||
|
|
||||||
|
@ -622,9 +639,9 @@ static u8 *funder_channel(struct state *state,
|
||||||
&state->chainparams->genesis_blockhash,
|
&state->chainparams->genesis_blockhash,
|
||||||
&state->funding_txid,
|
&state->funding_txid,
|
||||||
state->funding_txout,
|
state->funding_txout,
|
||||||
state->funding_satoshis,
|
state->funding.satoshis,
|
||||||
state->funding_satoshis * 1000
|
state->funding.satoshis * 1000
|
||||||
- state->push_msat,
|
- state->push_msat.millisatoshis,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
&state->localconf,
|
&state->localconf,
|
||||||
&state->remoteconf,
|
&state->remoteconf,
|
||||||
|
@ -805,7 +822,7 @@ static u8 *funder_channel(struct state *state,
|
||||||
&their_funding_pubkey,
|
&their_funding_pubkey,
|
||||||
&state->funding_txid,
|
&state->funding_txid,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
state->localconf.channel_reserve_satoshis);
|
state->localconf.channel_reserve.satoshis);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (taken(utxos))
|
if (taken(utxos))
|
||||||
|
@ -836,11 +853,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
*/
|
*/
|
||||||
if (!fromwire_open_channel(open_channel_msg, &chain_hash,
|
if (!fromwire_open_channel(open_channel_msg, &chain_hash,
|
||||||
&state->channel_id,
|
&state->channel_id,
|
||||||
&state->funding_satoshis, &state->push_msat,
|
&state->funding.satoshis,
|
||||||
&state->remoteconf.dust_limit_satoshis,
|
&state->push_msat.millisatoshis,
|
||||||
&state->remoteconf.max_htlc_value_in_flight_msat,
|
&state->remoteconf.dust_limit.satoshis,
|
||||||
&state->remoteconf.channel_reserve_satoshis,
|
&state->remoteconf.max_htlc_value_in_flight.millisatoshis,
|
||||||
&state->remoteconf.htlc_minimum_msat,
|
&state->remoteconf.channel_reserve.satoshis,
|
||||||
|
&state->remoteconf.htlc_minimum.millisatoshis,
|
||||||
&state->feerate_per_kw,
|
&state->feerate_per_kw,
|
||||||
&state->remoteconf.to_self_delay,
|
&state->remoteconf.to_self_delay,
|
||||||
&state->remoteconf.max_accepted_htlcs,
|
&state->remoteconf.max_accepted_htlcs,
|
||||||
|
@ -885,10 +903,11 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
*
|
*
|
||||||
* The receiving node ... MUST fail the channel if `funding-satoshis`
|
* The receiving node ... MUST fail the channel if `funding-satoshis`
|
||||||
* is greater than or equal to 2^24 */
|
* is greater than or equal to 2^24 */
|
||||||
if (state->funding_satoshis > state->chainparams->max_funding.satoshis) {
|
if (amount_sat_greater(state->funding, state->chainparams->max_funding)) {
|
||||||
negotiation_failed(state, false,
|
negotiation_failed(state, false,
|
||||||
"funding_satoshis %"PRIu64" too large",
|
"funding_satoshis %s too large",
|
||||||
state->funding_satoshis);
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,12 +917,15 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
* ...
|
* ...
|
||||||
* - `push_msat` is greater than `funding_satoshis` * 1000.
|
* - `push_msat` is greater than `funding_satoshis` * 1000.
|
||||||
*/
|
*/
|
||||||
if (state->push_msat > state->funding_satoshis * 1000) {
|
if (amount_msat_greater_sat(state->push_msat, state->funding)) {
|
||||||
peer_failed(&state->cs,
|
peer_failed(&state->cs,
|
||||||
&state->channel_id,
|
&state->channel_id,
|
||||||
"Our push_msat %"PRIu64
|
"Our push_msat %s"
|
||||||
" would be too large for funding_satoshis %"PRIu64,
|
" would be too large for funding_satoshis %s",
|
||||||
state->push_msat, state->funding_satoshis);
|
type_to_string(tmpctx, struct amount_msat,
|
||||||
|
&state->push_msat),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->funding));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,22 +962,26 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
* - MUST set `dust_limit_satoshis` less than or equal to
|
* - MUST set `dust_limit_satoshis` less than or equal to
|
||||||
* `channel_reserve_satoshis` from the `open_channel` message.
|
* `channel_reserve_satoshis` from the `open_channel` message.
|
||||||
*/
|
*/
|
||||||
if (state->localconf.channel_reserve_satoshis
|
if (amount_sat_greater(state->remoteconf.dust_limit,
|
||||||
< state->remoteconf.dust_limit_satoshis) {
|
state->localconf.channel_reserve)) {
|
||||||
negotiation_failed(state, false,
|
negotiation_failed(state, false,
|
||||||
"Our channel reserve %"PRIu64
|
"Our channel reserve %s"
|
||||||
" would be below their dust %"PRIu64,
|
" would be below their dust %s",
|
||||||
state->localconf.channel_reserve_satoshis,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->remoteconf.dust_limit_satoshis);
|
&state->localconf.channel_reserve),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->remoteconf.dust_limit));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (state->localconf.dust_limit_satoshis
|
if (amount_sat_greater(state->localconf.dust_limit,
|
||||||
> state->remoteconf.channel_reserve_satoshis) {
|
state->remoteconf.channel_reserve)) {
|
||||||
negotiation_failed(state, false,
|
negotiation_failed(state, false,
|
||||||
"Our dust limit %"PRIu64
|
"Our dust limit %s"
|
||||||
" would be above their reserve %"PRIu64,
|
" would be above their reserve %s",
|
||||||
state->localconf.dust_limit_satoshis,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
state->remoteconf.channel_reserve_satoshis);
|
&state->localconf.dust_limit),
|
||||||
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
|
&state->remoteconf.channel_reserve));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,11 +991,11 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
|
|
||||||
/* OK, we accept! */
|
/* OK, we accept! */
|
||||||
msg = towire_accept_channel(NULL, &state->channel_id,
|
msg = towire_accept_channel(NULL, &state->channel_id,
|
||||||
state->localconf.dust_limit_satoshis,
|
state->localconf.dust_limit.satoshis,
|
||||||
state->localconf
|
state->localconf
|
||||||
.max_htlc_value_in_flight_msat,
|
.max_htlc_value_in_flight.millisatoshis,
|
||||||
state->localconf.channel_reserve_satoshis,
|
state->localconf.channel_reserve.satoshis,
|
||||||
state->localconf.htlc_minimum_msat,
|
state->localconf.htlc_minimum.millisatoshis,
|
||||||
state->minimum_depth,
|
state->minimum_depth,
|
||||||
state->localconf.to_self_delay,
|
state->localconf.to_self_delay,
|
||||||
state->localconf.max_accepted_htlcs,
|
state->localconf.max_accepted_htlcs,
|
||||||
|
@ -1018,8 +1044,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
&chain_hash,
|
&chain_hash,
|
||||||
&state->funding_txid,
|
&state->funding_txid,
|
||||||
state->funding_txout,
|
state->funding_txout,
|
||||||
state->funding_satoshis,
|
state->funding.satoshis,
|
||||||
state->push_msat,
|
state->push_msat.millisatoshis,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
&state->localconf,
|
&state->localconf,
|
||||||
&state->remoteconf,
|
&state->remoteconf,
|
||||||
|
@ -1139,12 +1165,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
&their_funding_pubkey,
|
&their_funding_pubkey,
|
||||||
&state->funding_txid,
|
&state->funding_txid,
|
||||||
state->funding_txout,
|
state->funding_txout,
|
||||||
state->funding_satoshis,
|
state->funding.satoshis,
|
||||||
state->push_msat,
|
state->push_msat.millisatoshis,
|
||||||
channel_flags,
|
channel_flags,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
msg,
|
msg,
|
||||||
state->localconf.channel_reserve_satoshis);
|
state->localconf.channel_reserve.satoshis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*~ Standard "peer sent a message, handle it" demuxer. Though it really only
|
/*~ Standard "peer sent a message, handle it" demuxer. Though it really only
|
||||||
|
@ -1272,7 +1298,7 @@ static u8 *handle_master_in(struct state *state)
|
||||||
{
|
{
|
||||||
u8 *msg = wire_sync_read(tmpctx, REQ_FD);
|
u8 *msg = wire_sync_read(tmpctx, REQ_FD);
|
||||||
enum opening_wire_type t = fromwire_peektype(msg);
|
enum opening_wire_type t = fromwire_peektype(msg);
|
||||||
u64 change_satoshis;
|
struct amount_sat change;
|
||||||
u32 change_keyindex;
|
u32 change_keyindex;
|
||||||
u8 channel_flags;
|
u8 channel_flags;
|
||||||
struct utxo **utxos;
|
struct utxo **utxos;
|
||||||
|
@ -1281,16 +1307,17 @@ static u8 *handle_master_in(struct state *state)
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case WIRE_OPENING_FUNDER:
|
case WIRE_OPENING_FUNDER:
|
||||||
if (!fromwire_opening_funder(state, msg,
|
if (!fromwire_opening_funder(state, msg,
|
||||||
&state->funding_satoshis,
|
&state->funding.satoshis,
|
||||||
&state->push_msat,
|
&state->push_msat.millisatoshis,
|
||||||
&state->feerate_per_kw,
|
&state->feerate_per_kw,
|
||||||
&change_satoshis, &change_keyindex,
|
&change.satoshis,
|
||||||
|
&change_keyindex,
|
||||||
&channel_flags, &utxos,
|
&channel_flags, &utxos,
|
||||||
&bip32_base))
|
&bip32_base))
|
||||||
master_badmsg(WIRE_OPENING_FUNDER, msg);
|
master_badmsg(WIRE_OPENING_FUNDER, msg);
|
||||||
|
|
||||||
msg = funder_channel(state,
|
msg = funder_channel(state,
|
||||||
change_satoshis,
|
change,
|
||||||
change_keyindex, channel_flags,
|
change_keyindex, channel_flags,
|
||||||
take(utxos), &bip32_base);
|
take(utxos), &bip32_base);
|
||||||
return msg;
|
return msg;
|
||||||
|
@ -1340,7 +1367,7 @@ int main(int argc, char *argv[])
|
||||||
&chain_hash,
|
&chain_hash,
|
||||||
&state->localconf,
|
&state->localconf,
|
||||||
&state->max_to_self_delay,
|
&state->max_to_self_delay,
|
||||||
&state->min_effective_htlc_capacity_msat,
|
&state->min_effective_htlc_capacity.millisatoshis,
|
||||||
&state->cs,
|
&state->cs,
|
||||||
&state->our_points,
|
&state->our_points,
|
||||||
&state->our_funding_pubkey,
|
&state->our_funding_pubkey,
|
||||||
|
|
|
@ -998,10 +998,10 @@ static bool test_channel_config_crud(struct lightningd *ld, const tal_t *ctx)
|
||||||
struct wallet *w = create_test_wallet(ld, ctx);
|
struct wallet *w = create_test_wallet(ld, ctx);
|
||||||
CHECK(w);
|
CHECK(w);
|
||||||
|
|
||||||
cc1->dust_limit_satoshis = 1;
|
cc1->dust_limit.satoshis = 1;
|
||||||
cc1->max_htlc_value_in_flight_msat = 2;
|
cc1->max_htlc_value_in_flight.millisatoshis = 2;
|
||||||
cc1->channel_reserve_satoshis = 3;
|
cc1->channel_reserve.satoshis = 3;
|
||||||
cc1->htlc_minimum_msat = 4;
|
cc1->htlc_minimum.millisatoshis = 4;
|
||||||
cc1->to_self_delay = 5;
|
cc1->to_self_delay = 5;
|
||||||
cc1->max_accepted_htlcs = 6;
|
cc1->max_accepted_htlcs = 6;
|
||||||
|
|
||||||
|
|
|
@ -868,10 +868,10 @@ static void wallet_channel_config_save(struct wallet *w,
|
||||||
" to_self_delay=?,"
|
" to_self_delay=?,"
|
||||||
" max_accepted_htlcs=?"
|
" max_accepted_htlcs=?"
|
||||||
" WHERE id=?;");
|
" WHERE id=?;");
|
||||||
sqlite3_bind_int64(stmt, 1, cc->dust_limit_satoshis);
|
sqlite3_bind_amount_sat(stmt, 1, cc->dust_limit);
|
||||||
sqlite3_bind_int64(stmt, 2, cc->max_htlc_value_in_flight_msat);
|
sqlite3_bind_amount_msat(stmt, 2, cc->max_htlc_value_in_flight);
|
||||||
sqlite3_bind_int64(stmt, 3, cc->channel_reserve_satoshis);
|
sqlite3_bind_amount_sat(stmt, 3, cc->channel_reserve);
|
||||||
sqlite3_bind_int64(stmt, 4, cc->htlc_minimum_msat);
|
sqlite3_bind_amount_msat(stmt, 4, cc->htlc_minimum);
|
||||||
sqlite3_bind_int(stmt, 5, cc->to_self_delay);
|
sqlite3_bind_int(stmt, 5, cc->to_self_delay);
|
||||||
sqlite3_bind_int(stmt, 6, cc->max_accepted_htlcs);
|
sqlite3_bind_int(stmt, 6, cc->max_accepted_htlcs);
|
||||||
sqlite3_bind_int64(stmt, 7, cc->id);
|
sqlite3_bind_int64(stmt, 7, cc->id);
|
||||||
|
@ -893,10 +893,10 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cc->id = id;
|
cc->id = id;
|
||||||
cc->dust_limit_satoshis = sqlite3_column_int64(stmt, col++);
|
cc->dust_limit = sqlite3_column_amount_sat(stmt, col++);
|
||||||
cc->max_htlc_value_in_flight_msat = sqlite3_column_int64(stmt, col++);
|
cc->max_htlc_value_in_flight = sqlite3_column_amount_msat(stmt, col++);
|
||||||
cc->channel_reserve_satoshis = sqlite3_column_int64(stmt, col++);
|
cc->channel_reserve = sqlite3_column_amount_sat(stmt, col++);
|
||||||
cc->htlc_minimum_msat = sqlite3_column_int64(stmt, col++);
|
cc->htlc_minimum = sqlite3_column_amount_msat(stmt, col++);
|
||||||
cc->to_self_delay = sqlite3_column_int(stmt, col++);
|
cc->to_self_delay = sqlite3_column_int(stmt, col++);
|
||||||
cc->max_accepted_htlcs = sqlite3_column_int(stmt, col++);
|
cc->max_accepted_htlcs = sqlite3_column_int(stmt, col++);
|
||||||
assert(col == 7);
|
assert(col == 7);
|
||||||
|
|
Loading…
Add table
Reference in a new issue