diff --git a/common/psbt_open.c b/common/psbt_open.c index 3dc7942b9..f68b60dee 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -441,6 +442,35 @@ int psbt_find_serial_output(struct wally_psbt *psbt, u16 serial_id) return -1; } +static u16 get_random_serial(enum tx_role role) +{ + return pseudorand(1 << 15) << 1 | role; +} + +u16 psbt_new_input_serial(struct wally_psbt *psbt, enum tx_role role) +{ + u16 serial_id; + + while ((serial_id = get_random_serial(role)) && + psbt_find_serial_input(psbt, serial_id) != -1) { + /* keep going; */ + } + + return serial_id; +} + +u16 psbt_new_output_serial(struct wally_psbt *psbt, enum tx_role role) +{ + u16 serial_id; + + while ((serial_id = get_random_serial(role)) && + psbt_find_serial_output(psbt, serial_id) != -1) { + /* keep going; */ + } + + return serial_id; +} + bool psbt_has_required_fields(struct wally_psbt *psbt) { u16 serial_id; diff --git a/common/psbt_open.h b/common/psbt_open.h index c97585985..429ad1d5d 100644 --- a/common/psbt_open.h +++ b/common/psbt_open.h @@ -130,6 +130,24 @@ int psbt_find_serial_input(struct wally_psbt *psbt, u16 serial_id); */ int psbt_find_serial_output(struct wally_psbt *psbt, u16 serial_id); +/* psbt_new_input_serial - Generate a new serial for an input for {role} + * + * @psbt - psbt to get a new serial for + * @role - which tx role to generate the serial for + * + * Returns a new, unique serial of the correct parity for the specified {role} + */ +u16 psbt_new_input_serial(struct wally_psbt *psbt, enum tx_role role); + +/* psbt_new_output_serial - Generate a new serial for an output for {role} + * + * @psbt - psbt to get a new serial for + * @role - which tx role to generate the serial for + * + * Returns a new, unique serial of the correct parity for the specified {role} + */ +u16 psbt_new_output_serial(struct wally_psbt *psbt, enum tx_role role); + /* psbt_has_required_fields - Validates psbt field completion * * Required fields are: diff --git a/common/test/exp-run-psbt_diff.c b/common/test/exp-run-psbt_diff.c index 31ea08862..056f06ead 100644 --- a/common/test/exp-run-psbt_diff.c +++ b/common/test/exp-run-psbt_diff.c @@ -42,6 +42,9 @@ u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) /* Generated stub for fromwire_u8 */ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u8 called!\n"); abort(); } +/* Generated stub for pseudorand */ +uint64_t pseudorand(uint64_t max UNNEEDED) +{ fprintf(stderr, "pseudorand called!\n"); abort(); } /* Generated stub for towire */ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "towire called!\n"); abort(); } diff --git a/hsmd/Makefile b/hsmd/Makefile index b4acf20c7..06d4936d8 100644 --- a/hsmd/Makefile +++ b/hsmd/Makefile @@ -41,7 +41,8 @@ HSMD_COMMON_OBJS := \ common/version.o ifeq ($(EXPERIMENTAL_FEATURES),1) -HSMD_COMMON_OBJS += common/psbt_open.o +HSMD_COMMON_OBJS += common/psbt_open.o \ + common/pseudorand.o endif lightningd/lightning_hsmd: $(HSMD_OBJS) $(HSMD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 7d82d34c4..04ca3644d 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -359,16 +359,12 @@ static bool psbt_side_contribs_changed(struct wally_psbt *orig, static void psbt_add_serials(struct wally_psbt *psbt, enum tx_role role) { u16 serial_id; - const u64 serial_space = 100000; for (size_t i = 0; i < psbt->num_inputs; i++) { /* Skip ones that already have a serial id */ if (psbt_get_serial_id(&psbt->inputs[i].unknowns, &serial_id)) continue; - while ((serial_id = pseudorand(serial_space)) % 2 != role || - psbt_find_serial_input(psbt, serial_id) != -1) { - /* keep going; */ - } + serial_id = psbt_new_input_serial(psbt, role); psbt_input_add_serial_id(psbt, &psbt->inputs[i], serial_id); } for (size_t i = 0; i < psbt->num_outputs; i++) { @@ -376,10 +372,7 @@ static void psbt_add_serials(struct wally_psbt *psbt, enum tx_role role) if (psbt_get_serial_id(&psbt->outputs[i].unknowns, &serial_id)) continue; - while ((serial_id = pseudorand(serial_space)) % 2 != role || - psbt_find_serial_output(psbt, serial_id) != -1) { - /* keep going; */ - } + serial_id = psbt_new_output_serial(psbt, role); psbt_output_add_serial_id(psbt, &psbt->outputs[i], serial_id); } } diff --git a/onchaind/Makefile b/onchaind/Makefile index 42a6e523b..61b4e3b27 100644 --- a/onchaind/Makefile +++ b/onchaind/Makefile @@ -64,7 +64,8 @@ ONCHAIND_COMMON_OBJS := \ common/wallet.o ifeq ($(EXPERIMENTAL_FEATURES),1) -ONCHAIND_COMMON_OBJS += common/psbt_open.o +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) diff --git a/openingd/Makefile b/openingd/Makefile index 5c1db703f..5ac374d10 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -86,7 +86,8 @@ OPENINGD_COMMON_OBJS := \ lightningd/gossip_msg.o ifeq ($(EXPERIMENTAL_FEATURES),1) -OPENINGD_COMMON_OBJS += common/psbt_open.o +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) diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 51420b32e..6c3d9675b 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -1391,7 +1391,7 @@ static u8 *opener_start(struct state *state, u8 *msg) scriptpubkey_p2wsh(tmpctx, wscript), total); /* Add a serial_id for this output */ - serial_id = 0; /* FIXME: generate new serial */ + serial_id = psbt_new_input_serial(psbt, TX_INITIATOR); psbt_output_add_serial_id(psbt, funding_out, serial_id); /* Add all of our inputs/outputs to the changeset */