From b8e484b508b22fa5b6d5d841609f9c905cdfe1f9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 21 Feb 2019 14:15:54 +1030 Subject: [PATCH] struct channel_config: use amount_sat / amount_msat. Signed-off-by: Rusty Russell --- channeld/channeld.c | 55 +++- channeld/full_channel.c | 21 +- channeld/test/run-full_channel.c | 20 +- common/channel_config.c | 16 +- common/channel_config.h | 9 +- common/initial_channel.c | 4 +- common/initial_channel.h | 8 - lightningd/closing_control.c | 2 +- lightningd/invoice.c | 4 +- lightningd/onchain_control.c | 2 +- lightningd/opening_control.c | 22 +- lightningd/peer_control.c | 12 +- lightningd/peer_htlcs.c | 8 +- lightningd/test/run-invoice-select-inchan.c | 2 +- openingd/openingd.c | 289 +++++++++++--------- wallet/test/run-wallet.c | 8 +- wallet/wallet.c | 16 +- 17 files changed, 274 insertions(+), 224 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index f037b8568..3e2fd26ad 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -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) { - u64 lower_bound; - u64 cumulative_reserve_msat; + struct amount_sat cumulative_reserve, funding, lower_bound; + struct amount_msat lower_bound_msat; - cumulative_reserve_msat = - (channel->config[LOCAL].channel_reserve_satoshis + - channel->config[REMOTE].channel_reserve_satoshis) * 1000; + funding.satoshis = channel->funding_msat / 1000; - lower_bound = channel->config[REMOTE].max_htlc_value_in_flight_msat; - if (channel->funding_msat - cumulative_reserve_msat < lower_bound) - lower_bound = channel->funding_msat - cumulative_reserve_msat; + /* This shouldn't fail */ + if (!amount_sat_add(&cumulative_reserve, + 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 */ - if (channel->chainparams->max_payment.millisatoshis < lower_bound) - lower_bound = channel->chainparams->max_payment.millisatoshis; - return lower_bound; + if (amount_msat_greater(lower_bound_msat, + channel->chainparams->max_payment)) + lower_bound_msat = channel->chainparams->max_payment; + + return lower_bound_msat.millisatoshis; } /* 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 == ROUTING_FLAGS_DISABLED, peer->cltv_delta, - peer->channel->config[REMOTE].htlc_minimum_msat, + peer->channel->config[REMOTE].htlc_minimum.millisatoshis, peer->fee_base, peer->fee_per_satoshi, advertised_htlc_max(peer->channel)); @@ -2455,8 +2480,10 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) goto failed; case CHANNEL_ERR_HTLC_BELOW_MINIMUM: failcode = WIRE_AMOUNT_BELOW_MINIMUM; - failmsg = tal_fmt(inmsg, "HTLC too small (%"PRIu64" minimum)", - peer->channel->config[REMOTE].htlc_minimum_msat); + failmsg = tal_fmt(inmsg, "HTLC too small (%s minimum)", + type_to_string(tmpctx, + struct amount_msat, + &peer->channel->config[REMOTE].htlc_minimum)); goto failed; case CHANNEL_ERR_TOO_MANY_HTLCS: failcode = WIRE_TEMPORARY_CHANNEL_FAILURE; diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 3b76439b1..4e9189e28 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -262,7 +262,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, channel->config[!side].to_self_delay, &keyset, 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], committed, @@ -348,7 +348,7 @@ static enum channel_add_err add_htlc(struct channel *channel, if (htlc->msatoshi == 0) { 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; } @@ -389,7 +389,7 @@ static enum channel_add_err add_htlc(struct channel *channel, * - SHOULD fail the channel. */ 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; } @@ -404,7 +404,7 @@ static enum channel_add_err add_htlc(struct channel *channel, */ if (channel->funder == htlc_owner(htlc)) { 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; 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 * sender's reserve. */ 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 ", fee is %"PRIu64 - ", reserve is %"PRIu64, + ", reserve is %s", 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; } @@ -697,7 +698,7 @@ u32 approx_max_feerate(const struct channel *channel) /* We should never go below reserve. */ 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. */ 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) { - 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; const struct htlc **committed, **adding, **removing; 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 */ 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) diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index b5d7baad9..fde0e25ad 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -379,17 +379,17 @@ int main(void) funding_amount_satoshi = 10000000; 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 * 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; - remote_config->max_htlc_value_in_flight_msat = -1ULL; - local_config->channel_reserve_satoshis = 0; - remote_config->channel_reserve_satoshis = 0; - local_config->htlc_minimum_msat = 0; - remote_config->htlc_minimum_msat = 0; + local_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL); + remote_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL); + local_config->channel_reserve = AMOUNT_SAT(0); + remote_config->channel_reserve = AMOUNT_SAT(0); + local_config->htlc_minimum = AMOUNT_MSAT(0); + remote_config->htlc_minimum = AMOUNT_MSAT(0); local_config->max_accepted_htlcs = 0xFFFF; remote_config->max_accepted_htlcs = 0xFFFF; @@ -495,7 +495,7 @@ int main(void) LOCAL, remote_config->to_self_delay, &keyset, feerate_per_kw[LOCAL], - local_config->dust_limit_satoshis, + local_config->dust_limit.satoshis, to_local_msat, to_remote_msat, NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL); @@ -613,7 +613,7 @@ int main(void) LOCAL, remote_config->to_self_delay, &keyset, feerate_per_kw[LOCAL], - local_config->dust_limit_satoshis, + local_config->dust_limit.satoshis, to_local_msat, to_remote_msat, htlcs, &htlc_map, diff --git a/common/channel_config.c b/common/channel_config.c index f4de14357..5b8627c76 100644 --- a/common/channel_config.c +++ b/common/channel_config.c @@ -3,10 +3,10 @@ void towire_channel_config(u8 **pptr, const struct channel_config *config) { - towire_u64(pptr, config->dust_limit_satoshis); - towire_u64(pptr, config->max_htlc_value_in_flight_msat); - towire_u64(pptr, config->channel_reserve_satoshis); - towire_u32(pptr, config->htlc_minimum_msat); + towire_amount_sat(pptr, config->dust_limit); + towire_amount_msat(pptr, config->max_htlc_value_in_flight); + towire_amount_sat(pptr, config->channel_reserve); + towire_amount_msat(pptr, config->htlc_minimum); towire_u16(pptr, config->to_self_delay); 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, struct channel_config *config) { - config->dust_limit_satoshis = fromwire_u64(ptr, max); - config->max_htlc_value_in_flight_msat = fromwire_u64(ptr, max); - config->channel_reserve_satoshis = fromwire_u64(ptr, max); - config->htlc_minimum_msat = fromwire_u32(ptr, max); + config->dust_limit = fromwire_amount_sat(ptr, max); + config->max_htlc_value_in_flight = fromwire_amount_msat(ptr, max); + config->channel_reserve = fromwire_amount_sat(ptr, max); + config->htlc_minimum = fromwire_amount_msat(ptr, max); config->to_self_delay = fromwire_u16(ptr, max); config->max_accepted_htlcs = fromwire_u16(ptr, max); } diff --git a/common/channel_config.h b/common/channel_config.h index 3e7f2587e..5daeeb6de 100644 --- a/common/channel_config.h +++ b/common/channel_config.h @@ -3,6 +3,7 @@ #include "config.h" #include #include +#include /* BOLT #2: * @@ -38,27 +39,27 @@ struct channel_config { * * `dust_limit_satoshis` is the threshold below which outputs should * not be generated for this node's commitment or HTLC transaction */ - u64 dust_limit_satoshis; + struct amount_sat dust_limit; /* BOLT #2: * * `max_htlc_value_in_flight_msat` is a cap on total value of * outstanding HTLCs, which allows a node to limit its exposure to * HTLCs */ - u64 max_htlc_value_in_flight_msat; + struct amount_msat max_htlc_value_in_flight; /* BOLT #2: * * `channel_reserve_satoshis` is the minimum amount that the other * node is to keep as a direct payment. */ - u64 channel_reserve_satoshis; + struct amount_sat channel_reserve; /* BOLT #2: * * `htlc_minimum_msat` indicates the smallest value HTLC this node * will accept. */ - u64 htlc_minimum_msat; + struct amount_msat htlc_minimum; /* BOLT #2: * diff --git a/common/initial_channel.c b/common/initial_channel.c index fe23469f8..0fe160938 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -97,10 +97,10 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, channel->config[!side].to_self_delay, &keyset, 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_reserve_msat(channel, side), + channel->config[!side].channel_reserve.satoshis * 1000, 0 ^ channel->commitment_number_obscurer, side); } diff --git a/common/initial_channel.h b/common/initial_channel.h index d395b6d19..c45b6f599 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -62,14 +62,6 @@ struct channel { 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? * @ctx: tal context to allocate return value from. diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index ad3a50fa2..6316ccc62 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -227,7 +227,7 @@ void peer_start_closingd(struct channel *channel, channel->funder, our_msatoshi / 1000, /* Rounds down */ their_msatoshi / 1000, /* Rounds down */ - channel->our_config.dust_limit_satoshis, + channel->our_config.dust_limit.satoshis, minfee, feelimit, startfee, p2wpkh_for_keyidx(tmpctx, ld, channel->final_key_idx), diff --git a/lightningd/invoice.c b/lightningd/invoice.c index a947fae65..d67ffc4cd 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -178,11 +178,11 @@ static struct route_info **select_inchan(const tal_t *ctx, msatoshi_avail = c->funding_satoshi * 1000 - c->our_msatoshi; /* Even after reserve taken into account */ - if (c->our_config.channel_reserve_satoshis * 1000 + if (c->our_config.channel_reserve.satoshis * 1000 > msatoshi_avail) continue; - msatoshi_avail -= c->our_config.channel_reserve_satoshis * 1000; + msatoshi_avail -= c->our_config.channel_reserve.satoshis * 1000; if (msatoshi_avail < capacity_needed) continue; diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 7bd4c6b06..c0a2f9e4a 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -472,7 +472,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel, channel->channel_info.their_config.to_self_delay, channel->our_config.to_self_delay, feerate, - channel->our_config.dust_limit_satoshis, + channel->our_config.dust_limit.satoshis, &our_last_txid, p2wpkh_for_keyidx(tmpctx, ld, channel->final_key_idx), diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 9b9113527..abfb3de14 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -305,7 +305,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, &channel_info.remote_fundingkey, &expected_txid, &feerate, - &fc->uc->our_config.channel_reserve_satoshis)) { + &fc->uc->our_config.channel_reserve.satoshis)) { log_broken(fc->uc->log, "bad OPENING_FUNDER_REPLY %s", tal_hex(resp, resp)); @@ -495,7 +495,7 @@ static void opening_fundee_finished(struct subd *openingd, &channel_flags, &feerate, &funding_signed, - &uc->our_config.channel_reserve_satoshis)) { + &uc->our_config.channel_reserve.satoshis)) { log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s", tal_hex(reply, 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, struct channel_config *ours, u32 *max_to_self_delay, - u64 *min_effective_htlc_capacity_msat) + struct amount_msat *min_effective_htlc_capacity) { /* FIXME: depend on feerate. */ *max_to_self_delay = ld->config.locktime_max; /* This is 1c at $1000/BTC */ - *min_effective_htlc_capacity_msat = 1000000; + *min_effective_htlc_capacity = AMOUNT_MSAT(1000000); /* BOLT #2: * @@ -658,11 +658,11 @@ static void channel_config(struct lightningd *ld, * - set `dust_limit_satoshis` to a sufficient value to allow * commitment transactions to propagate through the Bitcoin network. */ - ours->dust_limit_satoshis = 546; - ours->max_htlc_value_in_flight_msat = UINT64_MAX; + ours->dust_limit = AMOUNT_SAT(546); + ours->max_htlc_value_in_flight = AMOUNT_MSAT(UINT64_MAX); /* Don't care */ - ours->htlc_minimum_msat = 0; + ours->htlc_minimum = AMOUNT_MSAT(0); /* BOLT #2: * @@ -682,7 +682,7 @@ static void channel_config(struct lightningd *ld, ours->max_accepted_htlcs = 483; /* 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, @@ -742,7 +742,7 @@ void peer_start_openingd(struct peer *peer, { int hsmfd; u32 max_to_self_delay; - u64 min_effective_htlc_capacity_msat; + struct amount_msat min_effective_htlc_capacity; struct uncommitted_channel *uc; const u8 *msg; @@ -773,7 +773,7 @@ void peer_start_openingd(struct peer *peer, channel_config(peer->ld, &uc->our_config, &max_to_self_delay, - &min_effective_htlc_capacity_msat); + &min_effective_htlc_capacity); /* BOLT #2: * @@ -787,7 +787,7 @@ void peer_start_openingd(struct peer *peer, &get_chainparams(peer->ld)->genesis_blockhash, &uc->our_config, max_to_self_delay, - min_effective_htlc_capacity_msat, + min_effective_htlc_capacity.millisatoshis, cs, &uc->local_basepoints, &uc->local_funding_pubkey, uc->minimum_depth, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index e0e3ac585..437a340cb 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -581,10 +581,10 @@ static void json_add_channel(struct lightningd *ld, /* channel config */ 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"); 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_total_htlc_in_msat"); @@ -596,23 +596,23 @@ static void json_add_channel(struct lightningd *ld, * configuration `channel_reserve_satoshis` is * imposed on ours. */ json_add_amount_sat(response, - (struct amount_sat){channel->our_config.channel_reserve_satoshis}, + channel->our_config.channel_reserve, "their_channel_reserve_satoshis", "their_reserve_msat"); 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_reserve_msat"); /* Compute how much we can send via this channel. */ if (!amount_msat_sub_sat(&spendable, (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); json_add_amount_msat(response, spendable, "spendable_msatoshi", "spendable_msat"); json_add_amount_msat(response, - (struct amount_msat){channel->our_config.htlc_minimum_msat}, + channel->our_config.htlc_minimum, "htlc_minimum_msat", "minimum_htlc_in_msat"); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index bdc111afa..019a4bcc3 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1108,12 +1108,14 @@ static bool channel_added_their_htlc(struct channel *channel, * - SHOULD fail the channel. */ 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, "trying to add HTLC msat %"PRIu64 - " but minimum is %"PRIu64, + " but minimum is %s", added->amount_msat, - channel->our_config.htlc_minimum_msat); + type_to_string(tmpctx, + struct amount_msat, + &channel->our_config.htlc_minimum)); return false; } diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index d1520b805..5dfce1f30 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -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 */ c->funding_satoshi = n+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); } diff --git a/openingd/openingd.c b/openingd/openingd.c index 325e7d865..d367f644a 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -61,7 +61,7 @@ struct state { /* Constraints on a channel they open. */ u32 minimum_depth; 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. */ u32 max_to_self_delay; @@ -79,7 +79,8 @@ struct state { struct channel_id channel_id; /* 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; struct bitcoin_txid funding_txid; u16 funding_txout; @@ -155,8 +156,8 @@ static bool check_config_bounds(struct state *state, const struct channel_config *remoteconf, bool am_funder) { - u64 capacity_msat; - u64 reserve_msat; + struct amount_sat capacity; + struct amount_sat reserve; /* BOLT #2: * @@ -185,67 +186,74 @@ static bool check_config_bounds(struct state *state, /* We accumulate this into an effective bandwidth minimum. */ /* Add both reserves to deduct from capacity. */ - if (mul_overflows_u64(remoteconf->channel_reserve_satoshis, 1000) - || add_overflows_u64(remoteconf->channel_reserve_satoshis * 1000, - state->localconf.channel_reserve_satoshis * 1000)) { + if (!amount_sat_add(&reserve, + remoteconf->channel_reserve, + state->localconf.channel_reserve)) { negotiation_failed(state, am_funder, - "channel_reserve_satoshis %"PRIu64 + "channel_reserve_satoshis %s" " too large", - remoteconf->channel_reserve_satoshis); + type_to_string(tmpctx, struct amount_sat, + &remoteconf->channel_reserve)); return false; } - reserve_msat = remoteconf->channel_reserve_satoshis * 1000 - + state->localconf.channel_reserve_satoshis * 1000; - /* We checked this before, or it's ours. */ - assert(!mul_overflows_u64(state->funding_satoshis, 1000)); - - /* If reserves are larger than total msat, we fail. */ - if (reserve_msat > state->funding_satoshis * 1000) { + /* If reserves are larger than total sat, we fail. */ + if (!amount_sat_sub(&capacity, state->funding, reserve)) { negotiation_failed(state, am_funder, - "channel_reserve_satoshis %"PRIu64 - " and %"PRIu64" too large for funding_satoshis %"PRIu64, - remoteconf->channel_reserve_satoshis, - state->localconf.channel_reserve_satoshis, - state->funding_satoshis); + "channel_reserve_satoshis %s" + " and %s too large for funding %s", + type_to_string(tmpctx, struct amount_sat, + &remoteconf->channel_reserve), + type_to_string(tmpctx, struct amount_sat, + &state->localconf.channel_reserve), + type_to_string(tmpctx, struct amount_sat, + &state->funding)); return false; } - capacity_msat = state->funding_satoshis * 1000 - reserve_msat; - /* If they set the max HTLC value to less than that number, it caps * the channel capacity. */ - if (remoteconf->max_htlc_value_in_flight_msat < capacity_msat) - capacity_msat = remoteconf->max_htlc_value_in_flight_msat; + if (amount_sat_greater(capacity, + 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 * useless. */ - if (mul_overflows_u64(remoteconf->htlc_minimum_msat, 1000) - || remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat) { + if (amount_msat_greater_sat(remoteconf->htlc_minimum, capacity)) { negotiation_failed(state, am_funder, - "htlc_minimum_msat %"PRIu64 - " too large for funding_satoshis %"PRIu64 - " capacity_msat %"PRIu64, - remoteconf->htlc_minimum_msat, - state->funding_satoshis, - capacity_msat); + "htlc_minimum_msat %s" + " too large for funding %s" + " capacity_msat %s", + type_to_string(tmpctx, struct amount_msat, + &remoteconf->htlc_minimum), + type_to_string(tmpctx, struct amount_sat, + &state->funding), + type_to_string(tmpctx, struct amount_sat, + &capacity)); return false; } /* If the resulting channel doesn't meet our minimum "effective capacity" * 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, - "channel capacity with funding %"PRIu64" msat," - " reserves %"PRIu64"/%"PRIu64" msat," - " max_htlc_value_in_flight_msat %"PRIu64 - " is %"PRIu64" msat, which is below %"PRIu64" msat", - state->funding_satoshis * 1000, - remoteconf->channel_reserve_satoshis * 1000, - state->localconf.channel_reserve_satoshis * 1000, - remoteconf->max_htlc_value_in_flight_msat, - capacity_msat, - state->min_effective_htlc_capacity_msat); + "channel capacity with funding %s," + " reserves %s/%s," + " max_htlc_value_in_flight_msat %s" + " is %s msat, which is below %s msat", + type_to_string(tmpctx, struct amount_sat, + &state->funding), + type_to_string(tmpctx, struct amount_sat, + &remoteconf->channel_reserve), + type_to_string(tmpctx, struct amount_sat, + &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; } @@ -276,14 +284,15 @@ static bool check_config_bounds(struct state *state, *... * - `dust_limit_satoshis` is greater than `channel_reserve_satoshis`. */ - if (remoteconf->dust_limit_satoshis - > remoteconf->channel_reserve_satoshis) { + if (amount_sat_greater(remoteconf->dust_limit, + remoteconf->channel_reserve)) { negotiation_failed(state, am_funder, - "dust_limit_satoshis %"PRIu64 - " too large for channel_reserve_satoshis %" - PRIu64, - remoteconf->dust_limit_satoshis, - remoteconf->channel_reserve_satoshis); + "dust_limit_satoshis %s" + " too large for channel_reserve_satoshis %s", + type_to_string(tmpctx, struct amount_sat, + &remoteconf->dust_limit), + type_to_string(tmpctx, struct amount_sat, + &remoteconf->channel_reserve)); return false; } @@ -293,8 +302,8 @@ static bool check_config_bounds(struct state *state, /* We always set channel_reserve_satoshis to 1%, rounded up. */ static void set_reserve(struct state *state) { - state->localconf.channel_reserve_satoshis - = (state->funding_satoshis + 99) / 100; + state->localconf.channel_reserve.satoshis + = (state->funding.satoshis + 99) / 100; /* BOLT #2: * @@ -303,10 +312,10 @@ static void set_reserve(struct state *state) * - MUST set `channel_reserve_satoshis` greater than or equal to * `dust_limit_satoshis`. */ - if (state->localconf.channel_reserve_satoshis - < state->localconf.dust_limit_satoshis) - state->localconf.channel_reserve_satoshis - = state->localconf.dust_limit_satoshis; + if (amount_sat_greater(state->localconf.dust_limit, + state->localconf.channel_reserve)) + state->localconf.channel_reserve + = state->localconf.dust_limit; } /* 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, * or NULL if something goes wrong. */ static u8 *funder_channel(struct state *state, - u64 change_satoshis, u32 change_keyindex, + struct amount_sat change, + u32 change_keyindex, u8 channel_flags, struct utxo **utxos TAKES, 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. */ - 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, - "funding_satoshis must be < %s, not %"PRIu64, + "funding_satoshis must be < %s, not %s", type_to_string(tmpctx, struct amount_sat, &state->chainparams->max_funding), - state->funding_satoshis); + type_to_string(tmpctx, struct amount_sat, + &state->funding)); /* BOLT #2: * @@ -463,19 +474,21 @@ static u8 *funder_channel(struct state *state, * - MUST set `push_msat` to equal or less than 1000 * * `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, - "push-msat must be < %"PRIu64, - 1000 * state->funding_satoshis); + "push-msat must be < %s", + type_to_string(tmpctx, struct amount_sat, + &state->funding)); msg = towire_open_channel(NULL, &state->chainparams->genesis_blockhash, &state->channel_id, - state->funding_satoshis, state->push_msat, - state->localconf.dust_limit_satoshis, - state->localconf.max_htlc_value_in_flight_msat, - state->localconf.channel_reserve_satoshis, - state->localconf.htlc_minimum_msat, + state->funding.satoshis, + state->push_msat.millisatoshis, + state->localconf.dust_limit.satoshis, + state->localconf.max_htlc_value_in_flight.millisatoshis, + state->localconf.channel_reserve.satoshis, + state->localconf.htlc_minimum.millisatoshis, state->feerate_per_kw, state->localconf.to_self_delay, state->localconf.max_accepted_htlcs, @@ -505,12 +518,12 @@ static u8 *funder_channel(struct state *state, * valid DER-encoded compressed secp256k1 pubkeys. */ if (!fromwire_accept_channel(msg, &id_in, - &state->remoteconf.dust_limit_satoshis, + &state->remoteconf.dust_limit.satoshis, &state->remoteconf - .max_htlc_value_in_flight_msat, + .max_htlc_value_in_flight.millisatoshis, &state->remoteconf - .channel_reserve_satoshis, - &state->remoteconf.htlc_minimum_msat, + .channel_reserve.satoshis, + &state->remoteconf.htlc_minimum.millisatoshis, &minimum_depth, &state->remoteconf.to_self_delay, &state->remoteconf.max_accepted_htlcs, @@ -564,22 +577,26 @@ static u8 *funder_channel(struct state *state, * less than `dust_limit_satoshis`: * - MUST reject the channel. */ - if (state->remoteconf.channel_reserve_satoshis - < state->localconf.dust_limit_satoshis) { + if (amount_sat_greater(state->localconf.dust_limit, + state->remoteconf.channel_reserve)) { negotiation_failed(state, true, - "channel reserve %"PRIu64 - " would be below our dust %"PRIu64, - state->remoteconf.channel_reserve_satoshis, - state->localconf.dust_limit_satoshis); + "channel reserve %s" + " would be below our dust %s", + type_to_string(tmpctx, struct amount_sat, + &state->remoteconf.channel_reserve), + type_to_string(tmpctx, struct amount_sat, + &state->localconf.dust_limit)); goto fail; } - if (state->localconf.channel_reserve_satoshis - < state->remoteconf.dust_limit_satoshis) { + if (amount_sat_greater(state->remoteconf.dust_limit, + state->localconf.channel_reserve)) { negotiation_failed(state, true, - "dust limit %"PRIu64 - " would be above our reserve %"PRIu64, - state->remoteconf.dust_limit_satoshis, - state->localconf.channel_reserve_satoshis); + "dust limit %s" + " would be above our reserve %s", + type_to_string(tmpctx, struct amount_sat, + &state->remoteconf.dust_limit), + type_to_string(tmpctx, struct amount_sat, + &state->localconf.channel_reserve)); 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 * that. */ - if (change_satoshis) { + if (!amount_sat_eq(change, AMOUNT_SAT(0))) { changekey = tal(tmpctx, struct pubkey); if (!bip32_pubkey(bip32_base, changekey, change_keyindex)) status_failed(STATUS_FAIL_MASTER_IO, @@ -603,10 +620,10 @@ static u8 *funder_channel(struct state *state, */ funding = funding_tx(state, &state->funding_txout, cast_const2(const struct utxo **, utxos), - state->funding_satoshis, + state->funding.satoshis, &state->our_funding_pubkey, &their_funding_pubkey, - change_satoshis, changekey, + change.satoshis, changekey, bip32_base); bitcoin_txid(funding, &state->funding_txid); @@ -622,9 +639,9 @@ static u8 *funder_channel(struct state *state, &state->chainparams->genesis_blockhash, &state->funding_txid, state->funding_txout, - state->funding_satoshis, - state->funding_satoshis * 1000 - - state->push_msat, + state->funding.satoshis, + state->funding.satoshis * 1000 + - state->push_msat.millisatoshis, state->feerate_per_kw, &state->localconf, &state->remoteconf, @@ -805,7 +822,7 @@ static u8 *funder_channel(struct state *state, &their_funding_pubkey, &state->funding_txid, state->feerate_per_kw, - state->localconf.channel_reserve_satoshis); + state->localconf.channel_reserve.satoshis); fail: 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, &state->channel_id, - &state->funding_satoshis, &state->push_msat, - &state->remoteconf.dust_limit_satoshis, - &state->remoteconf.max_htlc_value_in_flight_msat, - &state->remoteconf.channel_reserve_satoshis, - &state->remoteconf.htlc_minimum_msat, + &state->funding.satoshis, + &state->push_msat.millisatoshis, + &state->remoteconf.dust_limit.satoshis, + &state->remoteconf.max_htlc_value_in_flight.millisatoshis, + &state->remoteconf.channel_reserve.satoshis, + &state->remoteconf.htlc_minimum.millisatoshis, &state->feerate_per_kw, &state->remoteconf.to_self_delay, &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` * 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, - "funding_satoshis %"PRIu64" too large", - state->funding_satoshis); + "funding_satoshis %s too large", + type_to_string(tmpctx, struct amount_sat, + &state->funding)); 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. */ - if (state->push_msat > state->funding_satoshis * 1000) { + if (amount_msat_greater_sat(state->push_msat, state->funding)) { peer_failed(&state->cs, &state->channel_id, - "Our push_msat %"PRIu64 - " would be too large for funding_satoshis %"PRIu64, - state->push_msat, state->funding_satoshis); + "Our push_msat %s" + " would be too large for funding_satoshis %s", + type_to_string(tmpctx, struct amount_msat, + &state->push_msat), + type_to_string(tmpctx, struct amount_sat, + &state->funding)); 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 * `channel_reserve_satoshis` from the `open_channel` message. */ - if (state->localconf.channel_reserve_satoshis - < state->remoteconf.dust_limit_satoshis) { + if (amount_sat_greater(state->remoteconf.dust_limit, + state->localconf.channel_reserve)) { negotiation_failed(state, false, - "Our channel reserve %"PRIu64 - " would be below their dust %"PRIu64, - state->localconf.channel_reserve_satoshis, - state->remoteconf.dust_limit_satoshis); + "Our channel reserve %s" + " would be below their dust %s", + type_to_string(tmpctx, struct amount_sat, + &state->localconf.channel_reserve), + type_to_string(tmpctx, struct amount_sat, + &state->remoteconf.dust_limit)); return NULL; } - if (state->localconf.dust_limit_satoshis - > state->remoteconf.channel_reserve_satoshis) { + if (amount_sat_greater(state->localconf.dust_limit, + state->remoteconf.channel_reserve)) { negotiation_failed(state, false, - "Our dust limit %"PRIu64 - " would be above their reserve %"PRIu64, - state->localconf.dust_limit_satoshis, - state->remoteconf.channel_reserve_satoshis); + "Our dust limit %s" + " would be above their reserve %s", + type_to_string(tmpctx, struct amount_sat, + &state->localconf.dust_limit), + type_to_string(tmpctx, struct amount_sat, + &state->remoteconf.channel_reserve)); return NULL; } @@ -965,11 +991,11 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* OK, we accept! */ msg = towire_accept_channel(NULL, &state->channel_id, - state->localconf.dust_limit_satoshis, + state->localconf.dust_limit.satoshis, state->localconf - .max_htlc_value_in_flight_msat, - state->localconf.channel_reserve_satoshis, - state->localconf.htlc_minimum_msat, + .max_htlc_value_in_flight.millisatoshis, + state->localconf.channel_reserve.satoshis, + state->localconf.htlc_minimum.millisatoshis, state->minimum_depth, state->localconf.to_self_delay, state->localconf.max_accepted_htlcs, @@ -1018,8 +1044,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &chain_hash, &state->funding_txid, state->funding_txout, - state->funding_satoshis, - state->push_msat, + state->funding.satoshis, + state->push_msat.millisatoshis, state->feerate_per_kw, &state->localconf, &state->remoteconf, @@ -1139,12 +1165,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &their_funding_pubkey, &state->funding_txid, state->funding_txout, - state->funding_satoshis, - state->push_msat, + state->funding.satoshis, + state->push_msat.millisatoshis, channel_flags, state->feerate_per_kw, msg, - state->localconf.channel_reserve_satoshis); + state->localconf.channel_reserve.satoshis); } /*~ 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); enum opening_wire_type t = fromwire_peektype(msg); - u64 change_satoshis; + struct amount_sat change; u32 change_keyindex; u8 channel_flags; struct utxo **utxos; @@ -1281,16 +1307,17 @@ static u8 *handle_master_in(struct state *state) switch (t) { case WIRE_OPENING_FUNDER: if (!fromwire_opening_funder(state, msg, - &state->funding_satoshis, - &state->push_msat, + &state->funding.satoshis, + &state->push_msat.millisatoshis, &state->feerate_per_kw, - &change_satoshis, &change_keyindex, + &change.satoshis, + &change_keyindex, &channel_flags, &utxos, &bip32_base)) master_badmsg(WIRE_OPENING_FUNDER, msg); msg = funder_channel(state, - change_satoshis, + change, change_keyindex, channel_flags, take(utxos), &bip32_base); return msg; @@ -1340,7 +1367,7 @@ int main(int argc, char *argv[]) &chain_hash, &state->localconf, &state->max_to_self_delay, - &state->min_effective_htlc_capacity_msat, + &state->min_effective_htlc_capacity.millisatoshis, &state->cs, &state->our_points, &state->our_funding_pubkey, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 394f95d0e..6175c8fca 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -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); CHECK(w); - cc1->dust_limit_satoshis = 1; - cc1->max_htlc_value_in_flight_msat = 2; - cc1->channel_reserve_satoshis = 3; - cc1->htlc_minimum_msat = 4; + cc1->dust_limit.satoshis = 1; + cc1->max_htlc_value_in_flight.millisatoshis = 2; + cc1->channel_reserve.satoshis = 3; + cc1->htlc_minimum.millisatoshis = 4; cc1->to_self_delay = 5; cc1->max_accepted_htlcs = 6; diff --git a/wallet/wallet.c b/wallet/wallet.c index 8fc8ba13f..54650ede0 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -868,10 +868,10 @@ static void wallet_channel_config_save(struct wallet *w, " to_self_delay=?," " max_accepted_htlcs=?" " WHERE id=?;"); - sqlite3_bind_int64(stmt, 1, cc->dust_limit_satoshis); - sqlite3_bind_int64(stmt, 2, cc->max_htlc_value_in_flight_msat); - sqlite3_bind_int64(stmt, 3, cc->channel_reserve_satoshis); - sqlite3_bind_int64(stmt, 4, cc->htlc_minimum_msat); + sqlite3_bind_amount_sat(stmt, 1, cc->dust_limit); + sqlite3_bind_amount_msat(stmt, 2, cc->max_htlc_value_in_flight); + sqlite3_bind_amount_sat(stmt, 3, cc->channel_reserve); + sqlite3_bind_amount_msat(stmt, 4, cc->htlc_minimum); sqlite3_bind_int(stmt, 5, cc->to_self_delay); sqlite3_bind_int(stmt, 6, cc->max_accepted_htlcs); sqlite3_bind_int64(stmt, 7, cc->id); @@ -893,10 +893,10 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id, return false; } cc->id = id; - cc->dust_limit_satoshis = sqlite3_column_int64(stmt, col++); - cc->max_htlc_value_in_flight_msat = sqlite3_column_int64(stmt, col++); - cc->channel_reserve_satoshis = sqlite3_column_int64(stmt, col++); - cc->htlc_minimum_msat = sqlite3_column_int64(stmt, col++); + cc->dust_limit = sqlite3_column_amount_sat(stmt, col++); + cc->max_htlc_value_in_flight = sqlite3_column_amount_msat(stmt, col++); + cc->channel_reserve = sqlite3_column_amount_sat(stmt, col++); + cc->htlc_minimum = sqlite3_column_amount_msat(stmt, col++); cc->to_self_delay = sqlite3_column_int(stmt, col++); cc->max_accepted_htlcs = sqlite3_column_int(stmt, col++); assert(col == 7);