From aef5a5a0e55a34ddeb4927b15aa1d88e285fe73c Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 9 Sep 2020 19:40:29 +0930 Subject: [PATCH] psbt: psbt_has_serial_id -> psbt_find_serial_id Cleans up some awkward spots in the code, makes the footprint a bit neater Suggested-By: @rustyrussell --- common/psbt_open.c | 12 +++--- common/psbt_open.h | 16 ++++---- lightningd/dual_open_control.c | 4 +- openingd/dualopend.c | 72 ++++++++++++++++++---------------- 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/common/psbt_open.c b/common/psbt_open.c index bd4c6c759..c0a7b0f4a 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -416,28 +416,28 @@ void psbt_output_add_serial_id(struct wally_psbt_output *output, psbt_output_add_unknown(output, key, &bev, sizeof(bev)); } -bool psbt_has_serial_input(struct wally_psbt *psbt, u16 serial_id) +int psbt_find_serial_input(struct wally_psbt *psbt, u16 serial_id) { for (size_t i = 0; i < psbt->num_inputs; i++) { u16 in_serial; if (!psbt_get_serial_id(&psbt->inputs[i].unknowns, &in_serial)) continue; if (in_serial == serial_id) - return true; + return i; } - return false; + return -1; } -bool psbt_has_serial_output(struct wally_psbt *psbt, u16 serial_id) +int psbt_find_serial_output(struct wally_psbt *psbt, u16 serial_id) { for (size_t i = 0; i < psbt->num_outputs; i++) { u16 out_serial; if (!psbt_get_serial_id(&psbt->outputs[i].unknowns, &out_serial)) continue; if (out_serial == serial_id) - return true; + return i; } - return false; + return -1; } void psbt_input_add_max_witness_len(struct wally_psbt_input *input, diff --git a/common/psbt_open.h b/common/psbt_open.h index c6f0b8e3d..50c1ee72f 100644 --- a/common/psbt_open.h +++ b/common/psbt_open.h @@ -106,23 +106,23 @@ void psbt_output_add_serial_id(struct wally_psbt_output *output, */ void psbt_sort_by_serial_id(struct wally_psbt *psbt); -/* psbt_has_serial_input - Checks inputs for provided serial_id +/* psbt_find_serial_input - Checks inputs for provided serial_id * * @psbt - psbt's inputs to check * @serial_id - id to look for - * Returns true if serial_id found. + * + * Returns index of input with matching serial if found or -1 */ -WARN_UNUSED_RESULT bool -psbt_has_serial_input(struct wally_psbt *psbt, u16 serial_id); +int psbt_find_serial_input(struct wally_psbt *psbt, u16 serial_id); -/* psbt_has_serial_output - Checks outputs for provided serial_id +/* psbt_find_serial_output - Checks outputs for provided serial_id * * @psbt - psbt's outputs to check * @serial_id - id to look for - * Returns true if serial_id found. + * + * Returns index of output with matching serial if found or -1 */ -WARN_UNUSED_RESULT bool -psbt_has_serial_output(struct wally_psbt *psbt, u16 serial_id); +int psbt_find_serial_output(struct wally_psbt *psbt, u16 serial_id); /* psbt_input_add_max_witness_len - Put a max witness len on a thing * diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 14dfd304d..2cbfd38a3 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -428,7 +428,7 @@ static void psbt_add_serials(struct wally_psbt *psbt, enum side opener) continue; while ((serial_id = pseudorand(serial_space)) % 2 != opener || - psbt_has_serial_input(psbt, serial_id)) { + psbt_find_serial_input(psbt, serial_id) != -1) { /* keep going; */ } psbt_input_add_serial_id(&psbt->inputs[i], serial_id); @@ -439,7 +439,7 @@ static void psbt_add_serials(struct wally_psbt *psbt, enum side opener) continue; while ((serial_id = pseudorand(serial_space)) % 2 != opener || - psbt_has_serial_output(psbt, serial_id)) { + psbt_find_serial_output(psbt, serial_id) != -1) { /* keep going; */ } psbt_output_add_serial_id(&psbt->outputs[i], serial_id); diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 2bf9254b8..2b11394b2 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -629,7 +629,7 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb * ... * - it recieves a duplicate `serial_id` */ - if (psbt_has_serial_input(psbt, serial_id)) + if (psbt_find_serial_input(psbt, serial_id) != -1) peer_failed(state->pps, &state->channel_id, "Duplicate serial_id rcvd. %u", serial_id); @@ -703,7 +703,7 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb break; } case WIRE_TX_REMOVE_INPUT: { - bool input_found = false; + int input_index; if (!fromwire_tx_remove_input(msg, &cid, &serial_id)) peer_failed(state->pps, &state->channel_id, @@ -712,24 +712,21 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb check_channel_id(state, &cid, &state->channel_id); - for (size_t i = 0; i < psbt->num_inputs; i++) { - u16 input_serial; - if (!psbt_get_serial_id(&psbt->inputs[i].unknowns, - &input_serial)) { - peer_failed(state->pps, &state->channel_id, - "No input added with serial_id %u", - serial_id); - } - if (input_serial == serial_id) { - psbt_rm_input(psbt, i); - input_found = true; - break; - } - } - if (!input_found) + /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + * The sending node: + * - MUST NOT send a `tx_remove_input` for an + * input which is not theirs */ + if (serial_id % 2 != 0) + peer_failed(state->pps, &state->channel_id, + "Invalid serial_id rcvd. %u", serial_id); + + input_index = psbt_find_serial_input(psbt, serial_id); + if (input_index == -1) peer_failed(state->pps, &state->channel_id, "No input added with serial_id %u", serial_id); + + psbt_rm_input(psbt, input_index); break; } case WIRE_TX_ADD_OUTPUT: { @@ -745,7 +742,18 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb tal_hex(tmpctx, msg)); check_channel_id(state, &cid, &state->channel_id); - if (psbt_has_serial_output(psbt, serial_id)) + /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + * The receiving node: + * ... + * - MUST fail the transaction collaboration if: + * ... + * - it receives a `serial_id` from the peer with the + * incorrect parity */ + if (serial_id % 2 != 0) + peer_failed(state->pps, &state->channel_id, + "Invalid serial_id rcvd. %u", serial_id); + + if (psbt_find_serial_output(psbt, serial_id) != -1) peer_failed(state->pps, &state->channel_id, "Duplicate serial_id rcvd. %u", serial_id); amt = amount_sat(value); @@ -754,7 +762,7 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb break; } case WIRE_TX_REMOVE_OUTPUT: { - bool out_found = false; + int output_index; if (!fromwire_tx_remove_output(msg, &cid, &serial_id)) peer_failed(state->pps, &state->channel_id, @@ -763,24 +771,20 @@ static bool run_tx_interactive(struct state *state, struct wally_psbt **orig_psb check_channel_id(state, &cid, &state->channel_id); - for (size_t i = 0; i < psbt->num_outputs; i++) { - u16 output_serial; - if (!psbt_get_serial_id(&psbt->outputs[i].unknowns, - &output_serial)) { - peer_failed(state->pps, &state->channel_id, - "No output added with serial_id %u", - serial_id); - } - if (output_serial == serial_id) { - psbt_rm_output(psbt, i); - out_found = true; - break; - } - } - if (!out_found) + /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + * The sending node: + * - MUST NOT send a `tx_remove_ouput` for an + * input which is not theirs */ + if (serial_id % 2 != 0) + peer_failed(state->pps, &state->channel_id, + "Invalid serial_id rcvd. %u", serial_id); + + output_index = psbt_find_serial_output(psbt, serial_id); + if (output_index == -1) peer_failed(state->pps, &state->channel_id, "No output added with serial_id %u", serial_id); + psbt_rm_output(psbt, output_index); break; } case WIRE_TX_COMPLETE: