wallet: add "reserved_to_block" field to listfunds.

We already have this field in reserveinputs and unreserveinputs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `listfunds` has a new `reserved_to_block` field.
This commit is contained in:
Rusty Russell 2021-05-26 10:44:50 +09:30
parent 94419c7d73
commit f24dc9173d
5 changed files with 19 additions and 4 deletions

View File

@ -44,6 +44,8 @@ appended)
\fIstatus\fR (whether \fIunconfirmed\fR, \fIconfirmed\fR, or \fIspent\fR) \fIstatus\fR (whether \fIunconfirmed\fR, \fIconfirmed\fR, or \fIspent\fR)
.IP \[bu] .IP \[bu]
\fIreserved\fR (whether this is UTXO is currently reserved for an in-flight tx) \fIreserved\fR (whether this is UTXO is currently reserved for an in-flight tx)
.IP \[bu]
\fIreserved_to_block\fR (when reservation expires, if \fIreserved\fR is true)
.RE .RE
@ -92,4 +94,4 @@ Felix \fI<fixone@gmail.com\fR> is mainly responsible\.
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
\" SHA256STAMP:b59a2bed131c291e9650a6e330526b890f1e18182ccacd33aef60311f6ce2caa \" SHA256STAMP:d1566362ec4c99ec904f03569ccc99306a42414dc682fd88ca1a3dcb8616de53

View File

@ -34,6 +34,7 @@ Each entry in *outputs* will include:
- *redeemscript* (the redeemscript of the output, in hex, only if it's p2sh-wrapped) - *redeemscript* (the redeemscript of the output, in hex, only if it's p2sh-wrapped)
- *status* (whether *unconfirmed*, *confirmed*, or *spent*) - *status* (whether *unconfirmed*, *confirmed*, or *spent*)
- *reserved* (whether this is UTXO is currently reserved for an in-flight tx) - *reserved* (whether this is UTXO is currently reserved for an in-flight tx)
- *reserved_to_block* (when reservation expires, if *reserved* is true)
Each entry in *channels* will include: Each entry in *channels* will include:
- *peer\_id* - the peer with which the channel is opened. - *peer\_id* - the peer with which the channel is opened.

View File

@ -634,6 +634,7 @@ def test_withdraw_misc(node_factory, bitcoind, chainparams):
for out in l1.rpc.listfunds()['outputs']: for out in l1.rpc.listfunds()['outputs']:
if out['reserved']: if out['reserved']:
inputs += [{'txid': out['txid'], 'vout': out['output']}] inputs += [{'txid': out['txid'], 'vout': out['output']}]
assert out['reserved_to_block'] > bitcoind.rpc.getblockchaininfo()['blocks']
l1.rpc.unreserveinputs(bitcoind.rpc.createpsbt(inputs, [])) l1.rpc.unreserveinputs(bitcoind.rpc.createpsbt(inputs, []))
# Test withdrawal to self. # Test withdrawal to self.

View File

@ -441,27 +441,34 @@ def test_reserveinputs(node_factory, bitcoind, chainparams):
l1.rpc.reserveinputs(psbt) l1.rpc.reserveinputs(psbt)
assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs']) assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs'])
reserveheight = bitcoind.rpc.getblockchaininfo()['blocks'] + 72
assert all(o['reserved_to_block'] == reserveheight for o in l1.rpc.listfunds()['outputs'])
# Unreserve as a batch. # Unreserve as a batch.
psbt = bitcoind.rpc.createpsbt([{'txid': out[0], 'vout': out[1]} for out in outputs], []) psbt = bitcoind.rpc.createpsbt([{'txid': out[0], 'vout': out[1]} for out in outputs], [])
l1.rpc.unreserveinputs(psbt) l1.rpc.unreserveinputs(psbt)
assert not any(o['reserved'] for o in l1.rpc.listfunds()['outputs']) assert not any(o['reserved'] for o in l1.rpc.listfunds()['outputs'])
assert not any('reserved_to_block' in o for o in l1.rpc.listfunds()['outputs'])
# Reserve twice fails unless exclusive. # Reserve twice fails unless exclusive.
l1.rpc.reserveinputs(psbt) l1.rpc.reserveinputs(psbt)
with pytest.raises(RpcError, match=r"already reserved"): with pytest.raises(RpcError, match=r"already reserved"):
l1.rpc.reserveinputs(psbt) l1.rpc.reserveinputs(psbt)
l1.rpc.reserveinputs(psbt, False) l1.rpc.reserveinputs(psbt, False)
assert all(o['reserved_to_block'] == reserveheight + 72 for o in l1.rpc.listfunds()['outputs'])
l1.rpc.unreserveinputs(psbt) l1.rpc.unreserveinputs(psbt)
assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs']) assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs'])
assert all(o['reserved_to_block'] == reserveheight for o in l1.rpc.listfunds()['outputs'])
# Stays reserved across restarts. # Stays reserved across restarts.
l1.restart() l1.restart()
assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs']) assert all(o['reserved'] for o in l1.rpc.listfunds()['outputs'])
assert all(o['reserved_to_block'] == reserveheight for o in l1.rpc.listfunds()['outputs'])
# Final unreserve works. # Final unreserve works.
l1.rpc.unreserveinputs(psbt) l1.rpc.unreserveinputs(psbt)
assert not any(o['reserved'] for o in l1.rpc.listfunds()['outputs']) assert not any(o['reserved'] for o in l1.rpc.listfunds()['outputs'])
assert not any('reserved_to_block' in o for o in l1.rpc.listfunds()['outputs'])
def test_fundpsbt(node_factory, bitcoind, chainparams): def test_fundpsbt(node_factory, bitcoind, chainparams):

View File

@ -247,6 +247,7 @@ static void json_add_utxo(struct json_stream *response,
const struct utxo *utxo) const struct utxo *utxo)
{ {
const char *out; const char *out;
bool reserved;
json_object_start(response, fieldname); json_object_start(response, fieldname);
json_add_txid(response, "txid", &utxo->txid); json_add_txid(response, "txid", &utxo->txid);
@ -284,9 +285,12 @@ static void json_add_utxo(struct json_stream *response,
} else } else
json_add_string(response, "status", "unconfirmed"); json_add_string(response, "status", "unconfirmed");
json_add_bool(response, "reserved", reserved = utxo_is_reserved(utxo,
utxo_is_reserved(utxo, get_block_height(wallet->ld->topology));
get_block_height(wallet->ld->topology))); json_add_bool(response, "reserved", reserved);
if (reserved)
json_add_num(response, "reserved_to_block",
utxo->reserved_til);
json_object_end(response); json_object_end(response);
} }