Skip to content

Commit

Permalink
Test FaultySectors error with invalid PoSt.
Browse files Browse the repository at this point in the history
  • Loading branch information
porcuquine committed Sep 7, 2020
1 parent e1966db commit 0562d44
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 7 deletions.
2 changes: 2 additions & 0 deletions storage-proofs/core/src/merkle/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ impl<

let proof = self.inner.gen_cached_proof(i, rows_to_discard)?;

debug_assert!(proof.validate::<H::Function>().expect("validate failed"));

MerkleProof::try_from_proof(proof)
}

Expand Down
222 changes: 215 additions & 7 deletions storage-proofs/post/src/fallback/vanilla.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::BTreeSet;
use std::marker::PhantomData;

use anyhow::ensure;
Expand Down Expand Up @@ -297,7 +298,9 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree>
);

let mut partition_proofs = Vec::new();
let mut faulty_sectors = Vec::new();

// Use `BTreeSet` so failure result will be canonically ordered (sorted).
let mut faulty_sectors = BTreeSet::new();

for (j, (pub_sectors_chunk, priv_sectors_chunk)) in pub_inputs
.sectors
Expand Down Expand Up @@ -345,6 +348,7 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree>
);
let valid = if let Ok(proof) = &proof {
proof.validate(challenged_leaf_start as usize)
&& proof.root() == priv_sector.comm_r_last
} else {
false
};
Expand All @@ -357,8 +361,12 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree>
.collect::<Result<Vec<_>>>()?
{
match proof_or_fault {
ProofOrFault::Proof(proof) => inclusion_proofs.push(proof?),
ProofOrFault::Fault(sector_id) => faulty_sectors.push(sector_id),
ProofOrFault::Proof(proof) => {
inclusion_proofs.push(proof?);
}
ProofOrFault::Fault(sector_id) => {
faulty_sectors.insert(sector_id);
}
}
}

Expand All @@ -378,10 +386,9 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree>
partition_proofs.push(Proof { sectors: proofs });
}

ensure!(
faulty_sectors.is_empty(),
Error::FaultySectors(faulty_sectors)
);
ensure!(faulty_sectors.is_empty(), {
Error::FaultySectors(faulty_sectors.into_iter().collect())
});

Ok(partition_proofs)
}
Expand Down Expand Up @@ -593,102 +600,303 @@ mod tests {
assert!(is_valid);
}

fn test_invalid_fallback_post<Tree: MerkleTreeTrait>(
total_sector_count: usize,
sector_count: usize,
partitions: usize,
) where
Tree::Store: 'static,
{
let rng = &mut XorShiftRng::from_seed(crate::TEST_SEED);

let leaves = 64 * get_base_tree_count::<Tree>();
let sector_size = leaves * NODE_SIZE;

let pub_params = PublicParams {
sector_size: sector_size as u64,
challenge_count: 10,
sector_count,
};

let randomness = <Tree::Hasher as Hasher>::Domain::random(rng);
let prover_id = <Tree::Hasher as Hasher>::Domain::random(rng);

let temp_dir = tempfile::tempdir().unwrap();
let temp_path = temp_dir.path();

let mut pub_sectors = Vec::new();
let mut priv_sectors = Vec::new();

let mut trees = Vec::new();

let mut faulty_sectors = Vec::<SectorId>::new();

for _i in 0..total_sector_count {
let (_data, tree) =
generate_tree::<Tree, _>(rng, leaves, Some(temp_path.to_path_buf()));
trees.push(tree);
}

let faulty_denominator = 3;

let (_data, wrong_tree) =
generate_tree::<Tree, _>(rng, leaves, Some(temp_path.to_path_buf()));

for (i, tree) in trees.iter().enumerate() {
let make_faulty = i % faulty_denominator == 0;

let comm_c = <Tree::Hasher as Hasher>::Domain::random(rng);
let comm_r_last = tree.root();

priv_sectors.push(PrivateSector {
tree: if make_faulty { &wrong_tree } else { tree },
comm_c,
comm_r_last,
});

let comm_r = <Tree::Hasher as Hasher>::Function::hash2(&comm_c, &comm_r_last);

if make_faulty {
faulty_sectors.push((i as u64).into());
}

pub_sectors.push(PublicSector {
id: (i as u64).into(),
comm_r,
});
}

let pub_inputs = PublicInputs {
randomness,
prover_id,
sectors: &pub_sectors,
k: None,
};

let priv_inputs = PrivateInputs::<Tree> {
sectors: &priv_sectors[..],
};

let proof = FallbackPoSt::<Tree>::prove_all_partitions(
&pub_params,
&pub_inputs,
&priv_inputs,
partitions,
);

match proof {
Ok(proof) => {
let is_valid =
FallbackPoSt::<Tree>::verify_all_partitions(&pub_params, &pub_inputs, &proof)
.expect("verification failed");
assert!(!is_valid, "PoSt returned a valid proof with invalid input");
}
Err(e) => match e.downcast::<Error>() {
Err(_) => panic!("failed to downcast to Error"),
Ok(Error::FaultySectors(sector_ids)) => assert_eq!(faulty_sectors, sector_ids),
Ok(_) => panic!("PoSt failed to return FaultySector error."),
_ => (),
},
};
}

