@@ -17,14 +17,17 @@ use crate::{
1717use anyhow:: { anyhow, bail, Context } ;
1818use async_stm:: atomically;
1919use async_trait:: async_trait;
20- use fendermint_actor_blobs_shared:: params:: { GetBlobStatusParams , GetPendingBlobsParams } ;
21- use fendermint_actor_blobs_shared:: state:: BlobStatus ;
22- use fendermint_actor_blobs_shared:: Method :: DebitAccounts ;
20+ use fendermint_actor_blobs_shared:: params:: {
21+ GetBlobStatusParams , GetPendingBlobsParams , UpdatePowerTableParams ,
22+ } ;
23+ use fendermint_actor_blobs_shared:: state:: { BlobStatus , Power , PowerTableUpdates , Validator } ;
24+ use fendermint_actor_blobs_shared:: Method :: { DebitAccounts , UpdatePowerTable } ;
2325use fendermint_actor_blobs_shared:: {
2426 params:: FinalizeBlobParams ,
2527 Method :: { FinalizeBlob , GetBlobStatus , GetPendingBlobs } ,
2628} ;
2729use fendermint_tracing:: emit;
30+ use fendermint_vm_actor_interface:: eam:: { EthAddress , EAM_ACTOR_ID } ;
2831use fendermint_vm_actor_interface:: { blobs, ipc, system} ;
2932use fendermint_vm_event:: ParentFinalityMissingQuorum ;
3033use fendermint_vm_iroh_resolver:: pool:: {
@@ -746,10 +749,17 @@ where
746749 & self ,
747750 ( env, state) : Self :: State ,
748751 ) -> anyhow:: Result < ( Self :: State , Self :: EndOutput ) > {
749- let ( state, out) = self . inner . end ( state) . await ?;
752+ let ( mut state, out) = self . inner . end ( state) . await ?;
750753
751754 // Update any component that needs to know about changes in the power table.
752755 if !out. 0 . 0 . is_empty ( ) {
756+ state. state_tree_mut ( ) . begin_transaction ( ) ;
757+ update_blobs_power_table ( & mut state, & out. 0 ) ?;
758+ state
759+ . state_tree_mut ( )
760+ . end_transaction ( true )
761+ . expect ( "we just started a transaction" ) ;
762+
753763 let power_updates = out
754764 . 0
755765 . 0
@@ -873,6 +883,51 @@ fn relayed_bottom_up_ckpt_to_fvm(
873883 Ok ( msg)
874884}
875885
886+ fn update_blobs_power_table < DB > (
887+ state : & mut FvmExecState < DB > ,
888+ input_power_updates : & PowerUpdates ,
889+ ) -> anyhow:: Result < ( ) >
890+ where
891+ DB : Blockstore + Clone + ' static + Send + Sync ,
892+ {
893+ let blobs_power_table_updates = PowerTableUpdates (
894+ input_power_updates
895+ . 0
896+ . iter ( )
897+ . filter_map ( |validator| {
898+ let power = validator. power . 0 ;
899+ let public_key = validator. public_key . 0 . serialize ( ) ;
900+ EthAddress :: new_secp256k1 ( & public_key)
901+ . and_then ( |eth_address| Address :: new_delegated ( EAM_ACTOR_ID , & eth_address. 0 ) )
902+ . map ( Some )
903+ . unwrap_or_else ( |_error| {
904+ tracing:: debug!( "can not construct delegated address from public key" ) ;
905+ None
906+ } )
907+ . map ( |address| Validator {
908+ power : Power ( power) ,
909+ address,
910+ } )
911+ } )
912+ . collect :: < Vec < _ > > ( ) ,
913+ ) ;
914+ let params = RawBytes :: serialize ( UpdatePowerTableParams ( blobs_power_table_updates) ) ?;
915+ let msg = Message {
916+ version : Default :: default ( ) ,
917+ from : system:: SYSTEM_ACTOR_ADDR ,
918+ to : blobs:: BLOBS_ACTOR_ADDR ,
919+ sequence : 0 ,
920+ value : Default :: default ( ) ,
921+ method_num : UpdatePowerTable as u64 ,
922+ params,
923+ gas_limit : fvm_shared:: BLOCK_GAS_LIMIT ,
924+ gas_fee_cap : Default :: default ( ) ,
925+ gas_premium : Default :: default ( ) ,
926+ } ;
927+ state. execute_implicit ( msg) ?;
928+ Ok ( ( ) )
929+ }
930+
876931/// Get pending blobs from on chain state.
877932/// This approach uses an implicit FVM transaction to query a read-only blockstore.
878933fn get_pending_blobs < DB > (
0 commit comments