diff --git a/testing/integration/tests/main.rs b/testing/integration/tests/main.rs index b40f169db..fc3de3e9c 100644 --- a/testing/integration/tests/main.rs +++ b/testing/integration/tests/main.rs @@ -1115,7 +1115,7 @@ fn upgrade_actor_test() { ) .unwrap(); - let sender: [Account; 3] = tester.create_accounts().unwrap(); + let sender: [Account; 4] = tester.create_accounts().unwrap(); let receiver = Address::new_id(10000); let state_cid = tester.set_state(&[(); 0]).unwrap(); @@ -1197,6 +1197,28 @@ fn upgrade_actor_test() { res.failure_info ); } + + { + let message = Message { + from: sender[3].1, + to: receiver, + gas_limit: 1000000000, + method_num: 4, + sequence: 0_u64, + value: TokenAmount::from_atto(100), + ..Message::default() + }; + + let res = executor + .execute_message(message, ApplyKind::Explicit, 100) + .unwrap(); + + assert!( + res.msg_receipt.exit_code.is_success(), + "{:?}", + res.failure_info + ); + } } #[derive(Default)] diff --git a/testing/test_actors/actors/fil-upgrade-actor/src/actor.rs b/testing/test_actors/actors/fil-upgrade-actor/src/actor.rs index 525d25ec7..cb0c43386 100644 --- a/testing/test_actors/actors/fil-upgrade-actor/src/actor.rs +++ b/testing/test_actors/actors/fil-upgrade-actor/src/actor.rs @@ -4,6 +4,8 @@ use fvm_ipld_encoding::ipld_block::IpldBlock; use fvm_ipld_encoding::{to_vec, CBOR}; use fvm_sdk as sdk; use fvm_shared::address::Address; +use fvm_shared::econ::TokenAmount; +use fvm_shared::error::ErrorNumber; use fvm_shared::upgrade::UpgradeInfo; use serde_tuple::*; #[derive(Serialize_tuple, Deserialize_tuple, PartialEq, Eq, Clone, Debug)] @@ -95,6 +97,25 @@ pub fn invoke(_: u32) -> u32 { let _ = sdk::actor::upgrade_actor(new_code_cid, params); unreachable!("we should never return from a successful upgrade"); } + // test sending a message to ourself (putting us on the call stack) + 4 => { + sdk::send::send( + &Address::new_id(10000), + 5, + Default::default(), + TokenAmount::from_atto(100), + None, + Default::default(), + ) + .unwrap(); + } + // test that calling an upgrade with actor already on the call stack fails + 5 => { + let new_code_cid = sdk::actor::get_actor_code_cid(&Address::new_id(10000)).unwrap(); + let res = sdk::actor::upgrade_actor(new_code_cid, None); + assert_eq!(res, Err(ErrorNumber::Forbidden)); + } + other => { sdk::vm::abort( fvm_shared::error::ExitCode::FIRST_USER_EXIT_CODE,