diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index e5bae4501..c1fad569b 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -2941,6 +2941,31 @@ static struct command_result *json_openchannel_init(struct command *cmd, return command_still_pending(cmd); } +static void handle_validate_inputs(struct subd *dualopend, + const u8 *msg) +{ + struct wally_psbt *psbt; + enum tx_role role_to_validate; + + if (!fromwire_dualopend_validate_inputs(msg, msg, + &psbt, + &role_to_validate)) { + channel_internal_error(dualopend->channel, + "Bad DUALOPEND_VALIDATE_INPUTS: %s", + tal_hex(msg, msg)); + return; + } + + /* FIXME: actually validate inputs on psbt */ + log_debug(dualopend->ld->log, + "validating psbt for role: %s", + role_to_validate == TX_INITIATOR ? + "initiator" : "accepter"); + + subd_send_msg(dualopend, + take(towire_dualopend_validate_inputs_reply(NULL))); +} + static void channel_fail_fallen_behind(struct subd* dualopend, const u8 *msg) { @@ -3268,6 +3293,9 @@ static unsigned int dual_opend_msg(struct subd *dualopend, case WIRE_DUALOPEND_LOCAL_PRIVATE_CHANNEL: handle_local_private_channel(dualopend, msg); return 0; + case WIRE_DUALOPEND_VALIDATE_INPUTS: + handle_validate_inputs(dualopend, msg); + return 0; /* Messages we send */ case WIRE_DUALOPEND_INIT: case WIRE_DUALOPEND_REINIT: @@ -3275,6 +3303,7 @@ static unsigned int dual_opend_msg(struct subd *dualopend, case WIRE_DUALOPEND_RBF_INIT: case WIRE_DUALOPEND_GOT_OFFER_REPLY: case WIRE_DUALOPEND_GOT_RBF_OFFER_REPLY: + case WIRE_DUALOPEND_VALIDATE_INPUTS_REPLY: case WIRE_DUALOPEND_RBF_VALID: case WIRE_DUALOPEND_VALIDATE_LEASE_REPLY: case WIRE_DUALOPEND_FAIL: diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 0a2a5ffe6..267a477d0 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -3182,6 +3182,23 @@ static void opener_start(struct state *state, u8 *msg) return; } + /* 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 */ + open_abort(state, "%s", err_reason); + return; + } + } + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The sending node: * - if is the *opener*: @@ -3974,6 +3991,7 @@ static u8 *handle_master_in(struct state *state) case WIRE_DUALOPEND_RBF_VALID: case WIRE_DUALOPEND_VALIDATE_LEASE_REPLY: case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY: + case WIRE_DUALOPEND_VALIDATE_INPUTS_REPLY: /* Messages we send */ case WIRE_DUALOPEND_GOT_OFFER: @@ -3991,6 +4009,7 @@ static u8 *handle_master_in(struct state *state) case WIRE_DUALOPEND_DRY_RUN: case WIRE_DUALOPEND_VALIDATE_LEASE: case WIRE_DUALOPEND_LOCAL_PRIVATE_CHANNEL: + case WIRE_DUALOPEND_VALIDATE_INPUTS: break; } status_failed(STATUS_FAIL_MASTER_IO, diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index 9a734d84b..766bfd02b 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -245,6 +245,14 @@ msgdata,dualopend_dry_run,their_funding,amount_sat, # must go last because of embedded tu32 msgdata,dualopend_dry_run,lease_rates,?lease_rates, +# dualopend -> master: are inputs in this psbt confirmed? +msgtype,dualopend_validate_inputs,7029 +msgdata,dualopend_validate_inputs,psbt,wally_psbt, +msgdata,dualopend_validate_inputs,side,enum tx_role, + +# master -> dualopend: confirms inputs are valid +msgtype,dualopend_validate_inputs_reply,7030 + # dualopend -> master: validate liqudity offer sig msgtype,dualopend_validate_lease,7027 msgdata,dualopend_validate_lease,sig,secp256k1_ecdsa_signature,