@@ -960,14 +960,18 @@ async fn main() -> Result<()> {
960960 platform_rpc:: RpcP2PCommand :: BroadcastSudoAction { action } => {
961961 info!( "Received sudo action from RPC: {:?}" , action) ;
962962
963- // Apply to local chain state (RPC server already applied, but handle
964- // the case where this is received from P2P relay)
965- {
966- let mut cs = chain_state. write( ) ;
967- if let Err ( e) = cs. apply_sudo_action( & action) {
968- error!( "Failed to apply sudo action: {}" , e) ;
969- }
970- }
963+ // Apply to local chain state and persist
964+ mutate_and_persist(
965+ storage. clone( ) ,
966+ chain_state. clone( ) ,
967+ "sudo_action_rpc" ,
968+ |cs| {
969+ if let Err ( e) = cs. apply_sudo_action( & action) {
970+ error!( "Failed to apply sudo action: {}" , e) ;
971+ }
972+ } ,
973+ )
974+ . await ;
971975
972976 // Broadcast as a ChallengeUpdate with type "sudo_action"
973977 // so peer validators can receive and apply it
@@ -1102,31 +1106,35 @@ async fn main() -> Result<()> {
11021106 "WASM stored locally in distributed storage"
11031107 ) ;
11041108
1105- // Sync to ChainState for RPC
1106- {
1107- let challenge_name = name. as_deref( ) . unwrap_or( & challenge_id_str) . to_string( ) ;
1108- let mut cs = chain_state. write( ) ;
1109- let wasm_config = platform_core:: WasmChallengeConfig {
1110- challenge_id,
1111- name: challenge_name,
1112- description: String :: new( ) ,
1113- owner: keypair. hotkey( ) ,
1114- module: platform_core:: WasmModuleMetadata {
1115- module_path: challenge_id_str. clone( ) ,
1116- code_hash: hex:: encode( metadata. value_hash) ,
1117- version: metadata. version. to_string( ) ,
1118- ..Default :: default ( )
1119- } ,
1120- config: platform_core:: ChallengeConfig :: default ( ) ,
1121- is_active: true ,
1122- } ;
1123- cs. register_wasm_challenge( wasm_config) ;
1124- }
1125-
1126- // Persist core state immediately so challenge survives restart
1127- if let Err ( e) = persist_core_state_to_storage( & storage, & chain_state) . await {
1128- warn!( "Failed to persist core state after challenge registration: {}" , e) ;
1129- }
1109+ // Sync to ChainState for RPC and persist
1110+ let challenge_name = name. as_deref( ) . unwrap_or( & challenge_id_str) . to_string( ) ;
1111+ let owner = keypair. hotkey( ) ;
1112+ let code_hash = hex:: encode( metadata. value_hash) ;
1113+ let version = metadata. version. to_string( ) ;
1114+ let module_path = challenge_id_str. clone( ) ;
1115+ mutate_and_persist(
1116+ storage. clone( ) ,
1117+ chain_state. clone( ) ,
1118+ "wasm_upload_local" ,
1119+ |cs| {
1120+ let wasm_config = platform_core:: WasmChallengeConfig {
1121+ challenge_id,
1122+ name: challenge_name,
1123+ description: String :: new( ) ,
1124+ owner,
1125+ module: platform_core:: WasmModuleMetadata {
1126+ module_path,
1127+ code_hash,
1128+ version,
1129+ ..Default :: default ( )
1130+ } ,
1131+ config: platform_core:: ChallengeConfig :: default ( ) ,
1132+ is_active: true ,
1133+ } ;
1134+ cs. register_wasm_challenge( wasm_config) ;
1135+ } ,
1136+ )
1137+ . await ;
11301138
11311139 // Load routes in a blocking thread to avoid tokio runtime issues
11321140 if let Some ( ref executor) = wasm_executor {
@@ -2213,33 +2221,39 @@ async fn handle_network_event(
22132221 }
22142222 } ) ;
22152223
2216- // Sync challenge to ChainState for RPC
2217- {
2218- let mut cs = chain_state. write ( ) ;
2219- let wasm_config = platform_core:: WasmChallengeConfig {
2220- challenge_id : update. challenge_id ,
2221- name : challenge_name,
2222- description : String :: new ( ) ,
2223- owner : update. updater . clone ( ) ,
2224- module : platform_core:: WasmModuleMetadata {
2225- module_path : challenge_id_str. clone ( ) ,
2226- code_hash : hex:: encode ( metadata. value_hash ) ,
2227- version : metadata. version . to_string ( ) ,
2228- ..Default :: default ( )
2229- } ,
2230- config : platform_core:: ChallengeConfig :: default ( ) ,
2231- is_active : true ,
2232- } ;
2233- cs. register_wasm_challenge ( wasm_config) ;
2234- }
2235-
2236- // Persist core state immediately so challenge survives restart
2237- if let Err ( e) =
2238- persist_core_state_to_storage ( storage, chain_state)
2239- . await
2240- {
2241- warn ! ( "Failed to persist core state after P2P challenge registration: {}" , e) ;
2242- }
2224+ // Sync challenge to ChainState for RPC and persist
2225+ let cid = update. challenge_id ;
2226+ let owner = update. updater . clone ( ) ;
2227+ let code_hash = hex:: encode ( metadata. value_hash ) ;
2228+ let version = metadata. version . to_string ( ) ;
2229+ let module_path = challenge_id_str. clone ( ) ;
2230+ let cname = challenge_name. clone ( ) ;
2231+ mutate_and_persist (
2232+ storage. clone ( ) ,
2233+ chain_state. clone ( ) ,
2234+ "wasm_upload_p2p" ,
2235+ |cs| {
2236+ let wasm_config =
2237+ platform_core:: WasmChallengeConfig {
2238+ challenge_id : cid,
2239+ name : cname,
2240+ description : String :: new ( ) ,
2241+ owner,
2242+ module : platform_core:: WasmModuleMetadata {
2243+ module_path,
2244+ code_hash,
2245+ version,
2246+ ..Default :: default ( )
2247+ } ,
2248+ config :
2249+ platform_core:: ChallengeConfig :: default (
2250+ ) ,
2251+ is_active : true ,
2252+ } ;
2253+ cs. register_wasm_challenge ( wasm_config) ;
2254+ } ,
2255+ )
2256+ . await ;
22432257
22442258 // Load routes in a blocking thread to avoid tokio runtime issues
22452259 if let Some ( ref executor) = wasm_executor_ref {
@@ -2790,23 +2804,35 @@ async fn handle_network_event(
27902804 let wasm_key = StorageKey :: new ( "wasm" , & challenge_id_str) ;
27912805 match storage. put ( wasm_key, entry. data . clone ( ) , PutOptions :: default ( ) ) . await {
27922806 Ok ( metadata) => {
2793- let mut cs = chain_state. write ( ) ;
2794- let wasm_config = platform_core:: WasmChallengeConfig {
2795- challenge_id : * challenge_id,
2796- name : challenge_id_str. clone ( ) ,
2797- description : String :: new ( ) ,
2798- owner : entry. proposer . clone ( ) ,
2799- module : platform_core:: WasmModuleMetadata {
2800- module_path : challenge_id_str. clone ( ) ,
2801- code_hash : hex:: encode ( metadata. value_hash ) ,
2802- version : metadata. version . to_string ( ) ,
2803- ..Default :: default ( )
2807+ let cid = * challenge_id;
2808+ let owner = entry. proposer . clone ( ) ;
2809+ let code_hash = hex:: encode ( metadata. value_hash ) ;
2810+ let version = metadata. version . to_string ( ) ;
2811+ let module_path = challenge_id_str. clone ( ) ;
2812+ let cname = challenge_id_str. clone ( ) ;
2813+ mutate_and_persist (
2814+ storage. clone ( ) ,
2815+ chain_state. clone ( ) ,
2816+ "wasm_consensus" ,
2817+ |cs| {
2818+ let wasm_config = platform_core:: WasmChallengeConfig {
2819+ challenge_id : cid,
2820+ name : cname,
2821+ description : String :: new ( ) ,
2822+ owner,
2823+ module : platform_core:: WasmModuleMetadata {
2824+ module_path,
2825+ code_hash,
2826+ version,
2827+ ..Default :: default ( )
2828+ } ,
2829+ config : platform_core:: ChallengeConfig :: default ( ) ,
2830+ is_active : true ,
2831+ } ;
2832+ cs. register_wasm_challenge ( wasm_config) ;
28042833 } ,
2805- config : platform_core:: ChallengeConfig :: default ( ) ,
2806- is_active : true ,
2807- } ;
2808- cs. register_wasm_challenge ( wasm_config) ;
2809- drop ( cs) ;
2834+ )
2835+ . await ;
28102836
28112837 info ! (
28122838 challenge_id = %challenge_id,
0 commit comments