@@ -1998,6 +1998,13 @@ impl MpcContract {
19981998 let initial_participants = parameters. participants ( ) ;
19991999 let tee_state = TeeState :: with_mocked_participant_attestations ( initial_participants) ;
20002000
2001+ let config: Config = init_config. map ( Into :: into) . unwrap_or_default ( ) ;
2002+ config
2003+ . validate ( )
2004+ . map_err ( |reason| InvalidParameters :: MalformedPayload {
2005+ reason : reason. to_string ( ) ,
2006+ } ) ?;
2007+
20012008 Ok ( Self {
20022009 protocol_state : ProtocolContractState :: Running ( RunningContractState :: new (
20032010 DomainRegistry :: default ( ) ,
@@ -2011,7 +2018,7 @@ impl MpcContract {
20112018 StorageKey :: PendingVerifyForeignTxRequestsV2 ,
20122019 ) ,
20132020 proposed_updates : ProposedUpdates :: default ( ) ,
2014- config : init_config . map ( Into :: into ) . unwrap_or_default ( ) ,
2021+ config,
20152022 tee_state,
20162023 accept_requests : true ,
20172024 node_migrations : NodeMigrations :: default ( ) ,
@@ -2077,8 +2084,15 @@ impl MpcContract {
20772084 let initial_participants = parameters. participants ( ) ;
20782085 let tee_state = TeeState :: with_mocked_participant_attestations ( initial_participants) ;
20792086
2087+ let config: Config = init_config. map ( Into :: into) . unwrap_or_default ( ) ;
2088+ config
2089+ . validate ( )
2090+ . map_err ( |reason| InvalidParameters :: MalformedPayload {
2091+ reason : reason. to_string ( ) ,
2092+ } ) ?;
2093+
20802094 Ok ( MpcContract {
2081- config : init_config . map ( Into :: into ) . unwrap_or_default ( ) ,
2095+ config,
20822096 protocol_state : ProtocolContractState :: Running ( RunningContractState :: new (
20832097 domains,
20842098 keyset,
@@ -3939,6 +3953,33 @@ mod tests {
39393953 ( contract, participants, first_participant_id)
39403954 }
39413955
3956+ #[ test]
3957+ fn init_rejects_launcher_ttl_below_attestation_validity ( ) {
3958+ let participants = gen_participants ( 3 ) ;
3959+ let signer = participants. participants ( ) [ 0 ] . 0 . clone ( ) ;
3960+ testing_env ! (
3961+ VMContextBuilder :: new( )
3962+ . signer_account_id( signer. clone( ) )
3963+ . predecessor_account_id( signer)
3964+ . attached_deposit( NearToken :: from_near( 1 ) )
3965+ . build( )
3966+ ) ;
3967+ let parameters = ThresholdParameters :: new ( participants, Threshold :: new ( 2 ) ) . unwrap ( ) ;
3968+ let bad_config = dtos:: InitConfig {
3969+ launcher_hash_unused_ttl_seconds : Some (
3970+ mpc_attestation:: attestation:: DEFAULT_EXPIRATION_DURATION_SECONDS - 1 ,
3971+ ) ,
3972+ ..Default :: default ( )
3973+ } ;
3974+
3975+ let err = MpcContract :: init ( ( & parameters) . into_dto_type ( ) , Some ( bad_config) )
3976+ . expect_err ( "init must reject a launcher TTL below the attestation validity window" ) ;
3977+ assert ! (
3978+ format!( "{err:?}" ) . contains( "launcher_hash_unused_ttl_seconds" ) ,
3979+ "error should point at the invalid config field, got: {err:?}"
3980+ ) ;
3981+ }
3982+
39423983 #[ test]
39433984 #[ expect( non_snake_case) ]
39443985 fn vote_tee_verifier_change__should_apply_candidate_when_threshold_reached ( ) {
0 commit comments