Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,10 @@ jobs:
- uses: actions/checkout@v1
- name: Lint code for quality and style with Clippy
run: make lint
arbitrary-check:
runs-on: ubuntu-latest
needs: cargo-fmt
steps:
- uses: actions/checkout@v1
- name: Validate state_processing feature arbitrary-fuzz
run: make arbitrary-fuzz
379 changes: 103 additions & 276 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ eth2_ssz = { path = "eth2/utils/ssz" }
eth2_ssz_derive = { path = "eth2/utils/ssz_derive" }
eth2_ssz_types = { path = "eth2/utils/ssz_types" }
eth2_hashing = { path = "eth2/utils/eth2_hashing" }
web3 = { git = "https://github.com/tomusdrw/rust-web3" }
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ lint:
make-ef-tests:
make -C $(EF_TESTS)

# Verifies that state_processing feature arbitrary-fuzz will compile
arbitrary-fuzz:
cargo check --manifest-path=eth2/state_processing/Cargo.toml --features arbitrary-fuzz

# Performs a `cargo` clean and cleans the `ef_tests` directory.
clean:
cargo clean
Expand Down
10 changes: 10 additions & 0 deletions eth2/state_processing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ types = { path = "../types" }
rayon = "1.2.0"
eth2_hashing = { path = "../utils/eth2_hashing" }
int_to_bytes = { path = "../utils/int_to_bytes" }
arbitrary = { version = "0.4.3", features = ["derive"], optional = true }

[features]
fake_crypto = ["bls/fake_crypto"]
arbitrary-fuzz = [
"arbitrary",
"types/arbitrary-fuzz",
"bls/arbitrary",
"merkle_proof/arbitrary",
"eth2_ssz/arbitrary",
"eth2_ssz_types/arbitrary",
"tree_hash/arbitrary",
]
5 changes: 5 additions & 0 deletions eth2/state_processing/src/per_block_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ mod verify_deposit;
mod verify_exit;
mod verify_proposer_slashing;

#[cfg(feature = "arbitrary-fuzz")]
use arbitrary::Arbitrary;

