mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 20:09:18 +01:00
dualopend: if required, validate inputs rcvd from peer
Pass in the "validate inputs confirmed" flag from lightningd; use flag to determine whether or not to validate the inputs we've recieved from peer.
This commit is contained in:
parent
442b479d2c
commit
fa80f15f85
3 changed files with 98 additions and 20 deletions
|
@ -3636,7 +3636,8 @@ bool peer_start_dualopend(struct peer *peer,
|
|||
min_effective_htlc_capacity,
|
||||
&channel->local_basepoints,
|
||||
&channel->local_funding_pubkey,
|
||||
channel->minimum_depth);
|
||||
channel->minimum_depth,
|
||||
peer->ld->config.require_confirmed_inputs);
|
||||
subd_send_msg(channel->owner, take(msg));
|
||||
return true;
|
||||
}
|
||||
|
@ -3744,7 +3745,8 @@ bool peer_restart_dualopend(struct peer *peer,
|
|||
inflight->lease_chan_max_ppt,
|
||||
amount_sat_zero(inflight->lease_amt) ?
|
||||
NULL : &inflight->lease_amt,
|
||||
channel->type);
|
||||
channel->type,
|
||||
false); /* FIXME: use persisted state? */
|
||||
|
||||
subd_send_msg(channel->owner, take(msg));
|
||||
return true;
|
||||
|
|
|
@ -218,7 +218,7 @@ struct state {
|
|||
struct amount_sat *requested_lease;
|
||||
|
||||
/* Does this negotation require confirmed inputs? */
|
||||
bool require_confirmed_inputs;
|
||||
bool require_confirmed_inputs[NUM_SIDES];
|
||||
};
|
||||
|
||||
/* psbt_changeset_get_next - Get next message to send
|
||||
|
@ -517,6 +517,35 @@ static bool is_dust(struct tx_state *tx_state,
|
|||
|| !amount_sat_greater(amount, tx_state->remoteconf.dust_limit);
|
||||
}
|
||||
|
||||
static char *validate_inputs(struct state *state,
|
||||
struct tx_state *tx_state,
|
||||
enum tx_role role_to_validate)
|
||||
{
|
||||
/* BOLT-18195c86294f503ffd2f11563250c854a50bfa51 #2:
|
||||
* Upon receipt of consecutive `tx_complete`s, the receiving node:
|
||||
* ...
|
||||
* - if it has sent `require_confirmed_inputs` in `open_channel2`
|
||||
* or `accept_channel2`:
|
||||
* - MUST fail the negotiation if:
|
||||
* - one of the inputs added by the other peer is unconfirmed
|
||||
*/
|
||||
u8 *msg;
|
||||
char *err_reason;
|
||||
|
||||
msg = towire_dualopend_validate_inputs(NULL, tx_state->psbt,
|
||||
role_to_validate);
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
|
||||
if (!fromwire_dualopend_validate_inputs_reply(msg)) {
|
||||
if (!fromwire_dualopend_fail(tmpctx, msg, &err_reason))
|
||||
master_badmsg(fromwire_peektype(msg), msg);
|
||||
return err_reason;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void set_reserve(struct tx_state *tx_state,
|
||||
struct amount_sat funding_total,
|
||||
enum tx_role our_role)
|
||||
|
@ -1136,7 +1165,7 @@ fetch_psbt_changes(struct state *state,
|
|||
|
||||
/* Go ask lightningd what other changes we've got */
|
||||
msg = towire_dualopend_psbt_changed(NULL, &state->channel_id,
|
||||
state->require_confirmed_inputs,
|
||||
state->require_confirmed_inputs[REMOTE],
|
||||
tx_state->funding_serial,
|
||||
psbt);
|
||||
|
||||
|
@ -2207,7 +2236,8 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
|||
open_err_fatal(state, "Parsing open_channel2 %s",
|
||||
tal_hex(tmpctx, oc2_msg));
|
||||
|
||||
state->require_confirmed_inputs = open_tlv->require_confirmed_inputs != NULL;
|
||||
state->require_confirmed_inputs[REMOTE] =
|
||||
open_tlv->require_confirmed_inputs != NULL;
|
||||
|
||||
if (open_tlv->upfront_shutdown_script)
|
||||
set_remote_upfront_shutdown(state, open_tlv->upfront_shutdown_script);
|
||||
|
@ -2326,7 +2356,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
|||
state->upfront_shutdown_script[REMOTE],
|
||||
state->requested_lease,
|
||||
tx_state->blockheight,
|
||||
state->require_confirmed_inputs);
|
||||
state->require_confirmed_inputs[REMOTE]);
|
||||
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
|
@ -2493,6 +2523,16 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
|||
state->our_funding_pubkey,
|
||||
tx_state->blockheight);
|
||||
|
||||
/* BOLT-18195c86294f503ffd2f11563250c854a50bfa51 #2:
|
||||
*
|
||||
* The sending node may require the other participant to
|
||||
* only use confirmed inputs. This ensures that the sending
|
||||
* node doesn't end up paying the fees of a low feerate
|
||||
* unconfirmed ancestor of one of the other participant's inputs.
|
||||
*/
|
||||
if (state->require_confirmed_inputs[LOCAL])
|
||||
a_tlv->require_confirmed_inputs =
|
||||
tal(a_tlv, struct tlv_accept_tlvs_require_confirmed_inputs);
|
||||
|
||||
msg = towire_accept_channel2(tmpctx, &state->channel_id,
|
||||
/* Our amount w/o the lease fee */
|
||||
|
@ -2527,6 +2567,14 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
|||
if (!run_tx_interactive(state, tx_state, &tx_state->psbt, TX_ACCEPTER))
|
||||
return;
|
||||
|
||||
if (state->require_confirmed_inputs[LOCAL]) {
|
||||
err_reason = validate_inputs(state, tx_state, TX_INITIATOR);
|
||||
if (err_reason) {
|
||||
open_abort(state, "%s", err_reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
msg = accepter_commits(state, tx_state, total, &err_reason);
|
||||
if (!msg) {
|
||||
if (err_reason)
|
||||
|
@ -2927,6 +2975,17 @@ static void opener_start(struct state *state, u8 *msg)
|
|||
open_tlv->request_funds->blockheight = tx_state->blockheight;
|
||||
}
|
||||
|
||||
/* BOLT-18195c86294f503ffd2f11563250c854a50bfa51 #2:
|
||||
*
|
||||
* The sending node may require the other participant to
|
||||
* only use confirmed inputs. This ensures that the sending
|
||||
* node doesn't end up paying the fees of a low feerate
|
||||
* unconfirmed ancestor of one of the other participant's inputs.
|
||||
*/
|
||||
if (state->require_confirmed_inputs[LOCAL])
|
||||
open_tlv->require_confirmed_inputs =
|
||||
tal(open_tlv, struct tlv_opening_tlvs_require_confirmed_inputs);
|
||||
|
||||
msg = towire_open_channel2(NULL,
|
||||
&chainparams->genesis_blockhash,
|
||||
&state->channel_id,
|
||||
|
@ -2997,7 +3056,8 @@ static void opener_start(struct state *state, u8 *msg)
|
|||
}
|
||||
|
||||
/* Set the require confirms from peer's TLVs */
|
||||
state->require_confirmed_inputs = a_tlv->require_confirmed_inputs != NULL;
|
||||
state->require_confirmed_inputs[REMOTE] =
|
||||
a_tlv->require_confirmed_inputs != NULL;
|
||||
|
||||
if (a_tlv->upfront_shutdown_script)
|
||||
set_remote_upfront_shutdown(state, a_tlv->upfront_shutdown_script);
|
||||
|
@ -3015,7 +3075,7 @@ static void opener_start(struct state *state, u8 *msg)
|
|||
msg = towire_dualopend_dry_run(NULL, &state->channel_id,
|
||||
tx_state->opener_funding,
|
||||
tx_state->accepter_funding,
|
||||
state->require_confirmed_inputs,
|
||||
state->require_confirmed_inputs[REMOTE],
|
||||
a_tlv->will_fund
|
||||
? &a_tlv->will_fund->lease_rates
|
||||
: NULL);
|
||||
|
@ -3185,16 +3245,9 @@ static void opener_start(struct state *state, u8 *msg)
|
|||
|
||||
/* We need to check that the inputs we've already provided
|
||||
* via the API are confirmed :/ */
|
||||
if (state->require_confirmed_inputs) {
|
||||
msg = towire_dualopend_validate_inputs(NULL, tx_state->psbt,
|
||||
state->our_role);
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
|
||||
if (!fromwire_dualopend_validate_inputs_reply(msg)) {
|
||||
if (!fromwire_dualopend_fail(msg, msg, &err_reason))
|
||||
master_badmsg(fromwire_peektype(msg), msg);
|
||||
/* We abort, because we don't have valid inputs */
|
||||
if (state->require_confirmed_inputs[REMOTE]) {
|
||||
err_reason = validate_inputs(state, tx_state, state->our_role);
|
||||
if (err_reason) {
|
||||
open_abort(state, "%s", err_reason);
|
||||
return;
|
||||
}
|
||||
|
@ -3239,6 +3292,15 @@ static void opener_start(struct state *state, u8 *msg)
|
|||
if (!run_tx_interactive(state, tx_state, &tx_state->psbt, TX_INITIATOR))
|
||||
return;
|
||||
|
||||
if (state->require_confirmed_inputs[LOCAL]) {
|
||||
err_reason = validate_inputs(state, tx_state, TX_ACCEPTER);
|
||||
if (err_reason) {
|
||||
open_abort(state, "%s", err_reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
msg = opener_commits(state, tx_state, total, &err_reason);
|
||||
if (!msg) {
|
||||
if (err_reason)
|
||||
|
@ -3318,6 +3380,16 @@ static void rbf_wrap_up(struct state *state,
|
|||
return;
|
||||
}
|
||||
|
||||
if (state->require_confirmed_inputs[LOCAL]) {
|
||||
err_reason = validate_inputs(state, tx_state,
|
||||
state->our_role == TX_INITIATOR ?
|
||||
TX_ACCEPTER : TX_INITIATOR);
|
||||
if (err_reason) {
|
||||
open_abort(state, "%s", err_reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is this an eligible RBF (at least one overlapping input) */
|
||||
msg = towire_dualopend_rbf_validate(NULL, tx_state->psbt);
|
||||
wire_sync_write(REQ_FD, take(msg));
|
||||
|
@ -4156,7 +4228,8 @@ int main(int argc, char *argv[])
|
|||
&state->min_effective_htlc_capacity,
|
||||
&state->our_points,
|
||||
&state->our_funding_pubkey,
|
||||
&state->minimum_depth)) {
|
||||
&state->minimum_depth,
|
||||
&state->require_confirmed_inputs[LOCAL])) {
|
||||
/*~ Initially we're not associated with a channel, but
|
||||
* handle_peer_gossip_or_error compares this. */
|
||||
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
||||
|
@ -4215,7 +4288,8 @@ int main(int argc, char *argv[])
|
|||
&state->tx_state->lease_chan_max_msat,
|
||||
&state->tx_state->lease_chan_max_ppt,
|
||||
&requested_lease,
|
||||
&state->channel_type)) {
|
||||
&state->channel_type,
|
||||
&state->require_confirmed_inputs[LOCAL])) {
|
||||
|
||||
bool ok;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ msgdata,dualopend_init,our_basepoints,basepoints,
|
|||
msgdata,dualopend_init,our_funding_pubkey,pubkey,
|
||||
# Constraints in case the other end tries to open a channel.
|
||||
msgdata,dualopend_init,minimum_depth,u32,
|
||||
msgdata,dualopend_init,require_confirmed_inputs,bool,
|
||||
|
||||
# master-dualopend: peer has reconnected
|
||||
msgtype,dualopend_reinit,7001
|
||||
|
@ -71,6 +72,7 @@ msgdata,dualopend_reinit,lease_chan_max_msat,u32,
|
|||
msgdata,dualopend_reinit,lease_chan_max_ppt,u16,
|
||||
msgdata,dualopend_reinit,requested_lease,?amount_sat,
|
||||
msgdata,dualopend_reinit,channel_type,channel_type,
|
||||
msgdata,dualopend_reinit,we_require_confirmed_inputs,bool,
|
||||
|
||||
# dualopend->master: they offered channel, should we continue?
|
||||
msgtype,dualopend_got_offer,7005
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 16.
|
Loading…
Add table
Reference in a new issue