| 2102 | } |
| 2103 | |
| 2104 | static void handle_validate_rbf(struct subd *dualopend, |
| 2105 | const u8 *msg) |
| 2106 | { |
| 2107 | struct wally_psbt *candidate_psbt; |
| 2108 | struct channel_inflight *inflight; |
| 2109 | struct channel *channel = dualopend->channel; |
| 2110 | bool *inputs_present; |
| 2111 | struct amount_sat candidate_fee, last_fee; |
| 2112 | |
| 2113 | if (!fromwire_dualopend_rbf_validate(tmpctx, msg, |
| 2114 | &candidate_psbt)) { |
| 2115 | channel_internal_error(channel, |
| 2116 | "Bad DUALOPEND_RBF_VALIDATE: %s", |
| 2117 | tal_hex(tmpctx, msg)); |
| 2118 | return; |
| 2119 | } |
| 2120 | |
| 2121 | inputs_present = tal_arr(tmpctx, bool, candidate_psbt->num_inputs); |
| 2122 | memset(inputs_present, true, tal_bytelen(inputs_present)); |
| 2123 | |
| 2124 | /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: |
| 2125 | * The receiving node: ... |
| 2126 | * - MUST fail the negotiation if: ... |
| 2127 | * - the transaction does not share a common input with |
| 2128 | * all previous funding transactions |
| 2129 | */ |
| 2130 | list_for_each(&channel->inflights, inflight, list) { |
| 2131 | /* Remove every non-matching input from set */ |
| 2132 | for (size_t i = 0; i < candidate_psbt->num_inputs; i++) { |
| 2133 | struct wally_tx_input *input = |
| 2134 | &candidate_psbt->tx->inputs[i]; |
| 2135 | struct bitcoin_outpoint outpoint; |
| 2136 | |
| 2137 | wally_tx_input_get_outpoint(input, &outpoint); |
| 2138 | |
| 2139 | if (!psbt_has_input(inflight->funding_psbt, |
| 2140 | &outpoint)) |
| 2141 | inputs_present[i] = false; |
| 2142 | } |
| 2143 | } |
| 2144 | |
| 2145 | /* Are there any inputs that were present on all txs? */ |
| 2146 | if (memeqzero(inputs_present, tal_bytelen(inputs_present))) { |
| 2147 | char *errmsg; |
| 2148 | |
| 2149 | inflight = list_tail(&channel->inflights, |
| 2150 | struct channel_inflight, |
| 2151 | list); |
| 2152 | assert(inflight); |
| 2153 | |
| 2154 | errmsg = tal_fmt(tmpctx, "No overlapping input" |
| 2155 | " present. New: %s, last: %s", |
| 2156 | type_to_string(tmpctx, |
| 2157 | struct wally_psbt, |
| 2158 | candidate_psbt), |
| 2159 | type_to_string(tmpctx, |
| 2160 | struct wally_psbt, |
| 2161 | inflight->funding_psbt)); |
no test coverage detected