mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
dual-funding: update fee_step to be a feerate
Using a 'feestep' is more restrictive than you'd want, instead we enforce that the next feerate must be at least 1/64th more than the last, but put no upper limit on it Includes update to lnprototest changes Contributed-By: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Changelog-EXPERIMENTAL: Protocol: Replaces init_rbf's `fee_step` for RBF of v2 opens with `funding_feerate_perkw`, breaking change
This commit is contained in:
parent
04b6ad06cb
commit
376e6f8bd1
@ -1039,12 +1039,13 @@ class LightningRpc(UnixDomainSocketRpc):
|
||||
}
|
||||
return self.call("openchannel_update", payload)
|
||||
|
||||
def openchannel_bump(self, channel_id, amount, initialpsbt):
|
||||
def openchannel_bump(self, channel_id, amount, initialpsbt, funding_feerate=None):
|
||||
""" Initiate an RBF for an in-progress open """
|
||||
payload = {
|
||||
"channel_id": channel_id,
|
||||
"amount": amount,
|
||||
"initialpsbt": initialpsbt,
|
||||
"funding_feerate": funding_feerate,
|
||||
}
|
||||
return self.call("openchannel_bump", payload)
|
||||
|
||||
|
4
doc/lightning-listpeers.7
generated
4
doc/lightning-listpeers.7
generated
@ -273,8 +273,6 @@ If \fBinflight\fR is present:
|
||||
\fBlast_feerate\fR (string): The feerate for the latest funding transaction in per-1000-weight, with "kpw" appended
|
||||
.IP \[bu]
|
||||
\fBnext_feerate\fR (string): The minimum feerate for the next funding transaction in per-1000-weight, with "kpw" appended
|
||||
.IP \[bu]
|
||||
\fBnext_fee_step\fR (u32): The number of fee steps so far, plus one
|
||||
|
||||
.RE
|
||||
|
||||
@ -646,4 +644,4 @@ Main web site: \fIhttps://github.com/ElementsProject/lightning\fR Lightning
|
||||
RFC site (BOLT #9):
|
||||
\fIhttps://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md\fR
|
||||
|
||||
\" SHA256STAMP:0eee52605e08ff184fa052d51ada7eb5da26149c6bc3d2a553c8e6518a27818b
|
||||
\" SHA256STAMP:16d808a5a346bb7dbffc263846617d33c74fdc6e0d5165f462d634ed8409f882
|
||||
|
@ -132,7 +132,6 @@ On success, an object containing **peers** is returned. It is an array of objec
|
||||
- **initial_feerate** (string): The feerate for the initial funding transaction in per-1000-weight, with "kpw" appended
|
||||
- **last_feerate** (string): The feerate for the latest funding transaction in per-1000-weight, with "kpw" appended
|
||||
- **next_feerate** (string): The minimum feerate for the next funding transaction in per-1000-weight, with "kpw" appended
|
||||
- **next_fee_step** (u32): The number of fee steps so far, plus one
|
||||
- **log** (array of objects, optional): if *level* is specified, logs for this peer:
|
||||
- **type** (string) (one of "SKIPPED", "BROKEN", "UNUSUAL", "INFO", "DEBUG", "IO_IN", "IO_OUT")
|
||||
|
||||
@ -376,4 +375,4 @@ Main web site: <https://github.com/ElementsProject/lightning> Lightning
|
||||
RFC site (BOLT \#9):
|
||||
<https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md>
|
||||
|
||||
[comment]: # ( SHA256STAMP:6db6eb853f6c1953f05160cd9026ad6a8ccb97a016b15bc76242adc8026fa4ca)
|
||||
[comment]: # ( SHA256STAMP:91d30768a795456c75c72cf499df529ae8dbcc8088d06d1ed27150272425ab37)
|
||||
|
9
doc/lightning-openchannel_bump.7
generated
9
doc/lightning-openchannel_bump.7
generated
@ -3,7 +3,7 @@
|
||||
lightning-openchannel_bump - Command to initiate a channel RBF
|
||||
.SH SYNOPSIS
|
||||
|
||||
\fBopenchannel_bump\fR \fIchannel_id\fR \fIamount\fR \fIinitalpsbt\fR
|
||||
\fBopenchannel_bump\fR \fIchannel_id\fR \fIamount\fR \fIinitalpsbt\fR [\fIfunding_feerate\fR]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
@ -27,6 +27,11 @@ Must have the Non-Witness UTXO (PSBT_IN_NON_WITNESS_UTXO) set for
|
||||
every input\. An error (code 309) will be returned if this requirement
|
||||
is not met\.
|
||||
|
||||
|
||||
\fIfunding_feerate\fR is an optional field\. Sets the feerate for the
|
||||
funding transaction\. Defaults to 1/64th greater than the last
|
||||
feerate used for this channel\.
|
||||
|
||||
.SH RETURN VALUE
|
||||
|
||||
On success, an object is returned, containing:
|
||||
@ -89,4 +94,4 @@ lightning-fundchannel_\fBstart\fR(7), lightning-fundchannel_\fBcomplete\fR(7),
|
||||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:53b3a3b647564ae97a249226271642dc775985dce376065dd95d332d9f60dd95
|
||||
\" SHA256STAMP:357923fcd85b832cc52f77858c0744cae6c06d7612aaebb87e65f2ef0a42f367
|
||||
|
@ -4,7 +4,7 @@ lightning-openchannel\_bump -- Command to initiate a channel RBF
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
**openchannel_bump** *channel_id* *amount* *initalpsbt*
|
||||
**openchannel_bump** *channel_id* *amount* *initalpsbt* \[*funding_feerate*\]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -26,6 +26,10 @@ Must have the Non-Witness UTXO (PSBT\_IN\_NON\_WITNESS\_UTXO) set for
|
||||
every input. An error (code 309) will be returned if this requirement
|
||||
is not met.
|
||||
|
||||
*funding_feerate* is an optional field. Sets the feerate for the
|
||||
funding transaction. Defaults to 1/64th greater than the last
|
||||
feerate used for this channel.
|
||||
|
||||
RETURN VALUE
|
||||
------------
|
||||
|
||||
|
@ -579,7 +579,6 @@
|
||||
"short_channel_id": { },
|
||||
"channel_id": { },
|
||||
"funding_txid": { },
|
||||
"inflight": { },
|
||||
"close_to": { },
|
||||
"private": { },
|
||||
"opener": { },
|
||||
@ -635,7 +634,6 @@
|
||||
"initial_feerate": { },
|
||||
"last_feerate": { },
|
||||
"next_feerate": { },
|
||||
"next_fee_step": { },
|
||||
"inflight": { },
|
||||
"last_tx_fee": { },
|
||||
"last_tx_fee_msat": { },
|
||||
@ -715,12 +713,13 @@
|
||||
"out_fulfilled_msat": { },
|
||||
"out_msatoshi_fulfilled": { },
|
||||
"htlcs": { },
|
||||
"inflight": { },
|
||||
"initial_feerate": { },
|
||||
"last_feerate": { },
|
||||
"next_feerate": { },
|
||||
"close_to_addr": { },
|
||||
"initial_feerate": { },
|
||||
"last_feerate": { },
|
||||
"next_feerate": { },
|
||||
"next_fee_step": { },
|
||||
"direction": { },
|
||||
"last_tx_fee": {
|
||||
"deprecated": true
|
||||
@ -800,13 +799,14 @@
|
||||
"out_fulfilled_msat": { },
|
||||
"out_msatoshi_fulfilled": { },
|
||||
"htlcs": { },
|
||||
"inflight": { },
|
||||
"initial_feerate": { },
|
||||
"last_feerate": { },
|
||||
"next_feerate": { },
|
||||
"last_tx_fee": { },
|
||||
"close_to_addr": { },
|
||||
"initial_feerate": { },
|
||||
"last_feerate": { },
|
||||
"next_feerate": { },
|
||||
"next_fee_step": { },
|
||||
"last_tx_fee": { },
|
||||
"last_tx_fee_msat": { },
|
||||
"direction": {
|
||||
@ -822,7 +822,7 @@
|
||||
},
|
||||
"then": {
|
||||
"additionalProperties": false,
|
||||
"required": [ "initial_feerate", "last_feerate", "next_feerate", "next_fee_step" ],
|
||||
"required": [ "initial_feerate", "last_feerate", "next_feerate" ],
|
||||
"properties": {
|
||||
"state": { },
|
||||
"scratch_txid": { },
|
||||
@ -831,7 +831,6 @@
|
||||
"short_channel_id": { },
|
||||
"channel_id": { },
|
||||
"funding_txid": { },
|
||||
"inflight": { },
|
||||
"close_to": { },
|
||||
"private": { },
|
||||
"opener": { },
|
||||
@ -901,10 +900,6 @@
|
||||
"next_feerate": {
|
||||
"type": "string",
|
||||
"description": "The minimum feerate for the next funding transaction in per-1000-weight, with \"kpw\" appended"
|
||||
},
|
||||
"next_fee_step": {
|
||||
"type": "u32",
|
||||
"description": "The number of fee steps so far, plus one"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
external/lnprototest
vendored
2
external/lnprototest
vendored
@ -1 +1 @@
|
||||
Subproject commit 740f795bcb6370e205a9826b631c42ff423763ba
|
||||
Subproject commit ff3750b0ce88130c09dcd02086340baaec2be016
|
@ -1986,12 +1986,15 @@ json_openchannel_bump(struct command *cmd,
|
||||
struct channel *channel;
|
||||
struct amount_sat *amount, psbt_val;
|
||||
struct wally_psbt *psbt;
|
||||
u32 last_feerate_perkw, next_feerate_min, *feerate_per_kw_funding;
|
||||
struct open_attempt *oa;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("channel_id", param_channel_id, &cid),
|
||||
p_req("amount", param_sat, &amount),
|
||||
p_req("initialpsbt", param_psbt, &psbt),
|
||||
p_opt("funding_feerate", param_feerate,
|
||||
&feerate_per_kw_funding),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
@ -2033,6 +2036,20 @@ json_openchannel_bump(struct command *cmd,
|
||||
type_to_string(tmpctx, struct channel_id,
|
||||
cid));
|
||||
|
||||
last_feerate_perkw = channel_last_funding_feerate(channel);
|
||||
next_feerate_min = last_feerate_perkw * 65 / 64;
|
||||
assert(next_feerate_min > last_feerate_perkw);
|
||||
if (!feerate_per_kw_funding) {
|
||||
feerate_per_kw_funding = tal(cmd, u32);
|
||||
*feerate_per_kw_funding = next_feerate_min;
|
||||
} else if (*feerate_per_kw_funding < next_feerate_min)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Next feerate must be at least 1/64th"
|
||||
" greater than the last. Min req %u,"
|
||||
" you proposed %u",
|
||||
next_feerate_min,
|
||||
*feerate_per_kw_funding);
|
||||
|
||||
/* BOLT #2:
|
||||
* - if both nodes advertised `option_support_large_channel`:
|
||||
* - MAY set `funding_satoshis` greater than or equal to 2^24 satoshi.
|
||||
@ -2092,7 +2109,9 @@ json_openchannel_bump(struct command *cmd,
|
||||
psbt));
|
||||
|
||||
subd_send_msg(channel->owner,
|
||||
take(towire_dualopend_rbf_init(NULL, *amount, psbt)));
|
||||
take(towire_dualopend_rbf_init(NULL, *amount,
|
||||
*feerate_per_kw_funding,
|
||||
psbt)));
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
@ -2876,7 +2895,7 @@ void peer_restart_dualopend(struct peer *peer,
|
||||
u32 max_to_self_delay;
|
||||
struct amount_msat min_effective_htlc_capacity;
|
||||
struct channel_config unused_config;
|
||||
struct channel_inflight *inflight, *first_inflight;
|
||||
struct channel_inflight *inflight;
|
||||
int hsmfd;
|
||||
u8 *msg;
|
||||
|
||||
@ -2917,12 +2936,6 @@ void peer_restart_dualopend(struct peer *peer,
|
||||
inflight = channel_current_inflight(channel);
|
||||
assert(inflight);
|
||||
|
||||
/* Get the first inflight to figure out the original feerate
|
||||
* for this channel. It's fine if it's the same as the current */
|
||||
first_inflight = list_top(&channel->inflights,
|
||||
struct channel_inflight,
|
||||
list);
|
||||
assert(first_inflight);
|
||||
msg = towire_dualopend_reinit(NULL,
|
||||
chainparams,
|
||||
peer->ld->our_features,
|
||||
@ -2939,7 +2952,6 @@ void peer_restart_dualopend(struct peer *peer,
|
||||
channel->minimum_depth,
|
||||
&inflight->funding->txid,
|
||||
inflight->funding->outnum,
|
||||
first_inflight->funding->feerate,
|
||||
inflight->funding->feerate,
|
||||
channel->funding,
|
||||
channel->our_msat,
|
||||
|
@ -774,32 +774,32 @@ static void json_add_channel(struct lightningd *ld,
|
||||
|
||||
if (!list_empty(&channel->inflights)) {
|
||||
struct channel_inflight *initial, *inflight;
|
||||
u32 last_feerate, next_feerate, feerate;
|
||||
u8 feestep;
|
||||
|
||||
last_feerate = channel_last_funding_feerate(channel);
|
||||
assert(last_feerate > 0);
|
||||
next_feerate = last_feerate + last_feerate / 4;
|
||||
u32 last_feerate, next_feerate;
|
||||
|
||||
initial = list_top(&channel->inflights,
|
||||
struct channel_inflight, list);
|
||||
feerate = initial->funding->feerate;
|
||||
|
||||
json_add_string(response, "initial_feerate",
|
||||
tal_fmt(tmpctx, "%d%s", feerate,
|
||||
tal_fmt(tmpctx, "%d%s",
|
||||
initial->funding->feerate,
|
||||
feerate_style_name(FEERATE_PER_KSIPA)));
|
||||
|
||||
last_feerate = channel_last_funding_feerate(channel);
|
||||
assert(last_feerate > 0);
|
||||
json_add_string(response, "last_feerate",
|
||||
tal_fmt(tmpctx, "%d%s", last_feerate,
|
||||
feerate_style_name(FEERATE_PER_KSIPA)));
|
||||
|
||||
/* BOLT-9e7723387c8859b511e178485605a0b9133b9869 #2:
|
||||
* - MUST set `funding_feerate_perkw` greater than or equal to
|
||||
* 65/64 times the last sent `funding_feerate_perkw`
|
||||
* rounded down.
|
||||
*/
|
||||
next_feerate = last_feerate * 65 / 64;
|
||||
assert(next_feerate > last_feerate);
|
||||
json_add_string(response, "next_feerate",
|
||||
tal_fmt(tmpctx, "%d%s", next_feerate,
|
||||
feerate_style_name(FEERATE_PER_KSIPA)));
|
||||
|
||||
/* Now we derive the feestep */
|
||||
for (feestep = 0; feerate < next_feerate; feestep++)
|
||||
feerate += feerate / 4;
|
||||
json_add_num(response, "next_fee_step", feestep);
|
||||
|
||||
/* List the inflights */
|
||||
json_array_start(response, "inflight");
|
||||
list_for_each(&channel->inflights, inflight, list) {
|
||||
|
@ -165,7 +165,6 @@ struct state {
|
||||
|
||||
enum tx_role our_role;
|
||||
|
||||
u32 feerate_per_kw_funding;
|
||||
u32 feerate_per_kw_commitment;
|
||||
|
||||
/* If non-NULL, this is the scriptpubkey we/they *must* close with */
|
||||
@ -1957,9 +1956,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||
type_to_string(tmpctx, struct channel_id,
|
||||
&cid));
|
||||
|
||||
/* Save feerate on the state as well */
|
||||
state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The receiving node MUST fail the channel if:
|
||||
@ -2002,7 +1998,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||
tx_state->remoteconf.dust_limit,
|
||||
tx_state->remoteconf.max_htlc_value_in_flight,
|
||||
tx_state->remoteconf.htlc_minimum,
|
||||
state->feerate_per_kw_funding,
|
||||
tx_state->feerate_per_kw_funding,
|
||||
state->feerate_per_kw_commitment,
|
||||
tx_state->remoteconf.to_self_delay,
|
||||
tx_state->remoteconf.max_accepted_htlcs,
|
||||
@ -2410,13 +2406,12 @@ static void opener_start(struct state *state, u8 *msg)
|
||||
&tx_state->opener_funding,
|
||||
&state->upfront_shutdown_script[LOCAL],
|
||||
&state->feerate_per_kw_commitment,
|
||||
&state->feerate_per_kw_funding,
|
||||
&tx_state->feerate_per_kw_funding,
|
||||
&state->channel_flags))
|
||||
master_badmsg(WIRE_DUALOPEND_OPENER_INIT, msg);
|
||||
|
||||
state->our_role = TX_INITIATOR;
|
||||
tx_state->tx_locktime = tx_state->psbt->tx->locktime;
|
||||
tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding;
|
||||
open_tlv = tlv_opening_tlvs_new(tmpctx);
|
||||
|
||||
/* BOLT-* #2
|
||||
@ -2444,7 +2439,7 @@ static void opener_start(struct state *state, u8 *msg)
|
||||
msg = towire_open_channel2(NULL,
|
||||
&chainparams->genesis_blockhash,
|
||||
&state->channel_id,
|
||||
state->feerate_per_kw_funding,
|
||||
tx_state->feerate_per_kw_funding,
|
||||
state->feerate_per_kw_commitment,
|
||||
tx_state->opener_funding,
|
||||
tx_state->localconf.dust_limit,
|
||||
@ -2600,52 +2595,29 @@ static void opener_start(struct state *state, u8 *msg)
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
}
|
||||
|
||||
static bool update_feerate(struct tx_state *tx_state,
|
||||
u32 feerate_funding,
|
||||
u32 last_feerate,
|
||||
u8 fee_step)
|
||||
static bool check_funding_feerate(u32 proposed_next_feerate,
|
||||
u32 last_feerate)
|
||||
{
|
||||
u32 feerate = feerate_funding;
|
||||
|
||||
/*
|
||||
* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
||||
* BOLT-9e7723387c8859b511e178485605a0b9133b9869 #2:
|
||||
*
|
||||
* `fee_step` is an integer value, which specifies the
|
||||
* `feerate` for this funding transaction, as a rate of
|
||||
* increase above the `open_channel2`. `funding_feerate_perkw`.
|
||||
*
|
||||
* The effective `funding_feerate_perkw` for this RBF attempt
|
||||
* if calculated as 1.25^`fee_step` * `funding_feerate_perkw`.
|
||||
* E.g. if `feerate_per_kw_funding` is 512 and the `fee_step` is 1,
|
||||
* the effective `feerate` for this RBF attempt is 512 + 512 / 4
|
||||
* or 640 sat/kw. A `fee_step` 2 would be `1.25^2 * 512`
|
||||
* (or 640 + 640 / 4), 800 sat/kw.
|
||||
* The recipient: ...
|
||||
* - MUST fail the negotiation if:
|
||||
* - the `funding_feerate_perkw` is not greater than 65/64 times
|
||||
* `funding_feerate_perkw` of the last successfully negotiated
|
||||
* open attempt
|
||||
*/
|
||||
for (; fee_step > 0; fee_step--)
|
||||
feerate += feerate / 4;
|
||||
u32 next_min = last_feerate * 65 / 64;
|
||||
|
||||
/* It's possible they sent us a 'bad' feerate step,
|
||||
* i.e. less than the last one. */
|
||||
if (feerate <= last_feerate)
|
||||
if (next_min < last_feerate) {
|
||||
status_broken("Overflow calculating next feerate. last %u",
|
||||
last_feerate);
|
||||
return false;
|
||||
}
|
||||
if (last_feerate > proposed_next_feerate)
|
||||
return false;
|
||||
|
||||
tx_state->feerate_per_kw_funding = feerate;
|
||||
return true;
|
||||
}
|
||||
|
||||
static u8 find_next_feestep(u32 last_feerate, u32 feerate_funding,
|
||||
u32 *next_feerate)
|
||||
{
|
||||
u8 feestep;
|
||||
u32 feerate = feerate_funding;
|
||||
assert(last_feerate != 0 && feerate != 0);
|
||||
|
||||
for (feestep = 0; feerate <= last_feerate; feestep++)
|
||||
feerate = feerate + feerate / 4;
|
||||
|
||||
if (next_feerate)
|
||||
*next_feerate = feerate;
|
||||
return feestep;
|
||||
return next_min <= proposed_next_feerate;
|
||||
}
|
||||
|
||||
static void rbf_wrap_up(struct state *state,
|
||||
@ -2739,7 +2711,6 @@ static void rbf_local_start(struct state *state, u8 *msg)
|
||||
struct channel_id cid;
|
||||
struct amount_sat total;
|
||||
char *err_reason;
|
||||
u8 fee_step;
|
||||
|
||||
/* We need a new tx_state! */
|
||||
tx_state = new_tx_state(state);
|
||||
@ -2752,14 +2723,18 @@ static void rbf_local_start(struct state *state, u8 *msg)
|
||||
state->our_role == TX_INITIATOR ?
|
||||
&tx_state->opener_funding :
|
||||
&tx_state->accepter_funding,
|
||||
&tx_state->feerate_per_kw_funding,
|
||||
&tx_state->psbt))
|
||||
master_badmsg(WIRE_DUALOPEND_RBF_INIT, msg);
|
||||
|
||||
peer_billboard(false, "channel rbf: init received from master");
|
||||
|
||||
fee_step = find_next_feestep(state->tx_state->feerate_per_kw_funding,
|
||||
state->feerate_per_kw_funding,
|
||||
&tx_state->feerate_per_kw_funding);
|
||||
if (!check_funding_feerate(tx_state->feerate_per_kw_funding,
|
||||
state->tx_state->feerate_per_kw_funding)) {
|
||||
open_err_warn(state, "Proposed funding feerate (%u) invalid",
|
||||
tx_state->feerate_per_kw_funding);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Have you sent us everything we need yet ? */
|
||||
if (!state->tx_state->remote_funding_sigs_rcvd) {
|
||||
@ -2778,7 +2753,7 @@ static void rbf_local_start(struct state *state, u8 *msg)
|
||||
tx_state->opener_funding :
|
||||
tx_state->accepter_funding,
|
||||
tx_state->tx_locktime,
|
||||
fee_step);
|
||||
tx_state->feerate_per_kw_funding);
|
||||
|
||||
sync_crypto_write(state->pps, take(msg));
|
||||
|
||||
@ -2859,7 +2834,7 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
|
||||
char *err_reason;
|
||||
struct amount_sat total;
|
||||
enum dualopend_wire msg_type;
|
||||
u8 fee_step, *msg;
|
||||
u8 *msg;
|
||||
|
||||
/* We need a new tx_state! */
|
||||
tx_state = new_tx_state(state);
|
||||
@ -2869,7 +2844,7 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
|
||||
&tx_state->accepter_funding :
|
||||
&tx_state->opener_funding,
|
||||
&tx_state->tx_locktime,
|
||||
&fee_step))
|
||||
&tx_state->feerate_per_kw_funding))
|
||||
open_err_fatal(state, "Parsing init_rbf %s",
|
||||
tal_hex(tmpctx, rbf_msg));
|
||||
|
||||
@ -2895,13 +2870,11 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
|
||||
tx_state->localconf = state->tx_state->localconf;
|
||||
tx_state->remoteconf = state->tx_state->remoteconf;
|
||||
|
||||
if (!update_feerate(tx_state,
|
||||
state->feerate_per_kw_funding,
|
||||
state->tx_state->feerate_per_kw_funding,
|
||||
fee_step)) {
|
||||
open_err_warn(state, "Fee step not greater than last."
|
||||
" Fee step %d, last feerate %d",
|
||||
fee_step,
|
||||
if (!check_funding_feerate(tx_state->feerate_per_kw_funding,
|
||||
state->tx_state->feerate_per_kw_funding)) {
|
||||
open_err_warn(state, "Funding feerate not greater than last."
|
||||
"Proposed %u, last feerate %u",
|
||||
tx_state->feerate_per_kw_funding,
|
||||
state->tx_state->feerate_per_kw_funding);
|
||||
tal_free(tx_state);
|
||||
return;
|
||||
@ -3499,7 +3472,6 @@ int main(int argc, char *argv[])
|
||||
&state->minimum_depth,
|
||||
&state->tx_state->funding_txid,
|
||||
&state->tx_state->funding_txout,
|
||||
&state->feerate_per_kw_funding,
|
||||
&state->tx_state->feerate_per_kw_funding,
|
||||
&total_funding,
|
||||
&our_msat,
|
||||
|
@ -45,7 +45,6 @@ msgdata,dualopend_reinit,their_funding_pubkey,pubkey,
|
||||
msgdata,dualopend_reinit,minimum_depth,u32,
|
||||
msgdata,dualopend_reinit,funding_txid,bitcoin_txid,
|
||||
msgdata,dualopend_reinit,funding_txout,u16,
|
||||
msgdata,dualopend_reinit,orignal_feerate_per_kw_funding,u32,
|
||||
msgdata,dualopend_reinit,most_recent_feerate_per_kw_funding,u32,
|
||||
msgdata,dualopend_reinit,funding_satoshi,amount_sat,
|
||||
msgdata,dualopend_reinit,our_funding,amount_msat,
|
||||
@ -110,6 +109,7 @@ msgtype,dualopend_rbf_valid,7507
|
||||
# master->dualopend: attempt an RBF
|
||||
msgtype,dualopend_rbf_init,7509
|
||||
msgdata,dualopend_rbf_init,our_funding,amount_sat,
|
||||
msgdata,dualopend_rbf_init,funding_feerate_perkw,u32,
|
||||
msgdata,dualopend_rbf_init,psbt,wally_psbt,
|
||||
|
||||
# dualopend->master: ready to commit channel open to database and
|
||||
|
Can't render this file because it has a wrong number of fields in line 13.
|
14
openingd/dualopend_wiregen.c
generated
14
openingd/dualopend_wiregen.c
generated
@ -146,7 +146,7 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain
|
||||
|
||||
/* WIRE: DUALOPEND_REINIT */
|
||||
/* master-dualopend: peer has reconnected */
|
||||
u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags)
|
||||
u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags)
|
||||
{
|
||||
u16 their_init_features_len = tal_count(their_init_features);
|
||||
u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey);
|
||||
@ -170,7 +170,6 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar
|
||||
towire_u32(&p, minimum_depth);
|
||||
towire_bitcoin_txid(&p, funding_txid);
|
||||
towire_u16(&p, funding_txout);
|
||||
towire_u32(&p, orignal_feerate_per_kw_funding);
|
||||
towire_u32(&p, most_recent_feerate_per_kw_funding);
|
||||
towire_amount_sat(&p, funding_satoshi);
|
||||
towire_amount_msat(&p, our_funding);
|
||||
@ -192,7 +191,7 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar
|
||||
|
||||
return memcheck(p, tal_count(p));
|
||||
}
|
||||
bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags)
|
||||
bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags)
|
||||
{
|
||||
u16 their_init_features_len;
|
||||
u16 local_shutdown_len;
|
||||
@ -221,7 +220,6 @@ bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct cha
|
||||
*minimum_depth = fromwire_u32(&cursor, &plen);
|
||||
fromwire_bitcoin_txid(&cursor, &plen, funding_txid);
|
||||
*funding_txout = fromwire_u16(&cursor, &plen);
|
||||
*orignal_feerate_per_kw_funding = fromwire_u32(&cursor, &plen);
|
||||
*most_recent_feerate_per_kw_funding = fromwire_u32(&cursor, &plen);
|
||||
*funding_satoshi = fromwire_amount_sat(&cursor, &plen);
|
||||
*our_funding = fromwire_amount_msat(&cursor, &plen);
|
||||
@ -427,17 +425,18 @@ bool fromwire_dualopend_rbf_valid(const void *p)
|
||||
|
||||
/* WIRE: DUALOPEND_RBF_INIT */
|
||||
/* master->dualopend: attempt an RBF */
|
||||
u8 *towire_dualopend_rbf_init(const tal_t *ctx, struct amount_sat our_funding, const struct wally_psbt *psbt)
|
||||
u8 *towire_dualopend_rbf_init(const tal_t *ctx, struct amount_sat our_funding, u32 funding_feerate_perkw, const struct wally_psbt *psbt)
|
||||
{
|
||||
u8 *p = tal_arr(ctx, u8, 0);
|
||||
|
||||
towire_u16(&p, WIRE_DUALOPEND_RBF_INIT);
|
||||
towire_amount_sat(&p, our_funding);
|
||||
towire_u32(&p, funding_feerate_perkw);
|
||||
towire_wally_psbt(&p, psbt);
|
||||
|
||||
return memcheck(p, tal_count(p));
|
||||
}
|
||||
bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_sat *our_funding, struct wally_psbt **psbt)
|
||||
bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_sat *our_funding, u32 *funding_feerate_perkw, struct wally_psbt **psbt)
|
||||
{
|
||||
const u8 *cursor = p;
|
||||
size_t plen = tal_count(p);
|
||||
@ -445,6 +444,7 @@ bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_
|
||||
if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_RBF_INIT)
|
||||
return false;
|
||||
*our_funding = fromwire_amount_sat(&cursor, &plen);
|
||||
*funding_feerate_perkw = fromwire_u32(&cursor, &plen);
|
||||
*psbt = fromwire_wally_psbt(ctx, &cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
@ -912,4 +912,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak)
|
||||
*leak = fromwire_bool(&cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
// SHA256STAMP:a4678b6938e46bd8ab7c6076312789d0cdfa06076d745fd28fd65f3febc4c3a0
|
||||
// SHA256STAMP:2aa38c967abfcd0110b6c65f62b13aa77cefacaf5f036a9217bb5d63220f1e1f
|
||||
|
10
openingd/dualopend_wiregen.h
generated
10
openingd/dualopend_wiregen.h
generated
@ -91,8 +91,8 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain
|
||||
|
||||
/* WIRE: DUALOPEND_REINIT */
|
||||
/* master-dualopend: peer has reconnected */
|
||||
u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags);
|
||||
bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags);
|
||||
u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags);
|
||||
bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags);
|
||||
|
||||
/* WIRE: DUALOPEND_GOT_OFFER */
|
||||
/* dualopend->master: they offered channel */
|
||||
@ -126,8 +126,8 @@ bool fromwire_dualopend_rbf_valid(const void *p);
|
||||
|
||||
/* WIRE: DUALOPEND_RBF_INIT */
|
||||
/* master->dualopend: attempt an RBF */
|
||||
u8 *towire_dualopend_rbf_init(const tal_t *ctx, struct amount_sat our_funding, const struct wally_psbt *psbt);
|
||||
bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_sat *our_funding, struct wally_psbt **psbt);
|
||||
u8 *towire_dualopend_rbf_init(const tal_t *ctx, struct amount_sat our_funding, u32 funding_feerate_perkw, const struct wally_psbt *psbt);
|
||||
bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_sat *our_funding, u32 *funding_feerate_perkw, struct wally_psbt **psbt);
|
||||
|
||||
/* WIRE: DUALOPEND_COMMIT_RCVD */
|
||||
/* dualopend->master: ready to commit channel open to database and */
|
||||
@ -216,4 +216,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak);
|
||||
|
||||
|
||||
#endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */
|
||||
// SHA256STAMP:a4678b6938e46bd8ab7c6076312789d0cdfa06076d745fd28fd65f3febc4c3a0
|
||||
// SHA256STAMP:2aa38c967abfcd0110b6c65f62b13aa77cefacaf5f036a9217bb5d63220f1e1f
|
||||
|
@ -201,7 +201,7 @@ def test_v2_open_sigs_restart_while_dead(node_factory, bitcoind):
|
||||
|
||||
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
|
||||
@pytest.mark.openchannel('v2')
|
||||
def test_v2_rbf(node_factory, bitcoind, chainparams):
|
||||
def test_v2_rbf_single(node_factory, bitcoind, chainparams):
|
||||
l1, l2 = node_factory.get_nodes(2, opts={'wumbo': None})
|
||||
|
||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||
@ -227,8 +227,7 @@ def test_v2_rbf(node_factory, bitcoind, chainparams):
|
||||
info_1 = only_one(only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['channels'])
|
||||
assert info_1['initial_feerate'] == info_1['last_feerate']
|
||||
rate = int(info_1['last_feerate'][:-5])
|
||||
assert int(info_1['next_feerate'][:-5]) == rate + rate // 4
|
||||
assert info_1['next_fee_step'] == 1
|
||||
assert int(info_1['next_feerate'][:-5]) == rate * 65 // 64
|
||||
|
||||
# Initiate an RBF
|
||||
startweight = 42 + 172 # base weight, funding output
|
||||
@ -249,11 +248,36 @@ def test_v2_rbf(node_factory, bitcoind, chainparams):
|
||||
assert info_1['next_feerate'] == info_2['last_feerate']
|
||||
|
||||
rate = int(info_2['last_feerate'][:-5])
|
||||
assert int(info_2['next_feerate'][:-5]) == rate + rate // 4
|
||||
assert info_2['next_fee_step'] == 2
|
||||
assert int(info_2['next_feerate'][:-5]) == rate * 65 // 64
|
||||
|
||||
# Sign our inputs, and continue
|
||||
signed_psbt = l1.rpc.signpsbt(update['psbt'])['signed_psbt']
|
||||
|
||||
# Fails because we didn't put enough feerate in.
|
||||
with pytest.raises(RpcError, match=r'insufficient fee'):
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
|
||||
# Do it again, with a higher feerate
|
||||
info_2 = only_one(only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['channels'])
|
||||
assert info_1['initial_feerate'] == info_2['initial_feerate']
|
||||
assert info_1['next_feerate'] == info_2['last_feerate']
|
||||
rate = int(info_2['last_feerate'][:-5])
|
||||
assert int(info_2['next_feerate'][:-5]) == rate * 65 // 64
|
||||
|
||||
# We 4x the feerate to beat the min-relay fee
|
||||
next_rate = '{}perkw'.format(rate * 65 // 64 * 4)
|
||||
# Gotta unreserve the psbt and re-reserve with higher feerate
|
||||
l1.rpc.unreserveinputs(initpsbt['psbt'])
|
||||
initpsbt = l1.rpc.utxopsbt(chan_amount, next_rate, startweight,
|
||||
prev_utxos, reservedok=True,
|
||||
min_witness_weight=110,
|
||||
excess_as_change=True)
|
||||
# Do the bump+sign
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt'],
|
||||
funding_feerate=next_rate)
|
||||
update = l1.rpc.openchannel_update(chan_id, bump['psbt'])
|
||||
assert update['commitments_secured']
|
||||
signed_psbt = l1.rpc.signpsbt(update['psbt'])['signed_psbt']
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
|
||||
bitcoind.generate_block(1)
|
||||
@ -265,7 +289,6 @@ def test_v2_rbf(node_factory, bitcoind, chainparams):
|
||||
assert 'initial_feerate' not in info_1
|
||||
assert 'last_feerate' not in info_1
|
||||
assert 'next_feerate' not in info_1
|
||||
assert 'next_fee_step' not in info_1
|
||||
|
||||
# Shut l2 down, force close the channel.
|
||||
l2.stop()
|
||||
@ -304,7 +327,9 @@ def test_v2_rbf_multi(node_factory, bitcoind, chainparams):
|
||||
with pytest.raises(RpcError):
|
||||
l1.rpc.openchannel_abort(chan_id)
|
||||
|
||||
next_feerate = find_next_feerate(l1, l2)
|
||||
rate = int(find_next_feerate(l1, l2)[:-5])
|
||||
# We 4x the feerate to beat the min-relay fee
|
||||
next_feerate = '{}perkw'.format(rate * 4)
|
||||
|
||||
# Initiate an RBF
|
||||
startweight = 42 + 172 # base weight, funding output
|
||||
@ -314,15 +339,19 @@ def test_v2_rbf_multi(node_factory, bitcoind, chainparams):
|
||||
excess_as_change=True)
|
||||
|
||||
# Do the bump
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt'])
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount,
|
||||
initpsbt['psbt'],
|
||||
funding_feerate=next_feerate)
|
||||
|
||||
# Abort this open attempt! We will re-try
|
||||
aborted = l1.rpc.openchannel_abort(chan_id)
|
||||
assert not aborted['channel_canceled']
|
||||
|
||||
# Do the bump, again
|
||||
# Do the bump, again, same feerate
|
||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt'])
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount,
|
||||
initpsbt['psbt'],
|
||||
funding_feerate=next_feerate)
|
||||
|
||||
update = l1.rpc.openchannel_update(chan_id, bump['psbt'])
|
||||
assert update['commitments_secured']
|
||||
@ -331,9 +360,11 @@ def test_v2_rbf_multi(node_factory, bitcoind, chainparams):
|
||||
signed_psbt = l1.rpc.signpsbt(update['psbt'])['signed_psbt']
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
|
||||
next_feerate = find_next_feerate(l1, l2)
|
||||
# We 2x the feerate to beat the min-relay fee
|
||||
rate = int(find_next_feerate(l1, l2)[:-5])
|
||||
next_feerate = '{}perkw'.format(rate * 2)
|
||||
|
||||
# Initiate an RBF, double the channel amount this time
|
||||
# Initiate another RBF, double the channel amount this time
|
||||
startweight = 42 + 172 # base weight, funding output
|
||||
initpsbt = l1.rpc.utxopsbt(chan_amount * 2, next_feerate, startweight,
|
||||
prev_utxos, reservedok=True,
|
||||
@ -341,7 +372,9 @@ def test_v2_rbf_multi(node_factory, bitcoind, chainparams):
|
||||
excess_as_change=True)
|
||||
|
||||
# Do the bump
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount * 2, initpsbt['psbt'])
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount * 2,
|
||||
initpsbt['psbt'],
|
||||
funding_feerate=next_feerate)
|
||||
|
||||
update = l1.rpc.openchannel_update(chan_id, bump['psbt'])
|
||||
assert update['commitments_secured']
|
||||
@ -724,14 +757,18 @@ def test_rbf_fails_to_broadcast(node_factory, bitcoind, chainparams):
|
||||
|
||||
def run_retry():
|
||||
startweight = 42 + 173
|
||||
next_feerate = find_next_feerate(l1, l2)
|
||||
rate = int(find_next_feerate(l1, l2)[:-5])
|
||||
# We 2x the feerate to beat the min-relay fee
|
||||
next_feerate = '{}perkw'.format(rate * 2)
|
||||
initpsbt = l1.rpc.utxopsbt(chan_amount, next_feerate, startweight,
|
||||
prev_utxos, reservedok=True,
|
||||
min_witness_weight=110,
|
||||
excess_as_change=True)
|
||||
|
||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt'])
|
||||
bump = l1.rpc.openchannel_bump(chan_id, chan_amount,
|
||||
initpsbt['psbt'],
|
||||
funding_feerate=next_feerate)
|
||||
# We should be able to call this with while an open is progress
|
||||
# but not yet committed
|
||||
l1.rpc.dev_sign_last_tx(l2.info['id'])
|
||||
@ -741,37 +778,19 @@ def test_rbf_fails_to_broadcast(node_factory, bitcoind, chainparams):
|
||||
return l1.rpc.signpsbt(update['psbt'])['signed_psbt']
|
||||
|
||||
signed_psbt = run_retry()
|
||||
with pytest.raises(RpcError, match=r'insufficient fee, rejecting replacement'):
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
inflights = only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['inflight']
|
||||
assert inflights[-1]['funding_txid'] not in bitcoind.rpc.getrawmempool()
|
||||
assert inflights[-1]['funding_txid'] in bitcoind.rpc.getrawmempool()
|
||||
|
||||
# If we restart and listpeers, it will crash
|
||||
# Restart and listpeers, used to crash
|
||||
l1.restart()
|
||||
|
||||
l1.rpc.listpeers()
|
||||
|
||||
# We've restarted. Let's RBF until we successfully get a
|
||||
# new funding transaction for this channel
|
||||
# do it again
|
||||
signed_psbt = run_retry()
|
||||
with pytest.raises(RpcError, match=r'insufficient fee, rejecting replacement'):
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
inflights = only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['inflight']
|
||||
assert inflights[-1]['funding_txid'] not in bitcoind.rpc.getrawmempool()
|
||||
|
||||
# and again
|
||||
signed_psbt = run_retry()
|
||||
with pytest.raises(RpcError, match=r'insufficient fee, rejecting replacement'):
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
inflights = only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['inflight']
|
||||
assert inflights[-1]['funding_txid'] not in bitcoind.rpc.getrawmempool()
|
||||
|
||||
# now we should be ok
|
||||
# We've restarted. Let's RBF
|
||||
signed_psbt = run_retry()
|
||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||
inflights = only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['inflight']
|
||||
assert len(inflights) == 5
|
||||
assert len(inflights) == 3
|
||||
assert inflights[-1]['funding_txid'] in bitcoind.rpc.getrawmempool()
|
||||
|
||||
l1.restart()
|
||||
@ -896,7 +915,9 @@ def test_rbf_non_last_mined(node_factory, bitcoind, chainparams):
|
||||
|
||||
def run_retry():
|
||||
startweight = 42 + 173
|
||||
next_feerate = find_next_feerate(l1, l2)
|
||||
rate = int(find_next_feerate(l1, l2)[:-5])
|
||||
# We 2x the feerate to beat the min-relay fee
|
||||
next_feerate = '{}perkw'.format(rate * 2)
|
||||
initpsbt = l1.rpc.utxopsbt(chan_amount, next_feerate, startweight,
|
||||
prev_utxos, reservedok=True,
|
||||
min_witness_weight=110,
|
||||
|
@ -91,7 +91,7 @@
|
||||
+msgdata,init_rbf,channel_id,channel_id,
|
||||
+msgdata,init_rbf,funding_satoshis,u64,
|
||||
+msgdata,init_rbf,locktime,u32,
|
||||
+msgdata,init_rbf,fee_step,byte,
|
||||
+msgdata,init_rbf,funding_feerate_perkw,u32,
|
||||
+msgtype,ack_rbf,73
|
||||
+msgdata,ack_rbf,channel_id,channel_id,
|
||||
+msgdata,ack_rbf,funding_satoshis,u64,
|
||||
|
8
wire/peer_printgen.c
generated
8
wire/peer_printgen.c
generated
@ -1808,10 +1808,10 @@ void printwire_init_rbf(const char *fieldname, const u8 *cursor)
|
||||
printf("**TRUNCATED**\n");
|
||||
return;
|
||||
}
|
||||
printf("fee_step=");
|
||||
u8 fee_step = fromwire_u8(&cursor, &plen);
|
||||
printf("funding_feerate_perkw=");
|
||||
u32 funding_feerate_perkw = fromwire_u32(&cursor, &plen);
|
||||
|
||||
printwire_u8(tal_fmt(NULL, "%s.fee_step", fieldname), &fee_step);
|
||||
printwire_u32(tal_fmt(NULL, "%s.funding_feerate_perkw", fieldname), &funding_feerate_perkw);
|
||||
if (!cursor) {
|
||||
printf("**TRUNCATED**\n");
|
||||
return;
|
||||
@ -2935,4 +2935,4 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) {
|
||||
printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_onion_message_tlvs, ARRAY_SIZE(print_tlvs_onion_message_tlvs));
|
||||
}
|
||||
}
|
||||
// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd
|
||||
// SHA256STAMP:a3a508935b99ff0b985d0774432ae9d98f3ec7660bf4edf64095a3d0a37ba0e8
|
||||
|
2
wire/peer_printgen.h
generated
2
wire/peer_printgen.h
generated
@ -96,4 +96,4 @@ void printwire_channel_update_checksums(const char *fieldname, const u8 **cursor
|
||||
void printwire_channel_update_timestamps(const char *fieldname, const u8 **cursor, size_t *plen);
|
||||
void printwire_witness_stack(const char *fieldname, const u8 **cursor, size_t *plen);
|
||||
#endif /* LIGHTNING_WIRE_PEER_PRINTGEN_H */
|
||||
// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd
|
||||
// SHA256STAMP:a3a508935b99ff0b985d0774432ae9d98f3ec7660bf4edf64095a3d0a37ba0e8
|
||||
|
@ -166,7 +166,7 @@ msgtype,init_rbf,72
|
||||
msgdata,init_rbf,channel_id,channel_id,
|
||||
msgdata,init_rbf,funding_satoshis,u64,
|
||||
msgdata,init_rbf,locktime,u32,
|
||||
msgdata,init_rbf,fee_step,byte,
|
||||
msgdata,init_rbf,funding_feerate_perkw,u32,
|
||||
msgtype,ack_rbf,73
|
||||
msgdata,ack_rbf,channel_id,channel_id,
|
||||
msgdata,ack_rbf,funding_satoshis,u64,
|
||||
|
|
10
wire/peer_wiregen.c
generated
10
wire/peer_wiregen.c
generated
@ -1623,7 +1623,7 @@ bool fromwire_accept_channel2(const void *p, struct channel_id *channel_id, stru
|
||||
}
|
||||
|
||||
/* WIRE: INIT_RBF */
|
||||
u8 *towire_init_rbf(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat funding_satoshis, u32 locktime, u8 fee_step)
|
||||
u8 *towire_init_rbf(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat funding_satoshis, u32 locktime, u32 funding_feerate_perkw)
|
||||
{
|
||||
u8 *p = tal_arr(ctx, u8, 0);
|
||||
|
||||
@ -1631,11 +1631,11 @@ u8 *towire_init_rbf(const tal_t *ctx, const struct channel_id *channel_id, struc
|
||||
towire_channel_id(&p, channel_id);
|
||||
towire_amount_sat(&p, funding_satoshis);
|
||||
towire_u32(&p, locktime);
|
||||
towire_u8(&p, fee_step);
|
||||
towire_u32(&p, funding_feerate_perkw);
|
||||
|
||||
return memcheck(p, tal_count(p));
|
||||
}
|
||||
bool fromwire_init_rbf(const void *p, struct channel_id *channel_id, struct amount_sat *funding_satoshis, u32 *locktime, u8 *fee_step)
|
||||
bool fromwire_init_rbf(const void *p, struct channel_id *channel_id, struct amount_sat *funding_satoshis, u32 *locktime, u32 *funding_feerate_perkw)
|
||||
{
|
||||
const u8 *cursor = p;
|
||||
size_t plen = tal_count(p);
|
||||
@ -1645,7 +1645,7 @@ bool fromwire_init_rbf(const void *p, struct channel_id *channel_id, struct amou
|
||||
fromwire_channel_id(&cursor, &plen, channel_id);
|
||||
*funding_satoshis = fromwire_amount_sat(&cursor, &plen);
|
||||
*locktime = fromwire_u32(&cursor, &plen);
|
||||
*fee_step = fromwire_u8(&cursor, &plen);
|
||||
*funding_feerate_perkw = fromwire_u32(&cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
|
||||
@ -2330,4 +2330,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec
|
||||
*htlc_maximum_msat = fromwire_amount_msat(&cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd
|
||||
// SHA256STAMP:a3a508935b99ff0b985d0774432ae9d98f3ec7660bf4edf64095a3d0a37ba0e8
|
||||
|
6
wire/peer_wiregen.h
generated
6
wire/peer_wiregen.h
generated
@ -766,8 +766,8 @@ u8 *towire_accept_channel2(const tal_t *ctx, const struct channel_id *channel_id
|
||||
bool fromwire_accept_channel2(const void *p, struct channel_id *channel_id, struct amount_sat *funding_satoshis, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *minimum_depth, u16 *to_self_delay, u16 *max_accepted_htlcs, struct pubkey *funding_pubkey, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *first_per_commitment_point, struct tlv_accept_tlvs *tlvs);
|
||||
|
||||
/* WIRE: INIT_RBF */
|
||||
u8 *towire_init_rbf(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat funding_satoshis, u32 locktime, u8 fee_step);
|
||||
bool fromwire_init_rbf(const void *p, struct channel_id *channel_id, struct amount_sat *funding_satoshis, u32 *locktime, u8 *fee_step);
|
||||
u8 *towire_init_rbf(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat funding_satoshis, u32 locktime, u32 funding_feerate_perkw);
|
||||
bool fromwire_init_rbf(const void *p, struct channel_id *channel_id, struct amount_sat *funding_satoshis, u32 *locktime, u32 *funding_feerate_perkw);
|
||||
|
||||
/* WIRE: ACK_RBF */
|
||||
u8 *towire_ack_rbf(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat funding_satoshis);
|
||||
@ -859,4 +859,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec
|
||||
|
||||
|
||||
#endif /* LIGHTNING_WIRE_PEER_WIREGEN_H */
|
||||
// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd
|
||||
// SHA256STAMP:a3a508935b99ff0b985d0774432ae9d98f3ec7660bf4edf64095a3d0a37ba0e8
|
||||
|
Loading…
Reference in New Issue
Block a user