Skip to content

Commit

Permalink
Power actor tests part 8 (#287)
Browse files Browse the repository at this point in the history
* use create_miner_basic to reduce boilerplate

* power actor tests part 8
  • Loading branch information
LesnyRumcajs authored Apr 28, 2022
1 parent 63d6dad commit 42a6241
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 59 deletions.
92 changes: 91 additions & 1 deletion actors/power/tests/harness/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
use cid::Cid;
use fil_actor_power::epoch_key;
use fil_actor_power::ext::miner::ConfirmSectorProofsParams;
use fil_actor_power::ext::miner::CONFIRM_SECTOR_PROOFS_VALID_METHOD;
use fil_actor_power::ext::reward::Method::ThisEpochReward;
use fil_actor_power::ext::reward::UPDATE_NETWORK_KPI;
use fil_actor_power::CronEvent;
use fil_actor_power::EnrollCronEventParams;
use fil_actor_power::CRON_QUEUE_AMT_BITWIDTH;
use fil_actor_power::CRON_QUEUE_HAMT_BITWIDTH;
use fil_actors_runtime::test_utils::CRON_ACTOR_CODE_ID;
use fil_actors_runtime::Multimap;
use fil_actors_runtime::CRON_ACTOR_ADDR;
use fil_actors_runtime::REWARD_ACTOR_ADDR;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::{BytesDe, RawBytes};
use fvm_ipld_hamt::BytesKey;
use fvm_ipld_hamt::Error;
use fvm_shared::address::Address;
use fvm_shared::bigint::bigint_ser::BigIntDe;
use fvm_shared::bigint::bigint_ser::BigIntSer;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::reward::ThisEpochRewardReturn;
use fvm_shared::sector::SealVerifyInfo;
use fvm_shared::sector::SectorNumber;
use fvm_shared::sector::{RegisteredPoStProof, RegisteredSealProof, StoragePower};
use fvm_shared::smooth::FilterEstimate;
use fvm_shared::MethodNum;
Expand Down Expand Up @@ -80,7 +91,7 @@ pub struct Harness {
seal_proof: RegisteredSealProof,
pub window_post_proof: RegisteredPoStProof,
this_epoch_baseline_power: StoragePower,
this_epoch_reward_smoothed: FilterEstimate,
pub this_epoch_reward_smoothed: FilterEstimate,
}

impl Harness {
Expand Down Expand Up @@ -344,6 +355,85 @@ impl Harness {
let st: State = rt.get_state();
assert_eq!(count, st.miner_above_min_power_count);
}

pub fn expect_query_network_info(&self, rt: &mut MockRuntime) {
let current_reward = ThisEpochRewardReturn {
this_epoch_baseline_power: self.this_epoch_baseline_power.clone(),
this_epoch_reward_smoothed: self.this_epoch_reward_smoothed.clone(),
};

rt.expect_send(
*REWARD_ACTOR_ADDR,
ThisEpochReward as u64,
RawBytes::default(),
TokenAmount::from(0u8),
RawBytes::serialize(current_reward).unwrap(),
ExitCode::OK,
);
}

pub fn on_epoch_tick_end(
&self,
rt: &mut MockRuntime,
current_epoch: ChainEpoch,
expected_raw_power: &StoragePower,
confirmed_sectors: Vec<ConfirmedSectorSend>,
infos: Vec<SealVerifyInfo>,
) {
self.expect_query_network_info(rt);

let state: State = rt.get_state();

//expect sends for confirmed sectors
for sector in confirmed_sectors {
let param = ConfirmSectorProofsParams {
sectors: sector.sector_nums,
reward_smoothed: self.this_epoch_reward_smoothed.clone(),
reward_baseline_power: self.this_epoch_baseline_power.clone(),
quality_adj_power_smoothed: state.this_epoch_qa_power_smoothed.clone(),
};
rt.expect_send(
sector.miner,
CONFIRM_SECTOR_PROOFS_VALID_METHOD,
RawBytes::serialize(param).unwrap(),
TokenAmount::zero(),
RawBytes::default(),
ExitCode::new(0),
);
}

let verified_seals = batch_verify_default_output(&infos);
rt.expect_batch_verify_seals(infos, anyhow::Ok(verified_seals));

// expect power sends to reward actor
rt.expect_send(
*REWARD_ACTOR_ADDR,
UPDATE_NETWORK_KPI,
RawBytes::serialize(BigIntSer(expected_raw_power)).unwrap(),
TokenAmount::zero(),
RawBytes::default(),
ExitCode::new(0),
);
rt.expect_validate_caller_addr(vec![*CRON_ACTOR_ADDR]);

rt.set_epoch(current_epoch);
rt.set_caller(*CRON_ACTOR_CODE_ID, *CRON_ACTOR_ADDR);

rt.call::<PowerActor>(Method::OnEpochTickEnd as u64, &RawBytes::default()).unwrap();

rt.verify();
let state: State = rt.get_state();
assert!(state.proof_validation_batch.is_none());
}
}

pub struct ConfirmedSectorSend {
miner: Address,
sector_nums: Vec<SectorNumber>,
}

pub fn batch_verify_default_output(infos: &[SealVerifyInfo]) -> Vec<bool> {
vec![true; infos.len()]
}

/// Collects all keys from a map into a vector.
Expand Down
216 changes: 158 additions & 58 deletions actors/power/tests/power_actor_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,37 +263,11 @@ fn power_and_pledge_accounted_below_threshold() {

#[test]
fn enroll_cron_epoch_multiple_events() {
let (h, mut rt) = setup();

let peer = "miner".as_bytes().to_vec();
let multiaddrs = vec![BytesDe("multiaddr".as_bytes().to_vec())];

h.create_miner(
&mut rt,
&OWNER,
&OWNER,
&MINER,
&ACTOR,
peer.clone(),
multiaddrs.clone(),
RegisteredPoStProof::StackedDRGWindow32GiBV1,
&TokenAmount::zero(),
)
.unwrap();
let (mut h, mut rt) = setup();

h.create_miner_basic(&mut rt, *OWNER, *OWNER, *MINER).unwrap();
let miner2_address = Address::new_id(501);
h.create_miner(
&mut rt,
&OWNER,
&OWNER,
&miner2_address,
&ACTOR,
peer,
multiaddrs,
RegisteredPoStProof::StackedDRGWindow32GiBV1,
&TokenAmount::zero(),
)
.unwrap();
h.create_miner_basic(&mut rt, *OWNER, *OWNER, miner2_address).unwrap();

let mut enroll_and_check_cron_event = |epoch, miner_address, payload| {
let pre_existing_event_count = h.get_enrolled_cron_ticks(&rt, epoch).len();
Expand Down Expand Up @@ -323,22 +297,9 @@ fn enroll_cron_epoch_multiple_events() {

#[test]
fn enroll_cron_epoch_before_current_epoch() {
let (h, mut rt) = setup();
let (mut h, mut rt) = setup();

let peer = "miner".as_bytes().to_vec();
let multiaddrs = vec![BytesDe("multiaddr".as_bytes().to_vec())];
h.create_miner(
&mut rt,
&OWNER,
&OWNER,
&MINER,
&ACTOR,
peer,
multiaddrs,
RegisteredPoStProof::StackedDRGWindow32GiBV1,
&TokenAmount::zero(),
)
.unwrap();
h.create_miner_basic(&mut rt, *OWNER, *OWNER, *MINER).unwrap();

let current_epoch: ChainEpoch = 5;
rt.set_epoch(current_epoch);
Expand Down Expand Up @@ -630,20 +591,7 @@ fn claimed_power_is_externally_available() {
fn given_no_miner_claim_update_pledge_total_should_abort() {
let (mut h, mut rt) = setup();

let peer = "miner".as_bytes().to_vec();
let multiaddrs = vec![BytesDe("multiaddr".as_bytes().to_vec())];
h.create_miner(
&mut rt,
&OWNER,
&OWNER,
&MINER,
&ACTOR,
peer,
multiaddrs,
RegisteredPoStProof::StackedDRGWindow32GiBV1,
&TokenAmount::zero(),
)
.unwrap();
h.create_miner_basic(&mut rt, *OWNER, *OWNER, *MINER).unwrap();

// explicitly delete miner claim
h.delete_claim(&mut rt, &*MINER);
Expand All @@ -662,3 +610,155 @@ fn given_no_miner_claim_update_pledge_total_should_abort() {
rt.verify();
h.check_state();
}

#[cfg(test)]
mod cron_tests {
use super::*;

use fil_actor_power::ext::reward::Method as RewardMethod;
use fil_actor_power::ext::{
miner::{DeferredCronEventParams, ON_DEFERRED_CRON_EVENT_METHOD},
reward::UPDATE_NETWORK_KPI,
};
use fil_actors_runtime::{test_utils::CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR, REWARD_ACTOR_ADDR};
use fvm_shared::bigint::BigInt;

const OWNER: Address = Address::new_id(103);

#[test]
fn call_reward_actor() {
let (h, mut rt) = setup();

let expected_power = BigInt::zero();
rt.set_epoch(1);

rt.expect_validate_caller_addr(vec![*CRON_ACTOR_ADDR]);

h.expect_query_network_info(&mut rt);
rt.expect_send(
*REWARD_ACTOR_ADDR,
RewardMethod::UpdateNetworkKPI as u64,
RawBytes::serialize(BigIntSer(&expected_power)).unwrap(),
TokenAmount::zero(),
RawBytes::default(),
ExitCode::OK,
);
rt.set_caller(*CRON_ACTOR_CODE_ID, *CRON_ACTOR_ADDR);
rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new()));

rt.call::<PowerActor>(Method::OnEpochTickEnd as u64, &RawBytes::default()).unwrap();

rt.verify();
h.check_state();
}

#[test]
fn amount_sent_to_reward_actor_and_state_change() {
let (mut h, mut rt) = setup();
let power_unit = consensus_miner_min_power(
&Policy::default(),
RegisteredPoStProof::StackedDRGWindow2KiBV1,
)
.unwrap();

let miner1 = Address::new_id(101);
let miner2 = Address::new_id(102);
let miner3 = Address::new_id(103);
let miner4 = Address::new_id(104);

h.create_miner_basic(&mut rt, OWNER, OWNER, miner1).unwrap();
h.create_miner_basic(&mut rt, OWNER, OWNER, miner2).unwrap();
h.create_miner_basic(&mut rt, OWNER, OWNER, miner3).unwrap();
h.create_miner_basic(&mut rt, OWNER, OWNER, miner4).unwrap();

h.update_claimed_power(&mut rt, miner1, &power_unit, &power_unit);
h.update_claimed_power(&mut rt, miner2, &power_unit, &power_unit);
h.update_claimed_power(&mut rt, miner3, &power_unit, &power_unit);
h.update_claimed_power(&mut rt, miner4, &power_unit, &power_unit);

let expected_power: BigInt = power_unit * 4u8;

let delta = TokenAmount::from(1u8);
h.update_pledge_total(&mut rt, miner1, &delta);
h.on_epoch_tick_end(&mut rt, 0, &expected_power, Vec::new(), Vec::new());

let state: State = rt.get_state();

assert_eq!(delta, state.this_epoch_pledge_collateral);
assert_eq!(expected_power, state.this_epoch_quality_adj_power);
assert_eq!(expected_power, state.this_epoch_raw_byte_power);

rt.verify();
h.check_state();
}

#[test]
fn event_scheduled_in_null_round_called_next_round() {
let (mut h, mut rt) = setup();

let miner1 = Address::new_id(101);
let miner2 = Address::new_id(102);

h.create_miner_basic(&mut rt, OWNER, OWNER, miner1).unwrap();
h.create_miner_basic(&mut rt, OWNER, OWNER, miner2).unwrap();

// 0 - genesis
// 1 - block - registers events
// 2 - null - has event
// 3 - null
// 4 - block - has event

rt.set_epoch(1);
h.enroll_cron_event(&mut rt, 2, &miner1, &RawBytes::from(vec![0x01, 0x03]));
h.enroll_cron_event(&mut rt, 4, &miner2, &RawBytes::from(vec![0x02, 0x03]));

let expected_raw_byte_power = BigInt::zero();
rt.set_epoch(4);
rt.expect_validate_caller_addr(vec![*CRON_ACTOR_ADDR]);
h.expect_query_network_info(&mut rt);
let state: State = rt.get_state();

let params1 = DeferredCronEventParams {
event_payload: vec![0x01, 0x03],
reward_smoothed: h.this_epoch_reward_smoothed.clone(),
quality_adj_power_smoothed: state.this_epoch_qa_power_smoothed.clone(),
};
rt.expect_send(
miner1,
ON_DEFERRED_CRON_EVENT_METHOD,
RawBytes::serialize(params1).unwrap(),
TokenAmount::zero(),
RawBytes::default(),
ExitCode::OK,
);

let params2 = DeferredCronEventParams {
event_payload: vec![0x02, 0x03],
reward_smoothed: h.this_epoch_reward_smoothed.clone(),
quality_adj_power_smoothed: state.this_epoch_qa_power_smoothed,
};
rt.expect_send(
miner2,
ON_DEFERRED_CRON_EVENT_METHOD,
RawBytes::serialize(params2).unwrap(),
TokenAmount::zero(),
RawBytes::default(),
ExitCode::OK,
);

rt.expect_send(
*REWARD_ACTOR_ADDR,
UPDATE_NETWORK_KPI,
RawBytes::serialize(BigIntSer(&expected_raw_byte_power)).unwrap(),
BigInt::zero(),
RawBytes::default(),
ExitCode::OK,
);
rt.set_caller(*CRON_ACTOR_CODE_ID, *CRON_ACTOR_ADDR);
rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new()));
rt.call::<PowerActor>(Method::OnEpochTickEnd as u64, &RawBytes::default()).unwrap();

rt.verify();
h.check_state();
}
}

0 comments on commit 42a6241

Please sign in to comment.