From ed6a455a3c70f1f1a9a393cbd710cdeb61e5148e Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 22 Feb 2019 17:50:01 +0100 Subject: [PATCH] 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 --- CHANGELOG.md | 1 + tests/test_closing.py | 6 ++++++ wallet/walletrpc.c | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a1a04c8a..83beca535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. - 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: `listfunds` now displays addresses for all outputs owned by the wallet (#2387) ### Changed diff --git a/tests/test_closing.py b/tests/test_closing.py index e3a04b1b5..246f478ee 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -1469,6 +1469,12 @@ def test_permfail(node_factory, bitcoind): # generated some more blocks. 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() l1.rpc.withdraw(addr, "all") diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 28daa9ceb..075d2a6cc 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -246,6 +246,26 @@ encode_pubkey_to_addr(const tal_t *ctx, 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" */ static struct command_result *param_newaddr(struct command *cmd, const char *name, @@ -445,7 +465,13 @@ static struct command_result *json_listfunds(struct command *cmd, "p2wpkh address encoding failure."); } 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) json_add_string(response, "status", "spent"); else if (utxos[i]->blockheight)