v2 open: if flagged, check that all our inputs are confirmed

not amazing, since we'll probably call openchannel_update multiple
times per open, but this is the simplest way to confirm that we're
not sending unconfirmed outputs to peer.
This commit is contained in:
niftynei 2023-01-09 15:44:26 -06:00 committed by Alex Myers
parent 813401b2a6
commit 739d3c7b47
4 changed files with 108 additions and 1 deletions

View file

@ -70,6 +70,7 @@ struct open_attempt {
struct command *cmd;
struct amount_sat funding;
const u8 *our_upfront_shutdown_script;
bool req_confirmed_ins;
/* First msg to send to dualopend (to make it create channel) */
const u8 *open_msg;

View file

@ -2562,6 +2562,72 @@ json_openchannel_signed(struct command *cmd,
return command_still_pending(cmd);
}
struct psbt_validator {
struct command *cmd;
struct channel *channel;
struct wally_psbt *psbt;
size_t next_index;
};
static void validate_input_unspent(struct bitcoind *bitcoind,
const struct bitcoin_tx_output *txout,
void *arg)
{
struct psbt_validator *pv = arg;
u8 *msg;
/* First time thru bitcoind will be NULL, otherwise is response */
if (bitcoind && !txout) {
struct bitcoin_outpoint outpoint;
assert(pv->next_index > 0);
wally_tx_input_get_outpoint(&pv->psbt->tx->inputs[pv->next_index - 1],
&outpoint);
/* Check cmd is still around? */
was_pending(command_fail(pv->cmd,
FUNDING_PSBT_INVALID,
"Peer has requested only confirmed"
" inputs for this open."
" Input %s is not confirmed.",
type_to_string(tmpctx,
struct bitcoin_outpoint,
&outpoint)));
}
for (size_t i = pv->next_index; i < pv->psbt->num_inputs; i++) {
struct bitcoin_outpoint outpoint;
u64 serial;
if (!psbt_get_serial_id(&pv->psbt->inputs[i].unknowns, &serial)) {
was_pending(command_fail(pv->cmd, FUNDING_PSBT_INVALID,
"PSBT input at index %"PRIu64
" missing serial id", i));
return;
}
/* Ignore any input that's peer's */
if (serial % 2 == TX_ACCEPTER)
continue;
wally_tx_input_get_outpoint(&pv->psbt->tx->inputs[i],
&outpoint);
pv->next_index = i + 1;
/* Confirm input is in a block */
bitcoind_getutxout(pv->channel->owner->ld->topology->bitcoind,
&outpoint,
validate_input_unspent,
pv);
/* Command is still pending */
return;
}
pv->channel->open_attempt->cmd = pv->cmd;
msg = towire_dualopend_psbt_updated(NULL, pv->psbt);
subd_send_msg(pv->channel->owner, take(msg));
/* Command is still pending */
}
static struct command_result *json_openchannel_update(struct command *cmd,
const char *buffer,
@ -2614,6 +2680,24 @@ static struct command_result *json_openchannel_update(struct command *cmd,
type_to_string(tmpctx, struct wally_psbt,
psbt));
if (channel->open_attempt->req_confirmed_ins) {
struct psbt_validator *pv;
struct command_result *ret;
/* Save the info for the next round! */
pv = tal(cmd, struct psbt_validator);
pv->cmd = cmd;
pv->channel = channel;
pv->next_index = 0;
pv->psbt = psbt;
/* We might fail/terminate in validate's first call,
* which expects us to be at "command still pending" */
ret = command_still_pending(cmd);
validate_input_unspent(NULL, NULL, pv);
return ret;
}
channel->open_attempt->cmd = cmd;
msg = towire_dualopend_psbt_updated(NULL, psbt);

View file

@ -0,0 +1,20 @@
--- wire/peer_wire.csv 2023-01-09 12:09:54.439255190 -0600
+++ - 2023-01-09 12:15:37.608035051 -0600
@@ -171,6 +173,7 @@
tlvtype,opening_tlvs,request_funds,3
tlvdata,opening_tlvs,request_funds,requested_sats,u64,
tlvdata,opening_tlvs,request_funds,blockheight,u32,
+tlvtype,opening_tlvs,require_confirmed_inputs,2
msgtype,accept_channel2,65
msgdata,accept_channel2,zerod_channel_id,channel_id,
msgdata,accept_channel2,funding_satoshis,u64,
@@ -190,7 +191,8 @@
tlvdata,accept_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,...
tlvtype,accept_tlvs,channel_type,1
tlvdata,accept_tlvs,channel_type,type,byte,...
+tlvtype,accept_tlvs,require_confirmed_inputs,2
-tlvtype,accept_tlvs,will_fund,2
+tlvtype,accept_tlvs,will_fund,3
tlvdata,accept_tlvs,will_fund,signature,signature,
tlvdata,accept_tlvs,will_fund,lease_rates,lease_rates,
subtype,lease_rates

View file

@ -170,6 +170,7 @@ tlvdata,opening_tlvs,channel_type,type,byte,...
tlvtype,opening_tlvs,request_funds,3
tlvdata,opening_tlvs,request_funds,requested_sats,u64,
tlvdata,opening_tlvs,request_funds,blockheight,u32,
tlvtype,opening_tlvs,require_confirmed_inputs,2
msgtype,accept_channel2,65
msgdata,accept_channel2,zerod_channel_id,channel_id,
msgdata,accept_channel2,funding_satoshis,u64,
@ -190,7 +191,8 @@ tlvtype,accept_tlvs,upfront_shutdown_script,0
tlvdata,accept_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,...
tlvtype,accept_tlvs,channel_type,1
tlvdata,accept_tlvs,channel_type,type,byte,...
tlvtype,accept_tlvs,will_fund,2
tlvtype,accept_tlvs,require_confirmed_inputs,2
tlvtype,accept_tlvs,will_fund,3
tlvdata,accept_tlvs,will_fund,signature,signature,
tlvdata,accept_tlvs,will_fund,lease_rates,lease_rates,
subtype,lease_rates

1 msgtype,init,16
170 tlvtype,opening_tlvs,request_funds,3
171 tlvdata,opening_tlvs,request_funds,requested_sats,u64,
172 tlvdata,opening_tlvs,request_funds,blockheight,u32,
173 tlvtype,opening_tlvs,require_confirmed_inputs,2
174 msgtype,accept_channel2,65
175 msgdata,accept_channel2,zerod_channel_id,channel_id,
176 msgdata,accept_channel2,funding_satoshis,u64,
191 tlvdata,accept_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,...
192 tlvtype,accept_tlvs,channel_type,1
193 tlvdata,accept_tlvs,channel_type,type,byte,...
194 tlvtype,accept_tlvs,will_fund,2 tlvtype,accept_tlvs,require_confirmed_inputs,2
195 tlvtype,accept_tlvs,will_fund,3
196 tlvdata,accept_tlvs,will_fund,signature,signature,
197 tlvdata,accept_tlvs,will_fund,lease_rates,lease_rates,
198 subtype,lease_rates