use blstrs::Scalar as Fr;
use filecoin_hashers::{
poseidon::{PoseidonDomain, PoseidonHasher},
sha256::{Sha256Domain, Sha256Hasher},
};
use generic_array::typenum::{Unsigned, U0, U2, U8};
use lazy_static::lazy_static;
use merkletree::store::DiskStore;
use neptune::{
hash_type::{CType, HashType},
poseidon::PoseidonConstants,
Strength,
};
use storage_proofs_core::merkle::{BinaryMerkleTree, LCTree, MerkleTreeTrait};
pub const HASH_TYPE_GEN_RANDOMNESS: HashType<Fr, U2> = HashType::Custom(CType::Arbitrary(1));
lazy_static! {
pub static ref POSEIDON_CONSTANTS_GEN_RANDOMNESS: PoseidonConstants::<Fr, U2> =
PoseidonConstants::new_with_strength_and_type(Strength::Standard, HASH_TYPE_GEN_RANDOMNESS);
}
pub const SECTOR_SIZE_1_KIB: usize = 1 << 5;
pub const SECTOR_SIZE_2_KIB: usize = 1 << 6;
pub const SECTOR_SIZE_4_KIB: usize = 1 << 7;
pub const SECTOR_SIZE_8_KIB: usize = 1 << 8;
pub const SECTOR_SIZE_16_KIB: usize = 1 << 9;
pub const SECTOR_SIZE_32_KIB: usize = 1 << 10;
pub const SECTOR_SIZE_8_MIB: usize = 1 << 18;
pub const SECTOR_SIZE_16_MIB: usize = 1 << 19;
pub const SECTOR_SIZE_512_MIB: usize = 1 << 24;
pub const SECTOR_SIZE_32_GIB: usize = 1 << 30;
pub const SECTOR_SIZE_64_GIB: usize = 1 << 31;
pub const ALLOWED_SECTOR_SIZES: [usize; 11] = [
SECTOR_SIZE_1_KIB,
SECTOR_SIZE_2_KIB,
SECTOR_SIZE_4_KIB,
SECTOR_SIZE_8_KIB,
SECTOR_SIZE_16_KIB,
SECTOR_SIZE_32_KIB,
SECTOR_SIZE_8_MIB,
SECTOR_SIZE_16_MIB,
SECTOR_SIZE_512_MIB,
SECTOR_SIZE_32_GIB,
SECTOR_SIZE_64_GIB,
];
pub type TreeD = BinaryMerkleTree<TreeDHasher>;
pub type TreeDHasher = Sha256Hasher;
pub type TreeDDomain = Sha256Domain;
pub type TreeDStore = DiskStore<TreeDDomain>;
pub type TreeDArity = U2;
pub type TreeRHasher = PoseidonHasher;
pub type TreeRDomain = PoseidonDomain;
pub type TreeRBaseTree = LCTree<TreeRHasher, U8, U0, U0>;
pub const fn partition_count(sector_nodes: usize) -> usize {
if sector_nodes <= SECTOR_SIZE_8_KIB {
1
} else if sector_nodes <= SECTOR_SIZE_32_KIB {
2
} else if sector_nodes <= SECTOR_SIZE_16_MIB {
4
} else {
16
}
}
pub const fn challenge_count(sector_nodes: usize) -> usize {
if sector_nodes <= SECTOR_SIZE_16_MIB {
10
} else {
86
}
}
pub const fn challenge_count_poseidon(sector_nodes: usize) -> usize {
challenge_count(sector_nodes) * partition_count(sector_nodes)
}
pub const fn hs(sector_nodes: usize) -> [usize; 6] {
if sector_nodes <= SECTOR_SIZE_32_KIB {
[1; 6]
} else {
[7, 8, 9, 10, 11, 12]
}
}
pub const fn h_default(sector_nodes: usize) -> usize {
hs(sector_nodes)[3]
}
pub fn h_select(sector_nodes: usize, h: usize) -> u64 {
let h_index = hs(sector_nodes)
.iter()
.position(|h_allowed| *h_allowed == h)
.expect("invalid `h` for sector-size");
1u64 << h_index
}
pub const fn apex_leaf_count(sector_nodes: usize) -> usize {
if sector_nodes <= SECTOR_SIZE_8_KIB {
8
} else {
128
}
}
pub fn validate_tree_r_shape<TreeR: MerkleTreeTrait>(sector_nodes: usize) {
let base_arity = TreeR::Arity::to_usize();
let sub_arity = TreeR::SubTreeArity::to_usize();
let top_arity = TreeR::TopTreeArity::to_usize();
let arities = (base_arity, sub_arity, top_arity);
let arities_expected = match sector_nodes {
SECTOR_SIZE_1_KIB => (8, 4, 0),
SECTOR_SIZE_2_KIB => (8, 0, 0),
SECTOR_SIZE_4_KIB => (8, 2, 0),
SECTOR_SIZE_8_KIB => (8, 4, 0),
SECTOR_SIZE_16_KIB => (8, 8, 0),
SECTOR_SIZE_32_KIB => (8, 8, 2),
SECTOR_SIZE_8_MIB => (8, 0, 0),
SECTOR_SIZE_16_MIB => (8, 2, 0),
SECTOR_SIZE_512_MIB => (8, 0, 0),
SECTOR_SIZE_32_GIB => (8, 8, 0),
SECTOR_SIZE_64_GIB => (8, 8, 2),
_ => unreachable!(),
};
assert_eq!(arities, arities_expected);
}