From d1c7c7815968d6a70b785ac57c4172574d1e7fcf Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 8 Oct 2020 17:03:07 -0500 Subject: [PATCH] channeld-df: actually check serial_id of input when setting sigs We're about to totally upset the order that sigs are set on our PSBTs for new channel opens, making it such that our peer's sigs may arrive before ours do. We can no longer rely on the 'set witness means this is our input' since there's no guarantee that our input sigs have been added yet, so we check the serial_id and only set the stack on their (odd) inputs. --- channeld/channeld.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 60d1211b9..0d2959711 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -2009,6 +2009,9 @@ static void handle_tx_sigs(struct peer *peer, const u8 *msg) const struct witness_stack **ws; const struct wally_tx *wtx; size_t j = 0; + enum tx_role role = peer->channel->opener == REMOTE + ? TX_INITIATOR : TX_ACCEPTER; + if (!fromwire_tx_signatures(tmpctx, msg, &cid, &txid, cast_const3( @@ -2047,11 +2050,17 @@ static void handle_tx_sigs(struct peer *peer, const u8 *msg) for (size_t i = 0; i < peer->psbt->num_inputs; i++) { struct wally_psbt_input *in = &peer->psbt->inputs[i]; + u16 in_serial; const struct witness_element **elem; - /* Really we should check serial parity, but we can - * cheat and only check that the final witness - * stack hasn't been set yet */ - if (in->final_witness) + + if (!psbt_get_serial_id(&in->unknowns, &in_serial)) { + status_broken("PSBT input %zu missing serial_id %s", + i, type_to_string(tmpctx, + struct wally_psbt, + peer->psbt)); + return; + } + if (in_serial % 2 != role) continue; if (j == tal_count(ws))