@@ -1887,6 +1887,10 @@ struct commitsig_info {
18871887 *
18881888 * `commit_index` 0 refers to the funding commit. `commit_index` 1 and above
18891889 * refer to inflight splices.
1890+ *
1891+ * `msg_batch` refers to the entire batch of messages in this commit_sig bundle
1892+ * with index 0 being the funding commit_sig and the rest being inflights. The
1893+ * inflight msgs must be in the same order as the inflight array.
18901894 */
18911895static struct commitsig_info * handle_peer_commit_sig (struct peer * peer ,
18921896 const u8 * msg ,
@@ -1897,7 +1901,8 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer,
18971901 s64 remote_splice_amnt ,
18981902 u64 local_index ,
18991903 const struct pubkey * local_per_commit ,
1900- bool allow_empty_commit )
1904+ bool allow_empty_commit ,
1905+ const u8 * * msg_batch )
19011906{
19021907 struct commitsig_info * result ;
19031908 struct channel_id channel_id ;
@@ -1911,8 +1916,6 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer,
19111916 size_t i ;
19121917 struct simple_htlc * * htlcs ;
19131918 const u8 * msg2 ;
1914- u8 * splice_msg ;
1915- int type ;
19161919 struct bitcoin_outpoint outpoint ;
19171920 struct amount_sat funding_sats ;
19181921 struct channel_id active_id ;
@@ -2142,9 +2145,17 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer,
21422145 result -> old_secret = old_secret ;
21432146 /* Only the parent call continues from here.
21442147 * Return for all child calls. */
2145- if (commit_index )
2148+ if (commit_index )
21462149 return result ;
21472150
2151+ if (tal_count (msg_batch ) - 1 < tal_count (peer -> splice_state -> inflights ))
2152+ peer_failed_err (peer -> pps , & peer -> channel_id ,
2153+ "commit_sig batch was too small (%zu). It must"
2154+ " include a commit sig for all inflights plus"
2155+ " channel funding (req: %zu)." ,
2156+ tal_count (msg_batch ),
2157+ tal_count (peer -> splice_state -> inflights ));
2158+
21482159 commitsigs = tal_arr (NULL , const struct commitsig * , 0 );
21492160 /* We expect multiple consequtive commit_sig messages if we have
21502161 * inflight splices. Since consequtive is requred, we recurse for
@@ -2154,23 +2165,13 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer,
21542165 peer -> channel -> funding_sats );
21552166 s64 sub_splice_amnt = peer -> splice_state -> inflights [i ]-> splice_amnt ;
21562167
2157- splice_msg = peer_read (tmpctx , peer -> pps );
2158- check_tx_abort (peer , splice_msg );
2159- /* Check type for cleaner failure message */
2160- type = fromwire_peektype (msg );
2161- if (type != WIRE_COMMITMENT_SIGNED )
2162- peer_failed_err (peer -> pps , & peer -> channel_id ,
2163- "Expected splice related "
2164- "WIRE_COMMITMENT_SIGNED but got %s" ,
2165- peer_wire_name (type ));
2166-
21672168 /* We purposely just store the last commit msg in result */
2168- result = handle_peer_commit_sig (peer , splice_msg , i + 1 ,
2169+ result = handle_peer_commit_sig (peer , msg_batch [ i + 1 ] , i + 1 ,
21692170 peer -> splice_state -> inflights [i ]-> remote_funding ,
21702171 changed_htlcs , sub_splice_amnt ,
21712172 funding_diff - sub_splice_amnt ,
21722173 local_index , local_per_commit ,
2173- allow_empty_commit );
2174+ allow_empty_commit , NULL );
21742175 old_secret = result -> old_secret ;
21752176 tal_arr_expand (& commitsigs , result -> commitsig );
21762177 tal_steal (commitsigs , result );
@@ -2199,6 +2200,132 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer,
21992200 return result ;
22002201}
22012202
2203+ /* Returns 0 if this is for funding, and 1+ for items in inflight array.
2204+ * Returns -1 if the value is not recognized.
2205+ */
2206+ static int commit_index_from_msg (const u8 * msg , struct peer * peer )
2207+ {
2208+ struct channel_id funding_id ;
2209+ struct channel_id channel_id ;
2210+ struct bitcoin_signature commit_sig ;
2211+ secp256k1_ecdsa_signature * raw_sigs ;
2212+ struct tlv_commitment_signed_tlvs * cs_tlv
2213+ = tlv_commitment_signed_tlvs_new (NULL );
2214+ fromwire_commitment_signed (cs_tlv , msg , & channel_id , & commit_sig .s ,
2215+ & raw_sigs , & cs_tlv );
2216+ tal_free (cs_tlv );
2217+
2218+ derive_channel_id (& funding_id , & peer -> channel -> funding );
2219+ if (channel_id_eq (& funding_id , & channel_id ))
2220+ return 0 ;
2221+
2222+ for (int i = 0 ; i < tal_count (peer -> splice_state -> inflights ); i ++ ) {
2223+ struct channel_id splice_id ;
2224+ derive_channel_id (& splice_id ,
2225+ & peer -> splice_state -> inflights [i ]-> outpoint );
2226+
2227+ if (channel_id_eq (& splice_id , & channel_id ))
2228+ return i + 1 ;
2229+ }
2230+
2231+ return -1 ;
2232+ }
2233+
2234+ static int commit_cmp (const void * a , const void * n , void * peer )
2235+ {
2236+ int commit_index_a = commit_index_from_msg (a , peer );
2237+ int commit_index_n = commit_index_from_msg (n , peer );
2238+
2239+ if (commit_index_a == commit_index_n )
2240+ return 0 ;
2241+
2242+ /* Unrecognized commits go on the end */
2243+ if (commit_index_a == -1 )
2244+ return 1 ;
2245+
2246+ if (commit_index_n == -1 )
2247+ return -1 ;
2248+
2249+ /* Otherwise we sort by commit_index */
2250+ return commit_index_a - commit_index_n ;
2251+ }
2252+
2253+ static struct commitsig_info * handle_peer_commit_sig_batch (struct peer * peer ,
2254+ const u8 * msg ,
2255+ u32 commit_index ,
2256+ struct pubkey remote_funding ,
2257+ const struct htlc * * changed_htlcs ,
2258+ s64 splice_amnt ,
2259+ s64 remote_splice_amnt ,
2260+ u64 local_index ,
2261+ const struct pubkey * local_per_commit ,
2262+ bool allow_empty_commit )
2263+ {
2264+ struct channel_id channel_id ;
2265+ struct bitcoin_signature commit_sig ;
2266+ secp256k1_ecdsa_signature * raw_sigs ;
2267+ u16 batch_size ;
2268+ const u8 * * msg_batch ;
2269+ enum peer_wire type ;
2270+ struct tlv_commitment_signed_tlvs * cs_tlv
2271+ = tlv_commitment_signed_tlvs_new (tmpctx );
2272+ if (!fromwire_commitment_signed (tmpctx , msg ,
2273+ & channel_id , & commit_sig .s , & raw_sigs ,
2274+ & cs_tlv ))
2275+ peer_failed_warn (peer -> pps , & peer -> channel_id ,
2276+ "Bad commit_sig %s" , tal_hex (msg , msg ));
2277+
2278+ /* Default batch_size is 1 */
2279+ batch_size = 1 ;
2280+ if (cs_tlv -> splice_info && cs_tlv -> splice_info -> batch_size )
2281+ batch_size = cs_tlv -> splice_info -> batch_size ;
2282+
2283+ msg_batch = tal_arr (tmpctx , const u8 * , batch_size );
2284+ msg_batch [0 ] = msg ;
2285+
2286+ /* Already received commitment signed once, so start at i = 1 */
2287+ for (u16 i = 1 ; i < batch_size ; i ++ ) {
2288+ struct tlv_commitment_signed_tlvs * sub_cs_tlv
2289+ = tlv_commitment_signed_tlvs_new (tmpctx );
2290+ u8 * sub_msg = peer_read (tmpctx , peer -> pps );
2291+ check_tx_abort (peer , sub_msg );
2292+
2293+ /* Check type for cleaner failure message */
2294+ type = fromwire_peektype (sub_msg );
2295+ if (type != WIRE_COMMITMENT_SIGNED )
2296+ peer_failed_err (peer -> pps , & peer -> channel_id ,
2297+ "Expected splice related "
2298+ "WIRE_COMMITMENT_SIGNED but got %s" ,
2299+ peer_wire_name (type ));
2300+ if (!fromwire_commitment_signed (tmpctx , sub_msg ,
2301+ & channel_id , & commit_sig .s ,
2302+ & raw_sigs , & sub_cs_tlv ))
2303+ peer_failed_warn (peer -> pps , & peer -> channel_id ,
2304+ "Bad commit_sig %s"
2305+ " in commit_sig batch:"
2306+ " [%" PRIu16 "/%" PRIu16 "]" ,
2307+ tal_hex (sub_msg , sub_msg ), i , batch_size );
2308+
2309+ if (!sub_cs_tlv -> splice_info
2310+ || sub_cs_tlv -> splice_info -> batch_size != batch_size )
2311+ peer_failed_err (peer -> pps , & peer -> channel_id ,
2312+ "batch_size value mismatch in"
2313+ " commit_sig bundle, item [%" PRIu16
2314+ "/%" PRIu16 "] %s" , i , batch_size ,
2315+ tal_hex (sub_msg , sub_msg ));
2316+
2317+ msg_batch [i ] = sub_msg ;
2318+ }
2319+
2320+ asort (msg_batch , tal_count (msg_batch ), commit_cmp , peer );
2321+
2322+ return handle_peer_commit_sig (peer , msg , commit_index , remote_funding ,
2323+ changed_htlcs , splice_amnt ,
2324+ remote_splice_amnt , local_index ,
2325+ local_per_commit , allow_empty_commit ,
2326+ msg_batch );
2327+ }
2328+
22022329/* Pops the penalty base for the given commitnum from our internal list. There
22032330 * may not be one, in which case we return NULL and leave the list
22042331 * unmodified. */
@@ -2845,7 +2972,8 @@ static struct commitsig *interactive_send_commitments(struct peer *peer,
28452972 remote_splice_amnt ,
28462973 next_index_local - 1 ,
28472974 & my_current_per_commitment_point ,
2848- true);
2975+ true,
2976+ NULL );
28492977 }
28502978 }
28512979
@@ -4569,10 +4697,12 @@ static void peer_in(struct peer *peer, const u8 *msg)
45694697 handle_peer_add_htlc (peer , msg );
45704698 return ;
45714699 case WIRE_COMMITMENT_SIGNED :
4572- handle_peer_commit_sig (peer , msg , 0 ,
4573- peer -> channel -> funding_pubkey [REMOTE ],
4574- NULL , 0 , 0 , peer -> next_index [LOCAL ],
4575- & peer -> next_local_per_commit , false);
4700+ handle_peer_commit_sig_batch (peer , msg , 0 ,
4701+ peer -> channel -> funding_pubkey [REMOTE ],
4702+ NULL , 0 , 0 ,
4703+ peer -> next_index [LOCAL ],
4704+ & peer -> next_local_per_commit ,
4705+ false);
45764706 return ;
45774707 case WIRE_UPDATE_FEE :
45784708 handle_peer_feechange (peer , msg );
0 commit comments