jsonrpc: Let Base58 '2..' address work on both regtest and testnet.

This commit is contained in:
ZmnSCPxj 2018-02-24 14:59:39 +00:00 committed by Rusty Russell
parent 0e40c85691
commit bd07a91782
4 changed files with 66 additions and 26 deletions

View File

@ -107,7 +107,7 @@ static void json_invoice(struct command *cmd,
u64 *msatoshi_val;
const char *label_val;
const char *desc_val;
const char *bip173;
enum address_parse_result fallback_parse;
struct json_result *response = new_json_result(cmd);
struct wallet *wallet = cmd->ld->wallet;
struct bolt11 *b11;
@ -174,10 +174,17 @@ static void json_invoice(struct command *cmd,
/* fallback address */
if (fallback) {
bip173 = json_tok_address_scriptpubkey(cmd, buffer, fallback, &fallback_script);
if (!streq(get_chainparams(cmd->ld)->bip173_name, bip173)) {
command_fail(cmd, "Invalid fallback address for %s does not match network %s",
get_chainparams(cmd->ld)->network_name, bip173);
fallback_parse
= json_tok_address_scriptpubkey(cmd,
get_chainparams(cmd->ld),
buffer, fallback,
&fallback_script);
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, "Fallback address not valid");
return;
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd, "Fallback address does not match our network %s",
get_chainparams(cmd->ld)->network_name);
return;
}
}

View File

@ -831,8 +831,11 @@ static const char* segwit_addr_net_decode(int *witness_version,
return NULL;
}
const char *json_tok_address_scriptpubkey(const tal_t *cxt, const char *buffer,
const jsmntok_t *tok, const u8 **scriptpubkey)
enum address_parse_result
json_tok_address_scriptpubkey(const tal_t *cxt,
const struct chainparams *chainparams,
const char *buffer,
const jsmntok_t *tok, const u8 **scriptpubkey)
{
struct bitcoin_address p2pkh_destination;
struct ripemd160 p2sh_destination;
@ -846,21 +849,31 @@ const char *json_tok_address_scriptpubkey(const tal_t *cxt, const char *buffer,
char *addrz;
const char *bip173;
bool parsed;
bool right_network;
bool testnet;
bip173 = NULL;
parsed = false;
if (bitcoin_from_base58(&testnet, &p2pkh_destination,
buffer + tok->start, tok->end - tok->start)) {
*scriptpubkey = scriptpubkey_p2pkh(cxt, &p2pkh_destination);
bip173 = chainparams_for_network(testnet ? "testnet" : "bitcoin")->bip173_name;
parsed = true;
right_network = (testnet == chainparams->testnet);
} else if (p2sh_from_base58(&testnet, &p2sh_destination,
buffer + tok->start, tok->end - tok->start)) {
*scriptpubkey = scriptpubkey_p2sh_hash(cxt, &p2sh_destination);
bip173 = chainparams_for_network(testnet ? "testnet" : "bitcoin")->bip173_name;
parsed = true;
right_network = (testnet == chainparams->testnet);
}
/* Insert other parsers that accept pointer+len here. */
if (bip173) return bip173;
if (parsed) {
if (right_network)
return ADDRESS_PARSE_SUCCESS;
else
return ADDRESS_PARSE_WRONG_NETWORK;
}
/* Generate null-terminated address. */
addrz = tal_dup_arr(cxt, char, buffer + tok->start, tok->end - tok->start, 1);
@ -880,13 +893,20 @@ const char *json_tok_address_scriptpubkey(const tal_t *cxt, const char *buffer,
if (witness_ok) {
*scriptpubkey = scriptpubkey_witness_raw(cxt, witness_version,
witness_program, witness_program_len);
}
else {
bip173 = NULL;
parsed = true;
right_network = streq(bip173, chainparams->bip173_name);
}
}
/* Insert other parsers that accept null-terminated string here. */
tal_free(addrz);
return bip173;
if (parsed) {
if (right_network)
return ADDRESS_PARSE_SUCCESS;
else
return ADDRESS_PARSE_WRONG_NETWORK;
}
return ADDRESS_PARSE_UNRECOGNIZED;
}

View File

@ -1,6 +1,7 @@
#ifndef LIGHTNING_LIGHTNINGD_JSONRPC_H
#define LIGHTNING_LIGHTNINGD_JSONRPC_H
#include "config.h"
#include <bitcoin/chainparams.h>
#include <ccan/autodata/autodata.h>
#include <ccan/list/list.h>
#include <common/json.h>
@ -109,11 +110,22 @@ void json_add_address(struct json_result *response, const char *fieldname,
/* For initialization */
void setup_jsonrpc(struct lightningd *ld, const char *rpc_filename);
/* Returns NULL, or bip173 network name and fills in *scriptpubkey
* allocated off ctx
enum address_parse_result {
/* Not recognized as an onchain address */
ADDRESS_PARSE_UNRECOGNIZED,
/* Recognized as an onchain address, but targets wrong network */
ADDRESS_PARSE_WRONG_NETWORK,
/* Recognized and succeeds */
ADDRESS_PARSE_SUCCESS,
};
/* Return result of address parsing and fills in *scriptpubkey
* allocated off ctx if ADDRESS_PARSE_SUCCESS
*/
const char *json_tok_address_scriptpubkey(const tal_t *ctx, const char *buffer,
const jsmntok_t *tok, const u8 **scriptpubkey);
enum address_parse_result
json_tok_address_scriptpubkey(const tal_t *ctx,
const struct chainparams *chainparams,
const char *buffer,
const jsmntok_t *tok, const u8 **scriptpubkey);
AUTODATA_TYPE(json_command, struct json_command);
#endif /* LIGHTNING_LIGHTNINGD_JSONRPC_H */

View File

@ -91,7 +91,7 @@ static void json_withdraw(struct command *cmd,
u64 fee_estimate;
struct bitcoin_tx *tx;
bool withdraw_all = false;
const char *bip173 = NULL;
enum address_parse_result addr_parse;
if (!json_get_params(cmd, buffer, params,
"destination", &desttok,
@ -111,20 +111,21 @@ static void json_withdraw(struct command *cmd,
}
/* Parse address. */
bip173 = json_tok_address_scriptpubkey(cmd, buffer,
desttok, (const u8**)(&withdraw->destination));
addr_parse = json_tok_address_scriptpubkey(cmd,
get_chainparams(cmd->ld),
buffer, desttok,
(const u8**)(&withdraw->destination));
/* Check that destination address could be understood. */
if (!bip173) {
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, "Could not parse destination address");
return;
}
/* Check address given is compatible with the chain we are on. */
if (!streq(bip173, get_chainparams(cmd->ld)->bip173_name)) {
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd,
"Use of %s address on %s",
chainparams_by_bip173(bip173)->network_name,
"Destination address is not on network %s",
get_chainparams(cmd->ld)->network_name);
return;
}