Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions bitcoin/chainparams.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
#include <ccan/str/str.h>
#include <string.h>

/* 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",
Expand All @@ -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},
Expand All @@ -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,
Expand All @@ -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",
Expand All @@ -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,
Expand All @@ -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}
};
Expand Down Expand Up @@ -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;
}
7 changes: 7 additions & 0 deletions bitcoin/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */
22 changes: 19 additions & 3 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand All @@ -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),
Expand Down
9 changes: 6 additions & 3 deletions channeld/full_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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,
Expand All @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions channeld/full_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#ifndef LIGHTNING_CHANNELD_FULL_CHANNEL_H
#define LIGHTNING_CHANNELD_FULL_CHANNEL_H
#include "config.h"
#include <bitcoin/chainparams.h>
#include <channeld/channeld_htlc.h>
#include <channeld/full_channel_error.h>
#include <common/initial_channel.h>
Expand Down Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down
12 changes: 8 additions & 4 deletions channeld/test/run-full_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions lightningd/opening_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions openingd/openingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 0 additions & 8 deletions wire/peer_wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike removing spec quotes (our build checks they're valid, so if spec changes we know where to fix): can we move this into chainparams.c, and then use this value there?

#endif /* LIGHTNING_WIRE_PEER_WIRE_H */