use fil_actor_market::VerifiedDealInfo;
use fil_actor_miner::ext::verifreg::Claim as FILPlusClaim;
use fil_actor_miner::{
power_for_sector, seal_proof_sector_maximum_lifetime, ExpirationExtension,
ExpirationExtension2, ExtendSectorExpiration2Params, ExtendSectorExpirationParams,
PoStPartition, SectorClaim, SectorOnChainInfo, State,
};
use fil_actors_runtime::DealWeight;
use fil_actors_runtime::{
actor_error,
runtime::{Runtime, RuntimePolicy},
test_utils::{expect_abort_contains_message, make_piece_cid, MockRuntime},
EPOCHS_IN_DAY,
};
use fvm_ipld_bitfield::BitField;
use fvm_shared::{
address::Address,
clock::ChainEpoch,
error::ExitCode,
sector::{RegisteredSealProof, SectorNumber},
ActorID,
};
use std::collections::HashMap;
mod util;
use fil_actors_runtime::runtime::Policy;
use itertools::Itertools;
use test_case::test_case;
use util::*;
const DEFAULT_SECTOR_EXPIRATION: ChainEpoch = 220;
fn setup() -> (ActorHarness, MockRuntime) {
let period_offset = 100;
let precommit_epoch = 1;
let mut h = ActorHarness::new(period_offset);
h.set_proof_type(RegisteredSealProof::StackedDRG512MiBV1);
let mut rt = h.new_runtime();
rt.balance.replace(BIG_BALANCE.clone());
rt.set_epoch(precommit_epoch);
(h, rt)
}
fn commit_sector(h: &mut ActorHarness, rt: &mut MockRuntime) -> SectorOnChainInfo {
h.construct_and_verify(rt);
h.commit_and_prove_sectors(rt, 1, DEFAULT_SECTOR_EXPIRATION as u64, Vec::new(), true)[0]
.to_owned()
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn rejects_negative_extensions(v2: bool) {
let (mut h, mut rt) = setup();
let sector = commit_sector(&mut h, &mut rt);
let new_expiration = sector.expiration - rt.policy().wpost_proving_period;
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), sector.sector_number).unwrap();
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[sector.sector_number]),
new_expiration,
}],
};
let res = h.extend_sectors_versioned(&mut rt, params, v2);
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
&format!("cannot reduce sector {} expiration", sector.sector_number),
res,
);
h.check_state(&rt);
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn rejects_extension_too_far_in_future(v2: bool) {
let (mut h, mut rt) = setup();
let sector = commit_sector(&mut h, &mut rt);
rt.set_epoch(sector.expiration);
let extension = rt.policy().wpost_proving_period + rt.policy().max_sector_expiration_extension;
let new_expiration = rt.epoch + extension;
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), sector.sector_number).unwrap();
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[sector.sector_number]),
new_expiration,
}],
};
let res = h.extend_sectors_versioned(&mut rt, params, v2);
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
&format!(
"cannot be more than {} past current epoch",
rt.policy().max_sector_expiration_extension
),
res,
);
h.check_state(&rt);
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn rejects_extension_past_max_for_seal_proof(v2: bool) {
let (mut h, mut rt) = setup();
let mut sector = commit_sector(&mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![sector.clone()]);
let max_lifetime = seal_proof_sector_maximum_lifetime(sector.seal_proof).unwrap();
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), sector.sector_number).unwrap();
rt.set_epoch(sector.expiration);
let extension = rt.policy().min_sector_expiration;
let mut expiration = sector.expiration + extension;
while expiration - sector.activation < max_lifetime {
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[sector.sector_number]),
new_expiration: expiration,
}],
};
h.extend_sectors(&mut rt, params).unwrap();
sector.expiration = expiration;
expiration += extension;
}
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[sector.sector_number]),
new_expiration: expiration,
}],
};
let res = h.extend_sectors_versioned(&mut rt, params, v2);
expect_abort_contains_message(ExitCode::USR_ILLEGAL_ARGUMENT, "total sector lifetime", res);
h.check_state(&rt);
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn updates_expiration_with_valid_params(v2: bool) {
let (mut h, mut rt) = setup();
let old_sector = commit_sector(&mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[old_sector.sector_number]),
new_expiration,
}],
};
h.extend_sectors_versioned(&mut rt, params, v2).unwrap();
let new_sector = h.get_sector(&rt, old_sector.sector_number);
assert_eq!(new_expiration, new_sector.expiration);
let quant = state.quant_spec_for_deadline(rt.policy(), deadline_index);
let (_, mut partition) = h.get_deadline_and_partition(&rt, deadline_index, partition_index);
let expiration_set =
partition.pop_expired_sectors(rt.store(), new_expiration - 1, quant).unwrap();
assert!(expiration_set.is_empty());
let expiration_set = partition
.pop_expired_sectors(rt.store(), quant.quantize_up(new_expiration), quant)
.unwrap();
assert_eq!(expiration_set.len(), 1);
assert!(expiration_set.on_time_sectors.get(old_sector.sector_number));
h.check_state(&rt);
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn updates_many_sectors(v2: bool) {
let (mut h, mut rt) = setup();
h.construct_and_verify(&mut rt);
let sector_count = 4;
let sector_infos = h.commit_and_prove_sectors(
&mut rt,
sector_count as usize,
DEFAULT_SECTOR_EXPIRATION as u64,
Vec::new(),
true,
);
h.advance_and_submit_posts(&mut rt, §or_infos);
let new_expiration = sector_infos[0].expiration + 42 * rt.policy().wpost_proving_period;
let mut extensions: Vec<ExpirationExtension> = Vec::new();
let state: State = rt.get_state();
let deadlines = state.load_deadlines(rt.store()).unwrap();
deadlines
.for_each(rt.policy(), rt.store(), |deadline_index, deadline| {
let partitions = deadline.partitions_amt(rt.store()).unwrap();
partitions
.for_each(|partition_index, partition| {
let sectors = partition
.sectors
.bounded_iter(rt.policy().addressed_sectors_max)
.unwrap()
.filter(|n| n % 2 != 0)
.collect_vec();
extensions.push(ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(§ors),
new_expiration,
});
Ok(())
})
.unwrap();
Ok(())
})
.unwrap();
assert!(extensions.len() >= 2, "test error: this test should touch more than one partition");
let params = ExtendSectorExpirationParams { extensions };
h.extend_sectors_versioned(&mut rt, params, v2).unwrap();
let state: State = rt.get_state();
let deadlines = state.load_deadlines(rt.store()).unwrap();
let (mut on_time_total, mut extended_total) = (0, 0);
deadlines
.for_each(rt.policy(), rt.store(), |deadline_index, mut deadline| {
let expiration_set = deadline
.pop_expired_sectors(
rt.store(),
new_expiration - 1,
state.quant_spec_for_deadline(rt.policy(), deadline_index),
)
.unwrap();
on_time_total += expiration_set.len();
let quant = state.quant_spec_for_deadline(rt.policy(), deadline_index);
let expiration_set = deadline
.pop_expired_sectors(rt.store(), quant.quantize_up(new_expiration), quant)
.unwrap();
extended_total += expiration_set.len();
Ok(())
})
.unwrap();
assert_eq!(sector_count / 2, on_time_total);
assert_eq!(sector_count / 2, extended_total);
h.check_state(&rt);
}
#[test_case(false; "v1")]
#[test_case(true; "v2")]
fn supports_extensions_off_deadline_boundary(v2: bool) {
let (mut h, mut rt) = setup();
let old_sector = commit_sector(&mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period + rt.policy().wpost_proving_period / 3;
let new_expiration = old_sector.expiration + extension;
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[old_sector.sector_number]),
new_expiration,
}],
};
h.extend_sectors_versioned(&mut rt, params, v2).unwrap();
let mut state: State = rt.get_state();
let new_sector = h.get_sector(&rt, old_sector.sector_number);
assert_eq!(new_expiration, new_sector.expiration);
rt.set_epoch(new_sector.expiration);
state.proving_period_start += rt.policy().wpost_proving_period
* ((rt.epoch - state.proving_period_start) / rt.policy().wpost_proving_period + 1);
rt.replace_state(&state);
let deadline_info = h.deadline(&rt);
assert_ne!(deadline_index, deadline_info.index);
let deadline_info = h.advance_to_deadline(&mut rt, deadline_index);
let partitions = vec![PoStPartition { index: partition_index, skipped: BitField::default() }];
h.submit_window_post(
&mut rt,
&deadline_info,
partitions,
vec![new_sector.clone()],
PoStConfig::empty(),
);
let power = -power_for_sector(h.sector_size, &new_sector);
let mut cron_config = CronConfig::empty();
cron_config.no_enrollment = true;
cron_config.expired_sectors_power_delta = Some(power);
cron_config.expired_sectors_pledge_delta = -new_sector.initial_pledge;
h.advance_deadline(&mut rt, cron_config);
let state: State = rt.get_state();
assert!(!state.deadline_cron_active);
h.check_state(&rt);
}
#[test]
fn update_expiration2_multiple_claims() {
let (mut h, mut rt) = setup();
let verified_deals = vec![
test_verified_deal(h.sector_size as u64 / 2),
test_verified_deal(h.sector_size as u64 / 2),
];
let old_sector = commit_sector_verified_deals(&verified_deals, &mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let claim_ids = vec![400, 500];
let client = Address::new_id(3000).id().unwrap();
let claim0 = make_claim(
claim_ids[0],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[0],
rt.policy.minimum_verified_allocation_term,
);
let claim1 = make_claim(
claim_ids[1],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[1],
rt.policy.minimum_verified_allocation_term,
);
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0));
claims.insert(claim_ids[1], Ok(claim1));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: claim_ids,
drop_claims: vec![],
}],
}],
};
h.extend_sectors2(&mut rt, params, claims).unwrap();
check_for_expiration(
&mut h,
&mut rt,
new_expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
}
#[test]
fn update_expiration2_failure_cases() {
let (mut h, mut rt) = setup();
let verified_deals = vec![
test_verified_deal(h.sector_size as u64 / 2),
test_verified_deal(h.sector_size as u64 / 2),
];
let old_sector = commit_sector_verified_deals(&verified_deals, &mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let claim_ids = vec![400, 500];
let client = Address::new_id(3000).id().unwrap();
let claim0 = make_claim(
claim_ids[0],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[0],
rt.policy.minimum_verified_allocation_term,
);
let mut claim1 = make_claim(
claim_ids[1],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[1],
rt.policy.minimum_verified_allocation_term,
);
{
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: vec![claim_ids[0]],
drop_claims: vec![],
}],
}],
};
let res = h.extend_sectors2(&mut rt, params, claims);
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
"does not match verified deal space",
res,
);
check_for_expiration(
&mut h,
&mut rt,
old_sector.expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
rt.replace_state(&state);
rt.reset();
}
{
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
claims.insert(claim_ids[1], Err(actor_error!(not_found, "claim not found")));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: claim_ids.clone(),
drop_claims: vec![],
}],
}],
};
let res = h.extend_sectors2(&mut rt, params, claims);
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
"failed to get claims for sector",
res,
);
check_for_expiration(
&mut h,
&mut rt,
old_sector.expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
rt.replace_state(&state);
rt.reset();
}
{
claim1.term_max -= 1;
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0));
claims.insert(claim_ids[1], Ok(claim1));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: claim_ids,
drop_claims: vec![],
}],
}],
};
let res = h.extend_sectors2(&mut rt, params, claims);
expect_abort_contains_message(
ExitCode::USR_FORBIDDEN,
&format!(
"claim only allows extension to {} but declared new expiration is {}",
new_expiration - 1,
new_expiration
),
res,
);
check_for_expiration(
&mut h,
&mut rt,
old_sector.expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
rt.replace_state(&state);
rt.reset();
}
}
#[test]
fn extend_expiration2_drop_claims() {
let (mut h, mut rt) = setup();
let verified_deals = vec![
test_verified_deal(h.sector_size as u64 / 2),
test_verified_deal(h.sector_size as u64 / 2),
];
let policy = Policy::default();
let old_sector = commit_sector_verified_deals(&verified_deals, &mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let claim_ids = vec![400, 500];
let client = Address::new_id(3000).id().unwrap();
let second_expiration = new_expiration + 42 * EPOCHS_IN_DAY;
let claim0 = make_claim(
claim_ids[0],
&old_sector,
client,
h.receiver.id().unwrap(),
second_expiration,
&verified_deals[0],
rt.policy.minimum_verified_allocation_term,
);
let claim1 = make_claim(
claim_ids[1],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[1],
rt.policy.minimum_verified_allocation_term,
);
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
claims.insert(claim_ids[1], Ok(claim1));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: vec![claim_ids[0]],
drop_claims: vec![claim_ids[1]],
}],
}],
};
rt.set_epoch(old_sector.expiration - policy.end_of_life_claim_drop_period);
h.extend_sectors2(&mut rt, params, claims).unwrap();
check_for_expiration(
&mut h,
&mut rt,
new_expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
assert_sector_verified_space(
&mut h,
&mut rt,
old_sector.sector_number,
verified_deals[0].size.0,
);
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0));
let bad_params2 = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: bitfield_from_slice(&[old_sector.sector_number]),
new_expiration: second_expiration,
sectors_with_claims: vec![],
}],
};
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
"claim missing from declaration for sector",
h.extend_sectors2(&mut rt, bad_params2, claims.clone()),
);
rt.reset();
let params2 = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration: second_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: vec![claim_ids[0]],
drop_claims: vec![],
}],
}],
};
h.extend_sectors2(&mut rt, params2, claims).unwrap();
check_for_expiration(
&mut h,
&mut rt,
second_expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
assert_sector_verified_space(
&mut h,
&mut rt,
old_sector.sector_number,
verified_deals[0].size.0,
);
}
#[test]
fn update_expiration_legacy_fails_on_new_sector_with_deals() {
let (mut h, mut rt) = setup();
let verified_deals = vec![
test_verified_deal(h.sector_size as u64 / 2),
test_verified_deal(h.sector_size as u64 / 2),
];
let old_sector = commit_sector_verified_deals(&verified_deals, &mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let params = ExtendSectorExpirationParams {
extensions: vec![ExpirationExtension {
deadline: deadline_index,
partition: partition_index,
sectors: make_bitfield(&[old_sector.sector_number]),
new_expiration,
}],
};
expect_abort_contains_message(
ExitCode::USR_FORBIDDEN,
"cannot use legacy sector extension for simple qa power with deal weight",
h.extend_sectors(&mut rt, params),
);
check_for_expiration(
&mut h,
&mut rt,
old_sector.expiration,
old_sector.sector_number,
deadline_index,
partition_index,
);
}
#[test]
fn update_expiration2_drop_claims_failure_cases() {
let (mut h, mut rt) = setup();
let policy = Policy::default();
let verified_deals = vec![
test_verified_deal(h.sector_size as u64 / 2),
test_verified_deal(h.sector_size as u64 / 2),
];
let old_sector = commit_sector_verified_deals(&verified_deals, &mut h, &mut rt);
h.advance_and_submit_posts(&mut rt, &vec![old_sector.clone()]);
let state: State = rt.get_state();
let (deadline_index, partition_index) =
state.find_sector(rt.policy(), rt.store(), old_sector.sector_number).unwrap();
let extension = 42 * rt.policy().wpost_proving_period;
let new_expiration = old_sector.expiration + extension;
let claim_ids = vec![400, 500];
let client = Address::new_id(3000).id().unwrap();
let claim0 = make_claim(
claim_ids[0],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[0],
rt.policy.minimum_verified_allocation_term,
);
let mut claim1 = make_claim(
claim_ids[1],
&old_sector,
client,
h.receiver.id().unwrap(),
new_expiration,
&verified_deals[1],
rt.policy.minimum_verified_allocation_term,
);
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
claims.insert(claim_ids[1], Ok(claim1.clone()));
let params = ExtendSectorExpiration2Params {
extensions: vec![ExpirationExtension2 {
deadline: deadline_index,
partition: partition_index,
sectors: BitField::new(),
new_expiration,
sectors_with_claims: vec![SectorClaim {
sector_number: old_sector.sector_number,
maintain_claims: vec![claim_ids[0]],
drop_claims: vec![claim_ids[1]],
}],
}],
};
rt.set_epoch(old_sector.expiration - policy.end_of_life_claim_drop_period - 1);
expect_abort_contains_message(
ExitCode::USR_FORBIDDEN,
"attempt to drop claims with 86401 epochs > end of life claim drop period 86400 remaining",
h.extend_sectors2(&mut rt, params.clone(), claims.clone()),
);
rt.reset();
rt.set_epoch(old_sector.expiration - policy.end_of_life_claim_drop_period);
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
claims.insert(claim_ids[1], Err(actor_error!(not_found, "claim not found")));
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
"failed to get claims for sector",
h.extend_sectors2(&mut rt, params.clone(), claims.clone()),
);
rt.reset();
claim1.provider = h.receiver.id().unwrap() + 7;
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0.clone()));
claims.insert(claim_ids[1], Ok(claim1.clone()));
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
&format!(
"expected claim provider to be {} but found {}",
h.receiver.id().unwrap(),
h.receiver.id().unwrap() + 7
),
h.extend_sectors2(&mut rt, params.clone(), claims.clone()),
);
rt.reset();
claim1.provider = h.receiver.id().unwrap();
claim1.sector = old_sector.sector_number + 7;
let mut claims = HashMap::new();
claims.insert(claim_ids[0], Ok(claim0));
claims.insert(claim_ids[1], Ok(claim1.clone()));
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
&format!(
"expected claim sector number to be {} but found {}",
old_sector.sector_number,
old_sector.sector_number + 7
),
h.extend_sectors2(&mut rt, params, claims.clone()),
);
rt.reset();
claim1.sector = old_sector.sector_number;
}
fn commit_sector_verified_deals(
verified_deals: &Vec<VerifiedDealInfo>,
h: &mut ActorHarness,
rt: &mut MockRuntime,
) -> SectorOnChainInfo {
h.construct_and_verify(rt);
assert!(!verified_deals.is_empty());
let mut pcc = ProveCommitConfig::empty();
pcc.add_verified_deals(h.next_sector_no, verified_deals.clone());
let sector_info = &h.commit_and_prove_sectors_with_cfgs(
rt,
1,
DEFAULT_SECTOR_EXPIRATION as u64,
vec![vec![42]],
true,
pcc,
)[0];
sector_info.clone()
}
fn check_for_expiration(
h: &mut ActorHarness,
rt: &mut MockRuntime,
expiration: ChainEpoch,
sector_number: SectorNumber,
deadline_index: u64,
partition_index: u64,
) {
let new_sector = h.get_sector(rt, sector_number);
assert_eq!(expiration, new_sector.expiration);
let state: State = rt.get_state();
let quant = state.quant_spec_for_deadline(rt.policy(), deadline_index);
let (_, mut partition) = h.get_deadline_and_partition(rt, deadline_index, partition_index);
let expiration_set = partition.pop_expired_sectors(rt.store(), expiration - 1, quant).unwrap();
assert!(expiration_set.is_empty());
let expiration_set =
partition.pop_expired_sectors(rt.store(), quant.quantize_up(expiration), quant).unwrap();
assert_eq!(expiration_set.len(), 1);
assert!(expiration_set.on_time_sectors.get(sector_number));
h.check_state(rt);
}
fn assert_sector_verified_space(
h: &mut ActorHarness,
rt: &mut MockRuntime,
sector_number: SectorNumber,
v_deal_space: u64,
) {
let new_sector = h.get_sector(rt, sector_number);
assert_eq!(
DealWeight::from(v_deal_space),
new_sector.verified_deal_weight / (new_sector.expiration - new_sector.activation)
);
}
fn make_claim(
claim_id: u64,
sector: &SectorOnChainInfo,
client: ActorID,
provider: ActorID,
new_expiration: ChainEpoch,
deal: &VerifiedDealInfo,
term_min: ChainEpoch,
) -> FILPlusClaim {
FILPlusClaim {
provider,
client,
data: make_piece_cid(format!("piece for claim {}", claim_id).as_bytes()),
size: deal.size,
term_min,
term_max: new_expiration - sector.activation,
term_start: sector.activation,
sector: sector.sector_number,
}
}