From 45db5e22dcc40c60e5fa0ff49ec74cb1d647ae2f Mon Sep 17 00:00:00 2001
From: Rod Vagg <rod@vagg.org>
Date: Sat, 10 Feb 2024 12:32:45 +1100
Subject: [PATCH] fix(integration): cron_tick to use implicit executions to
 avoid sender checks (#1506)

fix: cron_tick to use implicit executions to avoid sender checks

when running in fvm the sender is checked for non-implicit executions,
which matters when running these in fvm-workbench
---
 .../src/tests/batch_onboarding.rs             | 19 ++------
 .../src/tests/commit_post_test.rs             | 38 ++++------------
 .../src/tests/replica_update_test.rs          | 30 +++----------
 integration_tests/src/tests/terminate_test.rs | 43 ++++---------------
 test_vm/src/lib.rs                            |  4 ++
 5 files changed, 31 insertions(+), 103 deletions(-)

diff --git a/integration_tests/src/tests/batch_onboarding.rs b/integration_tests/src/tests/batch_onboarding.rs
index 238a00b34..1405a0a4b 100644
--- a/integration_tests/src/tests/batch_onboarding.rs
+++ b/integration_tests/src/tests/batch_onboarding.rs
@@ -1,23 +1,19 @@
 use export_macro::vm_test;
-use fil_actor_cron::Method as CronMethod;
 use fil_actor_miner::SectorPreCommitOnChainInfo;
 use fil_actor_miner::{power_for_sector, State as MinerState};
-use fil_actors_runtime::builtin::SYSTEM_ACTOR_ADDR;
 use fil_actors_runtime::runtime::policy::policy_constants::PRE_COMMIT_CHALLENGE_DELAY;
 use fil_actors_runtime::runtime::policy_constants::{
     MAX_AGGREGATED_SECTORS, PRE_COMMIT_SECTOR_BATCH_MAX_SIZE,
 };
 use fil_actors_runtime::runtime::Policy;
-use fil_actors_runtime::CRON_ACTOR_ADDR;
-use fvm_ipld_encoding::RawBytes;
-use fvm_shared::bigint::{BigInt, Zero};
+use fvm_shared::bigint::BigInt;
 use fvm_shared::econ::TokenAmount;
 use fvm_shared::sector::{RegisteredSealProof, SectorNumber};
-use vm_api::util::{apply_ok, get_state, DynBlockstore};
+use vm_api::util::{get_state, DynBlockstore};
 use vm_api::VM;
 
 use crate::util::{
-    advance_to_proving_deadline, create_accounts, create_miner, expect_invariants,
+    advance_to_proving_deadline, create_accounts, create_miner, cron_tick, expect_invariants,
     get_network_stats, invariant_failure_patterns, miner_balance, precommit_sectors_v2,
     prove_commit_sectors, submit_windowed_post,
 };
@@ -142,14 +138,7 @@ pub fn batch_onboarding_test(v: &dyn VM) {
     );
     assert!(network_stats.total_pledge_collateral.is_positive());
 
-    apply_ok(
-        v,
-        &SYSTEM_ACTOR_ADDR,
-        &CRON_ACTOR_ADDR,
-        &TokenAmount::zero(),
-        CronMethod::EpochTick as u64,
-        None::<RawBytes>,
-    );
+    cron_tick(v);
 
     let network_stats = get_network_stats(v);
     let sector_size = seal_proof.sector_size().unwrap() as u64;
diff --git a/integration_tests/src/tests/commit_post_test.rs b/integration_tests/src/tests/commit_post_test.rs
index 25e325a24..18f02c223 100644
--- a/integration_tests/src/tests/commit_post_test.rs
+++ b/integration_tests/src/tests/commit_post_test.rs
@@ -3,7 +3,6 @@ use export_macro::vm_test;
 use fil_actors_runtime::runtime::policy_constants::MAX_SECTOR_NUMBER;
 use fvm_ipld_bitfield::BitField;
 use fvm_ipld_encoding::ipld_block::IpldBlock;
-use fvm_ipld_encoding::RawBytes;
 use fvm_shared::address::Address;
 use fvm_shared::bigint::Zero;
 use fvm_shared::econ::TokenAmount;
@@ -14,8 +13,8 @@ use fvm_shared::sector::{PoStProof, RegisteredSealProof, SectorNumber};
 use crate::expects::Expect;
 use crate::util::{
     advance_by_deadline_to_epoch, advance_to_proving_deadline, assert_invariants, create_accounts,
-    create_miner, expect_invariants, get_network_stats, invariant_failure_patterns, miner_balance,
-    precommit_sectors_v2, submit_windowed_post,
+    create_miner, cron_tick, expect_invariants, get_network_stats, invariant_failure_patterns,
+    miner_balance, precommit_sectors_v2, submit_windowed_post,
 };
 use crate::TEST_VM_RAND_ARRAY;
 use fil_actor_cron::Method as CronMethod;
@@ -29,7 +28,7 @@ use fil_actor_power::{Method as PowerMethod, State as PowerState};
 use fil_actors_runtime::runtime::Policy;
 use fil_actors_runtime::{
     CRON_ACTOR_ADDR, CRON_ACTOR_ID, STORAGE_MARKET_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR,
-    STORAGE_POWER_ACTOR_ID, SYSTEM_ACTOR_ADDR,
+    STORAGE_POWER_ACTOR_ID,
 };
 use vm_api::trace::{EmittedEvent, ExpectInvocation};
 use vm_api::util::{apply_code, apply_ok, get_state, DynBlockstore};
@@ -106,16 +105,9 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) {
         ..Default::default()
     }
     .matches(v.take_invocations().last().unwrap());
