2019-03-08 23:45:28 +00:00
|
|
|
use criterion::Criterion;
|
|
|
|
use criterion::{black_box, Benchmark};
|
2019-03-10 07:31:14 +00:00
|
|
|
use ssz::TreeHash;
|
2019-03-08 23:45:28 +00:00
|
|
|
use state_processing::{
|
|
|
|
per_epoch_processing,
|
|
|
|
per_epoch_processing::{
|
2019-03-14 03:59:00 +00:00
|
|
|
clean_attestations, initialize_validator_statuses, process_crosslinks, process_eth1_data,
|
2019-03-14 01:49:48 +00:00
|
|
|
process_justification, process_rewards_and_penalities, process_validator_registry,
|
|
|
|
update_active_tree_index_roots, update_latest_slashed_balances,
|
2019-03-08 23:45:28 +00:00
|
|
|
},
|
|
|
|
};
|
2019-03-11 00:17:27 +00:00
|
|
|
use types::test_utils::TestingBeaconStateBuilder;
|
2019-03-14 01:49:48 +00:00
|
|
|
use types::*;
|
2019-03-08 23:45:28 +00:00
|
|
|
|
2019-03-10 23:56:31 +00:00
|
|
|
pub const BENCHING_SAMPLE_SIZE: usize = 10;
|
2019-03-10 06:48:26 +00:00
|
|
|
pub const SMALL_BENCHING_SAMPLE_SIZE: usize = 10;
|
|
|
|
|
2019-03-08 23:45:28 +00:00
|
|
|
/// Run the benchmarking suite on a foundation spec with 16,384 validators.
|
2019-03-12 03:39:16 +00:00
|
|
|
pub fn bench_epoch_processing_n_validators(c: &mut Criterion, validator_count: usize) {
|
2019-03-08 23:45:28 +00:00
|
|
|
let spec = ChainSpec::foundation();
|
|
|
|
|
2019-03-12 03:39:16 +00:00
|
|
|
let mut builder =
|
|
|
|
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec);
|
2019-03-09 03:11:49 +00:00
|
|
|
|
|
|
|
// Set the state to be just before an epoch transition.
|
|
|
|
let target_slot = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch);
|
|
|
|
builder.teleport_to_slot(target_slot, &spec);
|
|
|
|
|
|
|
|
// Builds all caches; benches will not contain shuffling/committee building times.
|
|
|
|
builder.build_caches(&spec).unwrap();
|
|
|
|
|
|
|
|
// Inserts one attestation with full participation for each committee able to include an
|
|
|
|
// attestation in this state.
|
2019-03-08 23:45:28 +00:00
|
|
|
builder.insert_attestations(&spec);
|
2019-03-09 03:11:49 +00:00
|
|
|
|
|
|
|
let (state, _keypairs) = builder.build();
|
2019-03-08 23:45:28 +00:00
|
|
|
|
2019-03-10 02:38:57 +00:00
|
|
|
// Assert that the state has an attestations for each committee that is able to include an
|
|
|
|
// attestation in the state.
|
2019-03-08 23:45:28 +00:00
|
|
|
let committees_per_epoch = spec.get_epoch_committee_count(validator_count);
|
|
|
|
let committees_per_slot = committees_per_epoch / spec.slots_per_epoch;
|
|
|
|
let previous_epoch_attestations = committees_per_epoch;
|
|
|
|
let current_epoch_attestations =
|
|
|
|
committees_per_slot * (spec.slots_per_epoch - spec.min_attestation_inclusion_delay);
|
|
|
|
assert_eq!(
|
|
|
|
state.latest_attestations.len() as u64,
|
2019-03-10 02:38:57 +00:00
|
|
|
previous_epoch_attestations + current_epoch_attestations,
|
|
|
|
"The state should have an attestation for each committee."
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// Assert that each attestation in the state has full participation.
|
|
|
|
let committee_size = validator_count / committees_per_epoch as usize;
|
|
|
|
for a in &state.latest_attestations {
|
2019-03-10 02:38:57 +00:00
|
|
|
assert_eq!(
|
|
|
|
a.aggregation_bitfield.num_set_bits(),
|
|
|
|
committee_size,
|
|
|
|
"Each attestation in the state should have full participation"
|
|
|
|
);
|
2019-03-08 23:45:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assert that we will run the first arm of process_rewards_and_penalities
|
|
|
|
let epochs_since_finality = state.next_epoch(&spec) - state.finalized_epoch;
|
2019-03-10 02:38:57 +00:00
|
|
|
assert_eq!(
|
|
|
|
epochs_since_finality, 4,
|
|
|
|
"Epochs since finality should be 4"
|
|
|
|
);
|
2019-03-08 23:45:28 +00:00
|
|
|
|
2019-03-10 23:56:31 +00:00
|
|
|
bench_epoch_processing(c, &state, &spec, &format!("{}_validators", validator_count));
|
2019-03-08 23:45:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Run the detailed benchmarking suite on the given `BeaconState`.
|
|
|
|
///
|
|
|
|
/// `desc` will be added to the title of each bench.
|
|
|
|
fn bench_epoch_processing(c: &mut Criterion, state: &BeaconState, spec: &ChainSpec, desc: &str) {
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_eth1_data", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
|
|
|
process_eth1_data(&mut state, &spec_clone);
|
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-14 03:59:00 +00:00
|
|
|
Benchmark::new("initialize_validator_statuses", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
2019-03-14 03:59:00 +00:00
|
|
|
initialize_validator_statuses(&mut state, &spec_clone).unwrap();
|
2019-03-10 23:56:31 +00:00
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
2019-03-14 03:59:00 +00:00
|
|
|
let attesters = initialize_validator_statuses(&state, &spec).unwrap();
|
2019-03-08 23:45:28 +00:00
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_justification", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
|
|
|
|mut state| {
|
2019-03-14 03:59:00 +00:00
|
|
|
process_justification(&mut state, &attesters.total_balances, &spec_clone);
|
2019-03-10 23:56:31 +00:00
|
|
|
state
|
2019-03-08 23:45:28 +00:00
|
|
|
},
|
2019-03-10 23:56:31 +00:00
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.sample_size(10),
|
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_crosslinks", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
|
|
|
|mut state| black_box(process_crosslinks(&mut state, &spec_clone).unwrap()),
|
2019-03-10 23:56:31 +00:00
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let mut state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
2019-03-14 03:59:00 +00:00
|
|
|
let attesters = initialize_validator_statuses(&state, &spec).unwrap();
|
2019-03-08 23:45:28 +00:00
|
|
|
let winning_root_for_shards = process_crosslinks(&mut state_clone, &spec).unwrap();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_rewards_and_penalties", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-14 01:17:43 +00:00
|
|
|
|| (state_clone.clone(), attesters.clone()),
|
|
|
|
|(mut state, mut attesters)| {
|
2019-03-10 23:56:31 +00:00
|
|
|
process_rewards_and_penalities(
|
|
|
|
&mut state,
|
2019-03-14 01:17:43 +00:00
|
|
|
&mut attesters,
|
2019-03-10 23:56:31 +00:00
|
|
|
&winning_root_for_shards,
|
|
|
|
&spec_clone,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
2019-03-10 23:56:31 +00:00
|
|
|
.unwrap();
|
|
|
|
state
|
2019-03-08 23:45:28 +00:00
|
|
|
},
|
2019-03-10 23:56:31 +00:00
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(SMALL_BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_ejections", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
|
|
|
state.process_ejections(&spec_clone);
|
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
2019-03-14 01:49:48 +00:00
|
|
|
let state_clone = state.clone();
|
2019-03-08 23:45:28 +00:00
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("process_validator_registry", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
|
|
|
process_validator_registry(&mut state, &spec_clone).unwrap();
|
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("update_active_tree_index_roots", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
|
|
|
|mut state| {
|
2019-03-10 23:56:31 +00:00
|
|
|
update_active_tree_index_roots(&mut state, &spec_clone).unwrap();
|
|
|
|
state
|
2019-03-08 23:45:28 +00:00
|
|
|
},
|
2019-03-10 23:56:31 +00:00
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("update_latest_slashed_balances", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
|
|
|
update_latest_slashed_balances(&mut state, &spec_clone);
|
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-08 23:45:28 +00:00
|
|
|
Benchmark::new("clean_attestations", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-08 23:45:28 +00:00
|
|
|
|| state_clone.clone(),
|
2019-03-10 23:56:31 +00:00
|
|
|
|mut state| {
|
|
|
|
clean_attestations(&mut state, &spec_clone);
|
|
|
|
state
|
|
|
|
},
|
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-08 23:45:28 +00:00
|
|
|
)
|
|
|
|
})
|
2019-03-10 06:48:26 +00:00
|
|
|
.sample_size(BENCHING_SAMPLE_SIZE),
|
|
|
|
);
|
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
let spec_clone = spec.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-10 06:48:26 +00:00
|
|
|
Benchmark::new("per_epoch_processing", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter_batched(
|
2019-03-10 06:48:26 +00:00
|
|
|
|| state_clone.clone(),
|
|
|
|
|mut state| black_box(per_epoch_processing(&mut state, &spec_clone).unwrap()),
|
2019-03-10 23:56:31 +00:00
|
|
|
criterion::BatchSize::SmallInput,
|
2019-03-10 06:48:26 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.sample_size(SMALL_BENCHING_SAMPLE_SIZE),
|
2019-03-08 23:45:28 +00:00
|
|
|
);
|
2019-03-10 07:31:14 +00:00
|
|
|
|
|
|
|
let state_clone = state.clone();
|
|
|
|
c.bench(
|
2019-03-11 03:52:21 +00:00
|
|
|
&format!("{}/epoch_processing", desc),
|
2019-03-10 07:31:14 +00:00
|
|
|
Benchmark::new("tree_hash_state", move |b| {
|
2019-03-10 23:56:31 +00:00
|
|
|
b.iter(|| black_box(state_clone.hash_tree_root()))
|
2019-03-10 07:31:14 +00:00
|
|
|
})
|
|
|
|
.sample_size(SMALL_BENCHING_SAMPLE_SIZE),
|
|
|
|
);
|
2019-03-08 23:45:28 +00:00
|
|
|
}
|