diff --git a/bitcoin/chainparams.c b/bitcoin/chainparams.c index fe4a1c64537e..ed0716b1cabc 100644 --- a/bitcoin/chainparams.c +++ b/bitcoin/chainparams.c @@ -4,54 +4,65 @@ #include const struct chainparams networks[] = { - {.index = 0, - .network_name = "bitcoin", + {.network_name = "bitcoin", .bip173_name = "bc", .genesis_blockhash = {{{.u.u8 = {0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00}}}}, .rpc_port = 8332, .cli = "bitcoin-cli", .cli_args = NULL, .dust_limit = 546, + /* BOLT #2: + * + * The sending node: + *... + * - MUST set `funding_satoshis` to less than 2^24 satoshi. + */ + .max_funding_satoshi = (1 << 24) - 1, + .max_payment_msat = 0xFFFFFFFFULL, /* "Lightning Charge Powers Developers & Blockstream Store" */ .when_lightning_became_cool = 504500, .testnet = false}, - {.index = 1, - .network_name = "regtest", + {.network_name = "regtest", .bip173_name = "bcrt", .genesis_blockhash = {{{.u.u8 = {0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f}}}}, .rpc_port = 18332, .cli = "bitcoin-cli", .cli_args = "-regtest", .dust_limit = 546, + .max_funding_satoshi = (1 << 24) - 1, + .max_payment_msat = 0xFFFFFFFFULL, .when_lightning_became_cool = 1, .testnet = true}, - {.index = 2, - .network_name = "testnet", + {.network_name = "testnet", .bip173_name = "tb", .genesis_blockhash = {{{.u.u8 = {0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00}}}}, .rpc_port = 18332, .cli = "bitcoin-cli", .cli_args = "-testnet", .dust_limit = 546, + .max_funding_satoshi = (1 << 24) - 1, + .max_payment_msat = 0xFFFFFFFFULL, .testnet = true}, - {.index = 3, - .network_name = "litecoin", + {.network_name = "litecoin", .bip173_name = "ltc", .genesis_blockhash = {{{.u.u8 = {0xe2, 0xbf, 0x04, 0x7e, 0x7e, 0x5a, 0x19, 0x1a, 0xa4, 0xef, 0x34, 0xd3, 0x14, 0x97, 0x9d, 0xc9, 0x98, 0x6e, 0x0f, 0x19, 0x25, 0x1e, 0xda, 0xba, 0x59, 0x40, 0xfd, 0x1f, 0xe3, 0x65, 0xa7, 0x12 }}}}, .rpc_port = 9332, .cli = "litecoin-cli", .cli_args = NULL, .dust_limit = 100000, + .max_funding_satoshi = 60 * ((1 << 24) - 1), + .max_payment_msat = 60 * 0xFFFFFFFFULL, .when_lightning_became_cool = 1320000, .testnet = false}, - {.index = 4, - .network_name = "litecoin-testnet", + {.network_name = "litecoin-testnet", .bip173_name = "tltc", .genesis_blockhash = {{{.u.u8 = { 0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6, 0xe6, 0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f, 0x57, 0x88, 0x0d, 0x1a, 0x21, 0x56, 0x9e, 0x13, 0xee, 0xfd, 0xd9, 0x51, 0x28, 0x4b, 0x5a, 0x62, 0x66, 0x49 }}}}, .rpc_port = 19332, .cli = "litecoin-cli", .cli_args = "-testnet", .dust_limit = 100000, + .max_funding_satoshi = 60 * ((1 << 24) - 1), + .max_payment_msat = 60 * 0xFFFFFFFFULL, .when_lightning_became_cool = 1, .testnet = true} }; @@ -66,13 +77,14 @@ const struct chainparams *chainparams_for_network(const char *network_name) return NULL; } -const struct chainparams *chainparams_by_index(const int index) +const struct chainparams *chainparams_by_chainhash(const struct bitcoin_blkid *chain_hash) { - if (index >= ARRAY_SIZE(networks) || index < 0) { - return NULL; - } else { - return &networks[index]; + for (size_t i = 0; i < ARRAY_SIZE(networks); i++) { + if (bitcoin_blkid_eq(chain_hash, &networks[i].genesis_blockhash)) { + return &networks[i]; + } } + return NULL; } const struct chainparams *chainparams_by_bip173(const char *bip173_name) diff --git a/bitcoin/chainparams.h b/bitcoin/chainparams.h index 92a0d2d6dc32..44e762101747 100644 --- a/bitcoin/chainparams.h +++ b/bitcoin/chainparams.h @@ -7,7 +7,6 @@ #include struct chainparams { - const int index; const char *network_name; const char *bip173_name; const struct bitcoin_blkid genesis_blockhash; @@ -15,6 +14,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 */ @@ -26,18 +27,16 @@ struct chainparams { */ const struct chainparams *chainparams_for_network(const char *network_name); -/** - * chainparams_by_index - Helper to get a network by its numeric index - * - * We may not want to pass the network name through to subdaemons, so - * we allows lookup by index. - */ -const struct chainparams *chainparams_by_index(const int index); - /** * chainparams_by_bip173 - Helper to get a network by its bip173 name * * This lets us decode BOLT11 addresses. */ const struct chainparams *chainparams_by_bip173(const char *bip173_name); + +/** + * chainparams_by_chainhash - Helper to get a network by its genesis blockhash + */ +const struct chainparams *chainparams_by_chainhash(const struct bitcoin_blkid *chain_hash); + #endif /* LIGHTNING_BITCOIN_CHAINPARAMS_H */ diff --git a/channeld/channeld.c b/channeld/channeld.c index 7441c06ccccd..028228ac4ba0 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -2614,7 +2614,9 @@ static void init_channel(struct peer *peer) /* channel_id is set from funding txout */ derive_channel_id(&peer->channel_id, &funding_txid, funding_txout); - peer->channel = new_full_channel(peer, &funding_txid, funding_txout, + peer->channel = new_full_channel(peer, + &peer->chain_hash, + &funding_txid, funding_txout, funding_satoshi, local_msatoshi, feerate_per_kw, diff --git a/channeld/full_channel.c b/channeld/full_channel.c index e8b395a41240..98a22b5f8e19 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -22,6 +23,7 @@ #include "gen_full_channel_error_names.h" struct channel *new_full_channel(const tal_t *ctx, + const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u64 funding_satoshis, @@ -35,7 +37,9 @@ struct channel *new_full_channel(const tal_t *ctx, const struct pubkey *remote_funding_pubkey, enum side funder) { - struct channel *channel = new_initial_channel(ctx, funding_txid, + struct channel *channel = new_initial_channel(ctx, + chain_hash, + funding_txid, funding_txout, funding_satoshis, local_msatoshi, @@ -359,7 +363,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 > channel->chainparams->max_payment_msat) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } diff --git a/channeld/full_channel.h b/channeld/full_channel.h index b8ef156c8860..103de0a8f145 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -27,6 +27,7 @@ * Returns state, or NULL if malformed. */ struct channel *new_full_channel(const tal_t *ctx, + const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u64 funding_satoshis, diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 58e8bb3914ba..f8098acf1e34 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -336,6 +336,7 @@ int main(void) const struct htlc **htlc_map, **htlcs; const u8 *funding_wscript, **wscripts; size_t i; + const struct chainparams *chainparams = chainparams_for_network("bitcoin"); secp256k1_ctx = wally_get_secp_context(); setup_tmpctx(); @@ -443,7 +444,9 @@ int main(void) to_local_msat = 7000000000; to_remote_msat = 3000000000; feerate_per_kw[LOCAL] = feerate_per_kw[REMOTE] = 15000; - lchannel = new_full_channel(tmpctx, &funding_txid, funding_output_index, + lchannel = new_full_channel(tmpctx, + &chainparams->genesis_blockhash, + &funding_txid, funding_output_index, funding_amount_satoshi, to_local_msat, feerate_per_kw, local_config, @@ -452,7 +455,9 @@ int main(void) &local_funding_pubkey, &remote_funding_pubkey, LOCAL); - rchannel = new_full_channel(tmpctx, &funding_txid, funding_output_index, + rchannel = new_full_channel(tmpctx, + &chainparams->genesis_blockhash, + &funding_txid, funding_output_index, funding_amount_satoshi, to_remote_msat, feerate_per_kw, remote_config, diff --git a/common/initial_channel.c b/common/initial_channel.c index f2ad81c18004..ad65ec591c9f 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -8,6 +9,7 @@ #include struct channel *new_initial_channel(const tal_t *ctx, + const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u64 funding_satoshis, @@ -58,6 +60,9 @@ struct channel *new_initial_channel(const tal_t *ctx, channel->commitment_number_obscurer = commit_number_obscurer(&channel->basepoints[funder].payment, &channel->basepoints[!funder].payment); + channel->chainparams = chainparams_by_chainhash(chain_hash); + if (channel->chainparams == NULL) + return tal_free(channel); return channel; } diff --git a/common/initial_channel.h b/common/initial_channel.h index 9ea5df5732b1..a3ad474545c7 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -57,6 +57,9 @@ struct channel { /* What it looks like to each side. */ struct channel_view view[NUM_SIDES]; + + /* Chain params to check against */ + const struct chainparams *chainparams; }; /* Some requirements are self-specified (eg. my dust limit), others @@ -125,6 +128,7 @@ static inline u16 to_self_delay(const struct channel *channel, enum side side) /** * new_initial_channel: Given initial fees and funding, what is initial state? * @ctx: tal context to allocate return value from. + * @chain_hash: Which blockchain are we talking about? * @funding_txid: The commitment transaction id. * @funding_txout: The commitment transaction output number. * @funding_satoshis: The commitment transaction amount. @@ -142,6 +146,7 @@ static inline u16 to_self_delay(const struct channel *channel, enum side side) * Returns channel, or NULL if malformed. */ struct channel *new_initial_channel(const tal_t *ctx, + const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u64 funding_satoshis, diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index b03b9120d683..8d43890843b8 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -730,7 +730,8 @@ void peer_start_openingd(struct peer *peer, */ uc->minimum_depth = peer->ld->config.anchor_confirms; - msg = towire_opening_init(NULL, get_chainparams(peer->ld)->index, + msg = towire_opening_init(NULL, + &get_chainparams(peer->ld)->genesis_blockhash, &uc->our_config, max_to_self_delay, min_effective_htlc_capacity_msat, @@ -766,6 +767,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 +779,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 +822,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/opening_wire.csv b/openingd/opening_wire.csv index 51ae367777ba..5a25577c5b35 100644 --- a/openingd/opening_wire.csv +++ b/openingd/opening_wire.csv @@ -3,8 +3,8 @@ #include opening_init,6000 -# Which network are we configured for (as index into the chainparams)? -opening_init,,network_index,u32 +# Which network are we configured for? +opening_init,,chain_hash,struct bitcoin_blkid # Base configuration we'll offer (channel reserve will vary with amount) opening_init,,our_config,struct channel_config # Minimum/maximum configuration values we'll accept diff --git a/openingd/openingd.c b/openingd/openingd.c index 0aab661fbe52..b17e0eea3b89 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: @@ -503,6 +504,7 @@ static u8 *funder_channel(struct state *state, bitcoin_txid(funding, &state->funding_txid); state->channel = new_initial_channel(state, + &state->chainparams->genesis_blockhash, &state->funding_txid, state->funding_txout, state->funding_satoshis, @@ -721,7 +723,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); @@ -842,6 +844,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) type_to_string(msg, struct channel_id, &id_in)); state->channel = new_initial_channel(state, + &chain_hash, &state->funding_txid, state->funding_txout, state->funding_satoshis, @@ -1092,7 +1095,7 @@ int main(int argc, char *argv[]) u8 *msg, *inner; struct pollfd pollfd[3]; struct state *state = tal(NULL, struct state); - u32 network_index; + struct bitcoin_blkid chain_hash; struct secret *none; subdaemon_setup(argc, argv); @@ -1101,7 +1104,7 @@ int main(int argc, char *argv[]) msg = wire_sync_read(tmpctx, REQ_FD); if (!fromwire_opening_init(tmpctx, msg, - &network_index, + &chain_hash, &state->localconf, &state->max_to_self_delay, &state->min_effective_htlc_capacity_msat, @@ -1122,7 +1125,7 @@ int main(int argc, char *argv[]) fail_if_all_error(inner); } - state->chainparams = chainparams_by_index(network_index); + state->chainparams = chainparams_by_chainhash(&chain_hash); /* Initially we're not associated with a channel, but * handle_peer_gossip_or_error wants this. */ memset(&state->channel_id, 0, sizeof(state->channel_id)); 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 */