@@ -6,7 +6,7 @@ use anyhow::{anyhow, Context};
66use cid:: Cid ;
77use derive_more:: { Deref , DerefMut } ;
88use fvm_ipld_amt:: Amt ;
9- use fvm_ipld_encoding:: { to_vec, CBOR } ;
9+ use fvm_ipld_encoding:: { to_vec, RawBytes , CBOR } ;
1010use fvm_shared:: address:: { Address , Payload } ;
1111use fvm_shared:: econ:: TokenAmount ;
1212use fvm_shared:: error:: { ErrorNumber , ExitCode } ;
@@ -263,6 +263,15 @@ where
263263 ExecutionEvent :: CallError ( SyscallError :: new ( ErrorNumber :: Forbidden , "fatal" ) )
264264 }
265265 Err ( ExecutionError :: Syscall ( s) ) => ExecutionEvent :: CallError ( s. clone ( ) ) ,
266+ Err ( ExecutionError :: Abort ( Abort :: Return ( maybe_block) ) ) => {
267+ ExecutionEvent :: CallReturn (
268+ ExitCode :: OK ,
269+ match maybe_block {
270+ Some ( block) => RawBytes :: new ( block. data ( ) . to_vec ( ) ) . into ( ) ,
271+ None => RawBytes :: default ( ) . into ( ) ,
272+ } ,
273+ )
274+ }
266275 Err ( ExecutionError :: Abort ( _) ) => {
267276 ExecutionEvent :: CallError ( SyscallError :: new ( ErrorNumber :: Forbidden , "aborted" ) )
268277 }
@@ -421,14 +430,8 @@ where
421430 actor_id : ActorID ,
422431 new_code_cid : Cid ,
423432 params : Option < Block > ,
424- ) -> Result < BlockId > {
425- let result = match self . upgrade_actor_inner :: < K > ( actor_id, new_code_cid, params) {
426- Ok ( id) => id,
427- Err ( ExecutionError :: Abort ( Abort :: Exit ( ExitCode :: OK , _, result) ) ) => {
428- return Ok ( result) ;
429- }
430- Err ( e) => return Err ( e) ,
431- } ;
433+ ) -> Result < Option < Block > > {
434+ let result = self . upgrade_actor_inner :: < K > ( actor_id, new_code_cid, params) ?;
432435
433436 let origin = self . origin ;
434437 let state = self
@@ -447,21 +450,15 @@ where
447450 ) ,
448451 ) ;
449452
450- // when we successfully upgrade an actor we want to abort the calling actor which
451- // made the upgrade and return the block id of the new actor state.
452- Err ( ExecutionError :: from ( Abort :: Exit (
453- ExitCode :: OK ,
454- String :: from ( "actor upgraded" ) ,
455- result,
456- ) ) )
453+ Ok ( result)
457454 }
458455
459456 fn upgrade_actor_inner < K : Kernel < CallManager = Self > > (
460457 & mut self ,
461458 actor_id : ActorID ,
462459 new_code_cid : Cid ,
463460 params : Option < Block > ,
464- ) -> Result < BlockId > {
461+ ) -> Result < Option < Block > > {
465462 let state = self
466463 . state_tree ( )
467464 . get_actor ( actor_id) ?
@@ -551,7 +548,44 @@ where
551548
552549 let invocation_data = store. into_data ( ) ;
553550 let _last_error = invocation_data. last_error ;
554- let ( cm, _block_registry) = invocation_data. kernel . into_inner ( ) ;
551+ let ( cm, block_registry) = invocation_data. kernel . into_inner ( ) ;
552+
553+ let result: std:: result:: Result < Option < Block > , ExecutionError > = match result {
554+ Ok ( block_id) => {
555+ if block_id == NO_DATA_BLOCK_ID {
556+ Ok ( None )
557+ } else {
558+ Ok ( Some (
559+ block_registry
560+ . get ( block_id)
561+ . map_err ( |_| {
562+ Abort :: Exit (
563+ ExitCode :: SYS_MISSING_RETURN ,
564+ String :: from ( "returned block does not exist" ) ,
565+ NO_DATA_BLOCK_ID ,
566+ )
567+ } )
568+ . cloned ( )
569+ . unwrap ( ) ,
570+ ) )
571+ }
572+ }
573+ Err ( abort) => match abort {
574+ Abort :: Exit ( _, _, block_id) => match block_registry. get ( block_id) {
575+ Err ( e) => Err ( ExecutionError :: Fatal ( anyhow ! (
576+ "failed to retrieve block {}: {}" ,
577+ block_id,
578+ e
579+ ) ) ) ,
580+ Ok ( block) => Err ( ExecutionError :: Abort ( Abort :: Return ( Some ( block. clone ( ) ) ) ) ) ,
581+ } ,
582+ Abort :: OutOfGas => Err ( ExecutionError :: OutOfGas ) ,
583+ Abort :: Fatal ( err) => Err ( ExecutionError :: Fatal ( err) ) ,
584+ Abort :: Return ( _) => todo ! ( ) ,
585+ } ,
586+ } ;
587+
588+ //let ret: std::result::Result<Option<Block>, ExecutionError> = Ok(None);
555589
556590 ( result, cm)
557591 } )
@@ -967,6 +1001,14 @@ where
9671001 "fatal error" . to_owned ( ) ,
9681002 Err ( ExecutionError :: Fatal ( err) ) ,
9691003 ) ,
1004+ Abort :: Return ( value) => (
1005+ ExitCode :: OK ,
1006+ String :: from ( "aborted" ) ,
1007+ Ok ( InvocationResult {
1008+ exit_code : ExitCode :: OK ,
1009+ value,
1010+ } ) ,
1011+ ) ,
9701012 } ;
9711013
9721014 if !code. is_success ( ) {
0 commit comments