mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-17 10:48:28 +00:00
resolve merge conflicts
This commit is contained in:
@@ -22,5 +22,5 @@ fn main() {
|
||||
|
||||
fn write_test_def_to_yaml(filename: &str, def: ForkChoiceTestDefinition) {
|
||||
let file = File::create(filename).expect("Should be able to open file");
|
||||
serde_yaml::to_writer(file, &def).expect("Should be able to write YAML to file");
|
||||
yaml_serde::to_writer(file, &def).expect("Should be able to write YAML to file");
|
||||
}
|
||||
|
||||
@@ -54,6 +54,14 @@ pub enum Error {
|
||||
},
|
||||
InvalidEpochOffset(u64),
|
||||
Arith(ArithError),
|
||||
InvalidNodeVariant {
|
||||
block_root: Hash256,
|
||||
},
|
||||
BrokenBlock {
|
||||
block_root: Hash256,
|
||||
},
|
||||
NoViableChildren,
|
||||
OnBlockRequiresProposerIndex,
|
||||
}
|
||||
|
||||
impl From<ArithError> for Error {
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
mod execution_status;
|
||||
mod ffg_updates;
|
||||
mod gloas_payload;
|
||||
mod no_votes;
|
||||
mod votes;
|
||||
|
||||
use crate::proto_array_fork_choice::{Block, ExecutionStatus, ProtoArrayForkChoice};
|
||||
use crate::error::Error;
|
||||
use crate::proto_array_fork_choice::{Block, ExecutionStatus, PayloadStatus, ProtoArrayForkChoice};
|
||||
use crate::{InvalidationOperation, JustifiedBalances};
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::BitVector;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::time::Duration;
|
||||
use types::{
|
||||
AttestationShufflingId, Checkpoint, Epoch, EthSpec, ExecutionBlockHash, Hash256,
|
||||
AttestationShufflingId, ChainSpec, Checkpoint, Epoch, EthSpec, ExecutionBlockHash, Hash256,
|
||||
MainnetEthSpec, Slot,
|
||||
};
|
||||
|
||||
pub use execution_status::*;
|
||||
pub use ffg_updates::*;
|
||||
pub use gloas_payload::*;
|
||||
pub use no_votes::*;
|
||||
pub use votes::*;
|
||||
|
||||
@@ -25,6 +30,11 @@ pub enum Operation {
|
||||
finalized_checkpoint: Checkpoint,
|
||||
justified_state_balances: Vec<u64>,
|
||||
expected_head: Hash256,
|
||||
current_slot: Slot,
|
||||
// TODO(gloas): Make this non-optional. `find_head` always returns a `PayloadStatus`
|
||||
// (Empty for pre-GLOAS), so every test should assert on it explicitly.
|
||||
#[serde(default)]
|
||||
expected_payload_status: Option<PayloadStatus>,
|
||||
},
|
||||
ProposerBoostFindHead {
|
||||
justified_checkpoint: Checkpoint,
|
||||
@@ -44,11 +54,29 @@ pub enum Operation {
|
||||
parent_root: Hash256,
|
||||
justified_checkpoint: Checkpoint,
|
||||
finalized_checkpoint: Checkpoint,
|
||||
#[serde(default)]
|
||||
execution_payload_parent_hash: Option<ExecutionBlockHash>,
|
||||
#[serde(default)]
|
||||
execution_payload_block_hash: Option<ExecutionBlockHash>,
|
||||
},
|
||||
ProcessAttestation {
|
||||
validator_index: usize,
|
||||
block_root: Hash256,
|
||||
target_epoch: Epoch,
|
||||
attestation_slot: Slot,
|
||||
},
|
||||
ProcessGloasAttestation {
|
||||
validator_index: usize,
|
||||
block_root: Hash256,
|
||||
attestation_slot: Slot,
|
||||
payload_present: bool,
|
||||
},
|
||||
ProcessPayloadAttestation {
|
||||
validator_index: usize,
|
||||
block_root: Hash256,
|
||||
attestation_slot: Slot,
|
||||
payload_present: bool,
|
||||
#[serde(default)]
|
||||
blob_data_available: bool,
|
||||
},
|
||||
Prune {
|
||||
finalized_root: Hash256,
|
||||
@@ -63,6 +91,39 @@ pub enum Operation {
|
||||
block_root: Hash256,
|
||||
weight: u64,
|
||||
},
|
||||
AssertPayloadWeights {
|
||||
block_root: Hash256,
|
||||
expected_full_weight: u64,
|
||||
expected_empty_weight: u64,
|
||||
},
|
||||
AssertParentPayloadStatus {
|
||||
block_root: Hash256,
|
||||
expected_status: PayloadStatus,
|
||||
},
|
||||
SetPayloadTiebreak {
|
||||
block_root: Hash256,
|
||||
is_timely: bool,
|
||||
is_data_available: bool,
|
||||
},
|
||||
/// Simulate receiving and validating an execution payload for `block_root`.
|
||||
/// Sets `payload_received = true` on the V29 node via the live validation path.
|
||||
ProcessExecutionPayloadEnvelope {
|
||||
block_root: Hash256,
|
||||
},
|
||||
AssertPayloadReceived {
|
||||
block_root: Hash256,
|
||||
expected: bool,
|
||||
},
|
||||
AssertPayloadStatusByWeight {
|
||||
block_root: Hash256,
|
||||
expected_status: PayloadStatus,
|
||||
/// Override `current_slot`. Defaults to the `current_slot` of the last `FindHead`.
|
||||
#[serde(default)]
|
||||
current_slot: Option<Slot>,
|
||||
/// Override the proposer boost root. Defaults to `Hash256::zero()`.
|
||||
#[serde(default)]
|
||||
proposer_boost_root: Option<Hash256>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -71,12 +132,23 @@ pub struct ForkChoiceTestDefinition {
|
||||
pub justified_checkpoint: Checkpoint,
|
||||
pub finalized_checkpoint: Checkpoint,
|
||||
pub operations: Vec<Operation>,
|
||||
#[serde(default)]
|
||||
pub execution_payload_parent_hash: Option<ExecutionBlockHash>,
|
||||
#[serde(default)]
|
||||
pub execution_payload_block_hash: Option<ExecutionBlockHash>,
|
||||
#[serde(skip)]
|
||||
pub spec: Option<ChainSpec>,
|
||||
}
|
||||
|
||||
impl ForkChoiceTestDefinition {
|
||||
pub fn run(self) {
|
||||
let mut spec = MainnetEthSpec::default_spec();
|
||||
spec.proposer_score_boost = Some(50);
|
||||
let spec = self.spec.unwrap_or_else(|| {
|
||||
let mut spec = MainnetEthSpec::default_spec();
|
||||
spec.proposer_score_boost = Some(50);
|
||||
// Legacy test definitions target pre-Gloas behaviour unless explicitly overridden.
|
||||
spec.gloas_fork_epoch = None;
|
||||
spec
|
||||
});
|
||||
|
||||
let junk_shuffling_id =
|
||||
AttestationShufflingId::from_components(Epoch::new(0), Hash256::zero());
|
||||
@@ -90,9 +162,14 @@ impl ForkChoiceTestDefinition {
|
||||
junk_shuffling_id,
|
||||
HashMap::new(),
|
||||
ExecutionStatus::Optimistic(ExecutionBlockHash::zero()),
|
||||
self.execution_payload_parent_hash,
|
||||
self.execution_payload_block_hash,
|
||||
0,
|
||||
&spec,
|
||||
)
|
||||
.expect("should create fork choice struct");
|
||||
let equivocating_indices = BTreeSet::new();
|
||||
let mut last_current_slot = Slot::new(0);
|
||||
|
||||
for (op_index, op) in self.operations.into_iter().enumerate() {
|
||||
match op.clone() {
|
||||
@@ -101,18 +178,20 @@ impl ForkChoiceTestDefinition {
|
||||
finalized_checkpoint,
|
||||
justified_state_balances,
|
||||
expected_head,
|
||||
current_slot,
|
||||
expected_payload_status,
|
||||
} => {
|
||||
let justified_balances =
|
||||
JustifiedBalances::from_effective_balances(justified_state_balances)
|
||||
.unwrap();
|
||||
let head = fork_choice
|
||||
let (head, payload_status) = fork_choice
|
||||
.find_head::<MainnetEthSpec>(
|
||||
justified_checkpoint,
|
||||
finalized_checkpoint,
|
||||
&justified_balances,
|
||||
Hash256::zero(),
|
||||
&equivocating_indices,
|
||||
Slot::new(0),
|
||||
current_slot,
|
||||
&spec,
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
@@ -124,6 +203,23 @@ impl ForkChoiceTestDefinition {
|
||||
"Operation at index {} failed head check. Operation: {:?}",
|
||||
op_index, op
|
||||
);
|
||||
if let Some(expected_status) = expected_payload_status {
|
||||
assert_eq!(
|
||||
payload_status, expected_status,
|
||||
"Operation at index {} failed payload status check. Operation: {:?}",
|
||||
op_index, op
|
||||
);
|
||||
}
|
||||
assert_canonical_payload_status_matches_find_head(
|
||||
&fork_choice,
|
||||
&head,
|
||||
current_slot,
|
||||
Hash256::zero(),
|
||||
&spec,
|
||||
payload_status,
|
||||
op_index,
|
||||
);
|
||||
last_current_slot = current_slot;
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::ProposerBoostFindHead {
|
||||
@@ -136,7 +232,7 @@ impl ForkChoiceTestDefinition {
|
||||
let justified_balances =
|
||||
JustifiedBalances::from_effective_balances(justified_state_balances)
|
||||
.unwrap();
|
||||
let head = fork_choice
|
||||
let (head, payload_status) = fork_choice
|
||||
.find_head::<MainnetEthSpec>(
|
||||
justified_checkpoint,
|
||||
finalized_checkpoint,
|
||||
@@ -155,6 +251,15 @@ impl ForkChoiceTestDefinition {
|
||||
"Operation at index {} failed head check. Operation: {:?}",
|
||||
op_index, op
|
||||
);
|
||||
assert_canonical_payload_status_matches_find_head(
|
||||
&fork_choice,
|
||||
&head,
|
||||
Slot::new(0),
|
||||
proposer_boost_root,
|
||||
&spec,
|
||||
payload_status,
|
||||
op_index,
|
||||
);
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::InvalidFindHead {
|
||||
@@ -189,6 +294,8 @@ impl ForkChoiceTestDefinition {
|
||||
parent_root,
|
||||
justified_checkpoint,
|
||||
finalized_checkpoint,
|
||||
execution_payload_parent_hash,
|
||||
execution_payload_block_hash,
|
||||
} => {
|
||||
let block = Block {
|
||||
slot,
|
||||
@@ -212,14 +319,12 @@ impl ForkChoiceTestDefinition {
|
||||
),
|
||||
unrealized_justified_checkpoint: None,
|
||||
unrealized_finalized_checkpoint: None,
|
||||
execution_payload_parent_hash,
|
||||
execution_payload_block_hash,
|
||||
proposer_index: Some(0),
|
||||
};
|
||||
fork_choice
|
||||
.process_block::<MainnetEthSpec>(
|
||||
block,
|
||||
slot,
|
||||
self.justified_checkpoint,
|
||||
self.finalized_checkpoint,
|
||||
)
|
||||
.process_block::<MainnetEthSpec>(block, slot, &spec, Duration::ZERO)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"process_block op at index {} returned error: {:?}",
|
||||
@@ -231,10 +336,10 @@ impl ForkChoiceTestDefinition {
|
||||
Operation::ProcessAttestation {
|
||||
validator_index,
|
||||
block_root,
|
||||
target_epoch,
|
||||
attestation_slot,
|
||||
} => {
|
||||
fork_choice
|
||||
.process_attestation(validator_index, block_root, target_epoch)
|
||||
.process_attestation(validator_index, block_root, attestation_slot, false)
|
||||
.unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"process_attestation op at index {} returned error",
|
||||
@@ -243,6 +348,49 @@ impl ForkChoiceTestDefinition {
|
||||
});
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::ProcessGloasAttestation {
|
||||
validator_index,
|
||||
block_root,
|
||||
attestation_slot,
|
||||
payload_present,
|
||||
} => {
|
||||
fork_choice
|
||||
.process_attestation(
|
||||
validator_index,
|
||||
block_root,
|
||||
attestation_slot,
|
||||
payload_present,
|
||||
)
|
||||
.unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"process_attestation op at index {} returned error",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::ProcessPayloadAttestation {
|
||||
validator_index,
|
||||
block_root,
|
||||
attestation_slot: _,
|
||||
payload_present,
|
||||
blob_data_available,
|
||||
} => {
|
||||
fork_choice
|
||||
.process_payload_attestation(
|
||||
block_root,
|
||||
validator_index,
|
||||
payload_present,
|
||||
blob_data_available,
|
||||
)
|
||||
.unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"process_payload_attestation op at index {} returned error",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::Prune {
|
||||
finalized_root,
|
||||
prune_threshold,
|
||||
@@ -288,8 +436,173 @@ impl ForkChoiceTestDefinition {
|
||||
Operation::AssertWeight { block_root, weight } => assert_eq!(
|
||||
fork_choice.get_weight(&block_root).unwrap(),
|
||||
weight,
|
||||
"block weight"
|
||||
"block weight at op index {}",
|
||||
op_index
|
||||
),
|
||||
Operation::AssertPayloadWeights {
|
||||
block_root,
|
||||
expected_full_weight,
|
||||
expected_empty_weight,
|
||||
} => {
|
||||
let block_index = fork_choice
|
||||
.proto_array
|
||||
.indices
|
||||
.get(&block_root)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"AssertPayloadWeights: block root not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let node = fork_choice
|
||||
.proto_array
|
||||
.nodes
|
||||
.get(*block_index)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"AssertPayloadWeights: node not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let v29 = node.as_v29().unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"AssertPayloadWeights: node is not V29 at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
assert_eq!(
|
||||
v29.full_payload_weight, expected_full_weight,
|
||||
"full_payload_weight mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
assert_eq!(
|
||||
v29.empty_payload_weight, expected_empty_weight,
|
||||
"empty_payload_weight mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
}
|
||||
Operation::AssertParentPayloadStatus {
|
||||
block_root,
|
||||
expected_status,
|
||||
} => {
|
||||
let block_index = fork_choice
|
||||
.proto_array
|
||||
.indices
|
||||
.get(&block_root)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"AssertParentPayloadStatus: block root not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let node = fork_choice
|
||||
.proto_array
|
||||
.nodes
|
||||
.get(*block_index)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"AssertParentPayloadStatus: node not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let v29 = node.as_v29().unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"AssertParentPayloadStatus: node is not V29 at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
assert_eq!(
|
||||
v29.parent_payload_status, expected_status,
|
||||
"parent_payload_status mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
}
|
||||
Operation::SetPayloadTiebreak {
|
||||
block_root,
|
||||
is_timely,
|
||||
is_data_available,
|
||||
} => {
|
||||
let block_index = fork_choice
|
||||
.proto_array
|
||||
.indices
|
||||
.get(&block_root)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"SetPayloadTiebreak: block root not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let node = fork_choice
|
||||
.proto_array
|
||||
.nodes
|
||||
.get_mut(*block_index)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"SetPayloadTiebreak: node not found at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
let node_v29 = node.as_v29_mut().unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"SetPayloadTiebreak: node is not V29 at op index {}",
|
||||
op_index
|
||||
)
|
||||
});
|
||||
// Set all bits (exceeds any threshold) or clear all bits.
|
||||
let fill = if is_timely { 0xFF } else { 0x00 };
|
||||
node_v29.payload_timeliness_votes =
|
||||
BitVector::from_bytes(smallvec::smallvec![fill; 64])
|
||||
.expect("valid 512-bit bitvector");
|
||||
let fill = if is_data_available { 0xFF } else { 0x00 };
|
||||
node_v29.payload_data_availability_votes =
|
||||
BitVector::from_bytes(smallvec::smallvec![fill; 64])
|
||||
.expect("valid 512-bit bitvector");
|
||||
// Per spec, is_payload_timely/is_payload_data_available require
|
||||
// the payload to be in payload_states (payload_received).
|
||||
node_v29.payload_received = is_timely || is_data_available;
|
||||
}
|
||||
Operation::ProcessExecutionPayloadEnvelope { block_root } => {
|
||||
fork_choice
|
||||
.on_valid_payload_envelope_received(block_root)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"on_execution_payload op at index {} returned error: {}",
|
||||
op_index, e
|
||||
)
|
||||
});
|
||||
check_bytes_round_trip(&fork_choice);
|
||||
}
|
||||
Operation::AssertPayloadReceived {
|
||||
block_root,
|
||||
expected,
|
||||
} => {
|
||||
let actual = fork_choice.is_payload_received(&block_root);
|
||||
assert_eq!(
|
||||
actual, expected,
|
||||
"payload_received mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
}
|
||||
Operation::AssertPayloadStatusByWeight {
|
||||
block_root,
|
||||
expected_status,
|
||||
current_slot,
|
||||
proposer_boost_root,
|
||||
} => {
|
||||
let actual = fork_choice
|
||||
.get_canonical_payload_status::<MainnetEthSpec>(
|
||||
&block_root,
|
||||
current_slot.unwrap_or(last_current_slot),
|
||||
proposer_boost_root.unwrap_or_else(Hash256::zero),
|
||||
&spec,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
actual, expected_status,
|
||||
"canonical payload status mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,9 +627,39 @@ fn get_checkpoint(i: u64) -> Checkpoint {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that `get_canonical_payload_status` agrees with the `payload_status`
|
||||
/// returned by `find_head` for the head block.
|
||||
fn assert_canonical_payload_status_matches_find_head(
|
||||
fork_choice: &ProtoArrayForkChoice,
|
||||
head: &Hash256,
|
||||
current_slot: Slot,
|
||||
proposer_boost_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
expected: PayloadStatus,
|
||||
op_index: usize,
|
||||
) {
|
||||
match fork_choice.get_canonical_payload_status::<MainnetEthSpec>(
|
||||
head,
|
||||
current_slot,
|
||||
proposer_boost_root,
|
||||
spec,
|
||||
) {
|
||||
Ok(actual) => assert_eq!(
|
||||
actual, expected,
|
||||
"get_canonical_payload_status disagreed with find_head for head {:?} at op index {}",
|
||||
head, op_index
|
||||
),
|
||||
// Skip the check for pre-gloas nodes
|
||||
Err(Error::InvalidNodeVariant { .. }) => {}
|
||||
Err(e) => panic!(
|
||||
"get_canonical_payload_status failed at op index {}: {:?}",
|
||||
op_index, e
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_bytes_round_trip(original: &ProtoArrayForkChoice) {
|
||||
// The checkpoint are ignored `ProtoArrayForkChoice::from_bytes` so any value is ok
|
||||
let bytes = original.as_bytes(Checkpoint::default(), Checkpoint::default());
|
||||
let bytes = original.as_bytes();
|
||||
let decoded = ProtoArrayForkChoice::from_bytes(&bytes, original.balances.clone())
|
||||
.expect("fork choice should decode from bytes");
|
||||
assert!(
|
||||
|
||||
@@ -16,6 +16,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 2.
|
||||
@@ -35,6 +37,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is 2
|
||||
@@ -53,6 +57,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 1 that comes off the genesis block (this is a fork compared
|
||||
@@ -73,6 +79,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -91,6 +99,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to block 1
|
||||
@@ -101,7 +111,7 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 1, because 1 has a vote.
|
||||
@@ -120,6 +130,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -143,7 +155,7 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(2),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is 2 since 1 and 2 both have a vote
|
||||
@@ -162,6 +174,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -196,6 +210,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -216,6 +232,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -245,7 +263,7 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(3),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -266,6 +284,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -315,6 +335,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Invalidation of 3 should have removed upstream weight.
|
||||
@@ -347,7 +369,7 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Ensure that the head has switched back to 1
|
||||
@@ -368,6 +390,8 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -399,6 +423,9 @@ pub fn get_execution_status_test_definition_01() -> ForkChoiceTestDefinition {
|
||||
root: get_root(0),
|
||||
},
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,6 +445,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 2.
|
||||
@@ -437,6 +466,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is 2
|
||||
@@ -455,6 +486,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 1 that comes off the genesis block (this is a fork compared
|
||||
@@ -475,6 +508,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -493,6 +528,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to block 1
|
||||
@@ -503,7 +540,7 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 1, because 1 has a vote.
|
||||
@@ -522,6 +559,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -545,7 +584,7 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(2),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is 2 since 1 and 2 both have a vote
|
||||
@@ -564,6 +603,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -598,6 +639,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -618,6 +661,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -647,7 +692,7 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(3),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Move validator #1 vote from 2 to 3
|
||||
@@ -660,7 +705,7 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(3),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 3.
|
||||
@@ -681,6 +726,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(3),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -730,6 +777,8 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Invalidation of 3 should have removed upstream weight.
|
||||
@@ -763,6 +812,9 @@ pub fn get_execution_status_test_definition_02() -> ForkChoiceTestDefinition {
|
||||
root: get_root(0),
|
||||
},
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,6 +834,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 2.
|
||||
@@ -801,6 +855,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is 2
|
||||
@@ -819,6 +875,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 1 that comes off the genesis block (this is a fork compared
|
||||
@@ -839,6 +897,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -857,6 +917,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to block 1
|
||||
@@ -867,7 +929,7 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 1, because 1 has a vote.
|
||||
@@ -886,6 +948,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -909,7 +973,7 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is 1.
|
||||
@@ -928,6 +992,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertWeight {
|
||||
@@ -962,6 +1028,8 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is now 3, applying a proposer boost to 3 as well.
|
||||
@@ -985,13 +1053,15 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
proposer_boost_root: get_root(3),
|
||||
});
|
||||
|
||||
// Stored weights are pure attestation scores (proposer boost is applied
|
||||
// on-the-fly in the walk's `get_weight`, not baked into `node.weight()`).
|
||||
ops.push(Operation::AssertWeight {
|
||||
block_root: get_root(0),
|
||||
weight: 33_250,
|
||||
weight: 2_000,
|
||||
});
|
||||
ops.push(Operation::AssertWeight {
|
||||
block_root: get_root(1),
|
||||
weight: 33_250,
|
||||
weight: 2_000,
|
||||
});
|
||||
ops.push(Operation::AssertWeight {
|
||||
block_root: get_root(2),
|
||||
@@ -999,8 +1069,7 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
});
|
||||
ops.push(Operation::AssertWeight {
|
||||
block_root: get_root(3),
|
||||
// This is a "magic number" generated from `calculate_committee_fraction`.
|
||||
weight: 31_250,
|
||||
weight: 0,
|
||||
});
|
||||
|
||||
// Invalidate the payload of 3.
|
||||
@@ -1065,6 +1134,9 @@ pub fn get_execution_status_test_definition_03() -> ForkChoiceTestDefinition {
|
||||
root: get_root(0),
|
||||
},
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Build the following tree (stick? lol).
|
||||
@@ -27,6 +29,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(2),
|
||||
@@ -34,6 +38,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(1),
|
||||
justified_checkpoint: get_checkpoint(1),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(3),
|
||||
@@ -41,6 +47,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(2),
|
||||
justified_checkpoint: get_checkpoint(2),
|
||||
finalized_checkpoint: get_checkpoint(1),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that with justified epoch 0 we find 3
|
||||
@@ -57,6 +65,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(3),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that with justified epoch 1 we find 3
|
||||
@@ -77,6 +87,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(3),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that with justified epoch 2 we find 3
|
||||
@@ -93,6 +105,8 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(1),
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(3),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// END OF TESTS
|
||||
@@ -101,6 +115,9 @@ pub fn get_ffg_case_01_test_definition() -> ForkChoiceTestDefinition {
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +131,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Build the following tree.
|
||||
@@ -137,6 +156,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(2),
|
||||
@@ -147,6 +168,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(1),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(3),
|
||||
@@ -157,6 +180,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(1),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(4),
|
||||
@@ -167,6 +192,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(1),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(5),
|
||||
@@ -177,6 +204,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(3),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Right branch
|
||||
@@ -186,6 +215,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(2),
|
||||
@@ -193,6 +224,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(2),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(3),
|
||||
@@ -200,6 +233,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
parent_root: get_root(4),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(4),
|
||||
@@ -210,6 +245,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(2),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(5),
|
||||
@@ -220,6 +257,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(4),
|
||||
},
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that if we start at 0 we find 10 (just: 0, fin: 0).
|
||||
@@ -240,6 +279,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above, but with justified epoch 2.
|
||||
ops.push(Operation::FindHead {
|
||||
@@ -250,6 +291,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above, but with justified epoch 3.
|
||||
//
|
||||
@@ -264,6 +307,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to 1.
|
||||
@@ -282,7 +327,7 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(0),
|
||||
attestation_slot: Slot::new(0),
|
||||
});
|
||||
|
||||
// Ensure that if we start at 0 we find 9 (just: 0, fin: 0).
|
||||
@@ -303,6 +348,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Save as above but justified epoch 2.
|
||||
ops.push(Operation::FindHead {
|
||||
@@ -313,6 +360,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Save as above but justified epoch 3.
|
||||
//
|
||||
@@ -327,6 +376,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to 2.
|
||||
@@ -345,7 +396,7 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(2),
|
||||
target_epoch: Epoch::new(0),
|
||||
attestation_slot: Slot::new(0),
|
||||
});
|
||||
|
||||
// Ensure that if we start at 0 we find 10 (just: 0, fin: 0).
|
||||
@@ -366,6 +417,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 2.
|
||||
ops.push(Operation::FindHead {
|
||||
@@ -376,6 +429,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 3.
|
||||
//
|
||||
@@ -390,6 +445,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that if we start at 1 we find 9 (just: 0, fin: 0).
|
||||
@@ -413,6 +470,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 2.
|
||||
ops.push(Operation::FindHead {
|
||||
@@ -423,6 +482,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 3.
|
||||
//
|
||||
@@ -437,6 +498,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that if we start at 2 we find 10 (just: 0, fin: 0).
|
||||
@@ -457,6 +520,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 2.
|
||||
ops.push(Operation::FindHead {
|
||||
@@ -467,6 +532,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
// Same as above but justified epoch 3.
|
||||
//
|
||||
@@ -481,6 +548,8 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// END OF TESTS
|
||||
@@ -489,6 +558,9 @@ pub fn get_ffg_case_02_test_definition() -> ForkChoiceTestDefinition {
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: Hash256::zero(),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 2
|
||||
//
|
||||
@@ -36,6 +38,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure the head is 2
|
||||
//
|
||||
@@ -53,6 +57,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 1
|
||||
//
|
||||
@@ -71,6 +77,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure the head is still 2
|
||||
//
|
||||
@@ -88,6 +96,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 3
|
||||
//
|
||||
@@ -108,6 +118,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure 2 is still the head
|
||||
//
|
||||
@@ -127,6 +139,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 4
|
||||
//
|
||||
@@ -147,6 +161,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure the head is 4.
|
||||
//
|
||||
@@ -166,6 +182,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(4),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 5 with a justified epoch of 2
|
||||
//
|
||||
@@ -185,6 +203,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure the head is now 5 whilst the justified epoch is 0.
|
||||
//
|
||||
@@ -206,6 +226,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(5),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Ensure there is no error when starting from a block that has the
|
||||
// wrong justified epoch.
|
||||
@@ -232,6 +254,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(5),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Set the justified epoch to 2 and the start block to 5 and ensure 5 is the head.
|
||||
//
|
||||
@@ -250,6 +274,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(5),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
// Add block 6
|
||||
//
|
||||
@@ -271,6 +297,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
},
|
||||
// Ensure 6 is the head
|
||||
//
|
||||
@@ -291,6 +319,8 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(6),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -305,6 +335,9 @@ pub fn get_no_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: Hash256::zero(),
|
||||
},
|
||||
operations,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(0),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 2.
|
||||
@@ -35,6 +37,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is 2
|
||||
@@ -53,6 +57,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a block with a hash of 1 that comes off the genesis block (this is a fork compared
|
||||
@@ -73,6 +79,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -91,6 +99,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to block 1
|
||||
@@ -101,7 +111,7 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 1, because 1 has a vote.
|
||||
@@ -120,6 +130,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(1),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add a vote to block 2
|
||||
@@ -130,7 +142,7 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(2),
|
||||
target_epoch: Epoch::new(2),
|
||||
attestation_slot: Slot::new(2),
|
||||
});
|
||||
|
||||
// Ensure that the head is 2 since 1 and 2 both have a vote
|
||||
@@ -149,6 +161,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add block 3.
|
||||
@@ -170,6 +184,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -190,6 +206,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Move validator #0 vote from 1 to 3
|
||||
@@ -202,7 +220,7 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(3),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Ensure that the head is still 2
|
||||
@@ -223,6 +241,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Move validator #1 vote from 2 to 1 (this is an equivocation, but fork choice doesn't
|
||||
@@ -236,7 +256,7 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(1),
|
||||
target_epoch: Epoch::new(3),
|
||||
attestation_slot: Slot::new(3),
|
||||
});
|
||||
|
||||
// Ensure that the head is now 3
|
||||
@@ -257,6 +277,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(3),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add block 4.
|
||||
@@ -280,6 +302,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that the head is now 4
|
||||
@@ -302,6 +326,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(4),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add block 5, which has a justified epoch of 2.
|
||||
@@ -327,19 +353,22 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(1),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that 5 is filtered out and the head stays at 4.
|
||||
// Block 5 has incompatible finalized checkpoint, so `get_filtered_block_tree`
|
||||
// excludes the entire 1->3->4->5 branch (no viable leaf). Head moves to 2.
|
||||
//
|
||||
// 0
|
||||
// / \
|
||||
// 2 1
|
||||
// head-> 2 1
|
||||
// |
|
||||
// 3
|
||||
// |
|
||||
// 4 <- head
|
||||
// 4
|
||||
// /
|
||||
// 5
|
||||
// 5 <- incompatible finalized checkpoint
|
||||
ops.push(Operation::FindHead {
|
||||
justified_checkpoint: Checkpoint {
|
||||
epoch: Epoch::new(1),
|
||||
@@ -350,7 +379,9 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(0),
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(4),
|
||||
expected_head: get_root(2),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add block 6, which has a justified epoch of 0.
|
||||
@@ -376,6 +407,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(1),
|
||||
root: get_root(0),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Move both votes to 5.
|
||||
@@ -392,12 +425,12 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(5),
|
||||
target_epoch: Epoch::new(4),
|
||||
attestation_slot: Slot::new(4),
|
||||
});
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(5),
|
||||
target_epoch: Epoch::new(4),
|
||||
attestation_slot: Slot::new(4),
|
||||
});
|
||||
|
||||
// Add blocks 7, 8 and 9. Adding these blocks helps test the `best_descendant`
|
||||
@@ -430,6 +463,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(5),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(0),
|
||||
@@ -443,6 +478,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(5),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(0),
|
||||
@@ -456,6 +493,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(5),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure that 6 is the head, even though 5 has all the votes. This is testing to ensure
|
||||
@@ -487,6 +526,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(6),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Change fork-choice justified epoch to 1, and the start block to 5 and ensure that 9 is
|
||||
@@ -520,6 +561,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Change fork-choice justified epoch to 1, and the start block to 5 and ensure that 9 is
|
||||
@@ -545,12 +588,12 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 0,
|
||||
block_root: get_root(9),
|
||||
target_epoch: Epoch::new(5),
|
||||
attestation_slot: Slot::new(5),
|
||||
});
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 1,
|
||||
block_root: get_root(9),
|
||||
target_epoch: Epoch::new(5),
|
||||
attestation_slot: Slot::new(5),
|
||||
});
|
||||
|
||||
// Add block 10
|
||||
@@ -582,6 +625,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(5),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Double-check the head is still 9 (no diagram this time)
|
||||
@@ -596,6 +641,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Introduce 2 more validators into the system
|
||||
@@ -621,12 +668,12 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 2,
|
||||
block_root: get_root(10),
|
||||
target_epoch: Epoch::new(5),
|
||||
attestation_slot: Slot::new(5),
|
||||
});
|
||||
ops.push(Operation::ProcessAttestation {
|
||||
validator_index: 3,
|
||||
block_root: get_root(10),
|
||||
target_epoch: Epoch::new(5),
|
||||
attestation_slot: Slot::new(5),
|
||||
});
|
||||
|
||||
// Check the head is now 10.
|
||||
@@ -657,6 +704,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Set the balances of the last two validators to zero
|
||||
@@ -682,6 +731,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Set the balances of the last two validators back to 1
|
||||
@@ -707,6 +758,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(10),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Remove the last two validators
|
||||
@@ -733,6 +786,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that pruning below the prune threshold does not prune.
|
||||
@@ -754,6 +809,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Ensure that pruning above the prune threshold does prune.
|
||||
@@ -792,6 +849,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances.clone(),
|
||||
expected_head: get_root(9),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
// Add block 11
|
||||
@@ -817,6 +876,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
epoch: Epoch::new(2),
|
||||
root: get_root(5),
|
||||
},
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Ensure the head is now 11
|
||||
@@ -841,6 +902,8 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
},
|
||||
justified_state_balances: balances,
|
||||
expected_head: get_root(11),
|
||||
current_slot: Slot::new(0),
|
||||
expected_payload_status: None,
|
||||
});
|
||||
|
||||
ForkChoiceTestDefinition {
|
||||
@@ -854,6 +917,9 @@ pub fn get_votes_test_definition() -> ForkChoiceTestDefinition {
|
||||
root: get_root(0),
|
||||
},
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ mod ssz_container;
|
||||
pub use crate::justified_balances::JustifiedBalances;
|
||||
pub use crate::proto_array::{InvalidationOperation, calculate_committee_fraction};
|
||||
pub use crate::proto_array_fork_choice::{
|
||||
Block, DisallowedReOrgOffsets, DoNotReOrg, ExecutionStatus, ProposerHeadError,
|
||||
ProposerHeadInfo, ProtoArrayForkChoice, ReOrgThreshold,
|
||||
Block, DisallowedReOrgOffsets, DoNotReOrg, ExecutionStatus, LatestMessage, PayloadStatus,
|
||||
ProposerHeadError, ProposerHeadInfo, ProtoArrayForkChoice, ReOrgThreshold,
|
||||
};
|
||||
pub use error::Error;
|
||||
|
||||
pub mod core {
|
||||
pub use super::proto_array::{ProposerBoost, ProtoArray, ProtoNode};
|
||||
pub use super::proto_array_fork_choice::VoteTracker;
|
||||
pub use super::ssz_container::{SszContainer, SszContainerV17, SszContainerV28};
|
||||
pub use super::ssz_container::{SszContainer, SszContainerV28, SszContainerV29};
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
use crate::proto_array::ProposerBoost;
|
||||
use crate::{
|
||||
Error, JustifiedBalances,
|
||||
proto_array::{ProtoArray, ProtoNodeV17},
|
||||
proto_array_fork_choice::{ElasticList, ProtoArrayForkChoice, VoteTracker},
|
||||
proto_array::{ProtoArray, ProtoNode, ProtoNodeV17},
|
||||
proto_array_fork_choice::{ElasticList, ProtoArrayForkChoice, VoteTracker, VoteTrackerV28},
|
||||
};
|
||||
use ssz::{Encode, four_byte_option_impl};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -14,44 +14,44 @@ use types::{Checkpoint, Hash256, Slot};
|
||||
// selector.
|
||||
four_byte_option_impl!(four_byte_option_checkpoint, Checkpoint);
|
||||
|
||||
pub type SszContainer = SszContainerV28;
|
||||
pub type SszContainer = SszContainerV29;
|
||||
|
||||
#[superstruct(
|
||||
variants(V17, V28),
|
||||
variants(V28, V29),
|
||||
variant_attributes(derive(Encode, Decode, Clone)),
|
||||
no_enum
|
||||
)]
|
||||
pub struct SszContainer {
|
||||
#[superstruct(only(V28))]
|
||||
pub votes_v28: Vec<VoteTrackerV28>,
|
||||
#[superstruct(only(V29))]
|
||||
pub votes: Vec<VoteTracker>,
|
||||
#[superstruct(only(V17))]
|
||||
pub balances: Vec<u64>,
|
||||
pub prune_threshold: usize,
|
||||
// Deprecated, remove in a future schema migration
|
||||
#[superstruct(only(V28))]
|
||||
justified_checkpoint: Checkpoint,
|
||||
// Deprecated, remove in a future schema migration
|
||||
#[superstruct(only(V28))]
|
||||
finalized_checkpoint: Checkpoint,
|
||||
#[superstruct(only(V28))]
|
||||
pub nodes: Vec<ProtoNodeV17>,
|
||||
#[superstruct(only(V29))]
|
||||
pub nodes: Vec<ProtoNode>,
|
||||
pub indices: Vec<(Hash256, usize)>,
|
||||
#[superstruct(only(V28))]
|
||||
pub previous_proposer_boost: ProposerBoost,
|
||||
pub unsatisfied_inclusion_list_blocks: Vec<(Slot, Hash256)>,
|
||||
}
|
||||
|
||||
impl SszContainer {
|
||||
pub fn from_proto_array(
|
||||
from: &ProtoArrayForkChoice,
|
||||
justified_checkpoint: Checkpoint,
|
||||
finalized_checkpoint: Checkpoint,
|
||||
) -> Self {
|
||||
impl SszContainerV29 {
|
||||
pub fn from_proto_array(from: &ProtoArrayForkChoice) -> Self {
|
||||
let proto_array = &from.proto_array;
|
||||
|
||||
Self {
|
||||
votes: from.votes.0.clone(),
|
||||
prune_threshold: proto_array.prune_threshold,
|
||||
justified_checkpoint,
|
||||
finalized_checkpoint,
|
||||
nodes: proto_array.nodes.clone(),
|
||||
indices: proto_array.indices.iter().map(|(k, v)| (*k, *v)).collect(),
|
||||
previous_proposer_boost: proto_array.previous_proposer_boost,
|
||||
unsatisfied_inclusion_list_blocks: proto_array
|
||||
.unsatisfied_inclusion_list_blocks
|
||||
.iter()
|
||||
@@ -61,15 +61,15 @@ impl SszContainer {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(SszContainer, JustifiedBalances)> for ProtoArrayForkChoice {
|
||||
impl TryFrom<(SszContainerV29, JustifiedBalances)> for ProtoArrayForkChoice {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from((from, balances): (SszContainer, JustifiedBalances)) -> Result<Self, Error> {
|
||||
fn try_from((from, balances): (SszContainerV29, JustifiedBalances)) -> Result<Self, Error> {
|
||||
let proto_array = ProtoArray {
|
||||
prune_threshold: from.prune_threshold,
|
||||
nodes: from.nodes,
|
||||
indices: from.indices.into_iter().collect::<HashMap<_, _>>(),
|
||||
previous_proposer_boost: from.previous_proposer_boost,
|
||||
previous_proposer_boost: ProposerBoost::default(),
|
||||
unsatisfied_inclusion_list_blocks: from
|
||||
.unsatisfied_inclusion_list_blocks
|
||||
.into_iter()
|
||||
@@ -84,35 +84,51 @@ impl TryFrom<(SszContainer, JustifiedBalances)> for ProtoArrayForkChoice {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert V17 to V28 by dropping balances.
|
||||
impl From<SszContainerV17> for SszContainerV28 {
|
||||
fn from(v17: SszContainerV17) -> Self {
|
||||
// Convert legacy V28 to current V29.
|
||||
impl From<SszContainerV28> for SszContainerV29 {
|
||||
fn from(v28: SszContainerV28) -> Self {
|
||||
Self {
|
||||
votes: v17.votes,
|
||||
prune_threshold: v17.prune_threshold,
|
||||
justified_checkpoint: v17.justified_checkpoint,
|
||||
finalized_checkpoint: v17.finalized_checkpoint,
|
||||
nodes: v17.nodes,
|
||||
indices: v17.indices,
|
||||
previous_proposer_boost: v17.previous_proposer_boost,
|
||||
unsatisfied_inclusion_list_blocks: v17.unsatisfied_inclusion_list_blocks,
|
||||
votes: v28.votes_v28.into_iter().map(Into::into).collect(),
|
||||
prune_threshold: v28.prune_threshold,
|
||||
nodes: v28
|
||||
.nodes
|
||||
.into_iter()
|
||||
.map(|mut node| {
|
||||
// best_child/best_descendant are no longer used (replaced by
|
||||
// the virtual tree walk). Clear during conversion.
|
||||
node.best_child = None;
|
||||
node.best_descendant = None;
|
||||
ProtoNode::V17(node)
|
||||
})
|
||||
.collect(),
|
||||
indices: v28.indices,
|
||||
unsatisfied_inclusion_list_blocks: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert V28 to V17 by re-adding balances.
|
||||
impl From<(SszContainerV28, JustifiedBalances)> for SszContainerV17 {
|
||||
fn from((v28, balances): (SszContainerV28, JustifiedBalances)) -> Self {
|
||||
// Downgrade current V29 to legacy V28 (lossy: V29 nodes lose payload-specific fields).
|
||||
impl From<SszContainerV29> for SszContainerV28 {
|
||||
fn from(v29: SszContainerV29) -> Self {
|
||||
Self {
|
||||
votes: v28.votes,
|
||||
balances: balances.effective_balances.clone(),
|
||||
prune_threshold: v28.prune_threshold,
|
||||
justified_checkpoint: v28.justified_checkpoint,
|
||||
finalized_checkpoint: v28.finalized_checkpoint,
|
||||
nodes: v28.nodes,
|
||||
indices: v28.indices,
|
||||
previous_proposer_boost: v28.previous_proposer_boost,
|
||||
unsatisfied_inclusion_list_blocks: v28.unsatisfied_inclusion_list_blocks,
|
||||
votes_v28: v29.votes.into_iter().map(Into::into).collect(),
|
||||
prune_threshold: v29.prune_threshold,
|
||||
// These checkpoints are not consumed in v28 paths since the upgrade from v17,
|
||||
// we can safely default the values.
|
||||
justified_checkpoint: Checkpoint::default(),
|
||||
finalized_checkpoint: Checkpoint::default(),
|
||||
nodes: v29
|
||||
.nodes
|
||||
.into_iter()
|
||||
.filter_map(|node| match node {
|
||||
ProtoNode::V17(v17) => Some(v17),
|
||||
ProtoNode::V29(_) => None,
|
||||
})
|
||||
.collect(),
|
||||
indices: v29.indices,
|
||||
// Proposer boost is not tracked in V29 (computed on-the-fly), so reset it.
|
||||
previous_proposer_boost: ProposerBoost::default(),
|
||||
unsatisfied_inclusion_list_blocks: v29.unsatisfied_inclusion_list_blocks,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user