-    let res = v
-        .execute_message(
-            &SYSTEM_ACTOR_ADDR,
-            &CRON_ACTOR_ADDR,
-            &TokenAmount::zero(),
-            CronMethod::EpochTick as u64,
-            None,
-        )
-        .unwrap();
-    assert_eq!(ExitCode::OK, res.code);
+
+    cron_tick(v);
+
     let pieces: Vec<(Cid, u64)> = vec![];
     ExpectInvocation {
         to: CRON_ACTOR_ADDR,
@@ -253,14 +245,7 @@ pub fn missed_first_post_deadline_test(v: &dyn VM) {
     v.set_epoch(sector_info.deadline_info.last());
 
     // Run cron to detect missing PoSt
-    apply_ok(
-        v,
-        &SYSTEM_ACTOR_ADDR,
-        &CRON_ACTOR_ADDR,
-        &TokenAmount::zero(),
-        CronMethod::EpochTick as u64,
-        None::<RawBytes>,
-    );
+    cron_tick(v);
 
     ExpectInvocation {
         to: CRON_ACTOR_ADDR,
@@ -362,14 +347,7 @@ pub fn overdue_precommit_test(v: &dyn VM) {
     v.set_epoch(deadline_info.close);
 
     // run cron which should clean up precommit
-    apply_ok(
-        v,
-        &SYSTEM_ACTOR_ADDR,
-        &CRON_ACTOR_ADDR,
-        &TokenAmount::zero(),
-        CronMethod::EpochTick as u64,
-        None::<RawBytes>,
-    );
+    cron_tick(v);
 
     ExpectInvocation {
         to: CRON_ACTOR_ADDR,
diff --git a/integration_tests/src/tests/replica_update_test.rs b/integration_tests/src/tests/replica_update_test.rs
index e30283296..000430091 100644
--- a/integration_tests/src/tests/replica_update_test.rs
+++ b/integration_tests/src/tests/replica_update_test.rs
@@ -1,6 +1,5 @@
 use cid::Cid;
 use fvm_ipld_bitfield::BitField;
-use fvm_ipld_encoding::RawBytes;
 use fvm_shared::address::Address;
 use fvm_shared::bigint::{BigInt, Zero};
 use fvm_shared::clock::ChainEpoch;
@@ -13,7 +12,6 @@ use fvm_shared::sector::StoragePower;
 use fvm_shared::sector::{RegisteredSealProof, SectorNumber};
 
 use export_macro::vm_test;
-use fil_actor_cron::Method as CronMethod;
 use fil_actor_market::Method as MarketMethod;
 use fil_actor_market::State as MarketState;
 use fil_actor_miner::{
@@ -26,9 +24,7 @@ use fil_actor_verifreg::Method as VerifregMethod;
 use fil_actors_runtime::runtime::Policy;
 use fil_actors_runtime::test_utils::make_sealed_cid;
 use fil_actors_runtime::VERIFIED_REGISTRY_ACTOR_ADDR;
-use fil_actors_runtime::{
-    Array, CRON_ACTOR_ADDR, EPOCHS_IN_DAY, STORAGE_MARKET_ACTOR_ADDR, SYSTEM_ACTOR_ADDR,
-};
+use fil_actors_runtime::{Array, EPOCHS_IN_DAY, STORAGE_MARKET_ACTOR_ADDR};
 use vm_api::trace::ExpectInvocation;
 use vm_api::util::{apply_code, apply_ok, get_state, mutate_state, DynBlockstore};
 use vm_api::VM;
@@ -38,7 +34,7 @@ use crate::expects::Expect;
 use crate::util::{
     advance_by_deadline_to_epoch, advance_by_deadline_to_index, advance_to_proving_deadline,
     assert_invariants, bf_all, check_sector_active, check_sector_faulty, create_accounts,
-    create_miner, deadline_state, declare_recovery, expect_invariants, get_deal_weights,
+    create_miner, cron_tick, deadline_state, declare_recovery, expect_invariants, get_deal_weights,
     get_network_stats, invariant_failure_patterns, make_bitfield, market_publish_deal,
     miner_balance, miner_power, override_compute_unsealed_sector_cid, precommit_sectors_v2,
     prove_commit_sectors, sector_info, submit_invalid_post, submit_windowed_post,
@@ -887,14 +883,7 @@ pub fn deal_included_in_multiple_sectors_failure_test(v: &dyn VM) {
     prove_commit_sectors(v, &worker, &maddr, precommits, 100);
 
     // In the same epoch, trigger cron to validate prove commit
-    apply_ok(
-        v,
-        &SYSTEM_ACTOR_ADDR,
-        &CRON_ACTOR_ADDR,
-        &TokenAmount::zero(),
-        CronMethod::EpochTick as u64,
-        None::<RawBytes>,
-    );
+    cron_tick(v);
 
     // advance to proving period and submit post
     let (deadline_info, partition_index) =
@@ -1207,16 +1196,9 @@ pub fn create_sector(
         MinerMethod::ProveCommitSector as u64,
         Some(prove_commit_params),
     );
-    let res = v
-        .execute_message(
-            &SYSTEM_ACTOR_ADDR,
-            &CRON_ACTOR_ADDR,
-            &TokenAmount::zero(),
-            CronMethod::EpochTick as u64,
-            None,
-        )
-        .unwrap();
-    assert_eq!(ExitCode::OK, res.code);
+
+    cron_tick(v);
+
     let (dline_info, p_idx) = advance_to_proving_deadline(v, &maddr, sector_number);
     let d_idx = dline_info.index;
     // not active until post
diff --git a/integration_tests/src/tests/terminate_test.rs b/integration_tests/src/tests/terminate_test.rs
index e60449d73..f4eb9e086 100644
--- a/integration_tests/src/tests/terminate_test.rs
+++ b/integration_tests/src/tests/terminate_test.rs
@@ -2,13 +2,11 @@ use std::ops::Neg;
 
 use fvm_shared::bigint::Zero;
 use fvm_shared::econ::TokenAmount;
-use fvm_shared::error::ExitCode;
 use fvm_shared::piece::PaddedPieceSize;
 use fvm_shared::sector::{RegisteredSealProof, StoragePower};
 use num_traits::cast::FromPrimitive;
 
 use export_macro::vm_test;
-use fil_actor_cron::Method as CronMethod;
 use fil_actor_market::{
     DealMetaArray, Method as MarketMethod, State as MarketState, WithdrawBalanceParams,
 };
@@ -21,8 +19,8 @@ use fil_actor_verifreg::{Method as VerifregMethod, VerifierParams};
 use fil_actors_runtime::network::EPOCHS_IN_DAY;
 use fil_actors_runtime::runtime::Policy;
 use fil_actors_runtime::{
-    CRON_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ID, STORAGE_POWER_ACTOR_ADDR,
-    SYSTEM_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR,
+    STORAGE_MARKET_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ID, STORAGE_POWER_ACTOR_ADDR,
+    VERIFIED_REGISTRY_ACTOR_ADDR,
 };
 use fvm_shared::deal::DealID;
 use fvm_shared::ActorID;
@@ -33,7 +31,7 @@ use vm_api::VM;
 use crate::expects::Expect;
 use crate::util::{
     advance_by_deadline_to_epoch, advance_by_deadline_to_epoch_while_proving,
-    advance_to_proving_deadline, assert_invariants, create_accounts, create_miner,
+    advance_to_proving_deadline, assert_invariants, create_accounts, create_miner, cron_tick,
     deal_cid_for_testing, make_bitfield, market_publish_deal, miner_balance,
     miner_precommit_one_sector_v2, precommit_meta_data_from_deals, submit_windowed_post,
     verifreg_add_verifier,
@@ -152,16 +150,8 @@ pub fn terminate_sectors_test(v: &dyn VM) {
         deal_ids.push(*id);
     }
 
-    let res = v
-        .execute_message(
-            &SYSTEM_ACTOR_ADDR,
-            &CRON_ACTOR_ADDR,
-            &TokenAmount::zero(),
-            CronMethod::EpochTick as u64,
-            None,
-        )
-        .unwrap();
-    assert_eq!(ExitCode::OK, res.code);
+    cron_tick(v);
+
     let st: MarketState = get_state(v, &STORAGE_MARKET_ACTOR_ADDR).unwrap();
     let store = DynBlockstore::wrap(v.blockstore());
     let deal_states = DealMetaArray::load(&st.states, &store).unwrap();
@@ -194,16 +184,9 @@ pub fn terminate_sectors_test(v: &dyn VM) {
         MinerMethod::ProveCommitSector as u64,
         Some(prove_params),
     );
-    let res = v
-        .execute_message(
-            &SYSTEM_ACTOR_ADDR,
-            &CRON_ACTOR_ADDR,
-            &TokenAmount::zero(),
-            CronMethod::EpochTick as u64,
-            None,
-        )
-        .unwrap();
-    assert_eq!(ExitCode::OK, res.code);
+
+    cron_tick(v);
+
     let (dline_info, p_idx) = advance_to_proving_deadline(v, &miner_id_addr, sector_number);
     let d_idx = dline_info.index;
     let st: MinerState = get_state(v, &miner_id_addr).unwrap();
@@ -213,15 +196,7 @@ pub fn terminate_sectors_test(v: &dyn VM) {
     submit_windowed_post(v, &worker, &miner_id_addr, dline_info, p_idx, Some(sector_power.clone()));
     v.set_epoch(dline_info.last());
 
-    v.execute_message(
-        &SYSTEM_ACTOR_ADDR,
-        &CRON_ACTOR_ADDR,
-        &TokenAmount::zero(),
-        CronMethod::EpochTick as u64,
-        None,
-    )
-    .unwrap();
-    assert_eq!(ExitCode::OK, res.code);
+    cron_tick(v);
 
     // advance cron delay epochs so deals are active
     let start = dline_info.close;
diff --git a/test_vm/src/lib.rs b/test_vm/src/lib.rs
index 50b61b617..70e5fcda2 100644
--- a/test_vm/src/lib.rs
+++ b/test_vm/src/lib.rs
@@ -285,11 +285,15 @@ impl VM for TestVM {
         params: Option<IpldBlock>,
     ) -> Result<MessageResult, VMError> {
         let from_id = &self.resolve_id_address(from).unwrap();
+        // TODO: for non-implicit calls validate that from_id is either the
+        // account actor or the ethereum account actor and error otherwise
         let mut a = self.actor(from_id).unwrap();
         let call_seq = a.sequence;
         a.sequence = call_seq + 1;
         // EthAccount abstractions turns Placeholders into EthAccounts
         if a.code == *PLACEHOLDER_ACTOR_CODE_ID {
+            // TODO: for non-implicit calls validate that the actor has a
+            // delegated f4 address in the EAM's namespace
             a.code = *ETHACCOUNT_ACTOR_CODE_ID;
         }
         self.set_actor(from_id, a);