#[test]
fn fallback_post_pedersen_single_partition_matching_base_8() {
test_fallback_post::<LCTree<PedersenHasher, U8, U0, U0>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_pedersen_single_partition_matching_base_8() {
test_invalid_fallback_post::<LCTree<PedersenHasher, U8, U0, U0>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_matching_base_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_matching_base_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_smaller_base_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(3, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_smaller_base_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(3, 5, 1);
}

#[test]
fn fallback_post_poseidon_two_partitions_matching_base_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(4, 2, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_matching_base_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(4, 2, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_smaller_base_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(5, 3, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_smaller_base_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U0, U0>>(5, 3, 2);
}

#[test]
fn fallback_post_pedersen_single_partition_matching_sub_8_4() {
test_fallback_post::<LCTree<PedersenHasher, U8, U4, U0>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_pedersen_single_partition_matching_sub_8_4() {
test_invalid_fallback_post::<LCTree<PedersenHasher, U8, U4, U0>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_matching_sub_8_4() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_matching_sub_8_4() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_smaller_sub_8_4() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(3, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_smaller_sub_8_4() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(3, 5, 1);
}

#[test]
fn fallback_post_poseidon_two_partitions_matching_sub_8_4() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(4, 2, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_matching_sub_8_4() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(4, 2, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_matching_sub_8_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U8, U0>>(4, 2, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_matching_sub_8_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U8, U0>>(4, 2, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_smaller_sub_8_4() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(5, 3, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_smaller_sub_8_4() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U0>>(5, 3, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_smaller_sub_8_8() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U8, U0>>(5, 3, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_smaller_sub_8_8() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U8, U0>>(5, 3, 2);
}

#[test]
fn fallback_post_pedersen_single_partition_matching_top_8_4_2() {
test_fallback_post::<LCTree<PedersenHasher, U8, U4, U2>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_pedersen_single_partition_matching_top_8_4_2() {
test_invalid_fallback_post::<LCTree<PedersenHasher, U8, U4, U2>>(5, 5, 1);
}

#[test]
fn fallback_post_pedersen_single_partition_matching_top_8_8_2() {
test_fallback_post::<LCTree<PedersenHasher, U8, U8, U2>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_pedersen_single_partition_matching_top_8_8_2() {
test_invalid_fallback_post::<LCTree<PedersenHasher, U8, U8, U2>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_matching_top_8_4_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_matching_top_8_4_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_matching_top_8_8_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U8, U2>>(5, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_matching_top_8_8_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U8, U2>>(5, 5, 1);
}

#[test]
fn fallback_post_poseidon_single_partition_smaller_top_8_4_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(3, 5, 1);
}

#[test]
fn invalid_fallback_post_poseidon_single_partition_smaller_top_8_4_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(3, 5, 1);
}

#[test]
fn fallback_post_poseidon_two_partitions_matching_top_8_4_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(4, 2, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_matching_top_8_4_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(4, 2, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_smaller_top_8_4_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(5, 3, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_smaller_top_8_4_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U4, U2>>(5, 3, 2);
}

#[test]
fn fallback_post_poseidon_two_partitions_smaller_top_8_8_2() {
test_fallback_post::<LCTree<PoseidonHasher, U8, U8, U2>>(5, 3, 2);
}

#[test]
fn invalid_fallback_post_poseidon_two_partitions_smaller_top_8_8_2() {
test_invalid_fallback_post::<LCTree<PoseidonHasher, U8, U8, U2>>(5, 3, 2);
}
}

0 comments on commit 0562d44

Please sign in to comment.