mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
fundpsbt: let caller specify locktime.
Required for dual funding where the opener sets it. Changelog-Added: JSON-RPC: `fundpsbt` takes a new `locktime` parameter Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
neil saitug
parent
bf5e99403e
commit
14baaaa8ba
@@ -1126,7 +1126,7 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
}
|
}
|
||||||
return self.call("unreserveinputs", payload)
|
return self.call("unreserveinputs", payload)
|
||||||
|
|
||||||
def fundpsbt(self, satoshi, feerate, startweight, minconf=None, reserve=True):
|
def fundpsbt(self, satoshi, feerate, startweight, minconf=None, reserve=True, locktime=None):
|
||||||
"""
|
"""
|
||||||
Create a PSBT with inputs sufficient to give an output of satoshi.
|
Create a PSBT with inputs sufficient to give an output of satoshi.
|
||||||
"""
|
"""
|
||||||
@@ -1136,6 +1136,7 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
"startweight": startweight,
|
"startweight": startweight,
|
||||||
"minconf": minconf,
|
"minconf": minconf,
|
||||||
"reserve": reserve,
|
"reserve": reserve,
|
||||||
|
"locktime": locktime,
|
||||||
}
|
}
|
||||||
return self.call("fundpsbt", payload)
|
return self.call("fundpsbt", payload)
|
||||||
|
|
||||||
|
|||||||
6
doc/lightning-fundpsbt.7
generated
6
doc/lightning-fundpsbt.7
generated
@@ -3,7 +3,7 @@
|
|||||||
lightning-fundpsbt - Command to populate PSBT inputs from the wallet
|
lightning-fundpsbt - Command to populate PSBT inputs from the wallet
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
||||||
\fBfundpsbt\fR \fIsatoshi\fR \fIfeerate\fR \fIstartweight\fR [\fIminconf\fR] [\fIreserve\fR]
|
\fBfundpsbt\fR \fIsatoshi\fR \fIfeerate\fR \fIstartweight\fR [\fIminconf\fR] [\fIreserve\fR] [\fIlocktime\fR]
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
|
||||||
@@ -39,6 +39,10 @@ outputs should have\. Default is 1\.
|
|||||||
\fIreserve\fR is a boolean: if true (the default), then \fIreserveinputs\fR is
|
\fIreserve\fR is a boolean: if true (the default), then \fIreserveinputs\fR is
|
||||||
called (successfully, with \fIexclusive\fR true) on the returned PSBT\.
|
called (successfully, with \fIexclusive\fR true) on the returned PSBT\.
|
||||||
|
|
||||||
|
|
||||||
|
\fIlocktime\fR is an optional locktime: if not set, it is set to a recent
|
||||||
|
block height\.
|
||||||
|
|
||||||
.SH EXAMPLE USAGE
|
.SH EXAMPLE USAGE
|
||||||
|
|
||||||
Let's assume the caller is trying to produce a 100,000 satoshi output\.
|
Let's assume the caller is trying to produce a 100,000 satoshi output\.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ lightning-fundpsbt -- Command to populate PSBT inputs from the wallet
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**fundpsbt** *satoshi* *feerate* *startweight* \[*minconf*\] \[*reserve*\]
|
**fundpsbt** *satoshi* *feerate* *startweight* \[*minconf*\] \[*reserve*\] \[*locktime*\]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@@ -36,6 +36,9 @@ outputs should have. Default is 1.
|
|||||||
*reserve* is a boolean: if true (the default), then *reserveinputs* is
|
*reserve* is a boolean: if true (the default), then *reserveinputs* is
|
||||||
called (successfully, with *exclusive* true) on the returned PSBT.
|
called (successfully, with *exclusive* true) on the returned PSBT.
|
||||||
|
|
||||||
|
*locktime* is an optional locktime: if not set, it is set to a recent
|
||||||
|
block height.
|
||||||
|
|
||||||
EXAMPLE USAGE
|
EXAMPLE USAGE
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|||||||
@@ -508,6 +508,9 @@ def test_fundpsbt(node_factory, bitcoind, chainparams):
|
|||||||
# Should get one input, plus some excess
|
# Should get one input, plus some excess
|
||||||
funding = l1.rpc.fundpsbt(amount // 2, feerate, 0, reserve=False)
|
funding = l1.rpc.fundpsbt(amount // 2, feerate, 0, reserve=False)
|
||||||
psbt = bitcoind.rpc.decodepsbt(funding['psbt'])
|
psbt = bitcoind.rpc.decodepsbt(funding['psbt'])
|
||||||
|
# We can fuzz this up to 99 blocks back.
|
||||||
|
assert psbt['tx']['locktime'] > bitcoind.rpc.getblockcount() - 100
|
||||||
|
assert psbt['tx']['locktime'] <= bitcoind.rpc.getblockcount()
|
||||||
assert len(psbt['tx']['vin']) == 1
|
assert len(psbt['tx']['vin']) == 1
|
||||||
assert funding['excess_msat'] > Millisatoshi(0)
|
assert funding['excess_msat'] > Millisatoshi(0)
|
||||||
assert funding['excess_msat'] < Millisatoshi(amount // 2 * 1000)
|
assert funding['excess_msat'] < Millisatoshi(amount // 2 * 1000)
|
||||||
@@ -515,9 +518,10 @@ def test_fundpsbt(node_factory, bitcoind, chainparams):
|
|||||||
assert 'estimated_final_weight' in funding
|
assert 'estimated_final_weight' in funding
|
||||||
assert 'reservations' not in funding
|
assert 'reservations' not in funding
|
||||||
|
|
||||||
# This should add 99 to the weight, but otherwise be identical (might choose different inputs though!)
|
# This should add 99 to the weight, but otherwise be identical (might choose different inputs though!) except for locktime.
|
||||||
funding2 = l1.rpc.fundpsbt(amount // 2, feerate, 99, reserve=False)
|
funding2 = l1.rpc.fundpsbt(amount // 2, feerate, 99, reserve=False, locktime=bitcoind.rpc.getblockcount() + 1)
|
||||||
psbt2 = bitcoind.rpc.decodepsbt(funding2['psbt'])
|
psbt2 = bitcoind.rpc.decodepsbt(funding2['psbt'])
|
||||||
|
assert psbt2['tx']['locktime'] == bitcoind.rpc.getblockcount() + 1
|
||||||
assert len(psbt2['tx']['vin']) == 1
|
assert len(psbt2['tx']['vin']) == 1
|
||||||
assert funding2['excess_msat'] < funding['excess_msat']
|
assert funding2['excess_msat'] < funding['excess_msat']
|
||||||
assert funding2['feerate_per_kw'] == 7500
|
assert funding2['feerate_per_kw'] == 7500
|
||||||
|
|||||||
@@ -213,11 +213,11 @@ static struct command_result *finish_psbt(struct command *cmd,
|
|||||||
u32 feerate_per_kw,
|
u32 feerate_per_kw,
|
||||||
size_t weight,
|
size_t weight,
|
||||||
struct amount_sat excess,
|
struct amount_sat excess,
|
||||||
bool reserve)
|
bool reserve,
|
||||||
|
u32 *locktime)
|
||||||
{
|
{
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
u32 locktime;
|
|
||||||
u32 current_height = get_block_height(cmd->ld->topology);
|
u32 current_height = get_block_height(cmd->ld->topology);
|
||||||
|
|
||||||
/* Setting the locktime to the next block to be mined has multiple
|
/* Setting the locktime to the next block to be mined has multiple
|
||||||
@@ -229,18 +229,21 @@ static struct command_result *finish_psbt(struct command *cmd,
|
|||||||
* 0xFFFFFFFD by default. Other wallets are likely to implement
|
* 0xFFFFFFFD by default. Other wallets are likely to implement
|
||||||
* this too).
|
* this too).
|
||||||
*/
|
*/
|
||||||
locktime = current_height;
|
if (!locktime) {
|
||||||
|
locktime = tal(cmd, u32);
|
||||||
|
*locktime = current_height;
|
||||||
|
|
||||||
/* Eventually fuzz it too. */
|
/* Eventually fuzz it too. */
|
||||||
if (locktime > 100 && pseudorand(10) == 0)
|
if (*locktime > 100 && pseudorand(10) == 0)
|
||||||
locktime -= pseudorand(100);
|
*locktime -= pseudorand(100);
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: tx_spending_utxos does more than we need, but there
|
/* FIXME: tx_spending_utxos does more than we need, but there
|
||||||
* are other users right now. */
|
* are other users right now. */
|
||||||
tx = tx_spending_utxos(cmd, chainparams,
|
tx = tx_spending_utxos(cmd, chainparams,
|
||||||
cast_const2(const struct utxo **, utxos),
|
cast_const2(const struct utxo **, utxos),
|
||||||
cmd->ld->wallet->bip32_base,
|
cmd->ld->wallet->bip32_base,
|
||||||
false, 0, locktime,
|
false, 0, *locktime,
|
||||||
BITCOIN_TX_RBF_SEQUENCE);
|
BITCOIN_TX_RBF_SEQUENCE);
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -264,7 +267,7 @@ static struct command_result *json_fundpsbt(struct command *cmd,
|
|||||||
u32 *minconf, *weight;
|
u32 *minconf, *weight;
|
||||||
struct amount_sat *amount, input, diff;
|
struct amount_sat *amount, input, diff;
|
||||||
bool all, *reserve;
|
bool all, *reserve;
|
||||||
u32 maxheight;
|
u32 *locktime, maxheight;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("satoshi", param_sat_or_all, &amount),
|
p_req("satoshi", param_sat_or_all, &amount),
|
||||||
@@ -272,6 +275,7 @@ static struct command_result *json_fundpsbt(struct command *cmd,
|
|||||||
p_req("startweight", param_number, &weight),
|
p_req("startweight", param_number, &weight),
|
||||||
p_opt_def("minconf", param_number, &minconf, 1),
|
p_opt_def("minconf", param_number, &minconf, 1),
|
||||||
p_opt_def("reserve", param_bool, &reserve, true),
|
p_opt_def("reserve", param_bool, &reserve, true),
|
||||||
|
p_opt("locktime", param_number, &locktime),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
@@ -336,7 +340,8 @@ static struct command_result *json_fundpsbt(struct command *cmd,
|
|||||||
tal_count(utxos));
|
tal_count(utxos));
|
||||||
}
|
}
|
||||||
|
|
||||||
return finish_psbt(cmd, utxos, *feerate_per_kw, *weight, diff, *reserve);
|
return finish_psbt(cmd, utxos, *feerate_per_kw, *weight, diff, *reserve,
|
||||||
|
locktime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command fundpsbt_command = {
|
static const struct json_command fundpsbt_command = {
|
||||||
@@ -474,7 +479,7 @@ static struct command_result *json_utxopsbt(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return finish_psbt(cmd, utxos, *feerate_per_kw, *weight, excess,
|
return finish_psbt(cmd, utxos, *feerate_per_kw, *weight, excess,
|
||||||
*reserve);
|
*reserve, NULL);
|
||||||
}
|
}
|
||||||
static const struct json_command utxopsbt_command = {
|
static const struct json_command utxopsbt_command = {
|
||||||
"utxopsbt",
|
"utxopsbt",
|
||||||
|
|||||||
Reference in New Issue
Block a user