diff --git a/channeld/Makefile b/channeld/Makefile index d5c06a474..a6ec19ed4 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -70,6 +70,7 @@ CHANNELD_COMMON_OBJS := \ common/per_peer_state.o \ common/permute_tx.o \ common/ping.o \ + common/psbt_open.o \ common/pseudorand.o \ common/read_peer_msg.o \ common/setup.o \ @@ -90,7 +91,7 @@ CHANNELD_COMMON_OBJS := \ wire/towire.o ifeq ($(EXPERIMENTAL_FEATURES),1) -CHANNELD_COMMON_OBJS += common/psbt_open.o +CHANNELD_COMMON_OBJS += common/psbt_internal.o endif channeld/gen_full_channel_error_names.h: channeld/full_channel_error.h ccan/ccan/cdump/tools/cdump-enumstr diff --git a/channeld/channeld.c b/channeld/channeld.c index a65b11a4f..18a381014 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -2054,7 +2055,7 @@ static void handle_tx_sigs(struct peer *peer, const u8 *msg) elem = cast_const2(const struct witness_element **, ws[j++]->witness_element); - psbt_input_set_final_witness_stack(in, elem); + psbt_input_set_final_witness_stack(peer->psbt, in, elem); } /* Then we broadcast it, and let the command know we did it */ diff --git a/closingd/Makefile b/closingd/Makefile index 43591d79d..6e9ee1417 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -46,6 +46,7 @@ CLOSINGD_COMMON_OBJS := \ common/peer_failed.o \ common/per_peer_state.o \ common/permute_tx.o \ + common/psbt_open.o \ common/pseudorand.o \ common/read_peer_msg.o \ common/setup.o \ @@ -61,10 +62,6 @@ CLOSINGD_COMMON_OBJS := \ common/wireaddr.o \ gossipd/gossipd_peerd_wiregen.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -CLOSINGD_COMMON_OBJS += common/psbt_open.o -endif - lightningd/lightning_closingd: $(CLOSINGD_OBJS) $(WIRE_ONION_OBJS) $(CLOSINGD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(HSMD_CLIENT_OBJS) -include closingd/test/Makefile diff --git a/common/Makefile b/common/Makefile index 771834c81..132c47f8c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -56,6 +56,7 @@ COMMON_SRC_NOGEN := \ common/peer_failed.c \ common/permute_tx.c \ common/ping.c \ + common/psbt_open.c \ common/pseudorand.c \ common/random_select.c \ common/read_peer_msg.c \ @@ -77,7 +78,7 @@ COMMON_SRC_NOGEN := \ ifeq ($(EXPERIMENTAL_FEATURES),1) -COMMON_SRC_NOGEN += common/psbt_open.c +COMMON_SRC_NOGEN += common/psbt_internal.c endif COMMON_SRC_GEN := common/status_wiregen.c common/peer_status_wiregen.c diff --git a/common/psbt_internal.c b/common/psbt_internal.c new file mode 100644 index 000000000..e5cf042b4 --- /dev/null +++ b/common/psbt_internal.c @@ -0,0 +1,76 @@ +#include "common/psbt_internal.h" +#include +#include +#include + +#if EXPERIMENTAL_FEATURES +void psbt_input_set_final_witness_stack(const tal_t *ctx, + struct wally_psbt_input *in, + const struct witness_element **elements) +{ + tal_wally_start(); + wally_tx_witness_stack_init_alloc(tal_count(elements), + &in->final_witness); + + for (size_t i = 0; i < tal_count(elements); i++) + wally_tx_witness_stack_add(in->final_witness, + elements[i]->witness, + tal_bytelen(elements[i]->witness)); + tal_wally_end(ctx); +} + +const struct witness_stack ** +psbt_to_witness_stacks(const tal_t *ctx, + const struct wally_psbt *psbt, + enum tx_role side_to_stack) +{ + size_t stack_index; + u16 serial_id; + const struct witness_stack **stacks + = tal_arr(ctx, const struct witness_stack *, psbt->num_inputs); + + stack_index = 0; + for (size_t i = 0; i < psbt->num_inputs; i++) { + if (!psbt_get_serial_id(&psbt->inputs[i].unknowns, + &serial_id)) + /* FIXME: throw an error ? */ + return NULL; + + /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: + * - if is the `initiator`: + * - MUST send even `serial_id`s + */ + if (serial_id % 2 == side_to_stack) { + struct wally_tx_witness_stack *wtx_s = + psbt->inputs[i].final_witness; + struct witness_stack *stack = + tal(stacks, struct witness_stack); + /* Convert the wally_tx_witness_stack to + * a witness_stack entry */ + stack->witness_element = + tal_arr(stack, struct witness_element *, + wtx_s->num_items); + for (size_t j = 0; j < tal_count(stack->witness_element); j++) { + stack->witness_element[j] = tal(stack, + struct witness_element); + stack->witness_element[j]->witness = + tal_dup_arr(stack, u8, + wtx_s->items[j].witness, + wtx_s->items[j].witness_len, + 0); + + } + + stacks[stack_index++] = stack; + } + + } + + if (stack_index == 0) + return tal_free(stacks); + + tal_resize(&stacks, stack_index); + return stacks; +} + +#endif /* EXPERIMENTAL_FEATURES */ diff --git a/common/psbt_internal.h b/common/psbt_internal.h new file mode 100644 index 000000000..3cb187d5e --- /dev/null +++ b/common/psbt_internal.h @@ -0,0 +1,36 @@ +#ifndef LIGHTNING_COMMON_PSBT_INTERNAL_H +#define LIGHTNING_COMMON_PSBT_INTERNAL_H + +#include "config.h" +#include +#include + +struct wally_psbt; +struct wally_psbt_input; +#if EXPERIMENTAL_FEATURES +struct witness_element; +#endif /* EXPERIMENTAL_FEATURES */ + +#if EXPERIMENTAL_FEATURES +/* psbt_input_set_final_witness_stack - Set the witness stack for PSBT input + * + * @ctx - the context to allocate onto + * @in - input to set final_witness for + * @witness_element - elements to add to witness stack + */ +void psbt_input_set_final_witness_stack(const tal_t *ctx, + struct wally_psbt_input *in, + const struct witness_element **elements); +/* psbt_to_witness_stacks - Take all sigs on a PSBT and copy to a + * witness_stack + * + * @ctx - allocation context + * @psbt - PSBT to copy sigs from + * @opener - which side initiated this tx + */ +const struct witness_stack ** +psbt_to_witness_stacks(const tal_t *ctx, + const struct wally_psbt *psbt, + enum tx_role side_to_stack); +#endif /* EXPERIMENTAL_FEATURES */ +#endif /* LIGHTNING_COMMON_PSBT_INTERNAL_H */ diff --git a/common/psbt_open.c b/common/psbt_open.c index c8f459770..9137ccf86 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -6,10 +6,8 @@ #include #include #include -#include #include #include -#include bool psbt_get_serial_id(const struct wally_map *map, u16 *serial_id) { @@ -427,148 +425,6 @@ bool psbt_has_required_fields(struct wally_psbt *psbt) return true; } -u8 *psbt_changeset_get_next(const tal_t *ctx, struct channel_id *cid, - struct psbt_changeset *set) -{ - u16 serial_id; - u8 *msg; - - if (tal_count(set->added_ins) != 0) { - const struct input_set *in = &set->added_ins[0]; - u8 *script; - - if (!psbt_get_serial_id(&in->input.unknowns, &serial_id)) - abort(); - - const u8 *prevtx = linearize_wtx(ctx, - in->input.utxo); - - if (in->input.redeem_script_len) - script = tal_dup_arr(ctx, u8, - in->input.redeem_script, - in->input.redeem_script_len, 0); - else - script = NULL; - - msg = towire_tx_add_input(ctx, cid, serial_id, - prevtx, in->tx_input.index, - in->tx_input.sequence, - script, - NULL); - - tal_arr_remove(&set->added_ins, 0); - return msg; - } - if (tal_count(set->rm_ins) != 0) { - if (!psbt_get_serial_id(&set->rm_ins[0].input.unknowns, - &serial_id)) - abort(); - - msg = towire_tx_remove_input(ctx, cid, serial_id); - - tal_arr_remove(&set->rm_ins, 0); - return msg; - } - if (tal_count(set->added_outs) != 0) { - struct amount_sat sats; - struct amount_asset asset_amt; - - const struct output_set *out = &set->added_outs[0]; - if (!psbt_get_serial_id(&out->output.unknowns, &serial_id)) - abort(); - - asset_amt = wally_tx_output_get_amount(&out->tx_output); - sats = amount_asset_to_sat(&asset_amt); - const u8 *script = wally_tx_output_get_script(ctx, - &out->tx_output); - - msg = towire_tx_add_output(ctx, cid, serial_id, - sats.satoshis, /* Raw: wire interface */ - script); - - tal_arr_remove(&set->added_outs, 0); - return msg; - } - if (tal_count(set->rm_outs) != 0) { - if (!psbt_get_serial_id(&set->rm_outs[0].output.unknowns, - &serial_id)) - abort(); - - msg = towire_tx_remove_output(ctx, cid, serial_id); - - /* Is this a kosher way to move the list forward? */ - tal_arr_remove(&set->rm_outs, 0); - return msg; - } - return NULL; -} - -void psbt_input_set_final_witness_stack(struct wally_psbt_input *in, - const struct witness_element **elements) -{ - wally_tx_witness_stack_init_alloc(tal_count(elements), - &in->final_witness); - - for (size_t i = 0; i < tal_count(elements); i++) - wally_tx_witness_stack_add(in->final_witness, - elements[i]->witness, - tal_bytelen(elements[i]->witness)); -} - -const struct witness_stack ** -psbt_to_witness_stacks(const tal_t *ctx, - const struct wally_psbt *psbt, - enum tx_role side_to_stack) -{ - size_t stack_index; - u16 serial_id; - const struct witness_stack **stacks - = tal_arr(ctx, const struct witness_stack *, psbt->num_inputs); - - stack_index = 0; - for (size_t i = 0; i < psbt->num_inputs; i++) { - if (!psbt_get_serial_id(&psbt->inputs[i].unknowns, - &serial_id)) - /* FIXME: throw an error ? */ - return NULL; - - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * - if is the `initiator`: - * - MUST send even `serial_id`s - */ - if (serial_id % 2 == side_to_stack) { - struct wally_tx_witness_stack *wtx_s = - psbt->inputs[i].final_witness; - struct witness_stack *stack = - tal(stacks, struct witness_stack); - /* Convert the wally_tx_witness_stack to - * a witness_stack entry */ - stack->witness_element = - tal_arr(stack, struct witness_element *, - wtx_s->num_items); - for (size_t j = 0; j < tal_count(stack->witness_element); j++) { - stack->witness_element[j] = tal(stack, - struct witness_element); - stack->witness_element[j]->witness = - tal_dup_arr(stack, u8, - wtx_s->items[j].witness, - wtx_s->items[j].witness_len, - 0); - - } - - stacks[stack_index++] = stack; - } - - } - - if (stack_index == 0) - return tal_free(stacks); - - tal_resize(&stacks, stack_index); - return stacks; -} - bool psbt_side_finalized(const struct wally_psbt *psbt, enum tx_role role) { u16 serial_id; diff --git a/common/psbt_open.h b/common/psbt_open.h index 0da44b1c5..3fb20865d 100644 --- a/common/psbt_open.h +++ b/common/psbt_open.h @@ -15,7 +15,6 @@ struct wally_psbt; struct wally_psbt_input; struct wally_psbt_output; struct wally_map; -struct witness_element; struct input_set { struct wally_tx_input tx_input; @@ -71,20 +70,6 @@ struct psbt_changeset *psbt_get_changeset(const tal_t *ctx, struct wally_psbt *orig, struct wally_psbt *new); -/* psbt_changeset_get_next - Get next message to send - * - * This generates the next message to send from a changeset for the - * interactive transaction protocol. - * - * @ctx - allocation context of returned msg - * @cid - channel_id for the message - * @set - changeset to get next update from - * - * Returns a wire message or NULL if no changes. - */ -u8 *psbt_changeset_get_next(const tal_t *ctx, struct channel_id *cid, - struct psbt_changeset *set); - /* psbt_input_set_serial_id - Sets a serial id on given input * * @ctx - tal context for allocations @@ -160,26 +145,6 @@ u16 psbt_new_output_serial(struct wally_psbt *psbt, enum tx_role role); */ bool psbt_has_required_fields(struct wally_psbt *psbt); -/* psbt_input_set_final_witness_stack - Set the witness stack for PSBT input - * - * @in - input to set final_witness for - * @witness_element - elements to add to witness stack - */ -void psbt_input_set_final_witness_stack(struct wally_psbt_input *in, - const struct witness_element **elements); - -/* psbt_to_witness_stacks - Take all sigs on a PSBT and copy to a - * witness_stack - * - * @ctx - allocation context - * @psbt - PSBT to copy sigs from - * @opener - which side initiated this tx - */ -const struct witness_stack ** -psbt_to_witness_stacks(const tal_t *ctx, - const struct wally_psbt *psbt, - enum tx_role side_to_stack); - /* psbt_side_finalized - True if designated role has all signature data */ bool psbt_side_finalized(const struct wally_psbt *psbt, enum tx_role role); diff --git a/common/test/exp-run-psbt_diff.c b/common/test/exp-run-psbt_diff.c index aa1e7382e..9f34a7ecd 100644 --- a/common/test/exp-run-psbt_diff.c +++ b/common/test/exp-run-psbt_diff.c @@ -58,18 +58,6 @@ void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED, /* Generated stub for towire_sha256 */ void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED) { fprintf(stderr, "towire_sha256 called!\n"); abort(); } -/* Generated stub for towire_tx_add_input */ -u8 *towire_tx_add_input(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u16 serial_id UNNEEDED, const u8 *prevtx UNNEEDED, u32 prevtx_vout UNNEEDED, u32 sequence UNNEEDED, const u8 *script UNNEEDED, const struct tlv_tx_add_input_tlvs *tlvs UNNEEDED) -{ fprintf(stderr, "towire_tx_add_input called!\n"); abort(); } -/* Generated stub for towire_tx_add_output */ -u8 *towire_tx_add_output(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u16 serial_id UNNEEDED, u64 sats UNNEEDED, const u8 *script UNNEEDED) -{ fprintf(stderr, "towire_tx_add_output called!\n"); abort(); } -/* Generated stub for towire_tx_remove_input */ -u8 *towire_tx_remove_input(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u16 serial_id UNNEEDED) -{ fprintf(stderr, "towire_tx_remove_input called!\n"); abort(); } -/* Generated stub for towire_tx_remove_output */ -u8 *towire_tx_remove_output(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u16 serial_id UNNEEDED) -{ fprintf(stderr, "towire_tx_remove_output called!\n"); abort(); } /* Generated stub for towire_u16 */ void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED) { fprintf(stderr, "towire_u16 called!\n"); abort(); } diff --git a/connectd/Makefile b/connectd/Makefile index 5636deb1d..397558128 100644 --- a/connectd/Makefile +++ b/connectd/Makefile @@ -49,6 +49,7 @@ CONNECTD_COMMON_OBJS := \ common/node_id.o \ common/onionreply.o \ common/per_peer_state.o \ + common/psbt_open.o \ common/pseudorand.o \ common/setup.o \ common/status.o \ @@ -65,10 +66,6 @@ CONNECTD_COMMON_OBJS := \ lightningd/gossip_msg.o \ wire/onion$(EXP)_wiregen.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -CONNECTD_COMMON_OBJS += common/psbt_open.o -endif - lightningd/lightning_connectd: $(CONNECTD_OBJS) $(CONNECTD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(HSMD_CLIENT_OBJS) include connectd/test/Makefile diff --git a/devtools/Makefile b/devtools/Makefile index e541a8c35..988eb8a06 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -33,6 +33,7 @@ DEVTOOLS_COMMON_OBJS := \ common/memleak.o \ common/node_id.o \ common/per_peer_state.o \ + common/psbt_open.o \ common/pseudorand.o \ common/json.o \ common/json_helpers.o \ @@ -44,10 +45,6 @@ DEVTOOLS_COMMON_OBJS := \ wire/onion$(EXP)_wiregen.o \ wire/peer$(EXP)_wiregen.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -DEVTOOLS_COMMON_OBJS += common/psbt_open.o -endif - devtools/bolt11-cli: $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/bolt11-cli.o devtools/decodemsg: $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) $(WIRE_PRINT_OBJS) wire/fromwire.o wire/towire.o devtools/print_wire.o devtools/decodemsg.o diff --git a/gossipd/Makefile b/gossipd/Makefile index 5e819c062..c50a490d8 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -51,6 +51,7 @@ GOSSIPD_COMMON_OBJS := \ common/onionreply.o \ common/per_peer_state.o \ common/ping.o \ + common/psbt_open.o \ common/pseudorand.o \ common/random_select.o \ common/setup.o \ @@ -68,10 +69,6 @@ GOSSIPD_COMMON_OBJS := \ lightningd/gossip_msg.o \ wire/onion$(EXP)_wiregen.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -GOSSIPD_COMMON_OBJS += common/psbt_open.o -endif - lightningd/lightning_gossipd: $(GOSSIPD_OBJS) $(GOSSIPD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(HSMD_CLIENT_OBJS) include gossipd/test/Makefile diff --git a/hsmd/Makefile b/hsmd/Makefile index 06d4936d8..772aacf88 100644 --- a/hsmd/Makefile +++ b/hsmd/Makefile @@ -31,6 +31,8 @@ HSMD_COMMON_OBJS := \ common/msg_queue.o \ common/node_id.o \ common/permute_tx.o \ + common/psbt_open.o \ + common/pseudorand.o \ common/setup.o \ common/status.o \ common/status_wire.o \ @@ -40,11 +42,6 @@ HSMD_COMMON_OBJS := \ common/utxo.o \ common/version.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -HSMD_COMMON_OBJS += common/psbt_open.o \ - common/pseudorand.o -endif - lightningd/lightning_hsmd: $(HSMD_OBJS) $(HSMD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) -include hsmd/test/Makefile diff --git a/lightningd/Makefile b/lightningd/Makefile index 7d7798e82..39af51563 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -106,6 +106,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/penalty_base.o \ common/per_peer_state.o \ common/permute_tx.o \ + common/psbt_open.o \ common/pseudorand.o \ common/random_select.o \ common/setup.o \ @@ -120,10 +121,6 @@ LIGHTNINGD_COMMON_OBJS := \ common/wire_error.o \ common/wireaddr.o \ -ifeq ($(EXPERIMENTAL_FEATURES),1) -LIGHTNINGD_COMMON_OBJS += common/psbt_open.o -endif - include wallet/Makefile # All together in one convenient var diff --git a/onchaind/Makefile b/onchaind/Makefile index 61b4e3b27..8b7dbe0a1 100644 --- a/onchaind/Makefile +++ b/onchaind/Makefile @@ -53,6 +53,8 @@ ONCHAIND_COMMON_OBJS := \ common/onionreply.o \ common/peer_billboard.o \ common/permute_tx.o \ + common/psbt_open.o \ + common/pseudorand.o \ common/setup.o \ common/status.o \ common/status_wire.o \ @@ -63,11 +65,6 @@ ONCHAIND_COMMON_OBJS := \ common/version.o \ common/wallet.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -ONCHAIND_COMMON_OBJS += common/psbt_open.o \ - common/pseudorand.o -endif - lightningd/lightning_onchaind: $(ONCHAIND_OBJS) $(WIRE_ONION_OBJS) $(ONCHAIND_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(HSMD_CLIENT_OBJS) include onchaind/test/Makefile diff --git a/openingd/Makefile b/openingd/Makefile index 5ac374d10..16c135fe7 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -70,6 +70,7 @@ OPENINGD_COMMON_OBJS := \ common/peer_billboard.o \ common/peer_failed.o \ common/permute_tx.o \ + common/psbt_open.o \ common/pseudorand.o \ common/read_peer_msg.o \ common/setup.o \ @@ -85,11 +86,6 @@ OPENINGD_COMMON_OBJS := \ gossipd/gossipd_peerd_wiregen.o \ lightningd/gossip_msg.o -ifeq ($(EXPERIMENTAL_FEATURES),1) -OPENINGD_COMMON_OBJS += common/psbt_open.o \ - common/pseudorand.o -endif - lightningd/lightning_openingd: $(OPENINGD_OBJS) $(OPENINGD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(HSMD_CLIENT_OBJS) lightningd/lightning_dualopend: $(DUALOPEND_OBJS) $(OPENINGD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(HSMD_CLIENT_OBJS) diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 7ab9a4e1b..a08db1f63 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -124,6 +124,94 @@ struct state { }; #if EXPERIMENTAL_FEATURES +/* psbt_changeset_get_next - Get next message to send + * + * This generates the next message to send from a changeset for the + * interactive transaction protocol. + * + * @ctx - allocation context of returned msg + * @cid - channel_id for the message + * @set - changeset to get next update from + * + * Returns a wire message or NULL if no changes. + */ +static u8 *psbt_changeset_get_next(const tal_t *ctx, + struct channel_id *cid, + struct psbt_changeset *set) +{ + u16 serial_id; + u8 *msg; + + if (tal_count(set->added_ins) != 0) { + const struct input_set *in = &set->added_ins[0]; + u8 *script; + + if (!psbt_get_serial_id(&in->input.unknowns, &serial_id)) + abort(); + + const u8 *prevtx = linearize_wtx(ctx, + in->input.utxo); + + if (in->input.redeem_script_len) + script = tal_dup_arr(ctx, u8, + in->input.redeem_script, + in->input.redeem_script_len, 0); + else + script = NULL; + + msg = towire_tx_add_input(ctx, cid, serial_id, + prevtx, in->tx_input.index, + in->tx_input.sequence, + script, + NULL); + + tal_arr_remove(&set->added_ins, 0); + return msg; + } + if (tal_count(set->rm_ins) != 0) { + if (!psbt_get_serial_id(&set->rm_ins[0].input.unknowns, + &serial_id)) + abort(); + + msg = towire_tx_remove_input(ctx, cid, serial_id); + + tal_arr_remove(&set->rm_ins, 0); + return msg; + } + if (tal_count(set->added_outs) != 0) { + struct amount_sat sats; + struct amount_asset asset_amt; + + const struct output_set *out = &set->added_outs[0]; + if (!psbt_get_serial_id(&out->output.unknowns, &serial_id)) + abort(); + + asset_amt = wally_tx_output_get_amount(&out->tx_output); + sats = amount_asset_to_sat(&asset_amt); + const u8 *script = wally_tx_output_get_script(ctx, + &out->tx_output); + + msg = towire_tx_add_output(ctx, cid, serial_id, + sats.satoshis, /* Raw: wire interface */ + script); + + tal_arr_remove(&set->added_outs, 0); + return msg; + } + if (tal_count(set->rm_outs) != 0) { + if (!psbt_get_serial_id(&set->rm_outs[0].output.unknowns, + &serial_id)) + abort(); + + msg = towire_tx_remove_output(ctx, cid, serial_id); + + /* Is this a kosher way to move the list forward? */ + tal_arr_remove(&set->rm_outs, 0); + return msg; + } + return NULL; +} + /*~ If we can't agree on parameters, we fail to open the channel. If we're * the opener, we need to tell lightningd, otherwise it never really notices. */