use std::cmp;
use cid::{Cid, Version};
use fil_actors_shared::v12::network::*;
use fil_actors_shared::v12::runtime::Policy;
use fil_actors_shared::v12::{DealWeight, EXPECTED_LEADERS_PER_EPOCH};
use fvm_shared4::bigint::{BigInt, Integer};
use fvm_shared4::clock::ChainEpoch;
use fvm_shared4::commcid::{FIL_COMMITMENT_SEALED, POSEIDON_BLS12_381_A1_FC1};
use fvm_shared4::econ::TokenAmount;
use fvm_shared4::sector::{
RegisteredPoStProof, RegisteredSealProof, SectorQuality, SectorSize, StoragePower,
};
use lazy_static::lazy_static;
use super::types::SectorOnChainInfo;
use super::{PowerPair, BASE_REWARD_FOR_DISPUTED_WINDOW_POST};
pub const SECTOR_QUALITY_PRECISION: i64 = 20;
lazy_static! {
pub static ref QUALITY_BASE_MULTIPLIER: BigInt = BigInt::from(10);
pub static ref DEAL_WEIGHT_MULTIPLIER: BigInt = BigInt::from(10);
pub static ref VERIFIED_DEAL_WEIGHT_MULTIPLIER: BigInt = BigInt::from(100);
}
pub fn load_partitions_sectors_max(policy: &Policy, partition_sector_count: u64) -> u64 {
cmp::min(
policy.addressed_sectors_max / partition_sector_count,
policy.addressed_partitions_max,
)
}
pub fn is_sealed_sector(c: &Cid) -> bool {
c.version() == Version::V1
&& c.codec() == FIL_COMMITMENT_SEALED
&& c.hash().code() == POSEIDON_BLS12_381_A1_FC1
&& c.hash().size() == 32
}
pub fn can_pre_commit_seal_proof(policy: &Policy, proof: RegisteredSealProof) -> bool {
policy.valid_pre_commit_proof_type.contains(proof)
}
pub fn can_extend_seal_proof_type(_proof: RegisteredSealProof) -> bool {
true
}
pub fn max_prove_commit_duration(
policy: &Policy,
proof: RegisteredSealProof,
) -> Option<ChainEpoch> {
use RegisteredSealProof::*;
match proof {
StackedDRG32GiBV1 | StackedDRG2KiBV1 | StackedDRG8MiBV1 | StackedDRG512MiBV1
| StackedDRG64GiBV1 => Some(EPOCHS_IN_DAY + policy.pre_commit_challenge_delay),
StackedDRG32GiBV1P1
| StackedDRG64GiBV1P1
| StackedDRG512MiBV1P1
| StackedDRG8MiBV1P1
| StackedDRG2KiBV1P1
| StackedDRG32GiBV1P1_Feat_SyntheticPoRep
| StackedDRG64GiBV1P1_Feat_SyntheticPoRep
| StackedDRG512MiBV1P1_Feat_SyntheticPoRep
| StackedDRG8MiBV1P1_Feat_SyntheticPoRep
| StackedDRG2KiBV1P1_Feat_SyntheticPoRep => {
Some(30 * EPOCHS_IN_DAY + policy.pre_commit_challenge_delay)
}
_ => None,
}
}
pub fn seal_proof_sector_maximum_lifetime(proof: RegisteredSealProof) -> Option<ChainEpoch> {
use RegisteredSealProof::*;
match proof {
StackedDRG32GiBV1 | StackedDRG2KiBV1 | StackedDRG8MiBV1 | StackedDRG512MiBV1
| StackedDRG64GiBV1 => Some(EPOCHS_IN_DAY * 540),
StackedDRG32GiBV1P1
| StackedDRG2KiBV1P1
| StackedDRG8MiBV1P1
| StackedDRG512MiBV1P1
| StackedDRG64GiBV1P1
| StackedDRG32GiBV1P1_Feat_SyntheticPoRep
| StackedDRG2KiBV1P1_Feat_SyntheticPoRep
| StackedDRG8MiBV1P1_Feat_SyntheticPoRep
| StackedDRG512MiBV1P1_Feat_SyntheticPoRep
| StackedDRG64GiBV1P1_Feat_SyntheticPoRep => Some(EPOCHS_IN_YEAR * 5),
_ => None,
}
}
pub const MIN_SECTOR_EXPIRATION: i64 = 180 * EPOCHS_IN_DAY;
pub fn quality_for_weight(
size: SectorSize,
duration: ChainEpoch,
deal_weight: &DealWeight,
verified_weight: &DealWeight,
) -> SectorQuality {
let sector_space_time = BigInt::from(size as u64) * BigInt::from(duration);
let total_deal_space_time = deal_weight + verified_weight;
let weighted_base_space_time =
(§or_space_time - total_deal_space_time) * &*QUALITY_BASE_MULTIPLIER;
let weighted_deal_space_time = deal_weight * &*DEAL_WEIGHT_MULTIPLIER;
let weighted_verified_space_time = verified_weight * &*VERIFIED_DEAL_WEIGHT_MULTIPLIER;
let weighted_sum_space_time =
weighted_base_space_time + weighted_deal_space_time + weighted_verified_space_time;
let scaled_up_weighted_sum_space_time: SectorQuality =
weighted_sum_space_time << SECTOR_QUALITY_PRECISION;
scaled_up_weighted_sum_space_time
.div_floor(§or_space_time)
.div_floor(&QUALITY_BASE_MULTIPLIER)
}
pub fn qa_power_max(size: SectorSize) -> StoragePower {
(BigInt::from(size as u64) * &*VERIFIED_DEAL_WEIGHT_MULTIPLIER)
.div_floor(&QUALITY_BASE_MULTIPLIER)
}
pub fn qa_power_for_weight(
size: SectorSize,
duration: ChainEpoch,
deal_weight: &DealWeight,
verified_weight: &DealWeight,
) -> StoragePower {
let quality = quality_for_weight(size, duration, deal_weight, verified_weight);
(BigInt::from(size as u64) * quality) >> SECTOR_QUALITY_PRECISION
}
pub fn qa_power_for_sector(size: SectorSize, sector: &SectorOnChainInfo) -> StoragePower {
let duration = sector.expiration - sector.power_base_epoch;
qa_power_for_weight(
size,
duration,
§or.deal_weight,
§or.verified_deal_weight,
)
}
pub fn sector_deals_max(policy: &Policy, size: SectorSize) -> u64 {
cmp::max(256, size as u64 / policy.deal_limit_denominator)
}
pub struct VestSpec {
pub initial_delay: ChainEpoch,
pub vest_period: ChainEpoch,
pub step_duration: ChainEpoch,
pub quantization: ChainEpoch,
}
pub const REWARD_VESTING_SPEC: VestSpec = VestSpec {
initial_delay: 0, vest_period: 180 * EPOCHS_IN_DAY, step_duration: EPOCHS_IN_DAY, quantization: 12 * EPOCHS_IN_HOUR, };
pub const CONSENSUS_FAULT_REPORTER_DEFAULT_SHARE: u64 = 4;
pub fn reward_for_consensus_slash_report(epoch_reward: &TokenAmount) -> TokenAmount {
epoch_reward.div_floor(EXPECTED_LEADERS_PER_EPOCH * CONSENSUS_FAULT_REPORTER_DEFAULT_SHARE)
}
pub fn reward_for_disputed_window_post(
_proof_type: RegisteredPoStProof,
_disputed_power: PowerPair,
) -> TokenAmount {
BASE_REWARD_FOR_DISPUTED_WINDOW_POST.clone()
}