bitcoin/chainparams.h: Split BIP173 name into onchain and Lightning HRPs.

Fixes: #4937
This commit is contained in:
ZmnSCPxj jxPCSnmZ 2021-11-29 15:10:06 +08:00 committed by Rusty Russell
parent 3af15d2f5e
commit d088288daa
11 changed files with 51 additions and 39 deletions

View File

@ -27,7 +27,8 @@ static u8 liquid_regtest_fee_asset[] = {
const struct chainparams networks[] = {
{.network_name = "bitcoin",
.bip173_name = "bc",
.onchain_hrp = "bc",
.lightning_hrp = "bc",
.bip70_name = "main",
.genesis_blockhash = {{{.u.u8 = {0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3,
0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63,
@ -57,7 +58,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_MAIN_PRIVATE},
.is_elements = false},
{.network_name = "regtest",
.bip173_name = "bcrt",
.onchain_hrp = "bcrt",
.lightning_hrp = "bcrt",
.bip70_name = "regtest",
.genesis_blockhash = {{{.u.u8 = {0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b,
0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb,
@ -80,7 +82,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_TEST_PRIVATE},
.is_elements = false},
{.network_name = "signet",
.bip173_name = "tb",
.onchain_hrp = "tb",
.lightning_hrp = "tbs",
.bip70_name = "signet",
// 00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6
.genesis_blockhash = {{{.u.u8 = {0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80,
@ -103,7 +106,8 @@ const struct chainparams networks[] = {
.is_elements = false,
},
{.network_name = "testnet",
.bip173_name = "tb",
.onchain_hrp = "tb",
.lightning_hrp = "tb",
.bip70_name = "test",
.genesis_blockhash = {{{.u.u8 = {0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95,
0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
@ -125,7 +129,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_TEST_PRIVATE},
.is_elements = false},
{.network_name = "litecoin",
.bip173_name = "ltc",
.onchain_hrp = "ltc",
.lightning_hrp = "ltc",
.bip70_name = "main",
.genesis_blockhash = {{{.u.u8 = {0xe2, 0xbf, 0x04, 0x7e, 0x7e, 0x5a, 0x19,
0x1a, 0xa4, 0xef, 0x34, 0xd3, 0x14, 0x97,
@ -148,7 +153,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_MAIN_PRIVATE},
.is_elements = false},
{.network_name = "litecoin-testnet",
.bip173_name = "tltc",
.onchain_hrp = "tltc",
.lightning_hrp = "tltc",
.bip70_name = "test",
.genesis_blockhash = {{{.u.u8 = {0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6,
0xe6, 0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f,
@ -171,7 +177,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_TEST_PRIVATE},
.is_elements = false},
{.network_name = "liquid-regtest",
.bip173_name = "ert",
.onchain_hrp = "ert",
.lightning_hrp = "ert",
.bip70_name = "liquid-regtest",
.genesis_blockhash = {{{.u.u8 = {0x9f, 0x87, 0xeb, 0x58, 0x0b, 0x9e, 0x5f,
0x11, 0xdc, 0x21, 0x1e, 0x9f, 0xb6, 0x6a,
@ -193,7 +200,8 @@ const struct chainparams networks[] = {
.bip32_privkey_version = BIP32_VER_TEST_PRIVATE},
.is_elements = true},
{.network_name = "liquid",
.bip173_name = "ex",
.onchain_hrp = "ex",
.lightning_hrp = "ex",
.bip70_name = "liquidv1",
.genesis_blockhash = {{{.u.u8 = {0x14, 0x66, 0x27, 0x58, 0x36, 0x22, 0x0d,
0xb2, 0x94, 0x4c, 0xa0, 0x59, 0xa3, 0xa1,
@ -236,10 +244,10 @@ const struct chainparams *chainparams_by_chainhash(const struct bitcoin_blkid *c
return NULL;
}
const struct chainparams *chainparams_by_bip173(const char *bip173_name)
const struct chainparams *chainparams_by_lightning_hrp(const char *lightning_hrp)
{
for (size_t i = 0; i < ARRAY_SIZE(networks); i++) {
if (streq(bip173_name, networks[i].bip173_name)) {
if (streq(lightning_hrp, networks[i].lightning_hrp)) {
return &networks[i];
}
}

View File

@ -10,7 +10,13 @@
struct chainparams {
const char *network_name;
const char *bip173_name;
/* Unfortunately starting with signet, we now have diverging
* conventions for the "BIP173" Human Readable Part (HRP).
* On onchain signet, the HRP is `tb` , but on Lightning
* signet the HRP is `tbs`.
*/
const char *onchain_hrp;
const char *lightning_hrp;
/*'bip70_name' is corresponding to the 'chain' field of
* the API 'getblockchaininfo' */
const char *bip70_name;
@ -46,7 +52,7 @@ const struct chainparams *chainparams_for_network(const char *network_name);
*
* This lets us decode BOLT11 addresses.
*/
const struct chainparams *chainparams_by_bip173(const char *bip173_name);
const struct chainparams *chainparams_by_lightning_hrp(const char *lightning_hrp);
/**
* chainparams_by_chainhash - Helper to get a network by its genesis blockhash

View File

@ -20,8 +20,8 @@ char *encode_scriptpubkey_to_addr(const tal_t *ctx,
if (is_p2sh(scriptPubkey, &sh))
return p2sh_to_base58(ctx, chainparams, &sh);
out = tal_arr(ctx, char, 73 + strlen(chainparams->bip173_name));
if (!segwit_addr_encode(out, chainparams->bip173_name, 0,
out = tal_arr(ctx, char, 73 + strlen(chainparams->onchain_hrp));
if (!segwit_addr_encode(out, chainparams->onchain_hrp, 0,
scriptPubkey + 2, scriptLen - 2))
return tal_free(out);

View File

@ -598,17 +598,15 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
return decode_fail(b11, fail,
"Prefix '%s' does not start with ln", prefix);
/* Signet chose to use prefix 'tb', just like testnet. So we tread
* carefully here: */
if (must_be_chain) {
if (streq(prefix + 2, must_be_chain->bip173_name))
if (streq(prefix + 2, must_be_chain->lightning_hrp))
b11->chain = must_be_chain;
else
return decode_fail(b11, fail, "Prefix %s is not for %s",
prefix + 2,
must_be_chain->network_name);
} else {
b11->chain = chainparams_by_bip173(prefix + 2);
b11->chain = chainparams_by_lightning_hrp(prefix + 2);
if (!b11->chain)
return decode_fail(b11, fail, "Unknown chain %s",
prefix + 2);
@ -1097,9 +1095,9 @@ char *bolt11_encode_(const tal_t *ctx,
amount = msat * 10 / multipliers[i].m10;
}
hrp = tal_fmt(tmpctx, "ln%s%"PRIu64"%c",
b11->chain->bip173_name, amount, postfix);
b11->chain->lightning_hrp, amount, postfix);
} else
hrp = tal_fmt(tmpctx, "ln%s", b11->chain->bip173_name);
hrp = tal_fmt(tmpctx, "ln%s", b11->chain->lightning_hrp);
/* BOLT #11:
*

View File

@ -28,15 +28,15 @@ static void json_add_fallback(struct json_stream *response,
json_add_string(response, "addr",
p2sh_to_base58(tmpctx, chain, &sh));
} else if (is_p2wpkh(fallback, &pkh)) {
char out[73 + strlen(chain->bip173_name)];
char out[73 + strlen(chain->onchain_hrp)];
json_add_string(response, "type", "P2WPKH");
if (segwit_addr_encode(out, chain->bip173_name, 0,
if (segwit_addr_encode(out, chain->onchain_hrp, 0,
(const u8 *)&pkh, sizeof(pkh)))
json_add_string(response, "addr", out);
} else if (is_p2wsh(fallback, &wsh)) {
char out[73 + strlen(chain->bip173_name)];
char out[73 + strlen(chain->onchain_hrp)];
json_add_string(response, "type", "P2WSH");
if (segwit_addr_encode(out, chain->bip173_name, 0,
if (segwit_addr_encode(out, chain->onchain_hrp, 0,
(const u8 *)&wsh, sizeof(wsh)))
json_add_string(response, "addr", out);
}
@ -47,7 +47,7 @@ static void json_add_fallback(struct json_stream *response,
void json_add_bolt11(struct json_stream *response,
const struct bolt11 *b11)
{
json_add_string(response, "currency", b11->chain->bip173_name);
json_add_string(response, "currency", b11->chain->lightning_hrp);
json_add_u64(response, "created_at", b11->timestamp);
json_add_u64(response, "expiry", b11->expiry);
json_add_node_id(response, "payee", &b11->receiver_id);

View File

@ -377,9 +377,9 @@ static const char *segwit_addr_net_decode(int *witness_version,
const struct chainparams *chainparams)
{
if (segwit_addr_decode(witness_version, witness_program,
witness_program_len, chainparams->bip173_name,
witness_program_len, chainparams->onchain_hrp,
addrz))
return chainparams->bip173_name;
return chainparams->onchain_hrp;
else
return NULL;
}
@ -443,7 +443,7 @@ json_to_address_scriptpubkey(const tal_t *ctx,
*scriptpubkey = scriptpubkey_witness_raw(ctx, witness_version,
witness_program, witness_program_len);
parsed = true;
right_network = streq(bip173, chainparams->bip173_name);
right_network = streq(bip173, chainparams->onchain_hrp);
}
}
/* Insert other parsers that accept null-terminated string here. */

View File

@ -87,7 +87,7 @@ int main(int argc, char *argv[])
if (!b11)
errx(ERROR_BAD_DECODE, "%s", fail);
printf("currency: %s\n", b11->chain->bip173_name);
printf("currency: %s\n", b11->chain->lightning_hrp);
printf("timestamp: %"PRIu64" (%s)\n",
b11->timestamp, fmt_time(ctx, b11->timestamp));
printf("expiry: %"PRIu64" (%s)\n",
@ -136,13 +136,13 @@ int main(int argc, char *argv[])
b11->chain,
&sh));
} else if (is_p2wpkh(b11->fallbacks[i], &pkh)) {
char out[73 + strlen(b11->chain->bip173_name)];
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
char out[73 + strlen(b11->chain->onchain_hrp)];
if (segwit_addr_encode(out, b11->chain->onchain_hrp, 0,
(const u8 *)&pkh, sizeof(pkh)))
printf("fallback-P2WPKH: %s\n", out);
} else if (is_p2wsh(b11->fallbacks[i], &wsh)) {
char out[73 + strlen(b11->chain->bip173_name)];
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
char out[73 + strlen(b11->chain->onchain_hrp)];
if (segwit_addr_encode(out, b11->chain->onchain_hrp, 0,
(const u8 *)&wsh, sizeof(wsh)))
printf("fallback-P2WSH: %s\n", out);
}

View File

@ -110,7 +110,7 @@ static bool print_amount(const struct bitcoin_blkid *chains,
&chains[0]));
ok = false;
} else
currency = ch->bip173_name;
currency = ch->lightning_hrp;
}
minor_unit = 11;
} else {

View File

@ -20,7 +20,7 @@ void notify_channel_mvt(struct lightningd *ld, const struct channel_coin_mvt *mv
timestamp = time_now().ts.tv_sec;
count = update_count(ld);
cm = finalize_channel_mvt(mvt, mvt, chainparams->bip173_name,
cm = finalize_channel_mvt(mvt, mvt, chainparams->lightning_hrp,
timestamp, &ld->id, count);
notify_coin_mvt(ld, cm);
}
@ -33,7 +33,7 @@ void notify_chain_mvt(struct lightningd *ld, const struct chain_coin_mvt *mvt)
timestamp = time_now().ts.tv_sec;
count = update_count(ld);
cm = finalize_chain_mvt(mvt, mvt, chainparams->bip173_name,
cm = finalize_chain_mvt(mvt, mvt, chainparams->onchain_hrp,
timestamp, &ld->id, count);
notify_coin_mvt(ld, cm);
}

View File

@ -468,10 +468,10 @@ static bool json_add_fallback_address(struct json_stream *js,
const struct chainparams *chain,
u8 version, const u8 *address)
{
char out[73 + strlen(chain->bip173_name)];
char out[73 + strlen(chain->onchain_hrp)];
/* Does extra checks, in particular checks v0 sizes */
if (segwit_addr_encode(out, chain->bip173_name, version,
if (segwit_addr_encode(out, chain->onchain_hrp, version,
address, tal_bytelen(address))) {
json_add_string(js, "address", out);
return true;

View File

@ -48,7 +48,7 @@ encode_pubkey_to_addr(const tal_t *ctx,
chainparams,
&h160);
} else {
hrp = chainparams->bip173_name;
hrp = chainparams->onchain_hrp;
/* out buffer is 73 + strlen(human readable part),
* see common/bech32.h*/