diff --git a/bitcoin/chainparams.c b/bitcoin/chainparams.c index fe4a1c64537e..68d465587941 100644 --- a/bitcoin/chainparams.c +++ b/bitcoin/chainparams.c @@ -3,6 +3,21 @@ #include #include +/* BOLT #2: + * + * The sending node: + *... + * - MUST set `funding_satoshis` to less than 2^24 satoshi. + */ +#define MAX_FUNDING_SATOSHI ((1 << 24) - 1) + +/* BOLT #2: + * + * - for channels with `chain_hash` identifying the Bitcoin blockchain: + * - MUST set the four most significant bytes of `amount_msat` to 0. + */ +#define MAX_PAYMENT_MSAT 0xFFFFFFFFULL + const struct chainparams networks[] = { {.index = 0, .network_name = "bitcoin", @@ -12,6 +27,8 @@ const struct chainparams networks[] = { .cli = "bitcoin-cli", .cli_args = NULL, .dust_limit = 546, + .max_funding_satoshi = MAX_FUNDING_SATOSHI, + .max_payment_msat = MAX_PAYMENT_MSAT, /* "Lightning Charge Powers Developers & Blockstream Store" */ .when_lightning_became_cool = 504500, .testnet = false}, @@ -23,6 +40,8 @@ const struct chainparams networks[] = { .cli = "bitcoin-cli", .cli_args = "-regtest", .dust_limit = 546, + .max_funding_satoshi = MAX_FUNDING_SATOSHI, + .max_payment_msat = MAX_PAYMENT_MSAT, .when_lightning_became_cool = 1, .testnet = true}, {.index = 2, @@ -33,6 +52,8 @@ const struct chainparams networks[] = { .cli = "bitcoin-cli", .cli_args = "-testnet", .dust_limit = 546, + .max_funding_satoshi = MAX_FUNDING_SATOSHI, + .max_payment_msat = MAX_PAYMENT_MSAT, .testnet = true}, {.index = 3, .network_name = "litecoin", @@ -42,6 +63,8 @@ const struct chainparams networks[] = { .cli = "litecoin-cli", .cli_args = NULL, .dust_limit = 100000, + .max_funding_satoshi = 60 * MAX_FUNDING_SATOSHI, + .max_payment_msat = 60 * MAX_PAYMENT_MSAT, .when_lightning_became_cool = 1320000, .testnet = false}, {.index = 4, @@ -52,6 +75,8 @@ const struct chainparams networks[] = { .cli = "litecoin-cli", .cli_args = "-testnet", .dust_limit = 100000, + .max_funding_satoshi = 60 * MAX_FUNDING_SATOSHI, + .max_payment_msat = 60 * MAX_PAYMENT_MSAT, .when_lightning_became_cool = 1, .testnet = true} }; @@ -84,3 +109,13 @@ const struct chainparams *chainparams_by_bip173(const char *bip173_name) } return NULL; } + +const struct chainparams *chainparams_by_hash(const struct bitcoin_blkid *hash) +{ + for (size_t i = 0; i < ARRAY_SIZE(networks); i++) { + if (bitcoin_blkid_eq(hash, &networks[i].genesis_blockhash)) { + return &networks[i]; + } + } + return NULL; +} diff --git a/bitcoin/chainparams.h b/bitcoin/chainparams.h index 92a0d2d6dc32..c2914bcd17ba 100644 --- a/bitcoin/chainparams.h +++ b/bitcoin/chainparams.h @@ -15,6 +15,8 @@ struct chainparams { const char *cli; const char *cli_args; const u64 dust_limit; + const u64 max_funding_satoshi; + const u64 max_payment_msat; const u32 when_lightning_became_cool; /* Whether this is a test network or not */ @@ -40,4 +42,9 @@ const struct chainparams *chainparams_by_index(const int index); * This lets us decode BOLT11 addresses. */ const struct chainparams *chainparams_by_bip173(const char *bip173_name); + +/** + * chainparams_by_hash - Helper to get a network by its genesis blockhash + */ +const struct chainparams *chainparams_by_hash(const struct bitcoin_blkid *hash); #endif /* LIGHTNING_BITCOIN_CHAINPARAMS_H */ diff --git a/channeld/channeld.c b/channeld/channeld.c index 7441c06ccccd..e20b5ffe8641 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -99,6 +99,7 @@ struct peer { u64 htlc_id; struct bitcoin_blkid chain_hash; + const struct chainparams *chain_params; struct channel_id channel_id; struct channel *channel; @@ -539,7 +540,8 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg) &peer->channel_id, "Bad peer_add_htlc %s", tal_hex(msg, msg)); - add_err = channel_add_htlc(peer->channel, REMOTE, id, amount_msat, + add_err = channel_add_htlc(peer->channel, peer->chain_params, + REMOTE, id, amount_msat, cltv_expiry, &payment_hash, onion_routing_packet, &htlc); if (add_err != CHANNEL_ERR_ADD_OK) @@ -2278,7 +2280,8 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) onion_routing_packet)) master_badmsg(WIRE_CHANNEL_OFFER_HTLC, inmsg); - e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id, + e = channel_add_htlc(peer->channel, peer->chain_params, + LOCAL, peer->htlc_id, amount_msat, cltv_expiry, &payment_hash, onion_routing_packet, NULL); status_trace("Adding HTLC %"PRIu64" msat=%"PRIu64" cltv=%u gave %s", @@ -2603,6 +2606,18 @@ static void init_channel(struct peer *peer) feerate_per_kw[LOCAL], feerate_per_kw[REMOTE], peer->feerate_min, peer->feerate_max); + /* BOLT #2: + * + * The receiver: + * - if the `chain_hash` value... is set to a hash of a chain that is + * unknown to the receiver: + * - MUST reject the channel. + */ + peer->chain_params = chainparams_by_hash(&peer->chain_hash); + if (peer->chain_params == NULL) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Unknown genesis blockhash"); + /* First commit is used for opening: if we've sent 0, we're on * index 1. */ assert(peer->next_index[LOCAL] > 0); @@ -2624,7 +2639,8 @@ static void init_channel(struct peer *peer) &funding_pubkey[REMOTE], funder); - if (!channel_force_htlcs(peer->channel, htlcs, hstates, + if (!channel_force_htlcs(peer->channel, peer->chain_params, + htlcs, hstates, fulfilled, fulfilled_sides, cast_const2(const struct failed_htlc **, failed), diff --git a/channeld/full_channel.c b/channeld/full_channel.c index e8b395a41240..e50394f9504d 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -284,6 +284,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, } static enum channel_add_err add_htlc(struct channel *channel, + const struct chainparams *chain_params, enum htlc_state state, u64 id, u64 msatoshi, u32 cltv_expiry, const struct sha256 *payment_hash, @@ -359,7 +360,7 @@ static enum channel_add_err add_htlc(struct channel *channel, * - for channels with `chain_hash` identifying the Bitcoin blockchain: * - MUST set the four most significant bytes of `amount_msat` to 0. */ - if (htlc->msatoshi & 0xFFFFFFFF00000000ULL) { + if (htlc->msatoshi > chain_params->max_payment_msat) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } @@ -465,6 +466,7 @@ static enum channel_add_err add_htlc(struct channel *channel, } enum channel_add_err channel_add_htlc(struct channel *channel, + const struct chainparams *chain_params, enum side sender, u64 id, u64 msatoshi, @@ -481,7 +483,7 @@ enum channel_add_err channel_add_htlc(struct channel *channel, state = RCVD_ADD_HTLC; /* FIXME: check expiry etc. against config. */ - return add_htlc(channel, state, id, msatoshi, cltv_expiry, + return add_htlc(channel, chain_params, state, id, msatoshi, cltv_expiry, payment_hash, routing, htlcp, true); } @@ -919,6 +921,7 @@ static bool adjust_balance(struct channel *channel, struct htlc *htlc) } bool channel_force_htlcs(struct channel *channel, + const struct chainparams *chain_params, const struct added_htlc *htlcs, const enum htlc_state *hstates, const struct fulfilled_htlc *fulfilled, @@ -958,7 +961,7 @@ bool channel_force_htlcs(struct channel *channel, type_to_string(tmpctx, struct sha256, &htlcs[i].payment_hash)); - e = add_htlc(channel, hstates[i], + e = add_htlc(channel, chain_params, hstates[i], htlcs[i].id, htlcs[i].amount_msat, htlcs[i].cltv_expiry, &htlcs[i].payment_hash, diff --git a/channeld/full_channel.h b/channeld/full_channel.h index b8ef156c8860..626a0fa7a6d4 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -2,6 +2,7 @@ #ifndef LIGHTNING_CHANNELD_FULL_CHANNEL_H #define LIGHTNING_CHANNELD_FULL_CHANNEL_H #include "config.h" +#include #include #include #include @@ -81,6 +82,7 @@ u32 actual_feerate(const struct channel *channel, /** * channel_add_htlc: append an HTLC to channel if it can afford it * @channel: The channel + * @chain_params: parameters of the target blockchain * @offerer: the side offering the HTLC (to the other side). * @id: unique HTLC id. * @msatoshi: amount in millisatoshi. @@ -94,6 +96,7 @@ u32 actual_feerate(const struct channel *channel, * is changed. */ enum channel_add_err channel_add_htlc(struct channel *channel, + const struct chainparams *chain_params, enum side sender, u64 id, u64 msatoshi, @@ -223,6 +226,7 @@ size_t num_channel_htlcs(const struct channel *channel); /** * channel_force_htlcs: force these htlcs into the (new) channel * @channel: the channel + * @chain_params: parameters of the target blockchain * @htlcs: the htlcs to add (tal_arr) * @hstates: the states for the htlcs (tal_arr of same size) * @fulfilled: htlcs of those which are fulfilled @@ -233,6 +237,7 @@ size_t num_channel_htlcs(const struct channel *channel); * This is used for restoring a channel state. */ bool channel_force_htlcs(struct channel *channel, + const struct chainparams *chain_params, const struct added_htlc *htlcs, const enum htlc_state *hstates, const struct fulfilled_htlc *fulfilled, diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 58e8bb3914ba..dab5c04d5736 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -143,8 +143,10 @@ static const struct htlc **include_htlcs(struct channel *channel, enum side side memset(&preimage, i, sizeof(preimage)); sha256(&hash, &preimage, sizeof(preimage)); - e = channel_add_htlc(channel, sender, i, msatoshi, 500+i, &hash, - dummy_routing, NULL); + e = channel_add_htlc(channel, + chainparams_for_network("bitcoin"), + sender, i, msatoshi, 500+i, + &hash, dummy_routing, NULL); assert(e == CHANNEL_ERR_ADD_OK); htlcs[i] = channel_get_htlc(channel, sender, i); } @@ -235,8 +237,10 @@ static void send_and_fulfill_htlc(struct channel *channel, memset(&r, 0, sizeof(r)); sha256(&rhash, &r, sizeof(r)); - assert(channel_add_htlc(channel, sender, 1337, msatoshi, 900, &rhash, - dummy_routing, NULL) == CHANNEL_ERR_ADD_OK); + assert(channel_add_htlc(channel, + chainparams_for_network("bitcoin"), + sender, 1337, msatoshi, 900, + &rhash, dummy_routing, NULL) == CHANNEL_ERR_ADD_OK); changed_htlcs = tal_arr(channel, const struct htlc *, 0); diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index b03b9120d683..42f0b819a25a 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -766,6 +766,7 @@ static void json_fund_channel(struct command *cmd, struct channel *channel; u32 *feerate_per_kw; u8 *msg; + u64 max_funding_satoshi = get_chainparams(cmd->ld)->max_funding_satoshi; fc->cmd = cmd; fc->uc = NULL; @@ -777,7 +778,7 @@ static void json_fund_channel(struct command *cmd, NULL)) return; - if (!json_tok_wtx(&fc->wtx, buffer, sattok, MAX_FUNDING_SATOSHI)) + if (!json_tok_wtx(&fc->wtx, buffer, sattok, max_funding_satoshi)) return; if (!feerate_per_kw) { @@ -820,7 +821,7 @@ static void json_fund_channel(struct command *cmd, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN)) return; - assert(fc->wtx.amount <= MAX_FUNDING_SATOSHI); + assert(fc->wtx.amount <= max_funding_satoshi); peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc); fc->uc = peer->uncommitted_channel; diff --git a/openingd/openingd.c b/openingd/openingd.c index 0aab661fbe52..5dce403dee69 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -353,9 +353,10 @@ static u8 *funder_channel(struct state *state, temporary_channel_id(&state->channel_id); - if (state->funding_satoshis > MAX_FUNDING_SATOSHI) + if (state->funding_satoshis > state->chainparams->max_funding_satoshi) status_failed(STATUS_FAIL_MASTER_IO, - "funding_satoshis must be < 2^24, not %"PRIu64, + "funding_satoshis must be < %"PRIu64", not %"PRIu64, + state->chainparams->max_funding_satoshi, state->funding_satoshis); /* BOLT #2: @@ -721,7 +722,7 @@ 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 > MAX_FUNDING_SATOSHI) { + if (state->funding_satoshis > state->chainparams->max_funding_satoshi) { negotiation_failed(state, false, "funding_satoshis %"PRIu64" too large", state->funding_satoshis); diff --git a/wire/peer_wire.h b/wire/peer_wire.h index e1d68029d256..28dd4cec43cf 100644 --- a/wire/peer_wire.h +++ b/wire/peer_wire.h @@ -29,12 +29,4 @@ bool extract_channel_id(const u8 *in_pkt, struct channel_id *channel_id); * the network, as detailed within [BOLT #7] */ #define CHANNEL_FLAGS_ANNOUNCE_CHANNEL 1 - -/* BOLT #2: - * - * The sending node: - *... - * - MUST set `funding_satoshis` to less than 2^24 satoshi. - */ -#define MAX_FUNDING_SATOSHI ((1 << 24) - 1) #endif /* LIGHTNING_WIRE_PEER_WIRE_H */