wallet: Display addresses derived from scriptPubKey where available

In particular this matches the case of `their_unilateral/to_us` outputs, which
were missing their addresses so far.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-02-22 17:50:01 +01:00 committed by neil saitug
parent 478e2d7084
commit ed6a455a3c
3 changed files with 33 additions and 0 deletions

View File

@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- JSON API: `getroute` `riskfactor` argument is simplified; `pay` now defaults to setting it to 10. - JSON API: `getroute` `riskfactor` argument is simplified; `pay` now defaults to setting it to 10.
- pylightning: New class 'Millisatoshi' can be used for JSON API, and new '_msat' fields are turned into this on reading. - pylightning: New class 'Millisatoshi' can be used for JSON API, and new '_msat' fields are turned into this on reading.
- JSON API: `fundchannel` and `withdraw` now have a new parameter `minconf` that limits coinselection to outputs that have at least `minconf` confirmations (default 1). (#2380) - JSON API: `fundchannel` and `withdraw` now have a new parameter `minconf` that limits coinselection to outputs that have at least `minconf` confirmations (default 1). (#2380)
- JSON API: `listfunds` now displays addresses for all outputs owned by the wallet (#2387)
### Changed ### Changed

View File

@ -1469,6 +1469,12 @@ def test_permfail(node_factory, bitcoind):
# generated some more blocks. # generated some more blocks.
assert (closetxid, "confirmed") in set([(o['txid'], o['status']) for o in l1.rpc.listfunds()['outputs']]) assert (closetxid, "confirmed") in set([(o['txid'], o['status']) for o in l1.rpc.listfunds()['outputs']])
# Check that the all the addresses match what we generated ourselves:
for o in l1.rpc.listfunds()['outputs']:
txout = bitcoind.rpc.gettxout(o['txid'], o['output'])
addr = txout['scriptPubKey']['addresses'][0]
assert(addr == o['address'])
addr = l1.bitcoin.rpc.getnewaddress() addr = l1.bitcoin.rpc.getnewaddress()
l1.rpc.withdraw(addr, "all") l1.rpc.withdraw(addr, "all")

View File

@ -246,6 +246,26 @@ encode_pubkey_to_addr(const tal_t *ctx,
return out; return out;
} }
/* Returns NULL if the script is not a P2WPKH */
static char *
encode_scriptpubkey_to_addr(const tal_t *ctx,
const struct lightningd *ld,
const u8 *scriptPubkey)
{
char *out;
const char *hrp;
size_t scriptLen = tal_bytelen(scriptPubkey);
bool ok;
if (scriptLen != 22 || scriptPubkey[0] != 0x00 || scriptPubkey[1] != 0x14)
return NULL;
hrp = get_chainparams(ld)->bip173_name;
out = tal_arr(ctx, char, 73 + strlen(hrp));
ok = segwit_addr_encode(out, hrp, 0, scriptPubkey + 2, scriptLen - 2);
if (!ok)
return tal_free(out);
return out;
}
/* Extract a bool indicating "p2sh-segwit" or "bech32" */ /* Extract a bool indicating "p2sh-segwit" or "bech32" */
static struct command_result *param_newaddr(struct command *cmd, static struct command_result *param_newaddr(struct command *cmd,
const char *name, const char *name,
@ -445,7 +465,13 @@ static struct command_result *json_listfunds(struct command *cmd,
"p2wpkh address encoding failure."); "p2wpkh address encoding failure.");
} }
json_add_string(response, "address", out); json_add_string(response, "address", out);
} else if (utxos[i]->scriptPubkey != NULL) {
out = encode_scriptpubkey_to_addr(
cmd, cmd->ld, utxos[i]->scriptPubkey);
if (out)
json_add_string(response, "address", out);
} }
if (utxos[i]->spendheight) if (utxos[i]->spendheight)
json_add_string(response, "status", "spent"); json_add_string(response, "status", "spent");
else if (utxos[i]->blockheight) else if (utxos[i]->blockheight)