Skip to content

Commit

Permalink
Merge pull request ralexstokes#340 from ralexstokes/refactor-executor
Browse files Browse the repository at this point in the history
Refactor executor and get rest of spec-tests passing
  • Loading branch information
ralexstokes authored Mar 25, 2024
2 parents c21879c + e477edc commit c46721d
Show file tree
Hide file tree
Showing 23 changed files with 815 additions and 846 deletions.
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
use ethereum_consensus::{
altair::mainnet as altair,
bellatrix::mainnet as bellatrix,
phase0::mainnet as phase0,
ssz::prelude::*,
state_transition::mainnet::{Context, Executor},
types::mainnet::{BeaconState, SignedBeaconBlock},
};
use std::error::Error;

fn main() -> std::result::Result<(), Box<dyn Error>> {
println!("this example is for illustration purposes...");
println!("to get to the end, we need utilities to make correct blocks with respect to the state transition");
println!("this example illustrates how to use the codebase when applying state transitions");
println!("note: the code currently does not run to the end as the input data is not correct");

let genesis_state = phase0::BeaconState::default();
let genesis_state = BeaconState::Phase0(Default::default());
let context = Context::for_mainnet();
let mut executor = Executor::new(genesis_state.into(), context);
let mut executor = Executor::new(genesis_state, context);

let mut block = phase0::SignedBeaconBlock::default();
block.message.slot = 1;
executor.apply_block(&mut block.into())?;
let mut block = SignedBeaconBlock::Phase0(Default::default());
*block.message_mut().slot_mut() = 1;
executor.apply_block(&mut block)?;

let mut block = altair::SignedBeaconBlock::default();
block.message.slot = executor.context.altair_fork_epoch * executor.context.slots_per_epoch;
executor.apply_block(&mut block.into())?;
let mut block = SignedBeaconBlock::Altair(Default::default());
*block.message_mut().slot_mut() =
executor.context.altair_fork_epoch * executor.context.slots_per_epoch;
executor.apply_block(&mut block)?;

let mut block = bellatrix::SignedBeaconBlock::default();
block.message.slot = executor.context.bellatrix_fork_epoch * executor.context.slots_per_epoch;
executor.apply_block(&mut block.into())?;
let mut block = SignedBeaconBlock::Bellatrix(Default::default());
*block.message_mut().slot_mut() =
executor.context.bellatrix_fork_epoch * executor.context.slots_per_epoch;
executor.apply_block(&mut block)?;

let mut state = executor.state.bellatrix().unwrap();
let state = executor.state.bellatrix_mut().unwrap();
let state_root = state.hash_tree_root()?;
dbg!(state_root);
Ok(())
Expand Down
56 changes: 28 additions & 28 deletions ethereum-consensus/src/altair/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,20 @@ pub fn process_proposer_slashing<
if header_1.slot != header_2.slot {
return Err(invalid_operation_error(InvalidOperation::ProposerSlashing(
InvalidProposerSlashing::SlotMismatch(header_1.slot, header_2.slot),
)))
)));
}
if header_1.proposer_index != header_2.proposer_index {
return Err(invalid_operation_error(InvalidOperation::ProposerSlashing(
InvalidProposerSlashing::ProposerMismatch(
header_1.proposer_index,
header_2.proposer_index,
),
)))
)));
}
if header_1 == header_2 {
return Err(invalid_operation_error(InvalidOperation::ProposerSlashing(
InvalidProposerSlashing::HeadersAreEqual(header_1.clone()),
)))
)));
}
let proposer_index = header_1.proposer_index;
let proposer = state.validators.get(proposer_index).ok_or_else(|| {
Expand All @@ -114,7 +114,7 @@ pub fn process_proposer_slashing<
if !is_slashable_validator(proposer, get_current_epoch(state, context)) {
return Err(invalid_operation_error(InvalidOperation::ProposerSlashing(
InvalidProposerSlashing::ProposerIsNotSlashable(header_1.proposer_index),
)))
)));
}
let epoch = compute_epoch_at_slot(header_1.slot, context);
let domain = get_domain(state, DomainType::BeaconProposer, Some(epoch), context)?;
Expand All @@ -126,7 +126,7 @@ pub fn process_proposer_slashing<
if verify_signature(public_key, signing_root.as_ref(), &signed_header.signature).is_err() {
return Err(invalid_operation_error(InvalidOperation::ProposerSlashing(
InvalidProposerSlashing::InvalidSignature(signed_header.signature.clone()),
)))
)));
}
}
slash_validator(state, proposer_index, None, context)
Expand Down Expand Up @@ -162,7 +162,7 @@ pub fn process_attester_slashing<
Box::new(attestation_1.data.clone()),
Box::new(attestation_2.data.clone()),
),
)))
)));
}
is_valid_indexed_attestation(state, attestation_1, context)?;
is_valid_indexed_attestation(state, attestation_2, context)?;
Expand Down Expand Up @@ -237,20 +237,20 @@ pub fn process_voluntary_exit<
if !is_active_validator(validator, current_epoch) {
return Err(invalid_operation_error(InvalidOperation::VoluntaryExit(
InvalidVoluntaryExit::InactiveValidator(current_epoch),
)))
)));
}
if validator.exit_epoch != FAR_FUTURE_EPOCH {
return Err(invalid_operation_error(InvalidOperation::VoluntaryExit(
InvalidVoluntaryExit::ValidatorAlreadyExited {
index: voluntary_exit.validator_index,
epoch: validator.exit_epoch,
},
)))
)));
}
if current_epoch < voluntary_exit.epoch {
return Err(invalid_operation_error(InvalidOperation::VoluntaryExit(
InvalidVoluntaryExit::EarlyExit { current_epoch, exit_epoch: voluntary_exit.epoch },
)))
)));
}
let minimum_time_active =
validator.activation_eligibility_epoch + context.shard_committee_period;
Expand All @@ -260,7 +260,7 @@ pub fn process_voluntary_exit<
current_epoch,
minimum_time_active,
},
)))
)));
}
let domain = get_domain(state, DomainType::VoluntaryExit, Some(voluntary_exit.epoch), context)?;
let public_key = &validator.public_key;
Expand Down Expand Up @@ -313,27 +313,27 @@ pub fn process_block_header<
return Err(invalid_header_error(InvalidBeaconBlockHeader::StateSlotMismatch {
state_slot: state.slot,
block_slot: block.slot,
}))
}));
}
if block.slot <= state.latest_block_header.slot {
return Err(invalid_header_error(InvalidBeaconBlockHeader::OlderThanLatestBlockHeader {
block_slot: block.slot,
latest_block_header_slot: state.latest_block_header.slot,
}))
}));
}
let proposer_index = get_beacon_proposer_index(state, context)?;
if block.proposer_index != proposer_index {
return Err(invalid_header_error(InvalidBeaconBlockHeader::ProposerIndexMismatch {
block_proposer_index: block.proposer_index,
proposer_index,
}))
}));
}
let expected_parent_root = state.latest_block_header.hash_tree_root()?;
if block.parent_root != expected_parent_root {
return Err(invalid_header_error(InvalidBeaconBlockHeader::ParentBlockRootMismatch {
expected: expected_parent_root,
provided: block.parent_root,
}))
}));
}
state.latest_block_header = BeaconBlockHeader {
slot: block.slot,
Expand All @@ -344,7 +344,7 @@ pub fn process_block_header<
};
let proposer = &state.validators[block.proposer_index];
if proposer.slashed {
return Err(invalid_header_error(InvalidBeaconBlockHeader::ProposerSlashed(proposer_index)))
return Err(invalid_header_error(InvalidBeaconBlockHeader::ProposerSlashed(proposer_index)));
}
Ok(())
}
Expand Down Expand Up @@ -394,7 +394,7 @@ pub fn process_randao<
let domain = get_domain(state, DomainType::Randao, Some(epoch), context)?;
let signing_root = compute_signing_root(&mut epoch, domain)?;
if verify_signature(&proposer.public_key, signing_root.as_ref(), &body.randao_reveal).is_err() {
return Err(invalid_operation_error(InvalidOperation::Randao(body.randao_reveal.clone())))
return Err(invalid_operation_error(InvalidOperation::Randao(body.randao_reveal.clone())));
}
let mix = xor(get_randao_mix(state, epoch), &hash(body.randao_reveal.as_ref()));
let mix_index = epoch % context.epochs_per_historical_vector;
Expand Down Expand Up @@ -490,7 +490,7 @@ pub fn process_operations<
expected: expected_deposit_count,
count: body.deposits.len(),
},
)))
)));
}
body.proposer_slashings
.iter_mut()
Expand Down Expand Up @@ -871,7 +871,7 @@ pub fn is_valid_genesis_state<
context: &Context,
) -> bool {
if state.genesis_time < context.min_genesis_time {
return false
return false;
}
get_active_validator_indices(state, GENESIS_EPOCH).len() >=
context.min_genesis_active_validator_count
Expand Down Expand Up @@ -984,15 +984,15 @@ pub fn is_valid_indexed_attestation<
if attesting_indices.is_empty() {
return Err(invalid_operation_error(InvalidOperation::IndexedAttestation(
InvalidIndexedAttestation::AttestingIndicesEmpty,
)))
)));
}
let mut prev = attesting_indices[0];
let mut duplicates = HashSet::new();
for &index in &attesting_indices[1..] {
if index < prev {
return Err(invalid_operation_error(InvalidOperation::IndexedAttestation(
InvalidIndexedAttestation::AttestingIndicesNotSorted,
)))
)));
}
if index == prev {
duplicates.insert(index);
Expand All @@ -1002,7 +1002,7 @@ pub fn is_valid_indexed_attestation<
if !duplicates.is_empty() {
return Err(invalid_operation_error(InvalidOperation::IndexedAttestation(
InvalidIndexedAttestation::DuplicateIndices(Vec::from_iter(duplicates)),
)))
)));
}
let mut public_keys = vec![];
for &index in &attesting_indices[..] {
Expand Down Expand Up @@ -1132,7 +1132,7 @@ pub fn compute_shuffled_index(
context: &Context,
) -> Result<usize> {
if index >= index_count {
return Err(Error::InvalidShufflingIndex { index, total: index_count })
return Err(Error::InvalidShufflingIndex { index, total: index_count });
}
let mut pivot_input = [0u8; 33];
pivot_input[..32].copy_from_slice(seed.as_ref());
Expand Down Expand Up @@ -1179,7 +1179,7 @@ pub fn compute_proposer_index<
context: &Context,
) -> Result<ValidatorIndex> {
if indices.is_empty() {
return Err(Error::CollectionCannotBeEmpty)
return Err(Error::CollectionCannotBeEmpty);
}
let max_byte = u8::MAX as u64;
let mut i = 0;
Expand All @@ -1194,7 +1194,7 @@ pub fn compute_proposer_index<
let random_byte = hash(hash_input).as_ref()[i % 32] as u64;
let effective_balance = state.validators[candidate_index].effective_balance;
if effective_balance * max_byte >= context.max_effective_balance * random_byte {
return Ok(candidate_index)
return Ok(candidate_index);
}
i += 1;
}
Expand Down Expand Up @@ -1336,7 +1336,7 @@ pub fn get_block_root_at_slot<
requested: slot,
lower_bound: state.slot - 1,
upper_bound: state.slot + SLOTS_PER_HISTORICAL_ROOT as Slot,
})
});
}
Ok(&state.block_roots[slot as usize % SLOTS_PER_HISTORICAL_ROOT])
}
Expand Down Expand Up @@ -1669,7 +1669,7 @@ pub fn get_attesting_indices<
if bits.len() != committee.len() {
return Err(invalid_operation_error(InvalidOperation::Attestation(
InvalidAttestation::Bitfield { expected_length: committee.len(), length: bits.len() },
)))
)));
}
let mut indices = HashSet::with_capacity(bits.capacity());
for (i, validator_index) in committee.iter().enumerate() {
Expand Down Expand Up @@ -1757,7 +1757,7 @@ pub fn initiate_validator_exit<
context: &Context,
) {
if state.validators[index].exit_epoch != FAR_FUTURE_EPOCH {
return
return;
}
let mut exit_epochs: Vec<Epoch> = state
.validators
Expand Down Expand Up @@ -1834,7 +1834,7 @@ pub fn process_slots<
context: &Context,
) -> Result<()> {
if state.slot >= slot {
return Err(Error::TransitionToPreviousSlot { requested: slot, current: state.slot })
return Err(Error::TransitionToPreviousSlot { requested: slot, current: state.slot });
}
while state.slot < slot {
process_slot(state, context)?;
Expand Down
Loading

0 comments on commit c46721d

Please sign in to comment.