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

View File

@@ -10,7 +10,13 @@
struct chainparams { struct chainparams {
const char *network_name; 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 /*'bip70_name' is corresponding to the 'chain' field of
* the API 'getblockchaininfo' */ * the API 'getblockchaininfo' */
const char *bip70_name; const char *bip70_name;
@@ -46,7 +52,7 @@ const struct chainparams *chainparams_for_network(const char *network_name);
* *
* This lets us decode BOLT11 addresses. * 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 * 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)) if (is_p2sh(scriptPubkey, &sh))
return p2sh_to_base58(ctx, chainparams, &sh); return p2sh_to_base58(ctx, chainparams, &sh);
out = tal_arr(ctx, char, 73 + strlen(chainparams->bip173_name)); out = tal_arr(ctx, char, 73 + strlen(chainparams->onchain_hrp));
if (!segwit_addr_encode(out, chainparams->bip173_name, 0, if (!segwit_addr_encode(out, chainparams->onchain_hrp, 0,
scriptPubkey + 2, scriptLen - 2)) scriptPubkey + 2, scriptLen - 2))
return tal_free(out); 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, return decode_fail(b11, fail,
"Prefix '%s' does not start with ln", prefix); "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 (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; b11->chain = must_be_chain;
else else
return decode_fail(b11, fail, "Prefix %s is not for %s", return decode_fail(b11, fail, "Prefix %s is not for %s",
prefix + 2, prefix + 2,
must_be_chain->network_name); must_be_chain->network_name);
} else { } else {
b11->chain = chainparams_by_bip173(prefix + 2); b11->chain = chainparams_by_lightning_hrp(prefix + 2);
if (!b11->chain) if (!b11->chain)
return decode_fail(b11, fail, "Unknown chain %s", return decode_fail(b11, fail, "Unknown chain %s",
prefix + 2); prefix + 2);
@@ -1097,9 +1095,9 @@ char *bolt11_encode_(const tal_t *ctx,
amount = msat * 10 / multipliers[i].m10; amount = msat * 10 / multipliers[i].m10;
} }
hrp = tal_fmt(tmpctx, "ln%s%"PRIu64"%c", hrp = tal_fmt(tmpctx, "ln%s%"PRIu64"%c",
b11->chain->bip173_name, amount, postfix); b11->chain->lightning_hrp, amount, postfix);
} else } else
hrp = tal_fmt(tmpctx, "ln%s", b11->chain->bip173_name); hrp = tal_fmt(tmpctx, "ln%s", b11->chain->lightning_hrp);
/* BOLT #11: /* BOLT #11:
* *

View File

@@ -28,15 +28,15 @@ static void json_add_fallback(struct json_stream *response,
json_add_string(response, "addr", json_add_string(response, "addr",
p2sh_to_base58(tmpctx, chain, &sh)); p2sh_to_base58(tmpctx, chain, &sh));
} else if (is_p2wpkh(fallback, &pkh)) { } 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"); 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))) (const u8 *)&pkh, sizeof(pkh)))
json_add_string(response, "addr", out); json_add_string(response, "addr", out);
} else if (is_p2wsh(fallback, &wsh)) { } 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"); 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))) (const u8 *)&wsh, sizeof(wsh)))
json_add_string(response, "addr", out); 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, void json_add_bolt11(struct json_stream *response,
const struct bolt11 *b11) 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, "created_at", b11->timestamp);
json_add_u64(response, "expiry", b11->expiry); json_add_u64(response, "expiry", b11->expiry);
json_add_node_id(response, "payee", &b11->receiver_id); 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) const struct chainparams *chainparams)
{ {
if (segwit_addr_decode(witness_version, witness_program, if (segwit_addr_decode(witness_version, witness_program,
witness_program_len, chainparams->bip173_name, witness_program_len, chainparams->onchain_hrp,
addrz)) addrz))
return chainparams->bip173_name; return chainparams->onchain_hrp;
else else
return NULL; return NULL;
} }
@@ -443,7 +443,7 @@ json_to_address_scriptpubkey(const tal_t *ctx,
*scriptpubkey = scriptpubkey_witness_raw(ctx, witness_version, *scriptpubkey = scriptpubkey_witness_raw(ctx, witness_version,
witness_program, witness_program_len); witness_program, witness_program_len);
parsed = true; 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. */ /* Insert other parsers that accept null-terminated string here. */

View File

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

View File

@@ -110,7 +110,7 @@ static bool print_amount(const struct bitcoin_blkid *chains,
&chains[0])); &chains[0]));
ok = false; ok = false;
} else } else
currency = ch->bip173_name; currency = ch->lightning_hrp;
} }
minor_unit = 11; minor_unit = 11;
} else { } 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; timestamp = time_now().ts.tv_sec;
count = update_count(ld); 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); timestamp, &ld->id, count);
notify_coin_mvt(ld, cm); 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; timestamp = time_now().ts.tv_sec;
count = update_count(ld); 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); timestamp, &ld->id, count);
notify_coin_mvt(ld, cm); 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, const struct chainparams *chain,
u8 version, const u8 *address) 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 */ /* 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))) { address, tal_bytelen(address))) {
json_add_string(js, "address", out); json_add_string(js, "address", out);
return true; return true;

View File

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