/// The strategy to be used when validating the block's signatures.
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
#[derive(PartialEq, Clone, Copy)]
pub enum BlockSignatureStrategy {
/// Do not validate any signature. Use with caution.
Expand All @@ -45,6 +49,7 @@ pub enum BlockSignatureStrategy {
}

/// The strategy to be used when validating the block's signatures.
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
#[derive(PartialEq, Clone, Copy)]
pub enum VerifySignatures {
/// Validate all signatures encountered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::common::get_attesting_indices;
use safe_arith::SafeArith;
use types::*;

#[cfg(feature = "arbitrary-fuzz")]
use arbitrary::Arbitrary;

/// Sets the boolean `var` on `self` to be true if it is true on `other`. Otherwise leaves `self`
/// as is.
macro_rules! set_self_if_other_is_true {
Expand All @@ -13,6 +16,7 @@ macro_rules! set_self_if_other_is_true {
}

/// The information required to reward a block producer for including an attestation in a block.
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
#[derive(Debug, Clone, Copy)]
pub struct InclusionInfo {
/// The distance between the attestation slot and the slot that attestation was included in a
Expand Down Expand Up @@ -44,6 +48,7 @@ impl InclusionInfo {
}

/// Information required to reward some validator during the current and previous epoch.
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
#[derive(Debug, Default, Clone)]
pub struct ValidatorStatus {
/// True if the validator has been slashed, ever.
Expand Down Expand Up @@ -108,7 +113,9 @@ impl ValidatorStatus {

/// The total effective balances for different sets of validators during the previous and current
/// epochs.

#[derive(Clone, Debug)]
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
pub struct TotalBalances {
/// The effective balance increment from the spec.
effective_balance_increment: u64,
Expand Down Expand Up @@ -165,6 +172,7 @@ impl TotalBalances {

/// Summarised information about validator participation in the _previous and _current_ epochs of
/// some `BeaconState`.
#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))]
#[derive(Debug, Clone)]
pub struct ValidatorStatuses {
/// Information about each individual validator from the state's validator registry.
Expand Down
15 changes: 14 additions & 1 deletion eth2/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ compare_fields_derive = { path = "../utils/compare_fields_derive" }
dirs = "2.0.2"
derivative = "1.0.3"
eth2_interop_keypairs = { path = "../utils/eth2_interop_keypairs" }
ethereum-types = "0.8.0"
ethereum-types = "0.9.1"
eth2_hashing = "0.1.0"
hex = "0.3"
int_to_bytes = { path = "../utils/int_to_bytes" }
Expand All @@ -38,8 +38,21 @@ rand_xorshift = "0.2.0"
cached_tree_hash = { path = "../utils/cached_tree_hash" }
serde_yaml = "0.8.11"
tempfile = "3.1.0"
arbitrary = { version = "0.4", features = ["derive"], optional = true }

[dev-dependencies]
env_logger = "0.7.1"
serde_json = "1.0.41"
criterion = "0.3.0"

[features]
arbitrary-fuzz = [
"arbitrary",
"ethereum-types/arbitrary",
"bls/arbitrary",
"eth2_ssz/arbitrary",
"eth2_ssz_types/arbitrary",
"merkle_proof/arbitrary",
"swap_or_not_shuffle/arbitrary",
"tree_hash/arbitrary",
]
1 change: 1 addition & 0 deletions eth2/types/src/aggregate_and_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash;
/// A Validators aggregate attestation and selection proof.
///
/// Spec v0.10.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, TreeHash)]
#[serde(bound = "T: EthSpec")]
pub struct AggregateAndProof<T: EthSpec> {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub enum Error {
/// Details an attestation that can be slashable.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "T: EthSpec")]
pub struct Attestation<T: EthSpec> {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/attestation_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tree_hash_derive::TreeHash;
/// The data upon which an attestation is based.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug,
Clone,
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/attestation_duty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::*;
use serde_derive::{Deserialize, Serialize};

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize)]
pub struct AttestationDuty {
/// The slot during which the attester must attest.
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/attester_slashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tree_hash_derive::TreeHash;
/// Two conflicting attestations.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "T: EthSpec")]
pub struct AttesterSlashing<T: EthSpec> {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/beacon_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash;
/// A block of the `BeaconChain`.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "T: EthSpec")]
pub struct BeaconBlock<T: EthSpec> {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/beacon_block_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash;
/// The body of a `BeaconChain` block, containing operations.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "T: EthSpec")]
pub struct BeaconBlockBody<T: EthSpec> {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/beacon_block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use tree_hash_derive::TreeHash;
/// A header of a `BeaconBlock`.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
pub struct BeaconBlockHeader {
pub slot: Slot,
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/beacon_committee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl<'a> BeaconCommittee<'a> {
}
}

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Default, Clone, Debug, PartialEq)]
pub struct OwnedBeaconCommittee {
pub slot: Slot,
Expand Down
45 changes: 45 additions & 0 deletions eth2/types/src/beacon_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use self::committee_cache::get_active_validator_indices;
use self::exit_cache::ExitCache;
use crate::test_utils::TestRandom;
use crate::*;

use cached_tree_hash::{CacheArena, CachedTreeHash};
use compare_fields_derive::CompareFields;
use eth2_hashing::hash;
Expand Down Expand Up @@ -102,6 +103,7 @@ impl AllowNextEpoch {
}
}

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub struct BeaconStateHash(Hash256);

Expand Down Expand Up @@ -1155,3 +1157,46 @@ impl From<ArithError> for Error {
Error::ArithError(e)
}
}

#[cfg(feature = "arbitrary-fuzz")]
impl<T: EthSpec> arbitrary::Arbitrary for BeaconState<T> {
Comment thread
kirk-baird marked this conversation as resolved.
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(Self {
genesis_time: u64::arbitrary(u)?,
genesis_validators_root: Hash256::arbitrary(u)?,
slot: Slot::arbitrary(u)?,
fork: Fork::arbitrary(u)?,
latest_block_header: BeaconBlockHeader::arbitrary(u)?,
block_roots: <FixedVector<Hash256, T::SlotsPerHistoricalRoot>>::arbitrary(u)?,
state_roots: <FixedVector<Hash256, T::SlotsPerHistoricalRoot>>::arbitrary(u)?,
historical_roots: <VariableList<Hash256, T::HistoricalRootsLimit>>::arbitrary(u)?,
eth1_data: Eth1Data::arbitrary(u)?,
eth1_data_votes: <VariableList<Eth1Data, T::SlotsPerEth1VotingPeriod>>::arbitrary(u)?,
eth1_deposit_index: u64::arbitrary(u)?,
validators: <VariableList<Validator, T::ValidatorRegistryLimit>>::arbitrary(u)?,
balances: <VariableList<u64, T::ValidatorRegistryLimit>>::arbitrary(u)?,
randao_mixes: <FixedVector<Hash256, T::EpochsPerHistoricalVector>>::arbitrary(u)?,
slashings: <FixedVector<u64, T::EpochsPerSlashingsVector>>::arbitrary(u)?,
previous_epoch_attestations: <VariableList<
PendingAttestation<T>,
T::MaxPendingAttestations,
>>::arbitrary(u)?,
current_epoch_attestations: <VariableList<
PendingAttestation<T>,
T::MaxPendingAttestations,
>>::arbitrary(u)?,
justification_bits: <BitVector<T::JustificationBitsLength>>::arbitrary(u)?,
previous_justified_checkpoint: Checkpoint::arbitrary(u)?,
current_justified_checkpoint: Checkpoint::arbitrary(u)?,
finalized_checkpoint: Checkpoint::arbitrary(u)?,
committee_caches: [
CommitteeCache::arbitrary(u)?,
CommitteeCache::arbitrary(u)?,
CommitteeCache::arbitrary(u)?,
],
pubkey_cache: PubkeyCache::arbitrary(u)?,
exit_cache: ExitCache::arbitrary(u)?,
tree_hash_cache: None,
})
}
}
7 changes: 7 additions & 0 deletions eth2/types/src/beacon_state/committee_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,10 @@ pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> V

active
}

#[cfg(feature = "arbitrary-fuzz")]
impl arbitrary::Arbitrary for CommitteeCache {
fn arbitrary(_u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(Self::default())
}
}
7 changes: 7 additions & 0 deletions eth2/types/src/beacon_state/exit_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,10 @@ impl ExitCache {
Ok(self.exits_per_epoch.get(&epoch).cloned().unwrap_or(0))
}
}

#[cfg(feature = "arbitrary-fuzz")]
impl arbitrary::Arbitrary for ExitCache {
fn arbitrary(_u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(Self::default())
}
}
7 changes: 7 additions & 0 deletions eth2/types/src/beacon_state/pubkey_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@ impl PubkeyCache {
self.map.get(pubkey).copied()
}
}

#[cfg(feature = "arbitrary-fuzz")]
impl arbitrary::Arbitrary for PubkeyCache {
fn arbitrary(_u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(Self::default())
}
}
1 change: 1 addition & 0 deletions eth2/types/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub enum Domain {
/// Holds all the "constants" for a BeaconChain.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct ChainSpec {
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tree_hash_derive::TreeHash;
/// Casper FFG checkpoint, used in attestations.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug,
Clone,
Expand Down
4 changes: 2 additions & 2 deletions eth2/types/src/deposit.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::test_utils::TestRandom;
use crate::*;
use ssz_types::typenum::U33;

use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use ssz_types::typenum::U33;
use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;

Expand All @@ -12,6 +11,7 @@ pub const DEPOSIT_TREE_DEPTH: usize = 32;
/// A deposit to potentially become a beacon chain validator.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
pub struct Deposit {
pub proof: FixedVector<Hash256, U33>,
Expand Down
3 changes: 2 additions & 1 deletion eth2/types/src/deposit_data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::test_utils::TestRandom;
use crate::*;
use bls::{PublicKeyBytes, SignatureBytes};

use bls::{PublicKeyBytes, SignatureBytes};
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
Expand All @@ -10,6 +10,7 @@ use tree_hash_derive::TreeHash;
/// The data supplied by the user to the deposit contract.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
pub struct DepositData {
pub pubkey: PublicKeyBytes,
Expand Down
3 changes: 2 additions & 1 deletion eth2/types/src/deposit_message.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::test_utils::TestRandom;
use crate::*;
use bls::PublicKeyBytes;

use bls::PublicKeyBytes;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
Expand All @@ -10,6 +10,7 @@ use tree_hash_derive::TreeHash;
/// The data supplied by the user to the deposit contract.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
pub struct DepositMessage {
pub pubkey: PublicKeyBytes,
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/enr_fork_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash;
/// a nodes local ENR.
///
/// Spec v0.11
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)]
Expand Down
1 change: 1 addition & 0 deletions eth2/types/src/eth1_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tree_hash_derive::TreeHash;
/// Contains data obtained from the Eth1 chain.
///
/// Spec v0.11.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug,
PartialEq,
Expand Down
Loading