diff --git a/actors/miner/src/lib.rs b/actors/miner/src/lib.rs index 9d063d5b6..4db1b3898 100644 --- a/actors/miner/src/lib.rs +++ b/actors/miner/src/lib.rs @@ -109,7 +109,7 @@ pub enum Method { ChangePeerID = 4, SubmitWindowedPoSt = 5, //PreCommitSector = 6, // Deprecated - ProveCommitSector = 7, + //ProveCommitSector = 7, // Deprecated ExtendSectorExpiration = 8, TerminateSectors = 9, DeclareFaults = 10, @@ -119,7 +119,7 @@ pub enum Method { ApplyRewards = 14, ReportConsensusFault = 15, WithdrawBalance = 16, - ConfirmSectorProofsValid = 17, + //ConfirmSectorProofsValid = 17, // Deprecated ChangeMultiaddrs = 18, CompactPartitions = 19, CompactSectorNumbers = 20, @@ -1950,116 +1950,6 @@ impl Actor { Ok(ProveCommitSectors3Return { activation_results: result }) } - /// Checks state of the corresponding sector pre-commitment, then schedules the proof to be verified in bulk - /// by the power actor. - /// If valid, the power actor will call ConfirmSectorProofsValid at the end of the same epoch as this message. - fn prove_commit_sector( - rt: &impl Runtime, - params: ProveCommitSectorParams, - ) -> Result<(), ActorError> { - // Validate caller and parameters. - let st: State = rt.state()?; - let store = rt.store(); - // Note: this accepts any caller for legacy, but probably shouldn't. - // Since the miner can provide arbitrary control addresses, there's not much advantage - // in allowing any caller, but some risk if there's an exploitable bug. - rt.validate_immediate_caller_accept_any()?; - - if params.sector_number > MAX_SECTOR_NUMBER { - return Err(actor_error!(illegal_argument, "sector number greater than maximum")); - } - - // Validate pre-commit. - let precommit = st - .get_precommitted_sector(store, params.sector_number) - .with_context(|| format!("loading pre-commit {}", params.sector_number))? - .ok_or_else(|| { - actor_error!(not_found, "no pre-commited sector {}", params.sector_number) - })?; - - validate_seal_proofs(precommit.info.seal_proof, &[params.proof.clone()])?; - - let allow_deals = true; // Legacy onboarding entry points allow pre-committed deals. - let all_or_nothing = true; // The singleton must succeed. - let (_, proof_inputs) = - validate_precommits(rt, &vec![precommit], allow_deals, all_or_nothing)?; - let miner_actor_id = rt.message().receiver().id().unwrap(); - - let svi = proof_inputs[0].to_seal_verify_info(miner_actor_id, ¶ms.proof); - extract_send_result(rt.send_simple( - &STORAGE_POWER_ACTOR_ADDR, - ext::power::SUBMIT_POREP_FOR_BULK_VERIFY_METHOD, - IpldBlock::serialize_cbor(&svi)?, - TokenAmount::zero(), - ))?; - - Ok(()) - } - - fn confirm_sector_proofs_valid( - rt: &impl Runtime, - params: ConfirmSectorProofsParams, - ) -> Result<(), ActorError> { - rt.validate_immediate_caller_is(std::iter::once(&STORAGE_POWER_ACTOR_ADDR))?; - - /* validate params */ - // This should be enforced by the power actor. We log here just in case - // something goes wrong. - if params.sectors.len() > ext::power::MAX_MINER_PROVE_COMMITS_PER_EPOCH { - warn!( - "confirmed more prove commits in an epoch than permitted: {} > {}", - params.sectors.len(), - ext::power::MAX_MINER_PROVE_COMMITS_PER_EPOCH - ); - } - let st: State = rt.state()?; - let store = rt.store(); - // This skips missing pre-commits. - let precommited_sectors = - st.find_precommitted_sectors(store, ¶ms.sectors).map_err(|e| { - e.downcast_default( - ExitCode::USR_ILLEGAL_STATE, - "failed to load pre-committed sectors", - ) - })?; - - let data_activations: Vec = - precommited_sectors.iter().map(|x| x.clone().into()).collect(); - let info = get_miner_info(rt.store(), &st)?; - - /* - For all sectors - - CommD was specified at precommit - - If deal IDs were specified at precommit the CommD was checked against them - Therefore CommD on precommit has already been provided and checked so no further processing needed - */ - let compute_commd = false; - let (batch_return, data_activations) = - activate_sectors_deals(rt, &data_activations, compute_commd)?; - let successful_activations = batch_return.successes(&precommited_sectors); - - let pledge_inputs = NetworkPledgeInputs { - network_qap: params.quality_adj_power_smoothed, - network_baseline: params.reward_baseline_power, - circulating_supply: rt.total_fil_circ_supply(), - epoch_reward: params.reward_smoothed, - }; - activate_new_sector_infos( - rt, - successful_activations.clone(), - data_activations.clone(), - &pledge_inputs, - &info, - )?; - - for (pc, data) in successful_activations.iter().zip(data_activations.iter()) { - let unsealed_cid = pc.info.unsealed_cid.0; - emit::sector_activated(rt, pc.info.sector_number, unsealed_cid, &data.pieces)?; - } - - Ok(()) - } - fn check_sector_proven( rt: &impl Runtime, params: CheckSectorProvenParams, @@ -5711,7 +5601,6 @@ impl ActorCode for Actor { ChangeWorkerAddress|ChangeWorkerAddressExported => change_worker_address, ChangePeerID|ChangePeerIDExported => change_peer_id, SubmitWindowedPoSt => submit_windowed_post, - ProveCommitSector => prove_commit_sector, ExtendSectorExpiration => extend_sector_expiration, TerminateSectors => terminate_sectors, DeclareFaults => declare_faults, @@ -5721,7 +5610,6 @@ impl ActorCode for Actor { ApplyRewards => apply_rewards, ReportConsensusFault => report_consensus_fault, WithdrawBalance|WithdrawBalanceExported => withdraw_balance, - ConfirmSectorProofsValid => confirm_sector_proofs_valid, ChangeMultiaddrs|ChangeMultiaddrsExported => change_multiaddresses, CompactPartitions => compact_partitions, CompactSectorNumbers => compact_sector_numbers, diff --git a/actors/miner/src/types.rs b/actors/miner/src/types.rs index 5a5aca822..2831f37cb 100644 --- a/actors/miner/src/types.rs +++ b/actors/miner/src/types.rs @@ -14,7 +14,7 @@ use fvm_shared::piece::PaddedPieceSize; use fvm_shared::randomness::Randomness; use fvm_shared::sector::{ PoStProof, RegisteredAggregateProof, RegisteredPoStProof, RegisteredSealProof, - RegisteredUpdateProof, SectorNumber, SectorSize, StoragePower, + RegisteredUpdateProof, SectorNumber, SectorSize, }; use fvm_shared::ActorID; use serde::{Deserialize, Serialize}; @@ -88,15 +88,6 @@ pub struct ChangeMultiaddrsParams { pub new_multi_addrs: Vec, } -#[derive(Serialize_tuple, Deserialize_tuple)] -pub struct ConfirmSectorProofsParams { - pub sectors: Vec, - pub reward_smoothed: FilterEstimate, - #[serde(with = "bigint_ser")] - pub reward_baseline_power: StoragePower, - pub quality_adj_power_smoothed: FilterEstimate, -} - #[derive(Serialize_tuple, Deserialize_tuple)] pub struct DeferredCronEventParams { #[serde(with = "strict_bytes")] @@ -129,6 +120,7 @@ pub struct SubmitWindowedPoStParams { pub chain_commit_rand: Randomness, } +// Deprecated as of FIP 0084 -- kept for legacy testing #[derive(Serialize_tuple, Deserialize_tuple)] pub struct ProveCommitSectorParams { pub sector_number: SectorNumber, diff --git a/actors/miner/tests/exported_getters.rs b/actors/miner/tests/exported_getters.rs index b6c6bf9c8..a54679b74 100644 --- a/actors/miner/tests/exported_getters.rs +++ b/actors/miner/tests/exported_getters.rs @@ -115,8 +115,7 @@ fn collateral_getters() { let precommit_params = h.make_pre_commit_params(sector_no, precommit_epoch - 1, expiration, vec![]); - let precommit = - h.pre_commit_sector_and_get(&rt, precommit_params, PreCommitConfig::empty(), true); + h.pre_commit_sector_and_get(&rt, precommit_params, PreCommitConfig::empty(), true); // run prove commit logic rt.set_epoch(prove_commit_epoch); @@ -125,12 +124,7 @@ fn collateral_getters() { let pcc = ProveCommitConfig::empty(); let sector = h - .prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - pcc, - ) + .deprecated_sector_commit(&rt, &vec![], h.make_prove_commit_params(sector_no), pcc) .unwrap(); // query available balance diff --git a/actors/miner/tests/prove_commit.rs b/actors/miner/tests/prove_commit.rs index 279d5da4a..b5ef41f58 100644 --- a/actors/miner/tests/prove_commit.rs +++ b/actors/miner/tests/prove_commit.rs @@ -3,20 +3,11 @@ use fvm_shared::{ clock::ChainEpoch, econ::TokenAmount, error::ExitCode, - sector::StoragePower, }; -use std::collections::HashMap; -use fil_actor_miner::ext::market::NO_ALLOCATION_ID; -use fil_actor_miner::{ - initial_pledge_for_power, max_prove_commit_duration, pre_commit_deposit_for_power, - qa_power_for_weight, qa_power_max, PowerPair, PreCommitSectorBatchParams, VestSpec, -}; -use fil_actors_runtime::{ - reward::FilterEstimate, runtime::policy_constants::MAX_SECTOR_NUMBER, - test_utils::make_piece_cid, -}; -use fil_actors_runtime::{runtime::Runtime, test_utils::expect_abort, DealWeight}; +use fil_actor_miner::{max_prove_commit_duration, VestSpec}; +use fil_actors_runtime::reward::FilterEstimate; +use fil_actors_runtime::test_utils::expect_abort; use util::*; mod util; @@ -25,397 +16,8 @@ mod util; // between pre and prove commit const DEFAULT_SECTOR_EXPIRATION: ChainEpoch = 220; -const VERIFIED_DEAL_WEIGHT_MULTIPLIER: u64 = 100; -const QUALITY_BASE_MULTIPLIER: u64 = 10; const PERIOD_OFFSET: ChainEpoch = 100; -#[test] -fn prove_single_sector() { - let h = ActorHarness::new(PERIOD_OFFSET); - let rt = h.new_runtime(); - rt.balance.replace(BIG_BALANCE.clone()); - - let precommit_epoch = PERIOD_OFFSET + 1; - rt.set_epoch(precommit_epoch); - - h.construct_and_verify(&rt); - let dl_info = h.deadline(&rt); - - // Make a good commitment for the proof to target. - // Use the max sector number to make sure everything works. - let sector_no = MAX_SECTOR_NUMBER; - let prove_commit_epoch = precommit_epoch + rt.policy.pre_commit_challenge_delay + 1; - let expiration = - dl_info.period_end() + DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period; // something on deadline boundary but > 180 days - // Fill the sector with verified deals - let deal_space = BigInt::zero(); - let verified_deal = test_activated_deal(h.sector_size as u64, 1); - let verified_deal_space = BigInt::from(verified_deal.size.0); - - // Pre-commit with a deal in order to exercise non-zero deal weights. - let precommit_params = - h.make_pre_commit_params(sector_no, precommit_epoch - 1, expiration, vec![1]); - let precommit = - h.pre_commit_sector_and_get(&rt, precommit_params, PreCommitConfig::empty(), true); - - let pwr_estimate = qa_power_max(h.sector_size); - let expected_deposit = pre_commit_deposit_for_power( - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &pwr_estimate, - ); - assert_eq!(expected_deposit, precommit.pre_commit_deposit); - - // expect total precommit deposit to equal our new deposit - let st = h.get_state(&rt); - assert_eq!(expected_deposit, st.pre_commit_deposits); - - // run prove commit logic - rt.set_epoch(prove_commit_epoch); - rt.balance.replace(TokenAmount::from_whole(1000)); - let mut pcc = ProveCommitConfig::empty(); - pcc.add_activated_deals(sector_no, vec![verified_deal]); - - let sector = h - .prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - pcc, - ) - .unwrap(); - - assert_eq!(precommit.info.seal_proof, sector.seal_proof); - assert_eq!(precommit.info.sealed_cid, sector.sealed_cid); - assert_eq!(*rt.epoch.borrow(), sector.activation); - assert_eq!(precommit.info.expiration, sector.expiration); - - // expect precommit to have been removed - let st = h.get_state(&rt); - let found = st.get_precommitted_sector(&rt.store, sector_no).unwrap(); - assert!(found.is_none()); - - // expect deposit to have been transferred to initial pledges - assert!(st.pre_commit_deposits.is_zero()); - - // The sector is exactly full with verified deals, so expect fully verified power. - let duration = precommit.info.expiration - prove_commit_epoch; - let deal_weight = deal_space * duration; - let verified_deal_weight = verified_deal_space * duration; - let expected_power = StoragePower::from(h.sector_size as u64) - * (VERIFIED_DEAL_WEIGHT_MULTIPLIER / QUALITY_BASE_MULTIPLIER); - let qa_power = - qa_power_for_weight(h.sector_size, duration, &deal_weight, &verified_deal_weight); - assert_eq!(expected_power, qa_power); - let sector_power = - PowerPair { raw: StoragePower::from(h.sector_size as u64), qa: qa_power.clone() }; - - // expect deal weights to be transferred to on chain info - assert_eq!(deal_weight, sector.deal_weight); - assert_eq!(verified_deal_weight, sector.verified_deal_weight); - - // expect initial plege of sector to be set, and be total pledge requirement - let expected_initial_pledge = initial_pledge_for_power( - &qa_power, - &h.baseline_power, - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &rt.total_fil_circ_supply(), - ); - assert_eq!(expected_initial_pledge, sector.initial_pledge); - assert_eq!(expected_initial_pledge, st.initial_pledge); - - // expect sector to be assigned a deadline/partition - let (dl_idx, p_idx) = st.find_sector(rt.store(), sector_no).unwrap(); - let (deadline, partition) = h.get_deadline_and_partition(&rt, dl_idx, p_idx); - assert_eq!(1, deadline.live_sectors); - assert!(deadline.partitions_posted.is_empty()); - assert!(deadline.early_terminations.is_empty()); - - let quant = st.quant_spec_for_deadline(&rt.policy, dl_idx); - let quantized_expiration = quant.quantize_up(precommit.info.expiration); - - let d_queue = h.collect_deadline_expirations(&rt, &deadline); - assert_eq!(HashMap::from([(quantized_expiration, vec![p_idx])]), d_queue); - - assert_bitfield_equals(&partition.sectors, &[sector_no]); - assert!(partition.faults.is_empty()); - assert!(partition.recoveries.is_empty()); - assert!(partition.terminated.is_empty()); - assert_eq!(sector_power, partition.live_power); - assert!(partition.faulty_power.is_zero()); - assert!(partition.recovering_power.is_zero()); - - let p_queue = h.collect_partition_expirations(&rt, &partition); - let entry = &p_queue[&quantized_expiration]; - assert_bitfield_equals(&entry.on_time_sectors, &[sector_no]); - assert!(entry.early_sectors.is_empty()); - assert_eq!(expected_initial_pledge, entry.on_time_pledge); - assert_eq!(sector_power, entry.active_power); - assert!(entry.faulty_power.is_zero()); -} - -#[test] -fn prove_sectors_from_batch_pre_commit() { - let h = ActorHarness::new(PERIOD_OFFSET); - let rt = h.new_runtime(); - rt.balance.replace(BIG_BALANCE.clone()); - - let precommit_epoch = PERIOD_OFFSET + 1; - rt.set_epoch(precommit_epoch); - - h.construct_and_verify(&rt); - let dl_info = h.deadline(&rt); - - let sector_expiration = - dl_info.period_end() + DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period; - - let sectors = vec![ - h.make_pre_commit_params(100, precommit_epoch - 1, sector_expiration, vec![]), - h.make_pre_commit_params(101, precommit_epoch - 1, sector_expiration, vec![1]), // 1 * 32GiB verified deal - h.make_pre_commit_params(102, precommit_epoch - 1, sector_expiration, vec![2, 3]), // 2 * 16GiB verified deals - ]; - - let deal_space: i64 = 32 << 30; - let prove_commit_epoch = precommit_epoch + rt.policy.pre_commit_challenge_delay + 1; - let deal_lifespan = sector_expiration - prove_commit_epoch; - let verified_deal1 = test_activated_deal(deal_space as u64, 1); - let verified_deal2 = test_activated_deal(deal_space as u64 / 2, 2); - let verified_deal3 = test_activated_deal(deal_space as u64 / 2, 3); - let deal_weight = DealWeight::zero(); - let verified_deal_weight = deal_space * DealWeight::from(deal_lifespan); - - let conf = PreCommitBatchConfig { - sector_unsealed_cid: vec![None, Some(make_piece_cid(b"1")), Some(make_piece_cid(b"2|3"))], - first_for_miner: true, - }; - - let precommits = h.pre_commit_sector_batch_and_get( - &rt, - PreCommitSectorBatchParams { sectors }, - &conf, - &TokenAmount::zero(), - ); - - rt.set_epoch(prove_commit_epoch); - - let no_deal_power = qa_power_for_weight( - h.sector_size, - sector_expiration - prove_commit_epoch, - &DealWeight::zero(), - &DealWeight::zero(), - ); - let no_deal_pledge = initial_pledge_for_power( - &no_deal_power, - &h.baseline_power, - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &rt.total_fil_circ_supply(), - ); - let full_deal_power = qa_power_for_weight( - h.sector_size, - sector_expiration - prove_commit_epoch, - &deal_weight, - &verified_deal_weight, - ); - let expected_power = StoragePower::from(h.sector_size as u64) - * (VERIFIED_DEAL_WEIGHT_MULTIPLIER / QUALITY_BASE_MULTIPLIER); - assert_eq!(full_deal_power, expected_power); - let full_deal_pledge = initial_pledge_for_power( - &full_deal_power, - &h.baseline_power, - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &rt.total_fil_circ_supply(), - ); - - // Prove just the first sector, with no deals - { - let precommit = &precommits[0]; - let sector = h - .prove_commit_sector_and_confirm( - &rt, - precommit, - h.make_prove_commit_params(precommit.info.sector_number), - ProveCommitConfig::default(), - ) - .unwrap(); - assert_eq!(*rt.epoch.borrow(), sector.activation); - let st = h.get_state(&rt); - let expected_deposits = 2 * pre_commit_deposit_for_power( - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &qa_power_max(h.sector_size), - ); // first sector deposit released - - assert_eq!(expected_deposits, st.pre_commit_deposits); - - // Expect power/pledge for a sector with no deals - assert_eq!(no_deal_pledge, sector.initial_pledge); - assert_eq!(no_deal_pledge, st.initial_pledge); - } - // Prove the next, with one deal - { - let precommit = &precommits[1]; - let mut pcc = ProveCommitConfig::empty(); - pcc.add_activated_deals(precommit.info.sector_number, vec![verified_deal1]); - let sector = h - .prove_commit_sector_and_confirm( - &rt, - precommit, - h.make_prove_commit_params(precommit.info.sector_number), - pcc, - ) - .unwrap(); - assert_eq!(*rt.epoch.borrow(), sector.activation); - let st = h.get_state(&rt); - let expected_deposits = pre_commit_deposit_for_power( - &h.epoch_reward_smooth, - &h.epoch_qa_power_smooth, - &qa_power_max(h.sector_size), - ); // first and second deposit released - - assert_eq!(expected_deposits, st.pre_commit_deposits); - - // Expect power/pledge for the two sectors (only this one having any deal weight) - assert_eq!(full_deal_pledge, sector.initial_pledge); - assert_eq!(&no_deal_pledge + &full_deal_pledge, st.initial_pledge); - } - // Prove the last - { - let precommit = &precommits[2]; - let mut pcc = ProveCommitConfig::empty(); - pcc.add_activated_deals(precommit.info.sector_number, vec![verified_deal2, verified_deal3]); - let sector = h - .prove_commit_sector_and_confirm( - &rt, - precommit, - h.make_prove_commit_params(precommit.info.sector_number), - pcc, - ) - .unwrap(); - assert_eq!(*rt.epoch.borrow(), sector.activation); - let st = h.get_state(&rt); - assert!(st.pre_commit_deposits.is_zero()); - - // Expect power/pledge for the three sectors - assert_eq!(&full_deal_pledge, §or.initial_pledge); - assert_eq!(&no_deal_pledge + &full_deal_pledge + &full_deal_pledge, st.initial_pledge); - } -} - -#[test] -fn invalid_proof_rejected() { - let h = ActorHarness::new(PERIOD_OFFSET); - let rt = h.new_runtime(); - rt.balance.replace(BIG_BALANCE.clone()); - - let precommit_epoch = PERIOD_OFFSET + 1; - rt.set_epoch(precommit_epoch); - - h.construct_and_verify(&rt); - let deadline = h.deadline(&rt); - - // Make a good commitment for the proof to target. - let sector_no = 100; - let params = h.make_pre_commit_params( - sector_no, - precommit_epoch - 1, - deadline.period_end() + DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period, - vec![1], - ); - let precommit = h.pre_commit_sector_and_get(&rt, params, PreCommitConfig::default(), true); - - // Sector pre-commitment missing. - rt.set_epoch(precommit_epoch + rt.policy.pre_commit_challenge_delay + 1); - expect_abort( - ExitCode::USR_NOT_FOUND, - h.prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no + 1), - ProveCommitConfig::empty(), - ), - ); - rt.reset(); - - // Too late. - rt.set_epoch( - precommit_epoch - + max_prove_commit_duration(&rt.policy, precommit.info.seal_proof).unwrap() - + 1, - ); - expect_abort( - ExitCode::USR_ILLEGAL_ARGUMENT, - h.prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - ProveCommitConfig::empty(), - ), - ); - rt.reset(); - - // Too early. - rt.set_epoch(precommit_epoch + rt.policy.pre_commit_challenge_delay - 1); - expect_abort( - ExitCode::USR_FORBIDDEN, - h.prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - ProveCommitConfig::empty(), - ), - ); - rt.reset(); - - // Set the right epoch for all following tests - rt.set_epoch(precommit_epoch + rt.policy.pre_commit_challenge_delay + 1); - - // Invalid deals (market ActivateDeals aborts) - let verify_deals_exit = - HashMap::from([(precommit.info.sector_number, ExitCode::USR_ILLEGAL_ARGUMENT)]); - expect_abort( - ExitCode::USR_ILLEGAL_ARGUMENT, - h.prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - ProveCommitConfig { verify_deals_exit, ..Default::default() }, - ), - ); - rt.reset(); - - rt.balance.replace(TokenAmount::from_whole(1_000)); - - let prove_commit = h.make_prove_commit_params(sector_no); - h.prove_commit_sector_and_confirm(&rt, &precommit, prove_commit, ProveCommitConfig::empty()) - .unwrap(); - let st = h.get_state(&rt); - - // Verify new sectors - // TODO minerstate - //newSectors, err := st.NewSectors.All(miner.SectorsMax) - //require.NoError(t, err) - //assert.Equal(t, []uint64{uint64(sectorNo)}, newSectors) - // Verify pledge lock-up - assert!(st.initial_pledge.is_positive()); - rt.reset(); - - // Duplicate proof (sector no-longer pre-committed) - expect_abort( - ExitCode::USR_NOT_FOUND, - h.prove_commit_sector_and_confirm( - &rt, - &precommit, - h.make_prove_commit_params(sector_no), - ProveCommitConfig::empty(), - ), - ); - rt.reset(); - h.check_state(&rt); -} - #[test] fn prove_commit_aborts_if_pledge_requirement_not_met() { let mut h = ActorHarness::new(PERIOD_OFFSET); @@ -454,9 +56,9 @@ fn prove_commit_aborts_if_pledge_requirement_not_met() { ); expect_abort( ExitCode::USR_INSUFFICIENT_FUNDS, - h.prove_commit_sector_and_confirm( + h.deprecated_sector_commit( &rt, - &precommit, + &vec![], h.make_prove_commit_params(h.next_sector_no), ProveCommitConfig::empty(), ), @@ -467,9 +69,9 @@ fn prove_commit_aborts_if_pledge_requirement_not_met() { rt.balance.replace( &st.pre_commit_deposits + &st.initial_pledge + &st.initial_pledge + &st.locked_funds, ); - h.prove_commit_sector_and_confirm( + h.deprecated_sector_commit( &rt, - &precommit, + &vec![], h.make_prove_commit_params(h.next_sector_no), ProveCommitConfig::empty(), ) @@ -477,55 +79,9 @@ fn prove_commit_aborts_if_pledge_requirement_not_met() { h.check_state(&rt); } -#[test] -fn drop_invalid_prove_commit_while_processing_valid_one() { - let mut h = ActorHarness::new(PERIOD_OFFSET); - let rt = h.new_runtime(); - rt.balance.replace(BIG_BALANCE.clone()); - - h.construct_and_verify(&rt); - - // make two precommits - let expiration = DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period + PERIOD_OFFSET - 1; - let precommit_epoch = *rt.epoch.borrow() + 1; - rt.set_epoch(precommit_epoch); - let params_a = - h.make_pre_commit_params(h.next_sector_no, *rt.epoch.borrow() - 1, expiration, vec![1]); - let pre_commit_a = h.pre_commit_sector_and_get(&rt, params_a, PreCommitConfig::default(), true); - let sector_no_a = h.next_sector_no; - h.next_sector_no += 1; - let params_b = - h.make_pre_commit_params(h.next_sector_no, *rt.epoch.borrow() - 1, expiration, vec![2]); - let pre_commit_b = - h.pre_commit_sector_and_get(&rt, params_b, PreCommitConfig::default(), false); - let sector_no_b = h.next_sector_no; - - // handle both prove commits in the same epoch - rt.set_epoch( - precommit_epoch + max_prove_commit_duration(&rt.policy, h.seal_proof_type).unwrap() - 1, - ); - - h.prove_commit_sector(&rt, &pre_commit_a, h.make_prove_commit_params(sector_no_a)).unwrap(); - h.prove_commit_sector(&rt, &pre_commit_b, h.make_prove_commit_params(sector_no_b)).unwrap(); - - let conf = ProveCommitConfig { - verify_deals_exit: HashMap::from([(sector_no_a, ExitCode::USR_ILLEGAL_ARGUMENT)]), - activated_deals: HashMap::from([( - sector_no_b, - vec![test_activated_deal(100, NO_ALLOCATION_ID)], - )]), - ..Default::default() - }; - h.confirm_sector_proofs_valid(&rt, conf, vec![pre_commit_a, pre_commit_b]).unwrap(); - let st = h.get_state(&rt); - assert!(st.get_sector(&rt.store, sector_no_a).unwrap().is_none()); - assert!(st.get_sector(&rt.store, sector_no_b).unwrap().is_some()); - h.check_state(&rt); -} - #[test] fn prove_commit_just_after_period_start_permits_post() { - let h = ActorHarness::new(PERIOD_OFFSET); + let mut h = ActorHarness::new(PERIOD_OFFSET); let rt = h.new_runtime(); rt.balance.replace(BIG_BALANCE.clone()); @@ -536,51 +92,14 @@ fn prove_commit_just_after_period_start_permits_post() { // Commit a sector the very next epoch rt.set_epoch(PERIOD_OFFSET + 2); - let sector = - h.commit_and_prove_sector(&rt, MAX_SECTOR_NUMBER, DEFAULT_SECTOR_EXPIRATION, vec![]); + let sectors = + h.commit_and_prove_sectors(&rt, 1, DEFAULT_SECTOR_EXPIRATION as u64, vec![], true); // advance cron to activate power. - h.advance_and_submit_posts(&rt, &[sector]); + h.advance_and_submit_posts(&rt, &[sectors.first().unwrap().clone()]); h.check_state(&rt); } -#[test] -fn sector_with_non_positive_lifetime_fails_in_confirmation() { - let h = ActorHarness::new(PERIOD_OFFSET); - let rt = h.new_runtime(); - rt.balance.replace(BIG_BALANCE.clone()); - - let precommit_epoch = PERIOD_OFFSET + 1; - rt.set_epoch(precommit_epoch); - - h.construct_and_verify(&rt); - let deadline = h.deadline(&rt); - - let sector_no = 100; - let params = h.make_pre_commit_params( - sector_no, - precommit_epoch - 1, - deadline.period_end() + DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period, - vec![], - ); - let precommit = h.pre_commit_sector_and_get(&rt, params, PreCommitConfig::default(), true); - - // precommit at correct epoch - let epoch = *rt.epoch.borrow(); - rt.set_epoch(epoch + rt.policy.pre_commit_challenge_delay + 1); - h.prove_commit_sector(&rt, &precommit, h.make_prove_commit_params(sector_no)).unwrap(); - - // confirm at sector expiration (this probably can't happen) - rt.set_epoch(precommit.info.expiration); - // failure occurs - expect_abort( - ExitCode::USR_ILLEGAL_ARGUMENT, - h.confirm_sector_proofs_valid(&rt, ProveCommitConfig::empty(), vec![precommit]), - ); - h.check_state(&rt); - rt.reset(); -} - #[test] fn verify_proof_does_not_vest_funds() { let h = ActorHarness::new(PERIOD_OFFSET); @@ -599,9 +118,9 @@ fn verify_proof_does_not_vest_funds() { sector_no, precommit_epoch - 1, deadline.period_end() + DEFAULT_SECTOR_EXPIRATION * rt.policy.wpost_proving_period, - vec![1], + vec![], ); - let precommit = h.pre_commit_sector_and_get(&rt, params, PreCommitConfig::default(), true); + h.pre_commit_sector_and_get(&rt, params, PreCommitConfig::default(), true); // add 1000 tokens that vest immediately let mut st = h.get_state(&rt); @@ -620,6 +139,5 @@ fn verify_proof_does_not_vest_funds() { let prove_commit = h.make_prove_commit_params(sector_no); // The below call expects exactly the pledge delta for the proven sector, zero for any other vesting. - h.prove_commit_sector_and_confirm(&rt, &precommit, prove_commit, ProveCommitConfig::empty()) - .unwrap(); + h.deprecated_sector_commit(&rt, &vec![], prove_commit, ProveCommitConfig::empty()).unwrap(); } diff --git a/actors/miner/tests/prove_commit2_failures_test.rs b/actors/miner/tests/prove_commit2_failures_test.rs index cfd9a643c..028ccb383 100644 --- a/actors/miner/tests/prove_commit2_failures_test.rs +++ b/actors/miner/tests/prove_commit2_failures_test.rs @@ -25,14 +25,14 @@ const FIRST_SECTOR_NUMBER: SectorNumber = 100; #[test] fn reject_unauthorized_caller() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { caller: Some(Address::new_id(CLIENT_ID)), ..Default::default() }; expect_abort_contains_message( ExitCode::USR_FORBIDDEN, "caller", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -40,7 +40,7 @@ fn reject_unauthorized_caller() { #[test] fn reject_no_proof_types() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { param_twiddle: Some(Box::new(|p: &mut ProveCommitSectors3Params| { p.sector_proofs = vec![]; p.aggregate_proof = RawBytes::default(); @@ -50,7 +50,7 @@ fn reject_no_proof_types() { expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "exactly one of sector proofs or aggregate proof must be non-empty", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -58,7 +58,7 @@ fn reject_no_proof_types() { #[test] fn reject_both_proof_types() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { param_twiddle: Some(Box::new(|p: &mut ProveCommitSectors3Params| { p.sector_proofs = vec![RawBytes::new(vec![1, 2, 3, 4])]; p.aggregate_proof = RawBytes::new(vec![1, 2, 3, 4]) @@ -68,7 +68,7 @@ fn reject_both_proof_types() { expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "exactly one of sector proofs or aggregate proof must be non-empty", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -76,7 +76,7 @@ fn reject_both_proof_types() { #[test] fn reject_mismatched_proof_len() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { param_twiddle: Some(Box::new(|p: &mut ProveCommitSectors3Params| { p.sector_proofs.push(RawBytes::new(vec![1, 2, 3, 4])); })), @@ -85,7 +85,7 @@ fn reject_mismatched_proof_len() { expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "mismatched lengths", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -95,11 +95,11 @@ fn reject_too_soon() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); let epoch = *rt.epoch.borrow(); rt.set_epoch(epoch - 2); - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); expect_abort_contains_message( ExitCode::USR_FORBIDDEN, "too early to prove sector", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -109,11 +109,11 @@ fn reject_expired_precommit() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0)]); let epoch = *rt.epoch.borrow(); rt.set_epoch(epoch + 31 * EPOCHS_IN_DAY); // Expired. - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "no valid precommits", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -142,12 +142,12 @@ fn reject_precommit_deals() { .map(|s| make_activation_manifest(s.sector_number, &[(piece_size, 0, 0, 0)])) .collect(); - let cfg = ProveCommitSectors2Config { validation_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { validation_failure: vec![0], ..Default::default() }; // Single bad precommit aborts with require_activation_success=true. expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "invalid pre-commit 0 while requiring activation success", - h.prove_commit_sectors2(&rt, &manifests, true, false, false, cfg), + h.prove_commit_sectors3(&rt, &manifests, true, false, false, cfg), ); h.check_state(&rt); } @@ -155,12 +155,12 @@ fn reject_precommit_deals() { #[test] fn reject_all_proofs_fail() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0), (0, 0, 0)]); - let cfg = ProveCommitSectors2Config { proof_failure: vec![0, 1], ..Default::default() }; + let cfg = ProveCommitSectors3Config { proof_failure: vec![0, 1], ..Default::default() }; // If all proofs fail, no need for require_activation_success=true. expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "no valid proofs", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); h.check_state(&rt); } @@ -168,12 +168,12 @@ fn reject_all_proofs_fail() { #[test] fn reject_aggregate_proof_fails() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0); 4]); - let cfg = ProveCommitSectors2Config { proof_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { proof_failure: vec![0], ..Default::default() }; // If aggregate proof fails, no need for require_activation_success=true. expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "invalid aggregate proof", - h.prove_commit_sectors2(&rt, &activations, false, false, true, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, true, cfg), ); h.check_state(&rt); } @@ -181,12 +181,12 @@ fn reject_aggregate_proof_fails() { #[test] fn reject_required_proof_failure() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0); 4]); - let cfg = ProveCommitSectors2Config { proof_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { proof_failure: vec![0], ..Default::default() }; // Single proof failure aborts with require_activation_success=true. expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "invalid proof for sector 100 while requiring activation success", - h.prove_commit_sectors2(&rt, &activations, true, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, true, false, false, cfg), ); h.check_state(&rt); } @@ -197,23 +197,23 @@ fn reject_mismatched_commd() { // Set wrong CID for first sector. activations[0].pieces[0].cid = activations[1].pieces[0].cid; - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "unsealed CID does not match pieces", - h.prove_commit_sectors2(&rt, &activations, false, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, false, false, false, cfg), ); } #[test] fn reject_required_claim_failure() { let (h, rt, activations) = setup_precommits(&[(0, 0, 0), (CLIENT_ID, 1, 0)]); - let cfg = ProveCommitSectors2Config { claim_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { claim_failure: vec![0], ..Default::default() }; // Single claim failure aborts with require_activation_success=true. expect_abort_contains_message( ExitCode::USR_ILLEGAL_ARGUMENT, "error claiming allocations", - h.prove_commit_sectors2(&rt, &activations, true, false, false, cfg), + h.prove_commit_sectors3(&rt, &activations, true, false, false, cfg), ); h.check_state(&rt); } @@ -222,14 +222,14 @@ fn reject_required_claim_failure() { fn required_notification_abort() { let deal_id = 2000; let (h, rt, activations) = setup_precommits(&[(0, 0, deal_id)]); - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { notification_result: Some(ExitCode::USR_ILLEGAL_ARGUMENT), ..Default::default() }; expect_abort_contains_message( ERR_NOTIFICATION_RECEIVER_ABORTED, "receiver aborted", - h.prove_commit_sectors2(&rt, &activations, true, true, false, cfg), + h.prove_commit_sectors3(&rt, &activations, true, true, false, cfg), ); h.check_state(&rt); } @@ -238,12 +238,12 @@ fn required_notification_abort() { fn require_notification_rejected() { let deal_id = 2000; let (h, rt, activations) = setup_precommits(&[(0, 0, deal_id)]); - let cfg = ProveCommitSectors2Config { notification_rejected: true, ..Default::default() }; + let cfg = ProveCommitSectors3Config { notification_rejected: true, ..Default::default() }; // Require notification success. expect_abort_contains_message( ERR_NOTIFICATION_REJECTED, "sector change rejected", - h.prove_commit_sectors2(&rt, &activations, true, true, false, cfg), + h.prove_commit_sectors3(&rt, &activations, true, true, false, cfg), ); h.check_state(&rt); } diff --git a/actors/miner/tests/prove_commit2_test.rs b/actors/miner/tests/prove_commit2_test.rs index 63fa314b5..a2aaea21c 100644 --- a/actors/miner/tests/prove_commit2_test.rs +++ b/actors/miner/tests/prove_commit2_test.rs @@ -40,9 +40,9 @@ fn commit_batch() { make_activation_manifest(snos[3], &[(piece_size, CLIENT_ID, 1001, 2001)]), // Alloc and deal ]; - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); let (result, claims, notifications) = - h.prove_commit_sectors2(&rt, &manifests, true, true, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, true, true, false, cfg).unwrap(); assert_commit_result(&[ExitCode::OK; 4], &result); let sectors: Vec = snos.iter().map(|sno| h.get_sector(&rt, *sno)).collect(); @@ -140,9 +140,9 @@ fn multiple_pieces_in_sector() { ), ]; - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); let (result, claims, notifications) = - h.prove_commit_sectors2(&rt, &manifests, true, true, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, true, true, false, cfg).unwrap(); assert_commit_result(&[ExitCode::OK, ExitCode::OK], &result); let sectors: Vec = snos.iter().map(|sno| h.get_sector(&rt, *sno)).collect(); @@ -253,9 +253,9 @@ fn multiple_notifs_for_piece() { payload: RawBytes::from(vec![9, 9, 9, 9]), }); - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); let (result, _, notifications) = - h.prove_commit_sectors2(&rt, &manifests, true, true, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, true, true, false, cfg).unwrap(); assert_commit_result(&[ExitCode::OK, ExitCode::OK], &result); let sectors: Vec = snos.iter().map(|sno| h.get_sector(&rt, *sno)).collect(); @@ -325,9 +325,9 @@ fn expired_precommit_dropped_batch() { make_activation_manifest(snos[1], &[(piece_size, CLIENT_ID, 1001, 2001)]), ]; - let cfg = ProveCommitSectors2Config { validation_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { validation_failure: vec![0], ..Default::default() }; let (result, claims, notifications) = - h.prove_commit_sectors2(&rt, &manifests, false, false, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, false, false, false, cfg).unwrap(); assert_commit_result(&[ExitCode::USR_ILLEGAL_ARGUMENT, ExitCode::OK], &result); // Sector 0: not committed @@ -369,8 +369,8 @@ fn expired_precommit_dropped_aggregate() { make_activation_manifest(snos[3], &[(piece_size, CLIENT_ID, 1003, 2003)]), ]; - let cfg = ProveCommitSectors2Config { validation_failure: vec![0], ..Default::default() }; - let (result, _, _) = h.prove_commit_sectors2(&rt, &manifests, false, false, true, cfg).unwrap(); + let cfg = ProveCommitSectors3Config { validation_failure: vec![0], ..Default::default() }; + let (result, _, _) = h.prove_commit_sectors3(&rt, &manifests, false, false, true, cfg).unwrap(); assert_commit_result( &[ExitCode::USR_ILLEGAL_ARGUMENT, ExitCode::OK, ExitCode::OK, ExitCode::OK], &result, @@ -400,9 +400,9 @@ fn invalid_proof_dropped() { make_activation_manifest(snos[1], &[(piece_size, CLIENT_ID, 1001, 2001)]), ]; - let cfg = ProveCommitSectors2Config { proof_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { proof_failure: vec![0], ..Default::default() }; let (result, _, _) = - h.prove_commit_sectors2(&rt, &manifests, false, false, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, false, false, false, cfg).unwrap(); assert_commit_result(&[ExitCode::USR_ILLEGAL_ARGUMENT, ExitCode::OK], &result); // Sector 0: not committed @@ -426,9 +426,9 @@ fn invalid_claim_dropped() { make_activation_manifest(snos[1], &[(piece_size, CLIENT_ID, 1001, 2001)]), ]; - let cfg = ProveCommitSectors2Config { claim_failure: vec![0], ..Default::default() }; + let cfg = ProveCommitSectors3Config { claim_failure: vec![0], ..Default::default() }; let (result, _, _) = - h.prove_commit_sectors2(&rt, &manifests, false, false, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, false, false, false, cfg).unwrap(); assert_commit_result(&[ExitCode::USR_ILLEGAL_ARGUMENT, ExitCode::OK], &result); // Sector 0: not committed @@ -451,12 +451,12 @@ fn aborted_notification_dropped() { make_activation_manifest(snos[1], &[(piece_size, CLIENT_ID, 1001, 2001)]), ]; - let cfg = ProveCommitSectors2Config { + let cfg = ProveCommitSectors3Config { notification_result: Some(ExitCode::USR_UNSPECIFIED), ..Default::default() }; let (result, _, _) = - h.prove_commit_sectors2(&rt, &manifests, false, false, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, false, false, false, cfg).unwrap(); // All sectors succeed anyway. assert_commit_result(&[ExitCode::OK; 2], &result); @@ -478,9 +478,9 @@ fn rejected_notification_dropped() { make_activation_manifest(snos[1], &[(piece_size, CLIENT_ID, 1001, 2001)]), ]; - let cfg = ProveCommitSectors2Config { notification_rejected: true, ..Default::default() }; + let cfg = ProveCommitSectors3Config { notification_rejected: true, ..Default::default() }; let (result, _, _) = - h.prove_commit_sectors2(&rt, &manifests, false, false, false, cfg).unwrap(); + h.prove_commit_sectors3(&rt, &manifests, false, false, false, cfg).unwrap(); // All sectors succeed anyway. assert_commit_result(&[ExitCode::OK; 2], &result); diff --git a/actors/miner/tests/util.rs b/actors/miner/tests/util.rs index 28fc9e14b..7de6fe29c 100644 --- a/actors/miner/tests/util.rs +++ b/actors/miner/tests/util.rs @@ -64,15 +64,14 @@ use fil_actor_miner::{ ActiveBeneficiary, Actor, ApplyRewardParams, BeneficiaryTerm, BitFieldQueue, ChangeBeneficiaryParams, ChangeMultiaddrsParams, ChangePeerIDParams, ChangeWorkerAddressParams, CheckSectorProvenParams, CompactCommD, CompactPartitionsParams, CompactSectorNumbersParams, - ConfirmSectorProofsParams, CronEventPayload, DataActivationNotification, Deadline, - DeadlineInfo, Deadlines, DeclareFaultsParams, DeclareFaultsRecoveredParams, - DeferredCronEventParams, DisputeWindowedPoStParams, ExpirationQueue, ExpirationSet, - ExtendSectorExpiration2Params, ExtendSectorExpirationParams, FaultDeclaration, - GetAvailableBalanceReturn, GetBeneficiaryReturn, GetControlAddressesReturn, - GetMultiaddrsReturn, GetPeerIDReturn, Method, Method as MinerMethod, - MinerConstructorParams as ConstructorParams, MinerInfo, Partition, PendingBeneficiaryChange, - PieceActivationManifest, PieceChange, PieceReturn, PoStPartition, PowerPair, - PreCommitSectorBatchParams, PreCommitSectorBatchParams2, PreCommitSectorParams, + CronEventPayload, DataActivationNotification, Deadline, DeadlineInfo, Deadlines, + DeclareFaultsParams, DeclareFaultsRecoveredParams, DeferredCronEventParams, + DisputeWindowedPoStParams, ExpirationQueue, ExpirationSet, ExtendSectorExpiration2Params, + ExtendSectorExpirationParams, FaultDeclaration, GetAvailableBalanceReturn, + GetBeneficiaryReturn, GetControlAddressesReturn, GetMultiaddrsReturn, GetPeerIDReturn, Method, + Method as MinerMethod, MinerConstructorParams as ConstructorParams, MinerInfo, Partition, + PendingBeneficiaryChange, PieceActivationManifest, PieceChange, PieceReturn, PoStPartition, + PowerPair, PreCommitSectorBatchParams, PreCommitSectorBatchParams2, PreCommitSectorParams, ProveCommitAggregateParams, ProveCommitSectorParams, ProveCommitSectors3Params, ProveCommitSectors3Return, QuantSpec, RecoveryDeclaration, ReportConsensusFaultParams, SectorActivationManifest, SectorChanges, SectorContentChangedParams, @@ -97,6 +96,8 @@ use fil_actors_runtime::{ VERIFIED_REGISTRY_ACTOR_ADDR, }; +const DEFAULT_PIECE_SIZE: u64 = 128; + const RECEIVER_ID: u64 = 1000; pub const TEST_RANDOMNESS_ARRAY_FROM_ONE: [u8; 32] = [ @@ -412,19 +413,31 @@ impl ActorHarness { let sector_deal_ids = deal_ids.get(i).and_then(|ids| Some(ids.clone())).unwrap_or_default(); let has_deals = !sector_deal_ids.is_empty(); - let params = self.make_pre_commit_params( + + let compact_commd = if !has_deals { + CompactCommD::empty() + } else { + // Determine CommD from configuration in the same way as prove_commit_and_confirm + let piece_specs = + make_piece_specs_from_configs(sector_no, §or_deal_ids, &prove_cfg); + let manifest = make_activation_manifest(sector_no, &piece_specs); + let piece_cids: Vec = manifest.pieces.iter().map(|p| p.cid).collect(); + sector_commd_from_pieces(&piece_cids) + }; + + let info = self.make_pre_commit_params_v2( sector_no, precommit_epoch - 1, expiration, - sector_deal_ids, + // We may be committing with deals but if so pass their info in CommD as + // PreCommitSector with deal_ids will fail after nv21 + vec![], + compact_commd, ); - let pcc = if !has_deals { - PreCommitConfig::new(None) - } else { - PreCommitConfig::new(Some(make_unsealed_cid("1".as_bytes()))) - }; - let precommit = self.pre_commit_sector_and_get(rt, params, pcc, first && i == 0); - precommits.push(precommit); + + let precommit = + self.pre_commit_sector_batch_v2_and_get(rt, vec![info], first && i == 0); + precommits.extend(precommit); self.next_sector_no += 1; } @@ -434,11 +447,13 @@ impl ActorHarness { ); let mut info = Vec::with_capacity(num_sectors); - for pc in precommits { + for (i, pc) in precommits.iter().enumerate() { + let sector_deal_ids = + deal_ids.get(i).and_then(|ids| Some(ids.clone())).unwrap_or_default(); let sector = self - .prove_commit_sector_and_confirm( + .deprecated_sector_commit( rt, - &pc, + §or_deal_ids, self.make_prove_commit_params(pc.info.sector_number), prove_cfg.clone(), ) @@ -449,44 +464,6 @@ impl ActorHarness { info } - pub fn commit_and_prove_sector( - &self, - rt: &MockRuntime, - sector_no: SectorNumber, - lifetime_periods: i64, - deal_ids: Vec, - ) -> SectorOnChainInfo { - let precommit_epoch = *rt.epoch.borrow(); - let deadline = self.deadline(rt); - let expiration = deadline.period_end() + lifetime_periods * rt.policy.wpost_proving_period; - - // Precommit - let pre_commit_params = - self.make_pre_commit_params(sector_no, precommit_epoch - 1, expiration, deal_ids); - let precommit = self.pre_commit_sector_and_get( - rt, - pre_commit_params.clone(), - PreCommitConfig::default(), - true, - ); - - self.advance_to_epoch_with_cron( - rt, - precommit_epoch + rt.policy.pre_commit_challenge_delay + 1, - ); - - let sector_info = self - .prove_commit_sector_and_confirm( - rt, - &precommit, - self.make_prove_commit_params(pre_commit_params.sector_number), - ProveCommitConfig::empty(), - ) - .unwrap(); - rt.reset(); - sector_info - } - pub fn compact_sector_numbers_raw( &self, rt: &MockRuntime, @@ -703,6 +680,20 @@ impl ActorHarness { result } + pub fn pre_commit_sector_batch_v2_and_get( + &self, + rt: &MockRuntime, + sectors: Vec, + first: bool, + ) -> Vec { + let result = self.pre_commit_sector_batch_v2(rt, §ors, first, &self.base_fee).unwrap(); + + expect_empty(result); + rt.verify(); + + sectors.iter().map(|sector| self.get_precommit(rt, sector.sector_number)).collect() + } + pub fn pre_commit_sector_and_get( &self, rt: &MockRuntime, @@ -763,73 +754,56 @@ impl ActorHarness { ); } - pub fn prove_commit_sector_and_confirm( + // deprecated flow calling prove commit sector and then confirm sector proofs valid + // With FIP 0084 this is no longer realizable. Internally it now calls ProveCommitSectors3 + // The entrypoint is kept in tests + // 1) to ensure backwards compatibility between prove_commit_sector and prove_commit_sectors3 + // 2) to make use of existing test coverage without significant change + // + // This should be removed in favor of something else. Discussion: https://github.com/filecoin-project/builtin-actors/issues/1545 + pub fn deprecated_sector_commit( &self, rt: &MockRuntime, - pc: &SectorPreCommitOnChainInfo, + deal_ids: &Vec, params: ProveCommitSectorParams, cfg: ProveCommitConfig, ) -> Result { let sector_number = params.sector_number; - self.prove_commit_sector(rt, pc, params)?; - self.confirm_sector_proofs_valid(rt, cfg, vec![pc.clone()])?; - - Ok(self.get_sector(rt, sector_number)) - } + let piece_specs = make_piece_specs_from_configs(sector_number, deal_ids, &cfg); - pub fn prove_commit_sector( - &self, - rt: &MockRuntime, - pc: &SectorPreCommitOnChainInfo, - params: ProveCommitSectorParams, - ) -> Result<(), ActorError> { - rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, self.worker); - let seal_rand = TEST_RANDOMNESS_ARRAY_FROM_ONE; - let seal_int_rand = TEST_RANDOMNESS_ARRAY_FROM_TWO; - let interactive_epoch = pc.pre_commit_epoch + rt.policy.pre_commit_challenge_delay; - - // Prepare for and receive call to ProveCommitSector - let entropy = RawBytes::serialize(self.receiver).unwrap(); - rt.expect_get_randomness_from_tickets( - DomainSeparationTag::SealRandomness, - pc.info.seal_rand_epoch, - entropy.to_vec(), - seal_rand.clone(), - ); - rt.expect_get_randomness_from_beacon( - DomainSeparationTag::InteractiveSealChallengeSeed, - interactive_epoch, - entropy.to_vec(), - seal_int_rand.clone(), - ); + let manifest = make_activation_manifest(sector_number, &piece_specs); + let req_activation_succ = true; // Doesn't really matter since there's only 1 + let req_notif_succ = false; // CPSV could not require this as it happened in cron - let actor_id = RECEIVER_ID; - let seal = SealVerifyInfo { - sector_id: SectorID { miner: actor_id, number: pc.info.sector_number }, - sealed_cid: pc.info.sealed_cid, - registered_proof: pc.info.seal_proof, - proof: params.proof.clone().into(), - deal_ids: vec![], - randomness: Randomness(seal_rand.into()), - interactive_randomness: Randomness(seal_int_rand.into()), - unsealed_cid: pc.info.unsealed_cid.get_cid(pc.info.seal_proof).unwrap(), + let claim_failure = if cfg.claim_allocs_exit.contains_key(§or_number) { + vec![0] // only sector activating has claim failure + } else { + vec![] }; - rt.expect_send_simple( - STORAGE_POWER_ACTOR_ADDR, - PowerMethod::SubmitPoRepForBulkVerify as u64, - IpldBlock::serialize_cbor(&seal).unwrap(), - TokenAmount::zero(), - None, - ExitCode::OK, - ); - rt.expect_validate_caller_any(); - let result = rt.call::( - Method::ProveCommitSector as u64, - IpldBlock::serialize_cbor(¶ms).unwrap(), + let notification_result = if cfg.verify_deals_exit.get(§or_number).is_some() { + cfg.verify_deals_exit.get(§or_number).cloned() + } else { + None + }; + let cfg3 = ProveCommitSectors3Config { + proof_failure: vec![], // ProveCommitConfig doesn't support this + param_twiddle: None, + caller: None, + validation_failure: vec![], + claim_failure, + notification_result, + notification_rejected: notification_result.is_some(), + }; + let _ = self.prove_commit_sectors3( + rt, + &[manifest], + req_activation_succ, + req_notif_succ, + false, + cfg3, )?; - expect_empty(result); - rt.verify(); - Ok(()) + + Ok(self.get_sector(rt, sector_number)) } pub fn prove_commit_aggregate_sector( @@ -867,7 +841,7 @@ impl ActorHarness { rt.expect_aggregate_verify_seals(svis, params.aggregate_proof.clone().into(), Ok(())); // confirm sector proofs valid - let pieces = self.confirm_sector_proofs_valid_internal(rt, config, &precommits); + let pieces = self.expect_sectors_activated(rt, config, &precommits); // sector activated event for (i, sc) in precommits.iter().enumerate() { @@ -900,55 +874,9 @@ impl ActorHarness { Ok(()) } - pub fn confirm_sector_proofs_valid( - &self, - rt: &MockRuntime, - cfg: ProveCommitConfig, - pcs: Vec, - ) -> Result<(), ActorError> { - let pieces = self.confirm_sector_proofs_valid_internal(rt, cfg.clone(), &pcs); - - let mut all_sector_numbers = Vec::new(); - for pc in pcs.clone() { - all_sector_numbers.push(pc.info.sector_number); - } - - rt.set_caller(*POWER_ACTOR_CODE_ID, STORAGE_POWER_ACTOR_ADDR); - rt.expect_validate_caller_addr(vec![STORAGE_POWER_ACTOR_ADDR]); - - let params = ConfirmSectorProofsParams { - sectors: all_sector_numbers, - reward_smoothed: self.epoch_reward_smooth.clone(), - reward_baseline_power: self.baseline_power.clone(), - quality_adj_power_smoothed: self.epoch_qa_power_smooth.clone(), - }; - - for sc in pcs.iter() { - if cfg.verify_deals_exit.contains_key(&sc.info.sector_number) - || cfg.claim_allocs_exit.contains_key(&sc.info.sector_number) - { - continue; - } - let unsealed_cid = sc.info.unsealed_cid.0; - let num = &sc.info.sector_number; - expect_sector_event( - rt, - "sector-activated", - &num, - unsealed_cid, - pieces.get(&num).unwrap(), - ); - } - - rt.call::( - Method::ConfirmSectorProofsValid as u64, - IpldBlock::serialize_cbor(¶ms).unwrap(), - )?; - rt.verify(); - Ok(()) - } - - fn confirm_sector_proofs_valid_internal( + // Check that sectors are activating + // This is a separate method because historically this functionality was shared between various commitment entrypoints + fn expect_sectors_activated( &self, rt: &MockRuntime, cfg: ProveCommitConfig, @@ -1120,14 +1048,14 @@ impl ActorHarness { pieces } - pub fn prove_commit_sectors2( + pub fn prove_commit_sectors3( &self, rt: &MockRuntime, sector_activations: &[SectorActivationManifest], require_activation_success: bool, require_notification_success: bool, aggregate: bool, - cfg: ProveCommitSectors2Config, + cfg: ProveCommitSectors3Config, ) -> Result< (ProveCommitSectors3Return, Vec, Vec), ActorError, @@ -3057,7 +2985,7 @@ pub struct ProveReplicaUpdatesConfig { } #[derive(Default)] -pub struct ProveCommitSectors2Config { +pub struct ProveCommitSectors3Config { pub caller: Option
, pub param_twiddle: Option>, pub validation_failure: Vec, // Expect validation failure for these sector indices. @@ -3275,7 +3203,7 @@ pub fn onboard_sectors( // Prove the sectors in batch with ProveCommitSectors2. let prove_epoch = *rt.epoch.borrow() + rt.policy.pre_commit_challenge_delay + 1; rt.set_epoch(prove_epoch); - let cfg = ProveCommitSectors2Config::default(); + let cfg = ProveCommitSectors3Config::default(); let sector_activations: Vec = precommits .iter() .map(|pc| { @@ -3286,7 +3214,7 @@ pub fn onboard_sectors( make_activation_manifest(pc.info.sector_number, &piece_specs) }) .collect(); - h.prove_commit_sectors2(rt, §or_activations, true, false, false, cfg).unwrap(); + h.prove_commit_sectors3(rt, §or_activations, true, false, false, cfg).unwrap(); let sectors: Vec = precommits.iter().map(|pc| h.get_sector(rt, pc.info.sector_number)).collect(); @@ -3417,6 +3345,39 @@ pub fn make_piece_manifest( } } +pub fn make_piece_specs_from_configs( + sector_number: u64, + deal_ids: &Vec, + prove_cfg: &ProveCommitConfig, +) -> Vec<(u64, ActorID, AllocationID, DealID)> { + static EMPTY_VEC: Vec = Vec::new(); + let configured_deals = prove_cfg.activated_deals.get(§or_number).unwrap_or(&EMPTY_VEC); + // The old configuration system had duplicated information between cfg and precommit inputs + // To ensure passed in configuration is internally consistent check that cfg deals are a subset + // of precommitted deal ids + assert!(deal_ids.len() >= configured_deals.len()); + let mut piece_specs = vec![]; + const DEFAULT_CLIENT_ID: ActorID = 1000; + + for (i, deal_id) in deal_ids.iter().enumerate() { + if i < configured_deals.len() { + let deal = configured_deals.get(i).unwrap(); + // Configured deals don't specify deal_id use deal_ids configuration info + // Piece specs don't specify piece cid but deterministically derive it so ignore deal.Cid + piece_specs.push((deal.size.0, deal.client, deal.allocation_id, deal_id.clone())); + } else { + piece_specs.push(( + DEFAULT_PIECE_SIZE, + DEFAULT_CLIENT_ID, + NO_ALLOCATION_ID, + deal_id.clone(), + )); + } + } + + piece_specs +} + pub fn claims_from_pieces(pieces: &[PieceActivationManifest]) -> Vec { pieces .iter() diff --git a/actors/power/src/ext.rs b/actors/power/src/ext.rs index 270ca5591..9c821c1d0 100644 --- a/actors/power/src/ext.rs +++ b/actors/power/src/ext.rs @@ -3,8 +3,7 @@ use fvm_ipld_encoding::tuple::*; use fvm_ipld_encoding::{strict_bytes, BytesDe}; use fvm_shared::address::Address; -use fvm_shared::bigint::bigint_ser; -use fvm_shared::sector::{RegisteredPoStProof, SectorNumber, StoragePower}; +use fvm_shared::sector::RegisteredPoStProof; use fvm_shared::METHOD_CONSTRUCTOR; use num_derive::FromPrimitive; @@ -36,18 +35,8 @@ pub mod init { pub mod miner { use super::*; - pub const CONFIRM_SECTOR_PROOFS_VALID_METHOD: u64 = 17; pub const ON_DEFERRED_CRON_EVENT_METHOD: u64 = 12; - #[derive(Serialize_tuple, Deserialize_tuple)] - pub struct ConfirmSectorProofsParams { - pub sectors: Vec, - pub reward_smoothed: FilterEstimate, - #[serde(with = "bigint_ser")] - pub reward_baseline_power: StoragePower, - pub quality_adj_power_smoothed: FilterEstimate, - } - #[derive(Serialize_tuple, Deserialize_tuple)] pub struct MinerConstructorParams { pub owner: Address, diff --git a/actors/power/src/lib.rs b/actors/power/src/lib.rs index 7937fb4c2..45bc352e2 100644 --- a/actors/power/src/lib.rs +++ b/actors/power/src/lib.rs @@ -1,19 +1,13 @@ // Copyright 2019-2022 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use std::collections::BTreeSet; -use std::convert::TryInto; - -use anyhow::anyhow; use fil_actors_runtime::reward::ThisEpochRewardReturn; use fvm_ipld_encoding::ipld_block::IpldBlock; use fvm_ipld_encoding::RawBytes; -use fvm_shared::address::Address; use fvm_shared::bigint::bigint_ser::BigIntSer; use fvm_shared::econ::TokenAmount; use fvm_shared::error::ExitCode; -use fvm_shared::sector::SealVerifyInfo; -use fvm_shared::{MethodNum, HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR}; +use fvm_shared::{MethodNum, METHOD_CONSTRUCTOR}; use log::{debug, error}; use num_derive::FromPrimitive; use num_traits::Zero; @@ -42,12 +36,6 @@ mod types; // * Updated to specs-actors commit: 999e57a151cc7ada020ca2844b651499ab8c0dec (v3.0.1) -/// GasOnSubmitVerifySeal is amount of gas charged for SubmitPoRepForBulkVerify -/// This number is empirically determined -pub mod detail { - pub const GAS_ON_SUBMIT_VERIFY_SEAL: i64 = 34721049; -} - /// Storage power actor methods available #[derive(FromPrimitive)] #[repr(u64)] @@ -59,9 +47,8 @@ pub enum Method { EnrollCronEvent = 4, OnEpochTickEnd = 5, UpdatePledgeTotal = 6, - // * Deprecated in v2 - // OnConsensusFault = 7, - SubmitPoRepForBulkVerify = 8, + // OnConsensusFault = 7, // Deprecated v2 + // SubmitPoRepForBulkVerify = 8, // Deprecated CurrentTotalPower = 9, // Method numbers derived from FRC-0042 standards CreateMinerExported = frc42_dispatch::method_hash!("CreateMiner"), @@ -223,9 +210,6 @@ impl Actor { .map_err(|e| e.wrap("failed to check epoch baseline power"))?, )?; - if let Err(e) = Self::process_batch_proof_verifies(rt, &rewret) { - error!("unexpected error processing batch proof verifies: {}. Skipping all verification for epoch {}", e, rt.curr_epoch()); - } Self::process_deferred_cron_events(rt, rewret)?; let this_epoch_raw_byte_power = rt.transaction(|st: &mut State, _| { @@ -270,67 +254,6 @@ impl Actor { }) } - fn submit_porep_for_bulk_verify( - rt: &impl Runtime, - params: SubmitPoRepForBulkVerifyParams, - ) -> Result<(), ActorError> { - rt.validate_immediate_caller_type(std::iter::once(&Type::Miner))?; - - rt.transaction(|st: &mut State, rt| { - st.validate_miner_has_claim(rt.store(), &rt.message().caller())?; - - let mut mmap = if let Some(ref batch) = st.proof_validation_batch { - Multimap::from_root( - rt.store(), - batch, - HAMT_BIT_WIDTH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, - ) - .map_err(|e| { - e.downcast_default( - ExitCode::USR_ILLEGAL_STATE, - "failed to load proof batching set", - ) - })? - } else { - debug!("ProofValidationBatch created"); - Multimap::new(rt.store(), HAMT_BIT_WIDTH, PROOF_VALIDATION_BATCH_AMT_BITWIDTH) - }; - let miner_addr = rt.message().caller(); - let arr = mmap.get::(&miner_addr.to_bytes()).map_err(|e| { - e.downcast_default( - ExitCode::USR_ILLEGAL_STATE, - format!("failed to get seal verify infos at addr {}", miner_addr), - ) - })?; - if let Some(arr) = arr { - if arr.count() >= MAX_MINER_PROVE_COMMITS_PER_EPOCH { - return Err(ActorError::unchecked( - ERR_TOO_MANY_PROVE_COMMITS, - format!( - "miner {} attempting to prove commit over {} sectors in epoch", - miner_addr, MAX_MINER_PROVE_COMMITS_PER_EPOCH - ), - )); - } - } - - mmap.add(miner_addr.to_bytes().into(), params.seal_info).map_err(|e| { - e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to insert proof into set") - })?; - - let mmrc = mmap.root().map_err(|e| { - e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to flush proofs batch map") - })?; - - rt.charge_gas("OnSubmitVerifySeal", detail::GAS_ON_SUBMIT_VERIFY_SEAL); - st.proof_validation_batch = Some(mmrc); - Ok(()) - })?; - - Ok(()) - } - /// Returns the total power and pledge recorded by the power actor. /// The returned values are frozen during the cron tick before this epoch /// so that this method returns consistent values while processing all messages @@ -393,139 +316,6 @@ impl Actor { Ok(MinerConsensusCountReturn { miner_consensus_count: st.miner_above_min_power_count }) } - fn process_batch_proof_verifies( - rt: &impl Runtime, - rewret: &ThisEpochRewardReturn, - ) -> Result<(), String> { - let mut miners: Vec<(Address, usize)> = Vec::new(); - let mut infos: Vec = Vec::new(); - let mut st_err: Option = None; - let this_epoch_qa_power_smoothed = rt - .transaction(|st: &mut State, rt| { - let result = Ok(st.this_epoch_qa_power_smoothed.clone()); - let batch = match &st.proof_validation_batch { - None => { - debug!("ProofValidationBatch was nil, quitting verification"); - return result; - } - Some(batch) => batch, - }; - let mmap = match Multimap::from_root( - rt.store(), - batch, - HAMT_BIT_WIDTH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, - ) { - Ok(mmap) => mmap, - Err(e) => { - st_err = Some(format!("failed to load proofs validation batch {}", e)); - return result; - } - }; - - let claims = match st.load_claims(rt.store()) { - Ok(claims) => claims, - Err(e) => { - st_err = Some(format!("failed to load claims: {}", e)); - return result; - } - }; - - if let Err(e) = mmap.for_all::<_, SealVerifyInfo>(|k, arr| { - let addr = match Address::from_bytes(&k.0) { - Ok(addr) => addr, - Err(e) => { - return Err(anyhow!("failed to parse address key: {}", e)); - } - }; - - let contains_claim = match claims.contains_key(&addr) { - Ok(contains_claim) => contains_claim, - Err(e) => return Err(anyhow!("failed to look up clain: {}", e)), - }; - - if !contains_claim { - debug!("skipping batch verifies for unknown miner: {}", addr); - return Ok(()); - } - - let num_proofs: usize = arr.count().try_into()?; - infos.reserve(num_proofs); - arr.for_each(|_, svi| { - infos.push(svi.clone()); - Ok(()) - }) - .map_err(|e| { - anyhow!( - "failed to iterate over proof verify array for miner {}: {}", - addr, - e - ) - })?; - - miners.push((addr, num_proofs)); - Ok(()) - }) { - // Do not return immediately, all runs that get this far should wipe the ProofValidationBatchQueue. - // If we leave the validation batch then in the case of a repeating state error the queue - // will quickly fill up and repeated traversals will start ballooning cron execution time. - st_err = Some(format!("failed to iterate proof batch: {}", e)); - } - - st.proof_validation_batch = None; - result - }) - .map_err(|e| { - format!("failed to do transaction in process batch proof verifies: {}", e) - })?; - if let Some(st_err) = st_err { - return Err(st_err); - } - - let res = - rt.batch_verify_seals(&infos).map_err(|e| format!("failed to batch verify: {}", e))?; - - let mut res_iter = infos.iter().zip(res.iter().copied()); - for (m, count) in miners { - let successful: Vec<_> = res_iter - .by_ref() - // Take the miner's sectors. - .take(count) - // Filter by successful - .filter(|(_, r)| *r) - // Pull out the sector numbers. - .map(|(info, _)| info.sector_id.number) - // Deduplicate - .filter({ - let mut seen = BTreeSet::<_>::new(); - move |snum| seen.insert(*snum) - }) - .collect(); - - // Result intentionally ignored - if successful.is_empty() { - continue; - } - if let Err(e) = extract_send_result( - rt.send_simple( - &m, - ext::miner::CONFIRM_SECTOR_PROOFS_VALID_METHOD, - IpldBlock::serialize_cbor(&ext::miner::ConfirmSectorProofsParams { - sectors: successful, - reward_smoothed: rewret.this_epoch_reward_smoothed.clone(), - reward_baseline_power: rewret.this_epoch_baseline_power.clone(), - quality_adj_power_smoothed: this_epoch_qa_power_smoothed.clone(), - }) - .map_err(|e| format!("failed to serialize ConfirmSectorProofsParams: {}", e))?, - Default::default(), - ), - ) { - error!("failed to confirm sector proof validity to {}, error code {}", m, e); - } - } - Ok(()) - } - fn process_deferred_cron_events( rt: &impl Runtime, rewret: ThisEpochRewardReturn, @@ -643,7 +433,6 @@ impl ActorCode for Actor { EnrollCronEvent => enroll_cron_event, OnEpochTickEnd => on_epoch_tick_end, UpdatePledgeTotal => update_pledge_total, - SubmitPoRepForBulkVerify => submit_porep_for_bulk_verify, CurrentTotalPower => current_total_power, NetworkRawPowerExported => network_raw_power, MinerRawPowerExported => miner_raw_power, diff --git a/actors/power/src/state.rs b/actors/power/src/state.rs index b3f8c6a24..a30fa6760 100644 --- a/actors/power/src/state.rs +++ b/actors/power/src/state.rs @@ -40,7 +40,6 @@ lazy_static! { pub const CRON_QUEUE_HAMT_BITWIDTH: u32 = 6; pub const CRON_QUEUE_AMT_BITWIDTH: u32 = 6; -pub const PROOF_VALIDATION_BATCH_AMT_BITWIDTH: u32 = 4; pub type ClaimsMap = Map2; pub const CLAIMS_CONFIG: Config = DEFAULT_HAMT_CONFIG; @@ -79,6 +78,7 @@ pub struct State { /// Claimed power for each miner. pub claims: Cid, // Map, HAMT[address]Claim + // Deprecated as of FIP 0084 pub proof_validation_batch: Option, } diff --git a/actors/power/src/testing.rs b/actors/power/src/testing.rs index e6c9d8131..ef920af4f 100644 --- a/actors/power/src/testing.rs +++ b/actors/power/src/testing.rs @@ -2,20 +2,14 @@ use std::collections::HashMap; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::RawBytes; -use fvm_shared::{ - address::Address, - clock::ChainEpoch, - sector::{SealVerifyInfo, StoragePower}, - HAMT_BIT_WIDTH, -}; +use fvm_shared::{address::Address, clock::ChainEpoch, sector::StoragePower}; use num_traits::{Signed, Zero}; use fil_actors_runtime::{parse_uint_key, runtime::Policy, MessageAccumulator, Multimap}; use crate::{ consensus_miner_min_power, Claim, ClaimsMap, CronEvent, State, CLAIMS_CONFIG, - CRON_QUEUE_AMT_BITWIDTH, CRON_QUEUE_HAMT_BITWIDTH, MAX_MINER_PROVE_COMMITS_PER_EPOCH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, + CRON_QUEUE_AMT_BITWIDTH, CRON_QUEUE_HAMT_BITWIDTH, }; pub struct MinerCronEvent { @@ -25,12 +19,10 @@ pub struct MinerCronEvent { type CronEventsByAddress = HashMap>; type ClaimsByAddress = HashMap; -type ProofsByAddress = HashMap; pub struct StateSummary { pub crons: CronEventsByAddress, pub claims: ClaimsByAddress, - pub proofs: ProofsByAddress, } /// Checks internal invariants of power state @@ -90,9 +82,9 @@ pub fn check_state_invariants( let crons = check_cron_invariants(state, store, &acc); let claims = check_claims_invariants(policy, state, store, &acc); - let proofs = check_proofs_invariants(state, store, &claims, &acc); + check_proofs_invariants(state, &acc); - (StateSummary { crons, claims, proofs }, acc) + (StateSummary { crons, claims }, acc) } fn check_cron_invariants( @@ -209,55 +201,8 @@ fn check_claims_invariants( claims_by_address } -fn check_proofs_invariants( - state: &State, - store: &BS, - claims: &ClaimsByAddress, - acc: &MessageAccumulator, -) -> ProofsByAddress { - if state.proof_validation_batch.is_none() { - return ProofsByAddress::default(); +fn check_proofs_invariants(state: &State, acc: &MessageAccumulator) { + if state.proof_validation_batch.is_some() { + acc.add("proof validation batch should be empty after FIP 0084"); } - - let mut proofs_by_address = ProofsByAddress::new(); - match Multimap::from_root( - store, - &state.proof_validation_batch.unwrap(), - HAMT_BIT_WIDTH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, - ) { - Ok(queue) => { - let ret = queue.for_all::<_, SealVerifyInfo>(|key, infos| { - let address = Address::from_bytes(key)?; - let claim = if let Some(claim) = claims.get(&address) { - claim - } else { - acc.add(format!("miner {address} has proofs awaiting validation but no claim")); - return Ok(()) - }; - - let ret = infos.for_each(|_, info| { - match info.registered_proof.registered_window_post_proof() { - Ok(sector_window_post_proof_type) => { - acc.require(claim.window_post_proof_type == sector_window_post_proof_type, format!("miner submitted proof with proof type {:?} different from claim {:?}", sector_window_post_proof_type, claim.window_post_proof_type)); - }, - Err(e) => acc.add(format!("Invalid PoSt proof: {e}")) - } - proofs_by_address.insert(address, info.clone()); - Ok(()) - }); - - if ret.is_err() { - return ret.map_err(|e| anyhow::anyhow!("error iterating proof validation batch for address {}: {}", address, e)); - } - - acc.require(proofs_by_address.len() as u64 <= MAX_MINER_PROVE_COMMITS_PER_EPOCH, format!("miner {address} has submitted too many proofs ({}) for batch verification", proofs_by_address.len())); - Ok(()) - }); - acc.require_no_error(ret, "error iterating proof validation queue"); - } - Err(e) => acc.add(format!("error loading proof validation queue: {e}")), - } - - proofs_by_address } diff --git a/actors/power/tests/harness/mod.rs b/actors/power/tests/harness/mod.rs index 6b484177b..720251d65 100644 --- a/actors/power/tests/harness/mod.rs +++ b/actors/power/tests/harness/mod.rs @@ -10,8 +10,6 @@ use fvm_shared::bigint::BigInt; use fvm_shared::clock::ChainEpoch; use fvm_shared::econ::TokenAmount; use fvm_shared::error::ExitCode; -use fvm_shared::sector::SealVerifyInfo; -use fvm_shared::sector::SectorNumber; use fvm_shared::sector::{RegisteredPoStProof, RegisteredSealProof, StoragePower}; use fvm_shared::MethodNum; use lazy_static::lazy_static; @@ -19,11 +17,8 @@ use num_traits::Zero; use serde::de::DeserializeOwned; use serde::Serialize; -use fil_actor_power::detail::GAS_ON_SUBMIT_VERIFY_SEAL; use fil_actor_power::ext::init::ExecParams; -use fil_actor_power::ext::miner::ConfirmSectorProofsParams; use fil_actor_power::ext::miner::MinerConstructorParams; -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::testing::check_state_invariants; @@ -217,10 +212,6 @@ impl Harness { ret.miner_count } - pub fn this_epoch_baseline_power(&self) -> &StoragePower { - &self.this_epoch_baseline_power - } - pub fn get_claim(&self, rt: &MockRuntime, miner: &Address) -> Option { let st: State = rt.get_state(); st.get_claim(rt.store(), miner).unwrap() @@ -399,34 +390,8 @@ impl Harness { rt: &MockRuntime, current_epoch: ChainEpoch, expected_raw_power: &StoragePower, - confirmed_sectors: Vec, - infos: Vec, ) { 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_simple( - sector.miner, - CONFIRM_SECTOR_PROOFS_VALID_METHOD, - IpldBlock::serialize_cbor(¶m).unwrap(), - TokenAmount::zero(), - None, - 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_simple( REWARD_ACTOR_ADDR, @@ -447,37 +412,7 @@ impl Harness { let state: State = rt.get_state(); assert!(state.proof_validation_batch.is_none()); } - - pub fn submit_porep_for_bulk_verify( - &self, - rt: &MockRuntime, - miner_address: Address, - seal_info: SealVerifyInfo, - expect_success: bool, - ) -> Result<(), ActorError> { - if expect_success { - rt.expect_gas_charge(GAS_ON_SUBMIT_VERIFY_SEAL); - } - rt.expect_validate_caller_type(vec![Type::Miner]); - rt.set_caller(*MINER_ACTOR_CODE_ID, miner_address); - rt.call::( - Method::SubmitPoRepForBulkVerify as u64, - IpldBlock::serialize_cbor(&seal_info).unwrap(), - )?; - rt.verify(); - Ok(()) - } -} - -pub struct ConfirmedSectorSend { - pub miner: Address, - pub sector_nums: Vec, } - -pub fn batch_verify_default_output(infos: &[SealVerifyInfo]) -> Vec { - vec![true; infos.len()] -} - /// Collects all keys from a map into a vector. fn collect_keys(m: Map2) -> Result, ActorError> where diff --git a/actors/power/tests/power_actor_tests.rs b/actors/power/tests/power_actor_tests.rs index ea0bfe95c..554539433 100644 --- a/actors/power/tests/power_actor_tests.rs +++ b/actors/power/tests/power_actor_tests.rs @@ -668,7 +668,6 @@ mod cron_tests { ExitCode::OK, ); rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); @@ -704,7 +703,7 @@ mod cron_tests { let delta = TokenAmount::from_atto(1u8); h.update_pledge_total(&rt, miner1, &delta); - h.on_epoch_tick_end(&rt, 0, &expected_power, Vec::new(), Vec::new()); + h.on_epoch_tick_end(&rt, 0, &expected_power); let state: State = rt.get_state(); @@ -779,7 +778,6 @@ mod cron_tests { ExitCode::OK, ); rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); rt.verify(); @@ -808,8 +806,6 @@ mod cron_tests { ); rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); - rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); rt.verify(); @@ -846,7 +842,6 @@ mod cron_tests { ExitCode::OK, ); rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); rt.verify(); @@ -893,7 +888,6 @@ mod cron_tests { rt.expect_validate_caller_addr(vec![CRON_ACTOR_ADDR]); // process batch verifies first - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); h.expect_query_network_info(&rt); let state: State = rt.get_state(); @@ -957,9 +951,6 @@ mod cron_tests { rt.set_epoch(2); rt.expect_validate_caller_addr(vec![CRON_ACTOR_ADDR]); - // process batch verifies first - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); - h.expect_query_network_info(&rt); let state: State = rt.get_state(); @@ -1027,289 +1018,6 @@ mod cron_tests { ExitCode::OK, ); rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - rt.expect_batch_verify_seals(Vec::new(), Ok(Vec::new())); - - rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); - rt.verify(); - h.check_state(&rt); - } -} - -#[cfg(test)] -mod cron_batch_proof_verifies_tests { - use super::*; - use fil_actor_power::ext::{ - miner::{ConfirmSectorProofsParams, CONFIRM_SECTOR_PROOFS_VALID_METHOD}, - reward::UPDATE_NETWORK_KPI, - }; - use fil_actors_runtime::{ - test_utils::{make_piece_cid, make_sealed_cid, CRON_ACTOR_CODE_ID}, - CRON_ACTOR_ADDR, REWARD_ACTOR_ADDR, - }; - use fvm_shared::{ - bigint::BigInt, - sector::{InteractiveSealRandomness, SealRandomness, SealVerifyInfo, SectorID}, - }; - - fn create_basic_seal_info(id: u64) -> SealVerifyInfo { - SealVerifyInfo { - registered_proof: fvm_shared::sector::RegisteredSealProof::StackedDRG32GiBV1, - deal_ids: Vec::new(), - randomness: SealRandomness::default(), - interactive_randomness: InteractiveSealRandomness::default(), - proof: Vec::new(), - sealed_cid: make_sealed_cid(format!("CommR-{id}").as_bytes()), - unsealed_cid: make_piece_cid(format!("CommD-{id}").as_bytes()), - sector_id: SectorID { number: id, ..Default::default() }, - } - } - - const MINER_1: Address = Address::new_id(101); - const OWNER: Address = Address::new_id(102); - - #[test] - fn success_with_one_miner_and_one_confirmed_sector() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - let info = create_basic_seal_info(0); - h.submit_porep_for_bulk_verify(&rt, MINER_1, info.clone(), true).unwrap(); - - let confirmed_sectors = - vec![ConfirmedSectorSend { miner: MINER_1, sector_nums: vec![info.sector_id.number] }]; - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), confirmed_sectors, vec![info]); - - rt.verify(); - h.check_state(&rt); - } - - #[test] - fn success_with_one_miner_and_multiple_confirmed_sectors() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - let infos: Vec<_> = (1..=3).map(create_basic_seal_info).collect(); - infos.iter().for_each(|info| { - h.submit_porep_for_bulk_verify(&rt, MINER_1, info.clone(), true).unwrap() - }); - - let sector_id_nums = infos.iter().map(|info| info.sector_id.number).collect(); - let confirmed_sectors = - vec![ConfirmedSectorSend { miner: MINER_1, sector_nums: sector_id_nums }]; - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), confirmed_sectors, infos); - - rt.verify(); - h.check_state(&rt); - } - - #[test] - fn duplicate_sector_numbers_are_ignored_for_a_miner() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - // duplicates will be sent to the batch verify call - let infos = - vec![create_basic_seal_info(1), create_basic_seal_info(1), create_basic_seal_info(2)]; - - infos.iter().for_each(|info| { - h.submit_porep_for_bulk_verify(&rt, MINER_1, info.clone(), true).unwrap() - }); - - // however, duplicates will not be sent to the miner as confirmed - let sector_id_nums = vec![infos[0].sector_id.number, infos[2].sector_id.number]; - let confirmed_sectors = - vec![ConfirmedSectorSend { miner: MINER_1, sector_nums: sector_id_nums }]; - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), confirmed_sectors, infos); - - rt.verify(); - h.check_state(&rt); - } - - #[test] - fn skips_verify_if_miner_has_no_claim() { - let (mut h, rt) = setup(); - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - let info = create_basic_seal_info(1); - - h.submit_porep_for_bulk_verify(&rt, MINER_1, info, true).unwrap(); - - h.delete_claim(&rt, &MINER_1); - - let infos = vec![]; - - let confirmed_sectors = vec![]; - - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), confirmed_sectors, infos); - - h.check_state(&rt); - } - - #[test] - fn success_with_multiple_miners_and_multiple_confirmed_sectors_and_assert_expected_power() { - let miner1 = Address::new_id(101); - - // TODO: shares an id with constant `OWNER` - // this is a known issue however the ordering of the values - // are vital for this test and have been left as such - let miner2 = Address::new_id(102); - let miner3 = Address::new_id(103); - let miner4 = Address::new_id(104); - - let info1 = create_basic_seal_info(1); - let info2 = create_basic_seal_info(2); - let info3 = create_basic_seal_info(3); - let info4 = create_basic_seal_info(101); - let info5 = create_basic_seal_info(200); - let info6 = create_basic_seal_info(201); - let info7 = create_basic_seal_info(300); - let info8 = create_basic_seal_info(301); - - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, miner1).unwrap(); - h.create_miner_basic(&rt, OWNER, OWNER, miner2).unwrap(); - h.create_miner_basic(&rt, OWNER, OWNER, miner3).unwrap(); - h.create_miner_basic(&rt, OWNER, OWNER, miner4).unwrap(); - - h.submit_porep_for_bulk_verify(&rt, miner1, info1.clone(), true).unwrap(); - h.submit_porep_for_bulk_verify(&rt, miner1, info2.clone(), true).unwrap(); - - h.submit_porep_for_bulk_verify(&rt, miner2, info3.clone(), true).unwrap(); - h.submit_porep_for_bulk_verify(&rt, miner2, info4.clone(), true).unwrap(); - - h.submit_porep_for_bulk_verify(&rt, miner3, info5.clone(), true).unwrap(); - h.submit_porep_for_bulk_verify(&rt, miner3, info6.clone(), true).unwrap(); - - h.submit_porep_for_bulk_verify(&rt, miner4, info7.clone(), true).unwrap(); - h.submit_porep_for_bulk_verify(&rt, miner4, info8.clone(), true).unwrap(); - - // TODO Because read order of keys in a multi-map is not as per insertion order, - // we have to move around the expected sends - let confirmed_sectors = vec![ - ConfirmedSectorSend { - miner: MINER_1, - sector_nums: vec![info1.sector_id.number, info2.sector_id.number], - }, - ConfirmedSectorSend { - miner: miner3, - sector_nums: vec![info5.sector_id.number, info6.sector_id.number], - }, - ConfirmedSectorSend { - miner: miner4, - sector_nums: vec![info7.sector_id.number, info8.sector_id.number], - }, - ConfirmedSectorSend { - miner: miner2, - sector_nums: vec![info3.sector_id.number, info4.sector_id.number], - }, - ]; - - let infos = vec![info1, info2, info5, info6, info7, info8, info3, info4]; - - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), confirmed_sectors, infos); - h.check_state(&rt); - } - - #[test] - fn success_when_no_confirmed_sector() { - let (h, rt) = setup(); - h.on_epoch_tick_end(&rt, 0, &BigInt::zero(), vec![], vec![]); - - h.check_state(&rt); - } - - #[test] - fn verification_for_one_sector_fails_but_others_succeeds_for_a_miner() { - let (mut h, rt) = setup(); - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - let infos: Vec<_> = (1..=3).map(create_basic_seal_info).collect(); - infos.iter().for_each(|info| { - h.submit_porep_for_bulk_verify(&rt, MINER_1, info.clone(), true).unwrap() - }); - - let res = Ok(vec![true, false, true]); - - // send will only be for the first and third sector as the middle sector will fail verification - let cs = ConfirmedSectorSend { - miner: MINER_1, - sector_nums: vec![infos[0].sector_id.number, infos[2].sector_id.number], - }; - - h.expect_query_network_info(&rt); - - let state: State = rt.get_state(); - - // expect sends for confirmed sectors - let params = ConfirmSectorProofsParams { - sectors: cs.sector_nums, - reward_smoothed: h.this_epoch_reward_smoothed.clone(), - reward_baseline_power: h.this_epoch_baseline_power().clone(), - quality_adj_power_smoothed: state.this_epoch_qa_power_smoothed, - }; - - rt.expect_send_simple( - cs.miner, - CONFIRM_SECTOR_PROOFS_VALID_METHOD, - IpldBlock::serialize_cbor(¶ms).unwrap(), - TokenAmount::zero(), - None, - ExitCode::OK, - ); - - rt.expect_batch_verify_seals(infos, res); - - // expect power sends to reward actor - rt.expect_send_simple( - REWARD_ACTOR_ADDR, - UPDATE_NETWORK_KPI, - IpldBlock::serialize_cbor(&BigIntSer(&BigInt::zero())).unwrap(), - TokenAmount::zero(), - None, - ExitCode::OK, - ); - - rt.expect_validate_caller_addr(vec![CRON_ACTOR_ADDR]); - - rt.set_epoch(0); - rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); - - rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); - - rt.verify(); - h.check_state(&rt); - } - - #[test] - fn cron_tick_does_not_fail_if_batch_verify_seals_fails() { - let (mut h, rt) = setup(); - h.create_miner_basic(&rt, OWNER, OWNER, MINER_1).unwrap(); - - let infos: Vec<_> = (1..=3).map(create_basic_seal_info).collect(); - infos.iter().for_each(|info| { - h.submit_porep_for_bulk_verify(&rt, MINER_1, info.clone(), true).unwrap() - }); - - h.expect_query_network_info(&rt); - - rt.expect_batch_verify_seals(infos, Err(anyhow::Error::msg("fail"))); - rt.expect_validate_caller_addr(vec![CRON_ACTOR_ADDR]); - - // expect power sends to reward actor - rt.expect_send_simple( - REWARD_ACTOR_ADDR, - UPDATE_NETWORK_KPI, - IpldBlock::serialize_cbor(&BigIntSer(&BigInt::zero())).unwrap(), - TokenAmount::zero(), - None, - ExitCode::OK, - ); - rt.set_epoch(0); - rt.set_caller(*CRON_ACTOR_CODE_ID, CRON_ACTOR_ADDR); rt.call::(Method::OnEpochTickEnd as u64, None).unwrap(); rt.verify(); @@ -1317,129 +1025,6 @@ mod cron_batch_proof_verifies_tests { } } -#[cfg(test)] -mod submit_porep_for_bulk_verify_tests { - use super::*; - - use fil_actor_power::{ - ERR_TOO_MANY_PROVE_COMMITS, MAX_MINER_PROVE_COMMITS_PER_EPOCH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, - }; - use fil_actors_runtime::shared::HAMT_BIT_WIDTH; - use fil_actors_runtime::test_utils::{make_piece_cid, make_sealed_cid}; - use fil_actors_runtime::Multimap; - use fvm_shared::sector::{InteractiveSealRandomness, SealRandomness, SealVerifyInfo, SectorID}; - - const MINER: Address = Address::new_id(101); - const OWNER: Address = Address::new_id(101); - - #[test] - fn registers_porep_and_charges_gas() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER).unwrap(); - - let comm_r = make_sealed_cid("commR".as_bytes()); - let comm_d = make_piece_cid("commD".as_bytes()); - - let info = SealVerifyInfo { - registered_proof: fvm_shared::sector::RegisteredSealProof::StackedDRG32GiBV1P1, - deal_ids: Vec::new(), - randomness: SealRandomness::default(), - interactive_randomness: InteractiveSealRandomness::default(), - proof: Vec::new(), - sealed_cid: comm_r, - unsealed_cid: comm_d, - sector_id: SectorID { number: 0, ..Default::default() }, - }; - - h.submit_porep_for_bulk_verify(&rt, MINER, info, true).unwrap(); - let st: State = rt.get_state(); - let store = &rt.store; - assert!(st.proof_validation_batch.is_some()); - let mmap = Multimap::from_root( - store, - st.proof_validation_batch.as_ref().unwrap(), - HAMT_BIT_WIDTH, - PROOF_VALIDATION_BATCH_AMT_BITWIDTH, - ) - .unwrap(); - let arr = mmap.get::(&MINER.to_bytes()).unwrap(); - let found = arr.unwrap(); - assert_eq!(1_u64, found.count()); - let sealed_cid = found.get(0).unwrap().unwrap().sealed_cid; - assert_eq!(comm_r, sealed_cid); - h.check_state(&rt); - } - - #[test] - fn aborts_when_too_many_poreps() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER).unwrap(); - - fn create_basic_seal_info(id: u64) -> SealVerifyInfo { - SealVerifyInfo { - registered_proof: fvm_shared::sector::RegisteredSealProof::StackedDRG32GiBV1P1, - deal_ids: Vec::new(), - randomness: SealRandomness::default(), - interactive_randomness: InteractiveSealRandomness::default(), - proof: Vec::new(), - sealed_cid: make_sealed_cid(format!("CommR-{id}").as_bytes()), - unsealed_cid: make_piece_cid(format!("CommD-{id}").as_bytes()), - sector_id: SectorID { number: id, ..Default::default() }, - } - } - - // Adding MAX_MINER_PROVE_COMMITS_PER_EPOCH works without error - for i in 0..MAX_MINER_PROVE_COMMITS_PER_EPOCH { - h.submit_porep_for_bulk_verify(&rt, MINER, create_basic_seal_info(i), true).unwrap(); - } - - expect_abort( - ERR_TOO_MANY_PROVE_COMMITS, - h.submit_porep_for_bulk_verify( - &rt, - MINER, - create_basic_seal_info(MAX_MINER_PROVE_COMMITS_PER_EPOCH), - false, - ), - ); - - h.check_state(&rt); - } - - #[test] - fn aborts_when_miner_has_no_claim() { - let (mut h, rt) = setup(); - - h.create_miner_basic(&rt, OWNER, OWNER, MINER).unwrap(); - - let comm_r = make_sealed_cid("commR".as_bytes()); - let comm_d = make_piece_cid("commD".as_bytes()); - - let info = SealVerifyInfo { - registered_proof: fvm_shared::sector::RegisteredSealProof::StackedDRG32GiBV1, - deal_ids: Vec::new(), - randomness: SealRandomness::default(), - interactive_randomness: InteractiveSealRandomness::default(), - proof: Vec::new(), - sealed_cid: comm_r, - unsealed_cid: comm_d, - sector_id: SectorID { number: 0, ..Default::default() }, - }; - - // delete miner - h.delete_claim(&rt, &MINER); - - expect_abort( - ExitCode::USR_FORBIDDEN, - h.submit_porep_for_bulk_verify(&rt, MINER, info, false), - ); - h.check_state(&rt); - } -} - #[test] fn create_miner_restricted_correctly() { let (h, rt) = setup(); diff --git a/integration_tests/src/expects.rs b/integration_tests/src/expects.rs index 907d85b08..ebd6460bb 100644 --- a/integration_tests/src/expects.rs +++ b/integration_tests/src/expects.rs @@ -74,7 +74,7 @@ impl Expect { params: Some(params), value: Some(TokenAmount::zero()), subinvocs: Some(vec![]), - events, + events: Some(events), ..Default::default() } } @@ -103,7 +103,7 @@ impl Expect { params: Some(params), value: Some(TokenAmount::zero()), subinvocs: Some(vec![Expect::burn(STORAGE_MARKET_ACTOR_ID, None)]), - events, + events: Some(events), ..Default::default() } } @@ -167,17 +167,6 @@ impl Expect { ..Default::default() } } - pub fn power_submit_porep(from: ActorID) -> ExpectInvocation { - // Note: params are unchecked. - ExpectInvocation { - from, - to: STORAGE_POWER_ACTOR_ADDR, - method: fil_actor_power::Method::SubmitPoRepForBulkVerify as u64, - value: Some(TokenAmount::zero()), - subinvocs: Some(vec![]), - ..Default::default() - } - } pub fn power_update_claim(from: ActorID, delta: PowerPair) -> ExpectInvocation { let params = IpldBlock::serialize_cbor(&UpdateClaimedPowerParams { raw_byte_delta: delta.raw, @@ -267,7 +256,7 @@ impl Expect { .unwrap(), ), subinvocs: Some(burn_invocs), - events: claim_events, + events: Some(claim_events), ..Default::default() }]), ..Default::default() diff --git a/integration_tests/src/tests/batch_onboarding_deals_test.rs b/integration_tests/src/tests/batch_onboarding_deals_test.rs index 79f986125..6aa256e7e 100644 --- a/integration_tests/src/tests/batch_onboarding_deals_test.rs +++ b/integration_tests/src/tests/batch_onboarding_deals_test.rs @@ -144,7 +144,7 @@ pub fn batch_onboarding_deals_test(v: &dyn VM) { // Associate deals with sectors. let sector_precommit_data = deals .into_iter() - .map(|(id, _)| precommit_meta_data_from_deals(v, &[id], SEAL_PROOF)) + .map(|(id, _)| precommit_meta_data_from_deals(v, &[id], SEAL_PROOF, true)) .collect(); // Pre-commit as single batch. diff --git a/integration_tests/src/tests/commit_post_test.rs b/integration_tests/src/tests/commit_post_test.rs index a315b5344..95f200f29 100644 --- a/integration_tests/src/tests/commit_post_test.rs +++ b/integration_tests/src/tests/commit_post_test.rs @@ -14,15 +14,14 @@ use crate::expects::Expect; use crate::util::{ advance_by_deadline_to_epoch, advance_to_proving_deadline, assert_invariants, create_accounts, create_miner, cron_tick, expect_invariants, get_network_stats, invariant_failure_patterns, - miner_balance, precommit_sectors_v2, submit_windowed_post, + miner_balance, miner_prove_sector, precommit_sectors_v2, submit_windowed_post, }; use crate::TEST_VM_RAND_ARRAY; use fil_actor_cron::Method as CronMethod; use fil_actor_market::Method as MarketMethod; use fil_actor_miner::{ max_prove_commit_duration, power_for_sector, DeadlineInfo, Method as MinerMethod, - PoStPartition, ProveCommitAggregateParams, ProveCommitSectorParams, State as MinerState, - SubmitWindowedPoStParams, + PoStPartition, ProveCommitAggregateParams, State as MinerState, SubmitWindowedPoStParams, }; use fil_actor_power::{Method as PowerMethod, State as PowerState}; use fil_actors_runtime::runtime::Policy; @@ -52,7 +51,6 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) { let addrs = create_accounts(v, 1, &TokenAmount::from_whole(10_000)); let seal_proof = RegisteredSealProof::StackedDRG32GiBV1P1; let (owner, worker) = (addrs[0], addrs[0]); - let worker_id = worker.id().unwrap(); let (id_addr, robust_addr) = create_miner( v, &owner, @@ -64,7 +62,7 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) { // precommit and advance to prove commit time let sector_number: SectorNumber = 100; - let infos = precommit_sectors_v2( + let _ = precommit_sectors_v2( v, 1, 1, @@ -76,7 +74,6 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) { true, None, ); - let pc = &infos[0]; let balances = miner_balance(v, &id_addr); assert!(balances.pre_commit_deposit.is_positive()); @@ -84,31 +81,10 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) { let prove_time = v.epoch() + Policy::default().pre_commit_challenge_delay + 1; advance_by_deadline_to_epoch(v, &id_addr, prove_time); - let unsealed_cid = pc.info.unsealed_cid.0; // prove commit, cron, advance to post time - let prove_params = ProveCommitSectorParams { sector_number, proof: vec![].into() }; - let prove_params_ser = IpldBlock::serialize_cbor(&prove_params).unwrap(); - apply_ok( - v, - &worker, - &robust_addr, - &TokenAmount::zero(), - MinerMethod::ProveCommitSector as u64, - Some(prove_params), - ); - ExpectInvocation { - from: worker_id, - to: id_addr, - method: MinerMethod::ProveCommitSector as u64, - params: Some(prove_params_ser), - subinvocs: Some(vec![Expect::power_submit_porep(id_addr.id().unwrap())]), - ..Default::default() - } - .matches(v.take_invocations().last().unwrap()); - + miner_prove_sector(v, &worker, &id_addr, sector_number, vec![]); cron_tick(v); - let pieces: Vec<(Cid, u64)> = vec![]; ExpectInvocation { to: CRON_ACTOR_ADDR, method: CronMethod::EpochTick as u64, @@ -119,31 +95,16 @@ fn setup(v: &dyn VM) -> (MinerInfo, SectorInfo) { method: PowerMethod::OnEpochTickEnd as u64, subinvocs: Some(vec![ Expect::reward_this_epoch(STORAGE_POWER_ACTOR_ID), - ExpectInvocation { - from: STORAGE_POWER_ACTOR_ID, - to: id_addr, - method: MinerMethod::ConfirmSectorProofsValid as u64, - subinvocs: Some(vec![Expect::power_update_pledge( - id_addr.id().unwrap(), - None, - )]), - events: vec![Expect::build_sector_activation_event( - "sector-activated", - id_addr.id().unwrap(), - sector_number, - unsealed_cid, - &pieces, - )], - ..Default::default() - }, Expect::reward_update_kpi(), ]), + events: Some(vec![]), ..Default::default() }, ExpectInvocation { from: CRON_ACTOR_ID, to: STORAGE_MARKET_ACTOR_ADDR, method: MarketMethod::CronTick as u64, + events: Some(vec![]), ..Default::default() }, ]), @@ -775,7 +736,7 @@ pub fn aggregate_one_precommit_expires_test(v: &dyn VM) { Expect::power_update_pledge(miner_id, None), Expect::burn(miner_id, None), ]), - events, + events: Some(events), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/tests/extend_sectors_test.rs b/integration_tests/src/tests/extend_sectors_test.rs index 92871a9b0..03d41bbac 100644 --- a/integration_tests/src/tests/extend_sectors_test.rs +++ b/integration_tests/src/tests/extend_sectors_test.rs @@ -26,11 +26,11 @@ use crate::expects::Expect; use crate::util::{ advance_by_deadline_to_epoch, advance_by_deadline_to_epoch_while_proving, advance_by_deadline_to_index, advance_to_proving_deadline, bf_all, create_accounts, - create_miner, cron_tick, expect_invariants, invariant_failure_patterns, market_add_balance, - market_pending_deal_allocations, market_publish_deal, miner_precommit_one_sector_v2, - miner_prove_sector, override_compute_unsealed_sector_cid, precommit_meta_data_from_deals, - sector_deadline, submit_windowed_post, verifreg_add_client, verifreg_add_verifier, - PrecommitMetadata, + create_miner, cron_tick, expect_invariants, invariant_failure_patterns, + make_piece_manifests_from_deal_ids, market_add_balance, market_pending_deal_allocations, + market_publish_deal, miner_precommit_one_sector_v2, miner_prove_sector, + override_compute_unsealed_sector_cid, precommit_meta_data_from_deals, sector_deadline, + submit_windowed_post, verifreg_add_client, verifreg_add_verifier, PrecommitMetadata, }; #[allow(clippy::too_many_arguments)] @@ -165,14 +165,20 @@ pub fn extend_legacy_sector_with_deals_test(v: &dyn VM, do_extend2: bool) { &miner_id, seal_proof, sector_number, - precommit_meta_data_from_deals(v, &deals, seal_proof), + precommit_meta_data_from_deals(v, &deals, seal_proof, false), true, deal_start + 180 * EPOCHS_IN_DAY, ); // advance time to max seal duration and prove the sector advance_by_deadline_to_epoch(v, &miner_id, deal_start); - miner_prove_sector(v, &worker, &miner_id, sector_number); + miner_prove_sector( + v, + &worker, + &miner_id, + sector_number, + make_piece_manifests_from_deal_ids(v, deals), + ); // trigger cron to validate the prove commit cron_tick(v); @@ -393,14 +399,20 @@ pub fn commit_sector_with_max_duration_deal_test(v: &dyn VM) { &miner_id, seal_proof, sector_number, - precommit_meta_data_from_deals(v, &deals, seal_proof), + precommit_meta_data_from_deals(v, &deals, seal_proof, false), true, deal_start + deal_lifetime, ); // advance time to max seal duration and prove the sector advance_by_deadline_to_epoch(v, &miner_id, deal_start); - miner_prove_sector(v, &worker, &miner_id, sector_number); + miner_prove_sector( + v, + &worker, + &miner_id, + sector_number, + make_piece_manifests_from_deal_ids(v, deals), + ); // trigger cron to validate the prove commit cron_tick(v); @@ -465,7 +477,7 @@ pub fn extend_sector_up_to_max_relative_extension_test(v: &dyn VM) { // advance time to max seal duration and prove the sector advance_by_deadline_to_epoch(v, &miner_id, sector_start); - miner_prove_sector(v, &worker, &miner_id, sector_number); + miner_prove_sector(v, &worker, &miner_id, sector_number, vec![]); // trigger cron to validate the prove commit cron_tick(v); @@ -566,7 +578,7 @@ pub fn extend_updated_sector_with_claims_test(v: &dyn VM) { // advance time by a day and prove the sector let prove_epoch = v.epoch() + EPOCHS_IN_DAY; advance_by_deadline_to_epoch(v, &miner_addr, prove_epoch); - miner_prove_sector(v, &worker, &miner_addr, sector_number); + miner_prove_sector(v, &worker, &miner_addr, sector_number, vec![]); // trigger cron to validate the prove commit cron_tick(v); @@ -682,12 +694,12 @@ pub fn extend_updated_sector_with_claims_test(v: &dyn VM) { from: miner_id, to: VERIFIED_REGISTRY_ACTOR_ADDR, method: VerifregMethod::ClaimAllocations as u64, - events: vec![Expect::build_verifreg_event( + events: Some(vec![Expect::build_verifreg_event( "claim", claim_id, verified_client.id().unwrap(), miner_id, - )], + )]), ..Default::default() }, Expect::reward_this_epoch(miner_id), @@ -698,13 +710,13 @@ pub fn extend_updated_sector_with_claims_test(v: &dyn VM) { PowerPair { raw: StoragePower::zero(), qa: 9 * old_power.qa }, ), ]), - events: vec![Expect::build_sector_activation_event( + events: Some(vec![Expect::build_sector_activation_event( "sector-updated", miner_id, sector_number, Some(unsealed_cid), &pieces, - )], + )]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/tests/prove_commit3_test.rs b/integration_tests/src/tests/prove_commit3_test.rs index ab94e0b89..59a117b88 100644 --- a/integration_tests/src/tests/prove_commit3_test.rs +++ b/integration_tests/src/tests/prove_commit3_test.rs @@ -289,11 +289,11 @@ pub fn prove_commit_sectors2_test(v: &dyn VM) { }) .unwrap(), ), - events: vec![ + events: Some(vec![ Expect::build_verifreg_event("claim", alloc_ids_s2[0], client_id, miner_id), Expect::build_verifreg_event("claim", alloc_ids_s2[1], client_id, miner_id), Expect::build_verifreg_event("claim", alloc_ids_s4[0], client_id, miner_id), - ], + ]), ..Default::default() }, Expect::reward_this_epoch(miner_id), @@ -323,17 +323,24 @@ pub fn prove_commit_sectors2_test(v: &dyn VM) { ), value: Some(TokenAmount::zero()), subinvocs: Some(vec![]), - events: deal_ids_s3 - .iter() - .chain(deal_ids_s4.iter()) - .map(|deal_id| { - Expect::build_market_event("deal-activated", *deal_id, client_id, miner_id) - }) - .collect::>(), + events: Some( + deal_ids_s3 + .iter() + .chain(deal_ids_s4.iter()) + .map(|deal_id| { + Expect::build_market_event( + "deal-activated", + *deal_id, + client_id, + miner_id, + ) + }) + .collect::>(), + ), ..Default::default() }, ]), - events, + events: Some(events), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/tests/replica_update3_test.rs b/integration_tests/src/tests/replica_update3_test.rs index de31f6e2a..d68640899 100644 --- a/integration_tests/src/tests/replica_update3_test.rs +++ b/integration_tests/src/tests/replica_update3_test.rs @@ -352,11 +352,11 @@ pub fn prove_replica_update2_test(v: &dyn VM) { }) .unwrap(), ), - events: vec![ + events: Some(vec![ Expect::build_verifreg_event("claim", alloc_ids_s2[0], client_id, miner_id), Expect::build_verifreg_event("claim", alloc_ids_s2[1], client_id, miner_id), Expect::build_verifreg_event("claim", alloc_ids_s4[0], client_id, miner_id), - ], + ]), ..Default::default() }, Expect::reward_this_epoch(miner_id), @@ -387,18 +387,25 @@ pub fn prove_replica_update2_test(v: &dyn VM) { ), value: Some(TokenAmount::zero()), subinvocs: Some(vec![]), - events: deal_ids_s3 - .iter() - .chain(deal_ids_s4.iter()) - .map(|deal_id| { - Expect::build_market_event("deal-activated", *deal_id, client_id, miner_id) - }) - .collect::>(), + events: Some( + deal_ids_s3 + .iter() + .chain(deal_ids_s4.iter()) + .map(|deal_id| { + Expect::build_market_event( + "deal-activated", + *deal_id, + client_id, + miner_id, + ) + }) + .collect::>(), + ), ..Default::default() }, ]), - events, + events: Some(events), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/tests/replica_update_test.rs b/integration_tests/src/tests/replica_update_test.rs index 000430091..ff09c98c6 100644 --- a/integration_tests/src/tests/replica_update_test.rs +++ b/integration_tests/src/tests/replica_update_test.rs @@ -16,9 +16,9 @@ use fil_actor_market::Method as MarketMethod; use fil_actor_market::State as MarketState; use fil_actor_miner::{ power_for_sector, DisputeWindowedPoStParams, ExpirationExtension, ExtendSectorExpirationParams, - Method as MinerMethod, PowerPair, ProveCommitSectorParams, ProveReplicaUpdatesParams, - ReplicaUpdate, SectorOnChainInfo, SectorOnChainInfoFlags, Sectors, State as MinerState, - TerminateSectorsParams, TerminationDeclaration, SECTORS_AMT_BITWIDTH, + Method as MinerMethod, PowerPair, ProveReplicaUpdatesParams, ReplicaUpdate, SectorOnChainInfo, + SectorOnChainInfoFlags, Sectors, State as MinerState, TerminateSectorsParams, + TerminationDeclaration, SECTORS_AMT_BITWIDTH, }; use fil_actor_verifreg::Method as VerifregMethod; use fil_actors_runtime::runtime::Policy; @@ -36,9 +36,9 @@ use crate::util::{ assert_invariants, bf_all, check_sector_active, check_sector_faulty, create_accounts, 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, - verifreg_add_client, verifreg_add_verifier, + miner_balance, miner_power, miner_prove_sector, override_compute_unsealed_sector_cid, + precommit_sectors_v2, prove_commit_sectors, sector_info, submit_invalid_post, + submit_windowed_post, verifreg_add_client, verifreg_add_verifier, }; #[vm_test] @@ -1060,7 +1060,7 @@ pub fn replica_update_verified_deal_test(v: &dyn VM) { from: miner_id, to: VERIFIED_REGISTRY_ACTOR_ADDR, method: VerifregMethod::ClaimAllocations as u64, - events: vec![claim_event], + events: Some(vec![claim_event]), ..Default::default() }, Expect::reward_this_epoch(miner_id), @@ -1072,13 +1072,13 @@ pub fn replica_update_verified_deal_test(v: &dyn VM) { PowerPair { raw: StoragePower::zero(), qa: 9 * old_power.qa }, ), ]), - events: vec![Expect::build_sector_activation_event( + events: Some(vec![Expect::build_sector_activation_event( "sector-updated", miner_id, sector_number, Some(unsealed_cid), &pieces, - )], + )]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -1187,15 +1187,7 @@ pub fn create_sector( // prove commit let prove_time = v.epoch() + Policy::default().pre_commit_challenge_delay + 1; advance_by_deadline_to_epoch(v, &maddr, prove_time); - let prove_commit_params = ProveCommitSectorParams { sector_number, proof: vec![].into() }; - apply_ok( - v, - &worker, - &maddr, - &TokenAmount::zero(), - MinerMethod::ProveCommitSector as u64, - Some(prove_commit_params), - ); + miner_prove_sector(v, &worker, &maddr, sector_number, vec![]); cron_tick(v); diff --git a/integration_tests/src/tests/terminate_test.rs b/integration_tests/src/tests/terminate_test.rs index f4eb9e086..caf6e7668 100644 --- a/integration_tests/src/tests/terminate_test.rs +++ b/integration_tests/src/tests/terminate_test.rs @@ -11,8 +11,8 @@ use fil_actor_market::{ DealMetaArray, Method as MarketMethod, State as MarketState, WithdrawBalanceParams, }; use fil_actor_miner::{ - power_for_sector, Method as MinerMethod, ProveCommitSectorParams, State as MinerState, - TerminateSectorsParams, TerminationDeclaration, + power_for_sector, Method as MinerMethod, State as MinerState, TerminateSectorsParams, + TerminationDeclaration, }; use fil_actor_power::State as PowerState; use fil_actor_verifreg::{Method as VerifregMethod, VerifierParams}; @@ -32,9 +32,9 @@ 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, 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, + deal_cid_for_testing, make_bitfield, make_piece_manifests_from_deal_ids, market_publish_deal, + miner_balance, miner_precommit_one_sector_v2, miner_prove_sector, + precommit_meta_data_from_deals, submit_windowed_post, verifreg_add_verifier, }; #[vm_test] @@ -167,26 +167,20 @@ pub fn terminate_sectors_test(v: &dyn VM) { &miner_robust_addr, seal_proof, sector_number, - precommit_meta_data_from_deals(v, &deal_ids, seal_proof), + precommit_meta_data_from_deals(v, &deal_ids, seal_proof, false), true, v.epoch() + 220 * EPOCHS_IN_DAY, ); let prove_time = v.epoch() + Policy::default().pre_commit_challenge_delay + 1; advance_by_deadline_to_epoch(v, &miner_id_addr, prove_time); - - // prove commit, cron, advance to post time - let prove_params = ProveCommitSectorParams { sector_number, proof: vec![].into() }; - apply_ok( + miner_prove_sector( v, &worker, - &miner_robust_addr, - &TokenAmount::zero(), - MinerMethod::ProveCommitSector as u64, - Some(prove_params), + &miner_id_addr, + sector_number, + make_piece_manifests_from_deal_ids(v, deal_ids.clone()), ); - 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(); @@ -259,7 +253,7 @@ pub fn terminate_sectors_test(v: &dyn VM) { ), Expect::power_update_claim(miner_id, sector_power.neg()), ]), - events: vec![expect_event], + events: Some(vec![expect_event]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/tests/verified_claim_test.rs b/integration_tests/src/tests/verified_claim_test.rs index e72ed2662..f7d46aa76 100644 --- a/integration_tests/src/tests/verified_claim_test.rs +++ b/integration_tests/src/tests/verified_claim_test.rs @@ -1,8 +1,10 @@ use std::ops::Neg; use export_macro::vm_test; +use fvm_ipld_encoding::RawBytes; 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, SectorNumber, StoragePower}; @@ -11,7 +13,10 @@ use fil_actor_market::{DealArray, DealMetaArray, DealSettlementSummary}; use fil_actor_market::{ PendingDealAllocationsMap, State as MarketState, PENDING_ALLOCATIONS_CONFIG, }; -use fil_actor_miner::{max_prove_commit_duration, PowerPair, SectorClaim, State as MinerState}; +use fil_actor_miner::{ + max_prove_commit_duration, PowerPair, ProveCommitSectors3Params, SectorActivationManifest, + SectorClaim, State as MinerState, +}; use fil_actor_power::State as PowerState; use fil_actor_verifreg::{ Claim, Method as VerifregMethod, RemoveExpiredClaimsParams, RemoveExpiredClaimsReturn, @@ -27,18 +32,19 @@ use fil_actors_runtime::{ DealWeight, DATACAP_TOKEN_ACTOR_ADDR, EPOCHS_IN_DAY, STORAGE_MARKET_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR, }; -use vm_api::util::{apply_ok, get_state, DynBlockstore}; +use vm_api::trace::ExpectInvocation; +use vm_api::util::{apply_code, apply_ok, get_state, DynBlockstore}; use vm_api::VM; use crate::util::{ advance_by_deadline_to_epoch, advance_by_deadline_to_epoch_while_proving, advance_by_deadline_to_index, advance_to_proving_deadline, assert_invariants, create_accounts, create_miner, cron_tick, datacap_extend_claim, datacap_get_balance, expect_invariants, - invariant_failure_patterns, market_add_balance, market_pending_deal_allocations, - market_publish_deal, miner_extend_sector_expiration2, miner_precommit_one_sector_v2, - miner_prove_sector, precommit_meta_data_from_deals, provider_settle_deal_payments, - sector_deadline, submit_windowed_post, verifreg_add_client, verifreg_add_verifier, - verifreg_extend_claim_terms, verifreg_remove_expired_allocations, + invariant_failure_patterns, make_piece_manifests_from_deal_ids, market_add_balance, + market_pending_deal_allocations, market_publish_deal, miner_extend_sector_expiration2, + miner_precommit_one_sector_v2, miner_prove_sector, precommit_meta_data_from_deals, + provider_settle_deal_payments, sector_deadline, submit_windowed_post, verifreg_add_client, + verifreg_add_verifier, verifreg_extend_claim_terms, verifreg_remove_expired_allocations, }; /// Tests a scenario involving a verified deal from the built-in market, with associated @@ -102,14 +108,20 @@ pub fn verified_claim_scenario_test(v: &dyn VM) { &miner_id, seal_proof, sector_number, - precommit_meta_data_from_deals(v, &deals, seal_proof), + precommit_meta_data_from_deals(v, &deals, seal_proof, false), true, deal_start + sector_term, ); // Advance time to max seal duration and prove the sector advance_by_deadline_to_epoch(v, &miner_id, deal_start); - miner_prove_sector(v, &worker, &miner_id, sector_number); + miner_prove_sector( + v, + &worker, + &miner_id, + sector_number, + make_piece_manifests_from_deal_ids(v, deals.clone()), + ); // Trigger cron to validate the prove commit cron_tick(v); @@ -562,7 +574,7 @@ pub fn deal_passes_claim_fails_test(v: &dyn VM) { &miner_id, seal_proof, sector_number_a, - precommit_meta_data_from_deals(v, &[deal], seal_proof), + precommit_meta_data_from_deals(v, &[deal], seal_proof, false), true, sector_start + sector_term, ); @@ -573,15 +585,50 @@ pub fn deal_passes_claim_fails_test(v: &dyn VM) { &miner_id, seal_proof, sector_number_b, - precommit_meta_data_from_deals(v, &[bad_deal], seal_proof), + precommit_meta_data_from_deals(v, &[bad_deal], seal_proof, false), false, sector_start + sector_term, ); // Advance time and prove the sector advance_by_deadline_to_epoch(v, &miner_id, sector_start); - miner_prove_sector(v, &worker, &miner_id, sector_number_a); - miner_prove_sector(v, &worker, &miner_id, sector_number_b); + // ProveCommit3 fails on sector b because allocation is expired + let failing_prove_commit_params = ProveCommitSectors3Params { + sector_activations: vec![ + SectorActivationManifest { + sector_number: sector_number_b, + pieces: make_piece_manifests_from_deal_ids(v, vec![bad_deal]), + }, + SectorActivationManifest { + sector_number: sector_number_a, + pieces: make_piece_manifests_from_deal_ids(v, vec![deal]), + }, + ], + sector_proofs: vec![vec![].into(), vec![].into()], + aggregate_proof: RawBytes::default(), + aggregate_proof_type: None, + require_activation_success: true, // + require_notification_success: true, + }; + apply_code( + v, + &worker, + &miner_id, + &TokenAmount::zero(), + fil_actor_miner::Method::ProveCommitSectors3 as u64, + Some(failing_prove_commit_params), + ExitCode::USR_ILLEGAL_ARGUMENT, + ); + let worker_id = v.resolve_id_address(&worker).unwrap().id().unwrap(); + ExpectInvocation { + from: worker_id, + to: miner_id, + method: fil_actor_miner::Method::ProveCommitSectors3 as u64, + exit_code: ExitCode::USR_ILLEGAL_ARGUMENT, + ..Default::default() + } + .matches(v.take_invocations().last().unwrap()); + cron_tick(v); v.set_epoch(v.epoch() + 1); diff --git a/integration_tests/src/tests/verifreg_remove_datacap_test.rs b/integration_tests/src/tests/verifreg_remove_datacap_test.rs index 599d8d4d6..0112fcb8c 100644 --- a/integration_tests/src/tests/verifreg_remove_datacap_test.rs +++ b/integration_tests/src/tests/verifreg_remove_datacap_test.rs @@ -84,7 +84,7 @@ pub fn remove_datacap_simple_successful_path_test(v: &dyn VM) { subinvocs: None, ..Default::default() }]), - events: vec![verifier_balance_event(verifier1.id().unwrap(), verifier_datacap)], + events: Some(vec![verifier_balance_event(verifier1.id().unwrap(), verifier_datacap)]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); diff --git a/integration_tests/src/util/mod.rs b/integration_tests/src/util/mod.rs index 5f0ecc1d5..487c48544 100644 --- a/integration_tests/src/util/mod.rs +++ b/integration_tests/src/util/mod.rs @@ -12,6 +12,7 @@ use fil_actor_reward::State as RewardState; use fil_actor_verifreg::{Claim, ClaimID, State as VerifregState}; use fil_actors_runtime::cbor::serialize; use fil_actors_runtime::test_utils::make_piece_cid; +use fil_actors_runtime::ActorError; use fil_actors_runtime::{ parse_uint_key, runtime::Policy, MessageAccumulator, REWARD_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR, @@ -168,7 +169,20 @@ pub fn get_beneficiary(v: &dyn VM, from: &Address, m_addr: &Address) -> GetBenef .unwrap() } +pub fn market_pending_deal_allocations_raw( + v: &dyn VM, + deals: &[DealID], +) -> Result, ActorError> { + let mut st: MarketState = get_state(v, &STORAGE_MARKET_ACTOR_ADDR).unwrap(); + let bs = &DynBlockstore::wrap(v.blockstore()); + st.get_pending_deal_allocation_ids(bs, deals) +} + pub fn market_pending_deal_allocations(v: &dyn VM, deals: &[DealID]) -> Vec { + market_pending_deal_allocations_raw(v, deals).unwrap() +} + +pub fn market_maybe_pending_deal_allocations(v: &dyn VM, deals: &[DealID]) -> Vec { let mut st: MarketState = get_state(v, &STORAGE_MARKET_ACTOR_ADDR).unwrap(); let bs = &DynBlockstore::wrap(v.blockstore()); st.get_pending_deal_allocation_ids(bs, deals).unwrap() diff --git a/integration_tests/src/util/workflows.rs b/integration_tests/src/util/workflows.rs index 19ac93596..5266efeb3 100644 --- a/integration_tests/src/util/workflows.rs +++ b/integration_tests/src/util/workflows.rs @@ -39,12 +39,13 @@ use fil_actor_market::{ }; use fil_actor_miner::{ aggregate_pre_commit_network_fee, aggregate_prove_commit_network_fee, - max_prove_commit_duration, ChangeBeneficiaryParams, CompactCommD, DeadlineInfo, - DeclareFaultsRecoveredParams, ExpirationExtension2, ExtendSectorExpiration2Params, - Method as MinerMethod, PoStPartition, PowerPair, PreCommitSectorBatchParams2, - ProveCommitAggregateParams, ProveCommitSectorParams, RecoveryDeclaration, SectorClaim, - SectorPreCommitInfo, SectorPreCommitOnChainInfo, State as MinerState, SubmitWindowedPoStParams, - WithdrawBalanceParams, WithdrawBalanceReturn, + max_prove_commit_duration, ChangeBeneficiaryParams, CompactCommD, DataActivationNotification, + DeadlineInfo, DeclareFaultsRecoveredParams, ExpirationExtension2, + ExtendSectorExpiration2Params, Method as MinerMethod, PieceActivationManifest, PoStPartition, + PowerPair, PreCommitSectorBatchParams2, ProveCommitAggregateParams, ProveCommitSectors3Params, + RecoveryDeclaration, SectorActivationManifest, SectorClaim, SectorPreCommitInfo, + SectorPreCommitOnChainInfo, State as MinerState, SubmitWindowedPoStParams, + VerifiedAllocationKey, WithdrawBalanceParams, WithdrawBalanceReturn, }; use fil_actor_multisig::Method as MultisigMethod; use fil_actor_multisig::ProposeParams; @@ -86,6 +87,7 @@ use crate::expects::Expect; use crate::*; use super::make_bitfield; +use super::market_pending_deal_allocations_raw; use super::miner_dline_info; use super::sector_deadline; @@ -165,14 +167,22 @@ pub fn miner_prove_sector( worker: &Address, miner_id: &Address, sector_number: SectorNumber, + manifests: Vec, ) { - let prove_commit_params = ProveCommitSectorParams { sector_number, proof: vec![].into() }; + let prove_commit_params = ProveCommitSectors3Params { + sector_activations: vec![SectorActivationManifest { sector_number, pieces: manifests }], + sector_proofs: vec![vec![].into()], + aggregate_proof: RawBytes::default(), + aggregate_proof_type: None, + require_activation_success: true, + require_notification_success: true, + }; apply_ok( v, worker, miner_id, &TokenAmount::zero(), - MinerMethod::ProveCommitSector as u64, + MinerMethod::ProveCommitSectors3 as u64, Some(prove_commit_params), ); @@ -181,13 +191,7 @@ pub fn miner_prove_sector( ExpectInvocation { from: worker_id, to: *miner_id, - method: MinerMethod::ProveCommitSector as u64, - subinvocs: Some(vec![ExpectInvocation { - from: miner_id.id().unwrap(), - to: STORAGE_POWER_ACTOR_ADDR, - method: PowerMethod::SubmitPoRepForBulkVerify as u64, - ..Default::default() - }]), + method: MinerMethod::ProveCommitSectors3 as u64, ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -297,7 +301,7 @@ pub fn precommit_sectors_v2_expect_code( .unwrap(), ), subinvocs: Some(invocs), - events, + events: Some(events), ..Default::default() }; expect.matches(v.take_invocations().last().unwrap()); @@ -352,6 +356,7 @@ pub fn precommit_meta_data_from_deals( v: &dyn VM, deal_ids: &[u64], seal_proof: RegisteredSealProof, + include_ids: bool, ) -> PrecommitMetadata { let state: MarketState = get_state(v, &STORAGE_MARKET_ACTOR_ADDR).unwrap(); let pieces: Vec = deal_ids @@ -362,8 +367,9 @@ pub fn precommit_meta_data_from_deals( }) .collect(); + let ids = if include_ids { deal_ids.to_vec() } else { vec![] }; PrecommitMetadata { - deals: deal_ids.to_vec(), + deals: ids, commd: CompactCommD::of( v.primitives().compute_unsealed_sector_cid(seal_proof, &pieces).unwrap(), ), @@ -437,7 +443,7 @@ pub fn prove_commit_sectors( Expect::power_update_pledge(miner_id, None), Expect::burn(miner_id, Some(expected_fee)), ]), - events, + events: Some(events), ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -803,7 +809,7 @@ pub fn verifreg_add_verifier(v: &dyn VM, verifier: &Address, data_cap: StoragePo DATACAP_TOKEN_ACTOR_ADDR, *verifier, )]), - events: vec![verifier_balance_event(verifier.id().unwrap(), data_cap)], + events: Some(vec![verifier_balance_event(verifier.id().unwrap(), data_cap)]), ..Default::default() }]), ..Default::default() @@ -863,7 +869,10 @@ pub fn verifreg_add_client( )]), ..Default::default() }]), - events: vec![verifier_balance_event(verifier.id().unwrap(), updated_verifier_balance)], + events: Some(vec![verifier_balance_event( + verifier.id().unwrap(), + updated_verifier_balance, + )]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -955,7 +964,7 @@ pub fn verifreg_remove_expired_allocations( )]), ..Default::default() }]), - events: expected_events, + events: Some(expected_events), ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -1217,12 +1226,12 @@ pub fn market_publish_deal( }) .unwrap(), ), - events: vec![Expect::build_verifreg_event( + events: Some(vec![Expect::build_verifreg_event( "allocation", alloc_id, deal_client.id().unwrap(), miner_id.id().unwrap(), - )], + )]), ..Default::default() }]), ..Default::default() @@ -1239,12 +1248,12 @@ pub fn market_publish_deal( to: STORAGE_MARKET_ACTOR_ADDR, method: MarketMethod::PublishStorageDeals as u64, subinvocs: Some(expect_publish_invocs), - events: vec![Expect::build_market_event( + events: Some(vec![Expect::build_market_event( "deal-published", ret.ids[0], deal_client.id().unwrap(), miner_id.id().unwrap(), - )], + )]), ..Default::default() } .matches(v.take_invocations().last().unwrap()); @@ -1298,3 +1307,31 @@ pub fn get_deal_weights( } (DealWeight::from(deal.piece_size.0 * duration as u64), DealWeight::zero()) } + +pub fn make_piece_manifests_from_deal_ids( + v: &dyn VM, + deal_ids: Vec, +) -> Vec { + let mut piece_manifests = vec![]; + for deal_id in deal_ids { + let deal = get_deal(v, deal_id); + let alloc_key = match market_pending_deal_allocations_raw(v, &[deal_id]) { + Ok(alloc_ids) => Some(VerifiedAllocationKey { + id: *alloc_ids.first().unwrap(), + client: deal.client.id().unwrap(), + }), + Err(_) => None, + }; + + piece_manifests.push(PieceActivationManifest { + cid: deal.piece_cid, + size: deal.piece_size, + verified_allocation_key: alloc_key, + notify: vec![DataActivationNotification { + address: STORAGE_MARKET_ACTOR_ADDR, + payload: serialize(&deal_id, "dealid").unwrap(), + }], + }); + } + piece_manifests +} diff --git a/vm_api/src/trace.rs b/vm_api/src/trace.rs index 34ecd39e7..87395ee9e 100644 --- a/vm_api/src/trace.rs +++ b/vm_api/src/trace.rs @@ -52,7 +52,7 @@ pub struct ExpectInvocation { pub exit_code: ExitCode, pub return_value: Option, pub subinvocs: Option>, - pub events: Vec, + pub events: Option>, } impl ExpectInvocation { @@ -116,25 +116,26 @@ impl ExpectInvocation { } // match emitted events - let emitted_events = &invoc.events; - let expected_events = &self.events; - assert_eq!( - emitted_events.len(), - expected_events.len(), - "{} {} emitted={}, expected={}, {:?}, {:?}", - id, - "length of expected and emitted events do not match", - emitted_events.len(), - expected_events.len(), - emitted_events, - expected_events - ); + if let Some(expected_events) = &self.events { + let emitted_events = &invoc.events; + assert_eq!( + emitted_events.len(), + expected_events.len(), + "{} {} emitted={}, expected={}, {:?}, {:?}", + id, + "length of expected and emitted events do not match", + emitted_events.len(), + expected_events.len(), + emitted_events, + expected_events + ); - // use the zip method to iterate over the emitted events and expected_events - // vectors at the same time - for (emitted, expected) in emitted_events.iter().zip(expected_events.iter()) { - // only try to match if required fields match - assert_eq!(*emitted, *expected); + // use the zip method to iterate over the emitted events and expected_events + // vectors at the same time + for (emitted, expected) in emitted_events.iter().zip(expected_events.iter()) { + // only try to match if required fields match + assert_eq!(*emitted, *expected); + } } if let Some(expect_subinvocs) = &self.subinvocs { @@ -207,7 +208,7 @@ impl Default for ExpectInvocation { exit_code: ExitCode::OK, return_value: None, subinvocs: None, - events: vec![], + events: None, } } }