@@ -62,6 +62,65 @@ enum Commands {
6262 #[ arg( short, long) ]
6363 name : String ,
6464 } ,
65+ /// Set challenge weight/emission ratio on a mechanism
66+ SetEmission {
67+ /// Challenge ID (UUID)
68+ #[ arg( short = 'c' , long) ]
69+ challenge_id : String ,
70+ /// Mechanism ID (default: 0)
71+ #[ arg( short, long, default_value = "0" ) ]
72+ mechanism_id : u8 ,
73+ /// Weight ratio (0.0 - 1.0)
74+ #[ arg( short, long) ]
75+ weight : f64 ,
76+ } ,
77+ /// Set mechanism burn rate
78+ SetBurnRate {
79+ /// Mechanism ID
80+ #[ arg( short, long, default_value = "0" ) ]
81+ mechanism_id : u8 ,
82+ /// Burn rate (0.0 - 1.0), e.g., 0.1 = 10% to UID 0
83+ #[ arg( short, long) ]
84+ rate : f64 ,
85+ } ,
86+ /// Configure mechanism weight distribution
87+ SetMechanismConfig {
88+ /// Mechanism ID
89+ #[ arg( short, long, default_value = "0" ) ]
90+ mechanism_id : u8 ,
91+ /// Burn rate (0.0 - 1.0)
92+ #[ arg( long, default_value = "0.0" ) ]
93+ burn_rate : f64 ,
94+ /// Equal distribution among challenges
95+ #[ arg( long) ]
96+ equal_distribution : bool ,
97+ /// Minimum weight threshold
98+ #[ arg( long, default_value = "0.0001" ) ]
99+ min_weight : f64 ,
100+ } ,
101+ /// Emergency pause the network
102+ Pause {
103+ /// Reason for the pause
104+ #[ arg( short, long) ]
105+ reason : String ,
106+ } ,
107+ /// Resume the network after a pause
108+ Resume ,
109+ /// Set required validator version
110+ SetVersion {
111+ /// Minimum required version (e.g., "0.2.0")
112+ #[ arg( long) ]
113+ min : String ,
114+ /// Recommended version
115+ #[ arg( long) ]
116+ recommended : String ,
117+ /// Whether the update is mandatory
118+ #[ arg( long) ]
119+ mandatory : bool ,
120+ /// Deadline block (optional)
121+ #[ arg( long) ]
122+ deadline : Option < u64 > ,
123+ } ,
65124 /// List all challenges
66125 List ,
67126 /// Show validator status
@@ -292,6 +351,42 @@ impl SudoCli {
292351 Ok ( ( ) )
293352 }
294353
354+ async fn send_sudo_action ( & self , action : serde_json:: Value ) -> Result < ( ) > {
355+ let timestamp = chrono:: Utc :: now ( ) . timestamp_millis ( ) ;
356+
357+ let msg_to_sign = format ! ( "sudo:action:{}:{}" , action. to_string( ) , timestamp) ;
358+ let signature = self . sign ( msg_to_sign. as_bytes ( ) ) ?;
359+
360+ let request = serde_json:: json!( {
361+ "action" : action,
362+ "signature" : hex:: encode( & signature) ,
363+ "timestamp" : timestamp,
364+ } ) ;
365+
366+ let response = self
367+ . client
368+ . post ( format ! ( "{}/sudo/action" , self . rpc_url) )
369+ . json ( & request)
370+ . send ( )
371+ . await
372+ . context ( "Failed to send sudo action" ) ?;
373+
374+ if response. status ( ) . is_success ( ) {
375+ let result: SudoResponse = response. json ( ) . await ?;
376+ if result. success {
377+ info ! ( "Sudo action applied: {}" , result. message) ;
378+ } else {
379+ warn ! ( "Sudo action failed: {}" , result. message) ;
380+ }
381+ } else {
382+ let status = response. status ( ) ;
383+ let text = response. text ( ) . await . unwrap_or_default ( ) ;
384+ error ! ( status = %status, body = %text, "Sudo action request failed" ) ;
385+ }
386+
387+ Ok ( ( ) )
388+ }
389+
295390 async fn list_challenges ( & self ) -> Result < ( ) > {
296391 let response = self
297392 . client
@@ -443,6 +538,80 @@ async fn main() -> Result<()> {
443538 Some ( Commands :: Rename { id, name } ) => {
444539 sudo_cli. rename_challenge ( & id, & name) . await ?;
445540 }
541+ Some ( Commands :: SetEmission {
542+ challenge_id,
543+ mechanism_id,
544+ weight,
545+ } ) => {
546+ let cid = ChallengeId :: from_string ( & challenge_id) ;
547+ let action = serde_json:: json!( {
548+ "SetChallengeWeight" : {
549+ "challenge_id" : cid. 0 . to_string( ) ,
550+ "mechanism_id" : mechanism_id,
551+ "weight_ratio" : weight
552+ }
553+ } ) ;
554+ sudo_cli. send_sudo_action ( action) . await ?;
555+ }
556+ Some ( Commands :: SetBurnRate { mechanism_id, rate } ) => {
557+ let action = serde_json:: json!( {
558+ "SetMechanismBurnRate" : {
559+ "mechanism_id" : mechanism_id,
560+ "burn_rate" : rate
561+ }
562+ } ) ;
563+ sudo_cli. send_sudo_action ( action) . await ?;
564+ }
565+ Some ( Commands :: SetMechanismConfig {
566+ mechanism_id,
567+ burn_rate,
568+ equal_distribution,
569+ min_weight,
570+ } ) => {
571+ let action = serde_json:: json!( {
572+ "SetMechanismConfig" : {
573+ "mechanism_id" : mechanism_id,
574+ "config" : {
575+ "mechanism_id" : mechanism_id,
576+ "base_burn_rate" : burn_rate,
577+ "equal_distribution" : equal_distribution,
578+ "min_weight_threshold" : min_weight,
579+ "max_weight_cap" : 1.0 ,
580+ "active" : true
581+ }
582+ }
583+ } ) ;
584+ sudo_cli. send_sudo_action ( action) . await ?;
585+ }
586+ Some ( Commands :: Pause { reason } ) => {
587+ let action = serde_json:: json!( {
588+ "EmergencyPause" : {
589+ "reason" : reason
590+ }
591+ } ) ;
592+ sudo_cli. send_sudo_action ( action) . await ?;
593+ }
594+ Some ( Commands :: Resume ) => {
595+ let action = serde_json:: json!( "Resume" ) ;
596+ sudo_cli. send_sudo_action ( action) . await ?;
597+ }
598+ Some ( Commands :: SetVersion {
599+ min,
600+ recommended,
601+ mandatory,
602+ deadline,
603+ } ) => {
604+ let action = serde_json:: json!( {
605+ "SetRequiredVersion" : {
606+ "min_version" : min,
607+ "recommended_version" : recommended,
608+ "mandatory" : mandatory,
609+ "deadline_block" : deadline,
610+ "release_notes" : null
611+ }
612+ } ) ;
613+ sudo_cli. send_sudo_action ( action) . await ?;
614+ }
446615 Some ( Commands :: List ) => {
447616 sudo_cli. list_challenges ( ) . await ?;
448617 }
0 commit comments