@@ -147,3 +147,81 @@ where
147147 . cloned ( )
148148 . ok_or_else ( || anyhow:: anyhow!( "No keyshare for domain {:?}" , domain_id) )
149149}
150+
151+ #[ cfg( test) ]
152+ #[ expect( non_snake_case) ]
153+ mod tests {
154+ use super :: build_per_domain_data;
155+ use crate :: db:: SecretDB ;
156+ use crate :: network:: testing:: run_test_clients;
157+ use crate :: tests:: into_participant_ids;
158+ use crate :: tracking:: testing:: start_root_task_with_periodic_dump;
159+ use mpc_primitives:: ReconstructionThreshold ;
160+ use mpc_primitives:: domain:: DomainId ;
161+ use near_time:: Clock ;
162+ use rand:: SeedableRng ;
163+ use std:: collections:: HashMap ;
164+ use threshold_signatures:: ecdsa:: KeygenOutput ;
165+ use threshold_signatures:: frost_secp256k1:: Secp256K1Sha256 ;
166+ use threshold_signatures:: test_utils:: { generate_participants, run_keygen} ;
167+
168+ fn dummy_keygen_output ( ) -> KeygenOutput {
169+ let mut rng = rand:: rngs:: StdRng :: from_seed ( [ 7u8 ; 32 ] ) ;
170+ run_keygen :: < Secp256K1Sha256 , _ > ( & generate_participants ( 2 ) , 2usize , & mut rng)
171+ . into_iter ( )
172+ . next ( )
173+ . unwrap ( )
174+ . 1
175+ }
176+
177+ // Directly asserts the plumbing that `multidomain_with_distinct_reconstruction_thresholds`
178+ // only checks indirectly (by running a full multi-node signing round): each domain must keep
179+ // its OWN reconstruction threshold, never a single shared/governance value.
180+ #[ tokio:: test]
181+ async fn build_per_domain_data__should_pair_each_domain_with_its_own_reconstruction_threshold ( )
182+ {
183+ start_root_task_with_periodic_dump ( async move {
184+ run_test_clients (
185+ into_participant_ids ( & generate_participants ( 2 ) ) ,
186+ |client, _channel_receiver| async move {
187+ // Given two domains configured with distinct reconstruction thresholds
188+ let low = DomainId ( 0 ) ;
189+ let high = DomainId ( 1 ) ;
190+ let keygen_output = dummy_keygen_output ( ) ;
191+ let keyshares =
192+ HashMap :: from ( [ ( low, keygen_output. clone ( ) ) , ( high, keygen_output) ] ) ;
193+ let thresholds = HashMap :: from ( [
194+ ( low, ReconstructionThreshold :: new ( 2 ) ) ,
195+ ( high, ReconstructionThreshold :: new ( 3 ) ) ,
196+ ] ) ;
197+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
198+ let db = SecretDB :: new ( dir. path ( ) , [ 1 ; 16 ] ) . unwrap ( ) ;
199+
200+ // When
201+ let per_domain_data = build_per_domain_data :: < Vec < u8 > > (
202+ & Clock :: real ( ) ,
203+ & db,
204+ & client,
205+ keyshares,
206+ & thresholds,
207+ )
208+ . unwrap ( ) ;
209+
210+ // Then each domain keeps the threshold it was configured with
211+ assert_eq ! (
212+ per_domain_data[ & low] . reconstruction_threshold,
213+ ReconstructionThreshold :: new( 2 )
214+ ) ;
215+ assert_eq ! (
216+ per_domain_data[ & high] . reconstruction_threshold,
217+ ReconstructionThreshold :: new( 3 )
218+ ) ;
219+ Ok ( ( ) )
220+ } ,
221+ )
222+ . await
223+ . unwrap ( ) ;
224+ } )
225+ . await ;
226+ }
227+ }
0 commit comments