mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-04 21:34:36 +00:00
Remove TTD flags and safe-slots-to-import-* (#6489)
* Delete SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY * Update fork choice tests * Remove TTD related flags * Add deprecation warning * Remove more dead code * Delete EF on_merge_block tests * Remove even more dead code * Address Mac's review comments
This commit is contained in:
@@ -55,8 +55,8 @@ use crate::data_availability_checker::{AvailabilityCheckError, MaybeAvailableBlo
|
|||||||
use crate::data_column_verification::GossipDataColumnError;
|
use crate::data_column_verification::GossipDataColumnError;
|
||||||
use crate::eth1_finalization_cache::Eth1FinalizationData;
|
use crate::eth1_finalization_cache::Eth1FinalizationData;
|
||||||
use crate::execution_payload::{
|
use crate::execution_payload::{
|
||||||
is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block,
|
validate_execution_payload_for_gossip, validate_merge_block, AllowOptimisticImport,
|
||||||
AllowOptimisticImport, NotifyExecutionLayer, PayloadNotifier,
|
NotifyExecutionLayer, PayloadNotifier,
|
||||||
};
|
};
|
||||||
use crate::kzg_utils::blobs_to_data_column_sidecars;
|
use crate::kzg_utils::blobs_to_data_column_sidecars;
|
||||||
use crate::observed_block_producers::SeenBlock;
|
use crate::observed_block_producers::SeenBlock;
|
||||||
@@ -74,7 +74,7 @@ use lighthouse_metrics::TryExt;
|
|||||||
use parking_lot::RwLockReadGuard;
|
use parking_lot::RwLockReadGuard;
|
||||||
use proto_array::Block as ProtoBlock;
|
use proto_array::Block as ProtoBlock;
|
||||||
use safe_arith::ArithError;
|
use safe_arith::ArithError;
|
||||||
use slog::{debug, error, warn, Logger};
|
use slog::{debug, error, Logger};
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
@@ -95,9 +95,9 @@ use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp};
|
|||||||
use task_executor::JoinHandle;
|
use task_executor::JoinHandle;
|
||||||
use types::{
|
use types::{
|
||||||
data_column_sidecar::DataColumnSidecarError, BeaconBlockRef, BeaconState, BeaconStateError,
|
data_column_sidecar::DataColumnSidecarError, BeaconBlockRef, BeaconState, BeaconStateError,
|
||||||
BlobsList, ChainSpec, DataColumnSidecarList, Epoch, EthSpec, ExecPayload, ExecutionBlockHash,
|
BlobsList, ChainSpec, DataColumnSidecarList, Epoch, EthSpec, ExecutionBlockHash, FullPayload,
|
||||||
FullPayload, Hash256, InconsistentFork, PublicKey, PublicKeyBytes, RelativeEpoch,
|
Hash256, InconsistentFork, PublicKey, PublicKeyBytes, RelativeEpoch, SignedBeaconBlock,
|
||||||
SignedBeaconBlock, SignedBeaconBlockHeader, Slot,
|
SignedBeaconBlockHeader, Slot,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const POS_PANDA_BANNER: &str = r#"
|
pub const POS_PANDA_BANNER: &str = r#"
|
||||||
@@ -1388,28 +1388,6 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
|||||||
}
|
}
|
||||||
let payload_verification_status = payload_notifier.notify_new_payload().await?;
|
let payload_verification_status = payload_notifier.notify_new_payload().await?;
|
||||||
|
|
||||||
// If the payload did not validate or invalidate the block, check to see if this block is
|
|
||||||
// valid for optimistic import.
|
|
||||||
if payload_verification_status.is_optimistic() {
|
|
||||||
let block_hash_opt = block
|
|
||||||
.message()
|
|
||||||
.body()
|
|
||||||
.execution_payload()
|
|
||||||
.map(|full_payload| full_payload.block_hash());
|
|
||||||
|
|
||||||
// Ensure the block is a candidate for optimistic import.
|
|
||||||
if !is_optimistic_candidate_block(&chain, block.slot(), block.parent_root()).await?
|
|
||||||
{
|
|
||||||
warn!(
|
|
||||||
chain.log,
|
|
||||||
"Rejecting optimistic block";
|
|
||||||
"block_hash" => ?block_hash_opt,
|
|
||||||
"msg" => "the execution engine is not synced"
|
|
||||||
);
|
|
||||||
return Err(ExecutionPayloadError::UnverifiedNonOptimisticCandidate.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(PayloadVerificationOutcome {
|
Ok(PayloadVerificationOutcome {
|
||||||
payload_verification_status,
|
payload_verification_status,
|
||||||
is_valid_merge_transition_block,
|
is_valid_merge_transition_block,
|
||||||
|
|||||||
@@ -277,9 +277,7 @@ pub async fn validate_merge_block<'a, T: BeaconChainTypes>(
|
|||||||
}
|
}
|
||||||
.into()),
|
.into()),
|
||||||
None => {
|
None => {
|
||||||
if allow_optimistic_import == AllowOptimisticImport::Yes
|
if allow_optimistic_import == AllowOptimisticImport::Yes {
|
||||||
&& is_optimistic_candidate_block(chain, block.slot(), block.parent_root()).await?
|
|
||||||
{
|
|
||||||
debug!(
|
debug!(
|
||||||
chain.log,
|
chain.log,
|
||||||
"Optimistically importing merge transition block";
|
"Optimistically importing merge transition block";
|
||||||
@@ -297,36 +295,6 @@ pub async fn validate_merge_block<'a, T: BeaconChainTypes>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check to see if a block with the given parameters is valid to be imported optimistically.
|
|
||||||
pub async fn is_optimistic_candidate_block<T: BeaconChainTypes>(
|
|
||||||
chain: &Arc<BeaconChain<T>>,
|
|
||||||
block_slot: Slot,
|
|
||||||
block_parent_root: Hash256,
|
|
||||||
) -> Result<bool, BeaconChainError> {
|
|
||||||
let current_slot = chain.slot()?;
|
|
||||||
let inner_chain = chain.clone();
|
|
||||||
|
|
||||||
// Use a blocking task to check if the block is an optimistic candidate. Interacting
|
|
||||||
// with the `fork_choice` lock in an async task can block the core executor.
|
|
||||||
chain
|
|
||||||
.spawn_blocking_handle(
|
|
||||||
move || {
|
|
||||||
inner_chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_read_lock()
|
|
||||||
.is_optimistic_candidate_block(
|
|
||||||
current_slot,
|
|
||||||
block_slot,
|
|
||||||
&block_parent_root,
|
|
||||||
&inner_chain.spec,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
"validate_merge_block_optimistic_candidate",
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.map_err(BeaconChainError::from)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Validate the gossip block's execution_payload according to the checks described here:
|
/// Validate the gossip block's execution_payload according to the checks described here:
|
||||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/p2p-interface.md#beacon_block
|
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/p2p-interface.md#beacon_block
|
||||||
pub fn validate_execution_payload_for_gossip<T: BeaconChainTypes>(
|
pub fn validate_execution_payload_for_gossip<T: BeaconChainTypes>(
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
#![cfg(not(debug_assertions))]
|
#![cfg(not(debug_assertions))]
|
||||||
|
|
||||||
use beacon_chain::otb_verification_service::{
|
|
||||||
load_optimistic_transition_blocks, validate_optimistic_transition_blocks,
|
|
||||||
OptimisticTransitionBlock,
|
|
||||||
};
|
|
||||||
use beacon_chain::{
|
use beacon_chain::{
|
||||||
canonical_head::{CachedHead, CanonicalHead},
|
canonical_head::{CachedHead, CanonicalHead},
|
||||||
test_utils::{BeaconChainHarness, EphemeralHarnessType},
|
test_utils::{BeaconChainHarness, EphemeralHarnessType},
|
||||||
BeaconChainError, BlockError, ChainConfig, ExecutionPayloadError, NotifyExecutionLayer,
|
BeaconChainError, BlockError, ChainConfig, ExecutionPayloadError, NotifyExecutionLayer,
|
||||||
OverrideForkchoiceUpdate, StateSkipConfig, WhenSlotSkipped,
|
OverrideForkchoiceUpdate, StateSkipConfig, WhenSlotSkipped,
|
||||||
INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON,
|
|
||||||
INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON,
|
INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON,
|
||||||
};
|
};
|
||||||
use execution_layer::{
|
use execution_layer::{
|
||||||
json_structures::{JsonForkchoiceStateV1, JsonPayloadAttributes, JsonPayloadAttributesV1},
|
json_structures::{JsonForkchoiceStateV1, JsonPayloadAttributes, JsonPayloadAttributesV1},
|
||||||
test_utils::ExecutionBlockGenerator,
|
|
||||||
ExecutionLayer, ForkchoiceState, PayloadAttributes,
|
ExecutionLayer, ForkchoiceState, PayloadAttributes,
|
||||||
};
|
};
|
||||||
use fork_choice::{Error as ForkChoiceError, InvalidationOperation, PayloadVerificationStatus};
|
use fork_choice::{Error as ForkChoiceError, InvalidationOperation, PayloadVerificationStatus};
|
||||||
@@ -1270,552 +1264,6 @@ async fn attesting_to_optimistic_head() {
|
|||||||
get_aggregated_by_slot_and_root().unwrap();
|
get_aggregated_by_slot_and_root().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A helper struct to build out a chain of some configurable length which undergoes the merge
|
|
||||||
/// transition.
|
|
||||||
struct OptimisticTransitionSetup {
|
|
||||||
blocks: Vec<Arc<SignedBeaconBlock<E>>>,
|
|
||||||
execution_block_generator: ExecutionBlockGenerator<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OptimisticTransitionSetup {
|
|
||||||
async fn new(num_blocks: usize, ttd: u64) -> Self {
|
|
||||||
let mut spec = E::default_spec();
|
|
||||||
spec.terminal_total_difficulty = Uint256::from(ttd);
|
|
||||||
let mut rig = InvalidPayloadRig::new_with_spec(spec).enable_attestations();
|
|
||||||
rig.move_to_terminal_block();
|
|
||||||
|
|
||||||
let mut blocks = Vec::with_capacity(num_blocks);
|
|
||||||
for _ in 0..num_blocks {
|
|
||||||
let root = rig.import_block(Payload::Valid).await;
|
|
||||||
let block = rig.harness.chain.get_block(&root).await.unwrap().unwrap();
|
|
||||||
blocks.push(Arc::new(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
let execution_block_generator = rig
|
|
||||||
.harness
|
|
||||||
.mock_execution_layer
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.server
|
|
||||||
.execution_block_generator()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
blocks,
|
|
||||||
execution_block_generator,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a chain which has optimistically imported a transition block.
|
|
||||||
///
|
|
||||||
/// The initial chain will be built with respect to `block_ttd`, whilst the `rig` which imports the
|
|
||||||
/// chain will operate with respect to `rig_ttd`. This allows for testing mismatched TTDs.
|
|
||||||
async fn build_optimistic_chain(
|
|
||||||
block_ttd: u64,
|
|
||||||
rig_ttd: u64,
|
|
||||||
num_blocks: usize,
|
|
||||||
) -> InvalidPayloadRig {
|
|
||||||
let OptimisticTransitionSetup {
|
|
||||||
blocks,
|
|
||||||
execution_block_generator,
|
|
||||||
} = OptimisticTransitionSetup::new(num_blocks, block_ttd).await;
|
|
||||||
// Build a brand-new testing harness. We will apply the blocks from the previous harness to
|
|
||||||
// this one.
|
|
||||||
let mut spec = E::default_spec();
|
|
||||||
spec.terminal_total_difficulty = Uint256::from(rig_ttd);
|
|
||||||
let rig = InvalidPayloadRig::new_with_spec(spec);
|
|
||||||
|
|
||||||
let spec = &rig.harness.chain.spec;
|
|
||||||
let mock_execution_layer = rig.harness.mock_execution_layer.as_ref().unwrap();
|
|
||||||
|
|
||||||
// Ensure all the execution blocks from the first rig are available in the second rig.
|
|
||||||
*mock_execution_layer.server.execution_block_generator() = execution_block_generator;
|
|
||||||
|
|
||||||
// Make the execution layer respond `SYNCING` to all `newPayload` requests.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_payloads_syncing_on_new_payload(true);
|
|
||||||
// Make the execution layer respond `SYNCING` to all `forkchoiceUpdated` requests.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_payloads_syncing_on_forkchoice_updated();
|
|
||||||
// Make the execution layer respond `None` to all `getBlockByHash` requests.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_get_block_by_hash_requests_return_none();
|
|
||||||
|
|
||||||
let current_slot = std::cmp::max(
|
|
||||||
blocks[0].slot() + spec.safe_slots_to_import_optimistically,
|
|
||||||
num_blocks.into(),
|
|
||||||
);
|
|
||||||
rig.harness.set_current_slot(current_slot);
|
|
||||||
|
|
||||||
for block in blocks {
|
|
||||||
rig.harness
|
|
||||||
.chain
|
|
||||||
.process_block(
|
|
||||||
block.canonical_root(),
|
|
||||||
block,
|
|
||||||
NotifyExecutionLayer::Yes,
|
|
||||||
BlockImportSource::Lookup,
|
|
||||||
|| Ok(()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
rig.harness.chain.recompute_head_at_current_slot().await;
|
|
||||||
|
|
||||||
// Make the execution layer respond normally to `getBlockByHash` requests.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_get_block_by_hash_requests_return_natural_value();
|
|
||||||
|
|
||||||
// Perform some sanity checks to ensure that the transition happened exactly where we expected.
|
|
||||||
let pre_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(0), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let pre_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&pre_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
pre_transition_block_root,
|
|
||||||
post_transition_block.parent_root(),
|
|
||||||
"the blocks form a single chain"
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
pre_transition_block
|
|
||||||
.message()
|
|
||||||
.body()
|
|
||||||
.execution_payload()
|
|
||||||
.unwrap()
|
|
||||||
.is_default_with_empty_roots(),
|
|
||||||
"the block *has not* undergone the merge transition"
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
!post_transition_block
|
|
||||||
.message()
|
|
||||||
.body()
|
|
||||||
.execution_payload()
|
|
||||||
.unwrap()
|
|
||||||
.is_default_with_empty_roots(),
|
|
||||||
"the block *has* undergone the merge transition"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Assert that the transition block was optimistically imported.
|
|
||||||
//
|
|
||||||
// Note: we're using the "fallback" check for optimistic status, so if the block was
|
|
||||||
// pre-finality then we'll just use the optimistic status of the finalized block.
|
|
||||||
assert!(
|
|
||||||
rig.harness
|
|
||||||
.chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_read_lock()
|
|
||||||
.is_optimistic_or_invalid_block(&post_transition_block_root)
|
|
||||||
.unwrap(),
|
|
||||||
"the transition block should be imported optimistically"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get the mock execution layer to respond to `getBlockByHash` requests normally again.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_get_block_by_hash_requests_return_natural_value();
|
|
||||||
|
|
||||||
rig
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn optimistic_transition_block_valid_unfinalized() {
|
|
||||||
let ttd = 42;
|
|
||||||
let num_blocks = 16_usize;
|
|
||||||
let rig = build_optimistic_chain(ttd, ttd, num_blocks).await;
|
|
||||||
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
rig.cached_head()
|
|
||||||
.finalized_checkpoint()
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch())
|
|
||||||
< post_transition_block.slot(),
|
|
||||||
"the transition block should not be finalized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"There should be one optimistic transition block"
|
|
||||||
);
|
|
||||||
let valid_otb = OptimisticTransitionBlock::from_block(post_transition_block.message());
|
|
||||||
assert_eq!(
|
|
||||||
valid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.expect("should validate fine");
|
|
||||||
// now that the transition block has been validated, it should have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert!(
|
|
||||||
otbs.is_empty(),
|
|
||||||
"The valid optimistic transition block should have been removed from the database",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn optimistic_transition_block_valid_finalized() {
|
|
||||||
let ttd = 42;
|
|
||||||
let num_blocks = 130_usize;
|
|
||||||
let rig = build_optimistic_chain(ttd, ttd, num_blocks).await;
|
|
||||||
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
rig.cached_head()
|
|
||||||
.finalized_checkpoint()
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch())
|
|
||||||
> post_transition_block.slot(),
|
|
||||||
"the transition block should be finalized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"There should be one optimistic transition block"
|
|
||||||
);
|
|
||||||
let valid_otb = OptimisticTransitionBlock::from_block(post_transition_block.message());
|
|
||||||
assert_eq!(
|
|
||||||
valid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.expect("should validate fine");
|
|
||||||
// now that the transition block has been validated, it should have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert!(
|
|
||||||
otbs.is_empty(),
|
|
||||||
"The valid optimistic transition block should have been removed from the database",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn optimistic_transition_block_invalid_unfinalized() {
|
|
||||||
let block_ttd = 42;
|
|
||||||
let rig_ttd = 1337;
|
|
||||||
let num_blocks = 22_usize;
|
|
||||||
let rig = build_optimistic_chain(block_ttd, rig_ttd, num_blocks).await;
|
|
||||||
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
rig.cached_head()
|
|
||||||
.finalized_checkpoint()
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch())
|
|
||||||
< post_transition_block.slot(),
|
|
||||||
"the transition block should not be finalized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"There should be one optimistic transition block"
|
|
||||||
);
|
|
||||||
|
|
||||||
let invalid_otb = OptimisticTransitionBlock::from_block(post_transition_block.message());
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
// No shutdown should've been triggered.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
// It shouldn't be known as invalid yet
|
|
||||||
assert!(!rig
|
|
||||||
.execution_status(post_transition_block_root)
|
|
||||||
.is_invalid());
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Still no shutdown should've been triggered.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
// It should be marked invalid now
|
|
||||||
assert!(rig
|
|
||||||
.execution_status(post_transition_block_root)
|
|
||||||
.is_invalid());
|
|
||||||
|
|
||||||
// the invalid merge transition block should NOT have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"The invalid merge transition block should still be in the database",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn optimistic_transition_block_invalid_unfinalized_syncing_ee() {
|
|
||||||
let block_ttd = 42;
|
|
||||||
let rig_ttd = 1337;
|
|
||||||
let num_blocks = 22_usize;
|
|
||||||
let rig = build_optimistic_chain(block_ttd, rig_ttd, num_blocks).await;
|
|
||||||
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
rig.cached_head()
|
|
||||||
.finalized_checkpoint()
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch())
|
|
||||||
< post_transition_block.slot(),
|
|
||||||
"the transition block should not be finalized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"There should be one optimistic transition block"
|
|
||||||
);
|
|
||||||
|
|
||||||
let invalid_otb = OptimisticTransitionBlock::from_block(post_transition_block.message());
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
// No shutdown should've been triggered.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
// It shouldn't be known as invalid yet
|
|
||||||
assert!(!rig
|
|
||||||
.execution_status(post_transition_block_root)
|
|
||||||
.is_invalid());
|
|
||||||
|
|
||||||
// Make the execution layer respond `None` to all `getBlockByHash` requests to simulate a
|
|
||||||
// syncing EE.
|
|
||||||
let mock_execution_layer = rig.harness.mock_execution_layer.as_ref().unwrap();
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_get_block_by_hash_requests_return_none();
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Still no shutdown should've been triggered.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
|
|
||||||
// It should still be marked as optimistic.
|
|
||||||
assert!(rig
|
|
||||||
.execution_status(post_transition_block_root)
|
|
||||||
.is_strictly_optimistic());
|
|
||||||
|
|
||||||
// the optimistic merge transition block should NOT have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"The optimistic merge transition block should still be in the database",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
// Allow the EL to respond to `getBlockByHash`, as if it has finished syncing.
|
|
||||||
mock_execution_layer
|
|
||||||
.server
|
|
||||||
.all_get_block_by_hash_requests_return_natural_value();
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Still no shutdown should've been triggered.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
// It should be marked invalid now
|
|
||||||
assert!(rig
|
|
||||||
.execution_status(post_transition_block_root)
|
|
||||||
.is_invalid());
|
|
||||||
|
|
||||||
// the invalid merge transition block should NOT have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"The invalid merge transition block should still be in the database",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn optimistic_transition_block_invalid_finalized() {
|
|
||||||
let block_ttd = 42;
|
|
||||||
let rig_ttd = 1337;
|
|
||||||
let num_blocks = 130_usize;
|
|
||||||
let rig = build_optimistic_chain(block_ttd, rig_ttd, num_blocks).await;
|
|
||||||
|
|
||||||
let post_transition_block_root = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.block_root_at_slot(Slot::new(1), WhenSlotSkipped::None)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
let post_transition_block = rig
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.get_block(&post_transition_block_root)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
rig.cached_head()
|
|
||||||
.finalized_checkpoint()
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch())
|
|
||||||
> post_transition_block.slot(),
|
|
||||||
"the transition block should be finalized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"There should be one optimistic transition block"
|
|
||||||
);
|
|
||||||
|
|
||||||
let invalid_otb = OptimisticTransitionBlock::from_block(post_transition_block.message());
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
|
|
||||||
// No shutdown should've been triggered yet.
|
|
||||||
assert_eq!(rig.harness.shutdown_reasons(), vec![]);
|
|
||||||
|
|
||||||
validate_optimistic_transition_blocks(&rig.harness.chain, otbs)
|
|
||||||
.await
|
|
||||||
.expect("should invalidate merge transition block and shutdown the client");
|
|
||||||
|
|
||||||
// The beacon chain should have triggered a shutdown.
|
|
||||||
assert_eq!(
|
|
||||||
rig.harness.shutdown_reasons(),
|
|
||||||
vec![ShutdownReason::Failure(
|
|
||||||
INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
|
|
||||||
// the invalid merge transition block should NOT have been removed from the database
|
|
||||||
let otbs = load_optimistic_transition_blocks(&rig.harness.chain)
|
|
||||||
.expect("should load optimistic transition block from db");
|
|
||||||
assert_eq!(
|
|
||||||
otbs.len(),
|
|
||||||
1,
|
|
||||||
"The invalid merge transition block should still be in the database",
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
invalid_otb, otbs[0],
|
|
||||||
"The optimistic transition block stored in the database should be what we expect",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper for running tests where we generate a chain with an invalid head and then a
|
/// Helper for running tests where we generate a chain with an invalid head and then a
|
||||||
/// `fork_block` to recover it.
|
/// `fork_block` to recover it.
|
||||||
struct InvalidHeadSetup {
|
struct InvalidHeadSetup {
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ Example Response Body
|
|||||||
"TERMINAL_TOTAL_DIFFICULTY": "10790000",
|
"TERMINAL_TOTAL_DIFFICULTY": "10790000",
|
||||||
"TERMINAL_BLOCK_HASH": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
"TERMINAL_BLOCK_HASH": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH": "18446744073709551615",
|
"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH": "18446744073709551615",
|
||||||
"SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY": "128",
|
|
||||||
"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT": "16384",
|
"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT": "16384",
|
||||||
"MIN_GENESIS_TIME": "1614588812",
|
"MIN_GENESIS_TIME": "1614588812",
|
||||||
"GENESIS_FORK_VERSION": "0x00001020",
|
"GENESIS_FORK_VERSION": "0x00001020",
|
||||||
@@ -263,7 +262,6 @@ Example Response Body
|
|||||||
"HYSTERESIS_QUOTIENT": "4",
|
"HYSTERESIS_QUOTIENT": "4",
|
||||||
"HYSTERESIS_DOWNWARD_MULTIPLIER": "1",
|
"HYSTERESIS_DOWNWARD_MULTIPLIER": "1",
|
||||||
"HYSTERESIS_UPWARD_MULTIPLIER": "5",
|
"HYSTERESIS_UPWARD_MULTIPLIER": "5",
|
||||||
"SAFE_SLOTS_TO_UPDATE_JUSTIFIED": "8",
|
|
||||||
"MIN_DEPOSIT_AMOUNT": "1000000000",
|
"MIN_DEPOSIT_AMOUNT": "1000000000",
|
||||||
"MAX_EFFECTIVE_BALANCE": "32000000000",
|
"MAX_EFFECTIVE_BALANCE": "32000000000",
|
||||||
"EFFECTIVE_BALANCE_INCREMENT": "1000000000",
|
"EFFECTIVE_BALANCE_INCREMENT": "1000000000",
|
||||||
|
|||||||
@@ -326,14 +326,6 @@ Options:
|
|||||||
--quic-port6 <PORT>
|
--quic-port6 <PORT>
|
||||||
The UDP port that quic will listen on over IPv6 if listening over both
|
The UDP port that quic will listen on over IPv6 if listening over both
|
||||||
IPv4 and IPv6. Defaults to `port6` + 1
|
IPv4 and IPv6. Defaults to `port6` + 1
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
--self-limiter-protocols <self-limiter-protocols>
|
--self-limiter-protocols <self-limiter-protocols>
|
||||||
Enables the outbound rate limiter (requests made by this node).Rate
|
Enables the outbound rate limiter (requests made by this node).Rate
|
||||||
limit quotas per protocol can be set in the form of
|
limit quotas per protocol can be set in the form of
|
||||||
@@ -387,27 +379,6 @@ Options:
|
|||||||
database.
|
database.
|
||||||
--target-peers <target-peers>
|
--target-peers <target-peers>
|
||||||
The target number of peers.
|
The target number of peers.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
--trusted-peers <TRUSTED_PEERS>
|
--trusted-peers <TRUSTED_PEERS>
|
||||||
One or more comma-delimited trusted peer ids which always have the
|
One or more comma-delimited trusted peer ids which always have the
|
||||||
highest score according to the peer scoring system.
|
highest score according to the peer scoring system.
|
||||||
|
|||||||
@@ -77,39 +77,10 @@ Options:
|
|||||||
--network <network>
|
--network <network>
|
||||||
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
||||||
values: mainnet, gnosis, chiado, sepolia, holesky]
|
values: mainnet, gnosis, chiado, sepolia, holesky]
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
-t, --testnet-dir <DIR>
|
-t, --testnet-dir <DIR>
|
||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
-V, --version
|
-V, --version
|
||||||
Print version
|
Print version
|
||||||
|
|
||||||
|
|||||||
@@ -118,14 +118,6 @@ Options:
|
|||||||
specify nodes that are used to send beacon block proposals. A failure
|
specify nodes that are used to send beacon block proposals. A failure
|
||||||
will revert back to the standard beacon nodes specified in
|
will revert back to the standard beacon nodes specified in
|
||||||
--beacon-nodes.
|
--beacon-nodes.
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
--secrets-dir <SECRETS_DIRECTORY>
|
--secrets-dir <SECRETS_DIRECTORY>
|
||||||
The directory which contains the password to unlock the validator
|
The directory which contains the password to unlock the validator
|
||||||
voting keypairs. Each password should be contained in a file where the
|
voting keypairs. Each password should be contained in a file where the
|
||||||
@@ -140,27 +132,6 @@ Options:
|
|||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
--validator-registration-batch-size <INTEGER>
|
--validator-registration-batch-size <INTEGER>
|
||||||
Defines the number of validators per validator/register_validator
|
Defines the number of validators per validator/register_validator
|
||||||
request sent to the BN. This value can be reduced to avoid timeouts
|
request sent to the BN. This value can be reduced to avoid timeouts
|
||||||
|
|||||||
@@ -69,39 +69,10 @@ Options:
|
|||||||
--network <network>
|
--network <network>
|
||||||
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
||||||
values: mainnet, gnosis, chiado, sepolia, holesky]
|
values: mainnet, gnosis, chiado, sepolia, holesky]
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
-t, --testnet-dir <DIR>
|
-t, --testnet-dir <DIR>
|
||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
--disable-log-timestamp
|
--disable-log-timestamp
|
||||||
|
|||||||
@@ -91,14 +91,6 @@ Options:
|
|||||||
If this flag is set, Lighthouse will always prefer blocks constructed
|
If this flag is set, Lighthouse will always prefer blocks constructed
|
||||||
by builders, regardless of payload value. [possible values: true,
|
by builders, regardless of payload value. [possible values: true,
|
||||||
false]
|
false]
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
--suggested-fee-recipient <ETH1_ADDRESS>
|
--suggested-fee-recipient <ETH1_ADDRESS>
|
||||||
All created validators will use this value for the suggested fee
|
All created validators will use this value for the suggested fee
|
||||||
recipient. Omit this flag to use the default value from the VC.
|
recipient. Omit this flag to use the default value from the VC.
|
||||||
@@ -106,27 +98,6 @@ Options:
|
|||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
--disable-deposits
|
--disable-deposits
|
||||||
|
|||||||
@@ -50,39 +50,10 @@ Options:
|
|||||||
--network <network>
|
--network <network>
|
||||||
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
Name of the Eth2 chain Lighthouse will sync and follow. [possible
|
||||||
values: mainnet, gnosis, chiado, sepolia, holesky]
|
values: mainnet, gnosis, chiado, sepolia, holesky]
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
-t, --testnet-dir <DIR>
|
-t, --testnet-dir <DIR>
|
||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
--validators-file <PATH_TO_JSON_FILE>
|
--validators-file <PATH_TO_JSON_FILE>
|
||||||
The path to a JSON file containing a list of validators to be imported
|
The path to a JSON file containing a list of validators to be imported
|
||||||
to the validator client. This file is usually named "validators.json".
|
to the validator client. This file is usually named "validators.json".
|
||||||
|
|||||||
@@ -74,14 +74,6 @@ Options:
|
|||||||
If this flag is set, Lighthouse will always prefer blocks constructed
|
If this flag is set, Lighthouse will always prefer blocks constructed
|
||||||
by builders, regardless of payload value. [possible values: true,
|
by builders, regardless of payload value. [possible values: true,
|
||||||
false]
|
false]
|
||||||
--safe-slots-to-import-optimistically <INTEGER>
|
|
||||||
Used to coordinate manual overrides of the
|
|
||||||
SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override this parameter in the event of an
|
|
||||||
attack at the PoS transition block. Incorrect use of this flag can
|
|
||||||
cause your node to possibly accept an invalid chain or sync more
|
|
||||||
slowly. Be extremely careful with this flag.
|
|
||||||
--src-vc-token <PATH>
|
--src-vc-token <PATH>
|
||||||
The file containing a token required by the source validator client.
|
The file containing a token required by the source validator client.
|
||||||
--src-vc-url <HTTP_ADDRESS>
|
--src-vc-url <HTTP_ADDRESS>
|
||||||
@@ -95,27 +87,6 @@ Options:
|
|||||||
Path to directory containing eth2_testnet specs. Defaults to a
|
Path to directory containing eth2_testnet specs. Defaults to a
|
||||||
hard-coded Lighthouse testnet. Only effective if there is no existing
|
hard-coded Lighthouse testnet. Only effective if there is no existing
|
||||||
database.
|
database.
|
||||||
--terminal-block-hash-epoch-override <EPOCH>
|
|
||||||
Used to coordinate manual overrides to the
|
|
||||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH parameter. This flag should only
|
|
||||||
be used if the user has a clear understanding that the broad Ethereum
|
|
||||||
community has elected to override the terminal PoW block. Incorrect
|
|
||||||
use of this flag will cause your node to experience a consensus
|
|
||||||
failure. Be extremely careful with this flag.
|
|
||||||
--terminal-block-hash-override <TERMINAL_BLOCK_HASH>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH
|
|
||||||
parameter. This flag should only be used if the user has a clear
|
|
||||||
understanding that the broad Ethereum community has elected to
|
|
||||||
override the terminal PoW block. Incorrect use of this flag will cause
|
|
||||||
your node to experience a consensus failure. Be extremely careful with
|
|
||||||
this flag.
|
|
||||||
--terminal-total-difficulty-override <INTEGER>
|
|
||||||
Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY
|
|
||||||
parameter. Accepts a 256-bit decimal integer (not a hex value). This
|
|
||||||
flag should only be used if the user has a clear understanding that
|
|
||||||
the broad Ethereum community has elected to override the terminal
|
|
||||||
difficulty. Incorrect use of this flag will cause your node to
|
|
||||||
experience a consensus failure. Be extremely careful with this flag.
|
|
||||||
--validators <STRING>
|
--validators <STRING>
|
||||||
The validators to be moved. Either a list of 0x-prefixed validator
|
The validators to be moved. Either a list of 0x-prefixed validator
|
||||||
pubkeys or the keyword "all".
|
pubkeys or the keyword "all".
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
//! A helper library for parsing values from `clap::ArgMatches`.
|
//! A helper library for parsing values from `clap::ArgMatches`.
|
||||||
|
|
||||||
use alloy_primitives::U256 as Uint256;
|
|
||||||
use clap::builder::styling::*;
|
use clap::builder::styling::*;
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK};
|
use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK};
|
||||||
@@ -30,38 +29,9 @@ pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result<Eth2NetworkConfi
|
|||||||
Eth2NetworkConfig::constant(DEFAULT_HARDCODED_NETWORK)?
|
Eth2NetworkConfig::constant(DEFAULT_HARDCODED_NETWORK)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut eth2_network_config =
|
let eth2_network_config =
|
||||||
optional_network_config.ok_or_else(|| BAD_TESTNET_DIR_MESSAGE.to_string())?;
|
optional_network_config.ok_or_else(|| BAD_TESTNET_DIR_MESSAGE.to_string())?;
|
||||||
|
|
||||||
if let Some(string) = parse_optional::<String>(cli_args, "terminal-total-difficulty-override")?
|
|
||||||
{
|
|
||||||
let stripped = string.replace(',', "");
|
|
||||||
let terminal_total_difficulty = Uint256::from_str(&stripped).map_err(|e| {
|
|
||||||
format!(
|
|
||||||
"Could not parse --terminal-total-difficulty-override as decimal value: {:?}",
|
|
||||||
e
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
eth2_network_config.config.terminal_total_difficulty = terminal_total_difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(hash) = parse_optional(cli_args, "terminal-block-hash-override")? {
|
|
||||||
eth2_network_config.config.terminal_block_hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(epoch) = parse_optional(cli_args, "terminal-block-hash-epoch-override")? {
|
|
||||||
eth2_network_config
|
|
||||||
.config
|
|
||||||
.terminal_block_hash_activation_epoch = epoch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(slots) = parse_optional(cli_args, "safe-slots-to-import-optimistically")? {
|
|
||||||
eth2_network_config
|
|
||||||
.config
|
|
||||||
.safe_slots_to_import_optimistically = slots;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(eth2_network_config)
|
Ok(eth2_network_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1300,43 +1300,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Ok(false)` if a block is not viable to be imported optimistically.
|
|
||||||
///
|
|
||||||
/// ## Notes
|
|
||||||
///
|
|
||||||
/// Equivalent to the function with the same name in the optimistic sync specs:
|
|
||||||
///
|
|
||||||
/// https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md#helpers
|
|
||||||
pub fn is_optimistic_candidate_block(
|
|
||||||
&self,
|
|
||||||
current_slot: Slot,
|
|
||||||
block_slot: Slot,
|
|
||||||
block_parent_root: &Hash256,
|
|
||||||
spec: &ChainSpec,
|
|
||||||
) -> Result<bool, Error<T::Error>> {
|
|
||||||
// If the block is sufficiently old, import it.
|
|
||||||
if block_slot + spec.safe_slots_to_import_optimistically <= current_slot {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the parent block has execution enabled, always import the block.
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
//
|
|
||||||
// https://github.com/ethereum/consensus-specs/pull/2844
|
|
||||||
if self
|
|
||||||
.proto_array
|
|
||||||
.get_block(block_parent_root)
|
|
||||||
.map_or(false, |parent| {
|
|
||||||
parent.execution_status.is_execution_enabled()
|
|
||||||
})
|
|
||||||
{
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the current finalized checkpoint.
|
/// Return the current finalized checkpoint.
|
||||||
pub fn finalized_checkpoint(&self) -> Checkpoint {
|
pub fn finalized_checkpoint(&self) -> Checkpoint {
|
||||||
*self.fc_store.finalized_checkpoint()
|
*self.fc_store.finalized_checkpoint()
|
||||||
|
|||||||
@@ -256,36 +256,6 @@ impl ForkChoiceTest {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves to the next slot that is *outside* the `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` range.
|
|
||||||
///
|
|
||||||
/// If the chain is presently in an unsafe period, transition through it and the following safe
|
|
||||||
/// period.
|
|
||||||
///
|
|
||||||
/// Note: the `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` variable has been removed
|
|
||||||
/// from the fork choice spec in Q1 2023. We're still leaving references to
|
|
||||||
/// it in our tests because (a) it's easier and (b) it allows us to easily
|
|
||||||
/// test for the absence of that parameter.
|
|
||||||
pub fn move_to_next_unsafe_period(self) -> Self {
|
|
||||||
self.move_inside_safe_to_update()
|
|
||||||
.move_outside_safe_to_update()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves to the next slot that is *outside* the `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` range.
|
|
||||||
pub fn move_outside_safe_to_update(self) -> Self {
|
|
||||||
while is_safe_to_update(self.harness.chain.slot().unwrap(), &self.harness.chain.spec) {
|
|
||||||
self.harness.advance_slot()
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves to the next slot that is *inside* the `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` range.
|
|
||||||
pub fn move_inside_safe_to_update(self) -> Self {
|
|
||||||
while !is_safe_to_update(self.harness.chain.slot().unwrap(), &self.harness.chain.spec) {
|
|
||||||
self.harness.advance_slot()
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies a block directly to fork choice, bypassing the beacon chain.
|
/// Applies a block directly to fork choice, bypassing the beacon chain.
|
||||||
///
|
///
|
||||||
/// Asserts the block was applied successfully.
|
/// Asserts the block was applied successfully.
|
||||||
@@ -516,10 +486,6 @@ impl ForkChoiceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_safe_to_update(slot: Slot, spec: &ChainSpec) -> bool {
|
|
||||||
slot % E::slots_per_epoch() < spec.safe_slots_to_update_justified
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn justified_and_finalized_blocks() {
|
fn justified_and_finalized_blocks() {
|
||||||
let tester = ForkChoiceTest::new();
|
let tester = ForkChoiceTest::new();
|
||||||
@@ -536,15 +502,13 @@ fn justified_and_finalized_blocks() {
|
|||||||
assert!(fork_choice.get_finalized_block().is_ok());
|
assert!(fork_choice.get_finalized_block().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// - The new justified checkpoint descends from the current.
|
/// - The new justified checkpoint descends from the current. Near genesis.
|
||||||
/// - Current slot is within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn justified_checkpoint_updates_with_descendent_inside_safe_slots() {
|
async fn justified_checkpoint_updates_with_descendent_first_justification() {
|
||||||
ForkChoiceTest::new()
|
ForkChoiceTest::new()
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.move_inside_safe_to_update()
|
|
||||||
.assert_justified_epoch(0)
|
.assert_justified_epoch(0)
|
||||||
.apply_blocks(1)
|
.apply_blocks(1)
|
||||||
.await
|
.await
|
||||||
@@ -552,49 +516,29 @@ async fn justified_checkpoint_updates_with_descendent_inside_safe_slots() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// - The new justified checkpoint descends from the current.
|
/// - The new justified checkpoint descends from the current.
|
||||||
/// - Current slot is **not** within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`
|
|
||||||
/// - This is **not** the first justification since genesis
|
/// - This is **not** the first justification since genesis
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn justified_checkpoint_updates_with_descendent_outside_safe_slots() {
|
async fn justified_checkpoint_updates_with_descendent() {
|
||||||
ForkChoiceTest::new()
|
ForkChoiceTest::new()
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch <= 2)
|
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch <= 2)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.move_outside_safe_to_update()
|
|
||||||
.assert_justified_epoch(2)
|
.assert_justified_epoch(2)
|
||||||
.apply_blocks(1)
|
.apply_blocks(1)
|
||||||
.await
|
.await
|
||||||
.assert_justified_epoch(3);
|
.assert_justified_epoch(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// - The new justified checkpoint descends from the current.
|
|
||||||
/// - Current slot is **not** within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`
|
|
||||||
/// - This is the first justification since genesis
|
|
||||||
#[tokio::test]
|
|
||||||
async fn justified_checkpoint_updates_first_justification_outside_safe_to_update() {
|
|
||||||
ForkChoiceTest::new()
|
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.move_to_next_unsafe_period()
|
|
||||||
.assert_justified_epoch(0)
|
|
||||||
.apply_blocks(1)
|
|
||||||
.await
|
|
||||||
.assert_justified_epoch(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// - The new justified checkpoint **does not** descend from the current.
|
/// - The new justified checkpoint **does not** descend from the current.
|
||||||
/// - Current slot is within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`
|
|
||||||
/// - Finalized epoch has **not** increased.
|
/// - Finalized epoch has **not** increased.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn justified_checkpoint_updates_with_non_descendent_inside_safe_slots_without_finality() {
|
async fn justified_checkpoint_updates_with_non_descendent() {
|
||||||
ForkChoiceTest::new()
|
ForkChoiceTest::new()
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.apply_blocks(1)
|
.apply_blocks(1)
|
||||||
.await
|
.await
|
||||||
.move_inside_safe_to_update()
|
|
||||||
.assert_justified_epoch(2)
|
.assert_justified_epoch(2)
|
||||||
.apply_block_directly_to_fork_choice(|_, state| {
|
.apply_block_directly_to_fork_choice(|_, state| {
|
||||||
// The finalized checkpoint should not change.
|
// The finalized checkpoint should not change.
|
||||||
@@ -611,64 +555,6 @@ async fn justified_checkpoint_updates_with_non_descendent_inside_safe_slots_with
|
|||||||
.assert_justified_epoch(3);
|
.assert_justified_epoch(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// - The new justified checkpoint **does not** descend from the current.
|
|
||||||
/// - Current slot is **not** within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`.
|
|
||||||
/// - Finalized epoch has **not** increased.
|
|
||||||
#[tokio::test]
|
|
||||||
async fn justified_checkpoint_updates_with_non_descendent_outside_safe_slots_without_finality() {
|
|
||||||
ForkChoiceTest::new()
|
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.apply_blocks(1)
|
|
||||||
.await
|
|
||||||
.move_to_next_unsafe_period()
|
|
||||||
.assert_justified_epoch(2)
|
|
||||||
.apply_block_directly_to_fork_choice(|_, state| {
|
|
||||||
// The finalized checkpoint should not change.
|
|
||||||
state.finalized_checkpoint().epoch = Epoch::new(0);
|
|
||||||
|
|
||||||
// The justified checkpoint has changed.
|
|
||||||
state.current_justified_checkpoint_mut().epoch = Epoch::new(3);
|
|
||||||
// The new block should **not** include the current justified block as an ancestor.
|
|
||||||
state.current_justified_checkpoint_mut().root = *state
|
|
||||||
.get_block_root(Epoch::new(1).start_slot(E::slots_per_epoch()))
|
|
||||||
.unwrap();
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
// Now that `SAFE_SLOTS_TO_UPDATE_JUSTIFIED` has been removed, the new
|
|
||||||
// block should have updated the justified checkpoint.
|
|
||||||
.assert_justified_epoch(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// - The new justified checkpoint **does not** descend from the current.
|
|
||||||
/// - Current slot is **not** within `SAFE_SLOTS_TO_UPDATE_JUSTIFIED`
|
|
||||||
/// - Finalized epoch has increased.
|
|
||||||
#[tokio::test]
|
|
||||||
async fn justified_checkpoint_updates_with_non_descendent_outside_safe_slots_with_finality() {
|
|
||||||
ForkChoiceTest::new()
|
|
||||||
.apply_blocks_while(|_, state| state.current_justified_checkpoint().epoch == 0)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.apply_blocks(1)
|
|
||||||
.await
|
|
||||||
.move_to_next_unsafe_period()
|
|
||||||
.assert_justified_epoch(2)
|
|
||||||
.apply_block_directly_to_fork_choice(|_, state| {
|
|
||||||
// The finalized checkpoint should change.
|
|
||||||
state.finalized_checkpoint_mut().epoch = Epoch::new(1);
|
|
||||||
|
|
||||||
// The justified checkpoint has changed.
|
|
||||||
state.current_justified_checkpoint_mut().epoch = Epoch::new(3);
|
|
||||||
// The new block should **not** include the current justified block as an ancestor.
|
|
||||||
state.current_justified_checkpoint_mut().root = *state
|
|
||||||
.get_block_root(Epoch::new(1).start_slot(E::slots_per_epoch()))
|
|
||||||
.unwrap();
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.assert_justified_epoch(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the balances are obtained correctly.
|
/// Check that the balances are obtained correctly.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn justified_balances() {
|
async fn justified_balances() {
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
|||||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
|
|
||||||
|
|
||||||
# Fork Choice
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2**3 (= 8)
|
|
||||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
|
|
||||||
|
|
||||||
|
|
||||||
# Gwei values
|
# Gwei values
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
|||||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
|
|
||||||
|
|
||||||
# Fork Choice
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2**3 (= 8)
|
|
||||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
|
|
||||||
|
|
||||||
|
|
||||||
# Gwei values
|
# Gwei values
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
|||||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
|
|
||||||
|
|
||||||
# Fork Choice
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2**1 (= 1)
|
|
||||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 2
|
|
||||||
|
|
||||||
|
|
||||||
# Gwei values
|
# Gwei values
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ pub struct ChainSpec {
|
|||||||
/*
|
/*
|
||||||
* Fork choice
|
* Fork choice
|
||||||
*/
|
*/
|
||||||
pub safe_slots_to_update_justified: u64,
|
|
||||||
pub proposer_score_boost: Option<u64>,
|
pub proposer_score_boost: Option<u64>,
|
||||||
pub reorg_head_weight_threshold: Option<u64>,
|
pub reorg_head_weight_threshold: Option<u64>,
|
||||||
pub reorg_parent_weight_threshold: Option<u64>,
|
pub reorg_parent_weight_threshold: Option<u64>,
|
||||||
@@ -157,7 +156,6 @@ pub struct ChainSpec {
|
|||||||
pub terminal_total_difficulty: Uint256,
|
pub terminal_total_difficulty: Uint256,
|
||||||
pub terminal_block_hash: ExecutionBlockHash,
|
pub terminal_block_hash: ExecutionBlockHash,
|
||||||
pub terminal_block_hash_activation_epoch: Epoch,
|
pub terminal_block_hash_activation_epoch: Epoch,
|
||||||
pub safe_slots_to_import_optimistically: u64,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Capella hard fork params
|
* Capella hard fork params
|
||||||
@@ -705,7 +703,6 @@ impl ChainSpec {
|
|||||||
/*
|
/*
|
||||||
* Fork choice
|
* Fork choice
|
||||||
*/
|
*/
|
||||||
safe_slots_to_update_justified: 8,
|
|
||||||
proposer_score_boost: Some(40),
|
proposer_score_boost: Some(40),
|
||||||
reorg_head_weight_threshold: Some(20),
|
reorg_head_weight_threshold: Some(20),
|
||||||
reorg_parent_weight_threshold: Some(160),
|
reorg_parent_weight_threshold: Some(160),
|
||||||
@@ -756,7 +753,6 @@ impl ChainSpec {
|
|||||||
.expect("terminal_total_difficulty is a valid integer"),
|
.expect("terminal_total_difficulty is a valid integer"),
|
||||||
terminal_block_hash: ExecutionBlockHash::zero(),
|
terminal_block_hash: ExecutionBlockHash::zero(),
|
||||||
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
||||||
safe_slots_to_import_optimistically: 128u64,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Capella hard fork params
|
* Capella hard fork params
|
||||||
@@ -886,7 +882,6 @@ impl ChainSpec {
|
|||||||
inactivity_penalty_quotient: u64::checked_pow(2, 25).expect("pow does not overflow"),
|
inactivity_penalty_quotient: u64::checked_pow(2, 25).expect("pow does not overflow"),
|
||||||
min_slashing_penalty_quotient: 64,
|
min_slashing_penalty_quotient: 64,
|
||||||
proportional_slashing_multiplier: 2,
|
proportional_slashing_multiplier: 2,
|
||||||
safe_slots_to_update_justified: 2,
|
|
||||||
// Altair
|
// Altair
|
||||||
epochs_per_sync_committee_period: Epoch::new(8),
|
epochs_per_sync_committee_period: Epoch::new(8),
|
||||||
altair_fork_version: [0x01, 0x00, 0x00, 0x01],
|
altair_fork_version: [0x01, 0x00, 0x00, 0x01],
|
||||||
@@ -1026,7 +1021,6 @@ impl ChainSpec {
|
|||||||
/*
|
/*
|
||||||
* Fork choice
|
* Fork choice
|
||||||
*/
|
*/
|
||||||
safe_slots_to_update_justified: 8,
|
|
||||||
proposer_score_boost: Some(40),
|
proposer_score_boost: Some(40),
|
||||||
reorg_head_weight_threshold: Some(20),
|
reorg_head_weight_threshold: Some(20),
|
||||||
reorg_parent_weight_threshold: Some(160),
|
reorg_parent_weight_threshold: Some(160),
|
||||||
@@ -1077,7 +1071,6 @@ impl ChainSpec {
|
|||||||
.expect("terminal_total_difficulty is a valid integer"),
|
.expect("terminal_total_difficulty is a valid integer"),
|
||||||
terminal_block_hash: ExecutionBlockHash::zero(),
|
terminal_block_hash: ExecutionBlockHash::zero(),
|
||||||
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
||||||
safe_slots_to_import_optimistically: 128u64,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Capella hard fork params
|
* Capella hard fork params
|
||||||
@@ -1212,9 +1205,6 @@ pub struct Config {
|
|||||||
pub terminal_block_hash: ExecutionBlockHash,
|
pub terminal_block_hash: ExecutionBlockHash,
|
||||||
#[serde(default = "default_terminal_block_hash_activation_epoch")]
|
#[serde(default = "default_terminal_block_hash_activation_epoch")]
|
||||||
pub terminal_block_hash_activation_epoch: Epoch,
|
pub terminal_block_hash_activation_epoch: Epoch,
|
||||||
#[serde(default = "default_safe_slots_to_import_optimistically")]
|
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
|
||||||
pub safe_slots_to_import_optimistically: u64,
|
|
||||||
|
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
min_genesis_active_validator_count: u64,
|
min_genesis_active_validator_count: u64,
|
||||||
@@ -1425,10 +1415,6 @@ fn default_terminal_block_hash_activation_epoch() -> Epoch {
|
|||||||
Epoch::new(u64::MAX)
|
Epoch::new(u64::MAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_safe_slots_to_import_optimistically() -> u64 {
|
|
||||||
128u64
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_subnets_per_node() -> u8 {
|
fn default_subnets_per_node() -> u8 {
|
||||||
2u8
|
2u8
|
||||||
}
|
}
|
||||||
@@ -1649,7 +1635,6 @@ impl Config {
|
|||||||
terminal_total_difficulty: spec.terminal_total_difficulty,
|
terminal_total_difficulty: spec.terminal_total_difficulty,
|
||||||
terminal_block_hash: spec.terminal_block_hash,
|
terminal_block_hash: spec.terminal_block_hash,
|
||||||
terminal_block_hash_activation_epoch: spec.terminal_block_hash_activation_epoch,
|
terminal_block_hash_activation_epoch: spec.terminal_block_hash_activation_epoch,
|
||||||
safe_slots_to_import_optimistically: spec.safe_slots_to_import_optimistically,
|
|
||||||
|
|
||||||
min_genesis_active_validator_count: spec.min_genesis_active_validator_count,
|
min_genesis_active_validator_count: spec.min_genesis_active_validator_count,
|
||||||
min_genesis_time: spec.min_genesis_time,
|
min_genesis_time: spec.min_genesis_time,
|
||||||
@@ -1751,7 +1736,6 @@ impl Config {
|
|||||||
terminal_total_difficulty,
|
terminal_total_difficulty,
|
||||||
terminal_block_hash,
|
terminal_block_hash,
|
||||||
terminal_block_hash_activation_epoch,
|
terminal_block_hash_activation_epoch,
|
||||||
safe_slots_to_import_optimistically,
|
|
||||||
min_genesis_active_validator_count,
|
min_genesis_active_validator_count,
|
||||||
min_genesis_time,
|
min_genesis_time,
|
||||||
genesis_fork_version,
|
genesis_fork_version,
|
||||||
@@ -1851,7 +1835,6 @@ impl Config {
|
|||||||
terminal_total_difficulty,
|
terminal_total_difficulty,
|
||||||
terminal_block_hash,
|
terminal_block_hash,
|
||||||
terminal_block_hash_activation_epoch,
|
terminal_block_hash_activation_epoch,
|
||||||
safe_slots_to_import_optimistically,
|
|
||||||
gossip_max_size,
|
gossip_max_size,
|
||||||
min_epochs_for_block_requests,
|
min_epochs_for_block_requests,
|
||||||
max_chunk_size,
|
max_chunk_size,
|
||||||
@@ -2103,7 +2086,6 @@ mod yaml_tests {
|
|||||||
#TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638911
|
#TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638911
|
||||||
#TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000001
|
#TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000001
|
||||||
#TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551614
|
#TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551614
|
||||||
#SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY: 2
|
|
||||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
|
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
|
||||||
MIN_GENESIS_TIME: 1606824000
|
MIN_GENESIS_TIME: 1606824000
|
||||||
GENESIS_FORK_VERSION: 0x00000000
|
GENESIS_FORK_VERSION: 0x00000000
|
||||||
@@ -2152,7 +2134,6 @@ mod yaml_tests {
|
|||||||
check_default!(terminal_total_difficulty);
|
check_default!(terminal_total_difficulty);
|
||||||
check_default!(terminal_block_hash);
|
check_default!(terminal_block_hash);
|
||||||
check_default!(terminal_block_hash_activation_epoch);
|
check_default!(terminal_block_hash_activation_epoch);
|
||||||
check_default!(safe_slots_to_import_optimistically);
|
|
||||||
check_default!(bellatrix_fork_version);
|
check_default!(bellatrix_fork_version);
|
||||||
check_default!(gossip_max_size);
|
check_default!(gossip_max_size);
|
||||||
check_default!(min_epochs_for_block_requests);
|
check_default!(min_epochs_for_block_requests);
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ pub struct BasePreset {
|
|||||||
#[serde(with = "serde_utils::quoted_u64")]
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
pub hysteresis_upward_multiplier: u64,
|
pub hysteresis_upward_multiplier: u64,
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
pub safe_slots_to_update_justified: u64,
|
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
|
||||||
pub min_deposit_amount: u64,
|
pub min_deposit_amount: u64,
|
||||||
#[serde(with = "serde_utils::quoted_u64")]
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
pub max_effective_balance: u64,
|
pub max_effective_balance: u64,
|
||||||
@@ -90,7 +88,6 @@ impl BasePreset {
|
|||||||
hysteresis_quotient: spec.hysteresis_quotient,
|
hysteresis_quotient: spec.hysteresis_quotient,
|
||||||
hysteresis_downward_multiplier: spec.hysteresis_downward_multiplier,
|
hysteresis_downward_multiplier: spec.hysteresis_downward_multiplier,
|
||||||
hysteresis_upward_multiplier: spec.hysteresis_upward_multiplier,
|
hysteresis_upward_multiplier: spec.hysteresis_upward_multiplier,
|
||||||
safe_slots_to_update_justified: spec.safe_slots_to_update_justified,
|
|
||||||
min_deposit_amount: spec.min_deposit_amount,
|
min_deposit_amount: spec.min_deposit_amount,
|
||||||
max_effective_balance: spec.max_effective_balance,
|
max_effective_balance: spec.max_effective_balance,
|
||||||
effective_balance_increment: spec.effective_balance_increment,
|
effective_balance_increment: spec.effective_balance_increment,
|
||||||
|
|||||||
@@ -323,57 +323,43 @@ fn main() {
|
|||||||
Arg::new("terminal-total-difficulty-override")
|
Arg::new("terminal-total-difficulty-override")
|
||||||
.long("terminal-total-difficulty-override")
|
.long("terminal-total-difficulty-override")
|
||||||
.value_name("INTEGER")
|
.value_name("INTEGER")
|
||||||
.help("Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY parameter. \
|
.help("DEPRECATED")
|
||||||
Accepts a 256-bit decimal integer (not a hex value). \
|
|
||||||
This flag should only be used if the user has a clear understanding that \
|
|
||||||
the broad Ethereum community has elected to override the terminal difficulty. \
|
|
||||||
Incorrect use of this flag will cause your node to experience a consensus \
|
|
||||||
failure. Be extremely careful with this flag.")
|
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.global(true)
|
.global(true)
|
||||||
.display_order(0)
|
.display_order(0)
|
||||||
|
.hide(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("terminal-block-hash-override")
|
Arg::new("terminal-block-hash-override")
|
||||||
.long("terminal-block-hash-override")
|
.long("terminal-block-hash-override")
|
||||||
.value_name("TERMINAL_BLOCK_HASH")
|
.value_name("TERMINAL_BLOCK_HASH")
|
||||||
.help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH parameter. \
|
.help("DEPRECATED")
|
||||||
This flag should only be used if the user has a clear understanding that \
|
|
||||||
the broad Ethereum community has elected to override the terminal PoW block. \
|
|
||||||
Incorrect use of this flag will cause your node to experience a consensus \
|
|
||||||
failure. Be extremely careful with this flag.")
|
|
||||||
.requires("terminal-block-hash-epoch-override")
|
.requires("terminal-block-hash-epoch-override")
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.global(true)
|
.global(true)
|
||||||
.display_order(0)
|
.display_order(0)
|
||||||
|
.hide(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("terminal-block-hash-epoch-override")
|
Arg::new("terminal-block-hash-epoch-override")
|
||||||
.long("terminal-block-hash-epoch-override")
|
.long("terminal-block-hash-epoch-override")
|
||||||
.value_name("EPOCH")
|
.value_name("EPOCH")
|
||||||
.help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH \
|
.help("DEPRECATED")
|
||||||
parameter. This flag should only be used if the user has a clear understanding \
|
|
||||||
that the broad Ethereum community has elected to override the terminal PoW block. \
|
|
||||||
Incorrect use of this flag will cause your node to experience a consensus \
|
|
||||||
failure. Be extremely careful with this flag.")
|
|
||||||
.requires("terminal-block-hash-override")
|
.requires("terminal-block-hash-override")
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.global(true)
|
.global(true)
|
||||||
.display_order(0)
|
.display_order(0)
|
||||||
|
.hide(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("safe-slots-to-import-optimistically")
|
Arg::new("safe-slots-to-import-optimistically")
|
||||||
.long("safe-slots-to-import-optimistically")
|
.long("safe-slots-to-import-optimistically")
|
||||||
.value_name("INTEGER")
|
.value_name("INTEGER")
|
||||||
.help("Used to coordinate manual overrides of the SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY \
|
.help("DEPRECATED")
|
||||||
parameter. This flag should only be used if the user has a clear understanding \
|
|
||||||
that the broad Ethereum community has elected to override this parameter in the event \
|
|
||||||
of an attack at the PoS transition block. Incorrect use of this flag can cause your \
|
|
||||||
node to possibly accept an invalid chain or sync more slowly. Be extremely careful with \
|
|
||||||
this flag.")
|
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.global(true)
|
.global(true)
|
||||||
.display_order(0)
|
.display_order(0)
|
||||||
|
.hide(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("genesis-state-url")
|
Arg::new("genesis-state-url")
|
||||||
@@ -631,6 +617,20 @@ fn run<E: EthSpec>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warn for DEPRECATED global flags. This code should be removed when we finish deleting these
|
||||||
|
// flags.
|
||||||
|
let deprecated_flags = [
|
||||||
|
"terminal-total-difficulty-override",
|
||||||
|
"terminal-block-hash-override",
|
||||||
|
"terminal-block-hash-epoch-override",
|
||||||
|
"safe-slots-to-import-optimistically",
|
||||||
|
];
|
||||||
|
for flag in deprecated_flags {
|
||||||
|
if matches.get_one::<String>(flag).is_some() {
|
||||||
|
slog::warn!(log, "The {} flag is deprecated and does nothing", flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note: the current code technically allows for starting a beacon node _and_ a validator
|
// Note: the current code technically allows for starting a beacon node _and_ a validator
|
||||||
// client at the same time.
|
// client at the same time.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use std::string::ToString;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use types::non_zero_usize::new_non_zero_usize;
|
use types::non_zero_usize::new_non_zero_usize;
|
||||||
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, Hash256, MainnetEthSpec};
|
use types::{Address, Checkpoint, Epoch, Hash256, MainnetEthSpec};
|
||||||
use unused_port::{unused_tcp4_port, unused_tcp6_port, unused_udp4_port, unused_udp6_port};
|
use unused_port::{unused_tcp4_port, unused_tcp6_port, unused_udp4_port, unused_udp6_port};
|
||||||
|
|
||||||
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
||||||
@@ -742,61 +742,30 @@ fn jwt_optional_flags() {
|
|||||||
fn jwt_optional_alias_flags() {
|
fn jwt_optional_alias_flags() {
|
||||||
run_jwt_optional_flags_test("jwt-secrets", "jwt-id", "jwt-version");
|
run_jwt_optional_flags_test("jwt-secrets", "jwt-id", "jwt-version");
|
||||||
}
|
}
|
||||||
|
// DEPRECATED. This flag is deprecated but should not cause a crash.
|
||||||
#[test]
|
#[test]
|
||||||
fn terminal_total_difficulty_override_flag() {
|
fn terminal_total_difficulty_override_flag() {
|
||||||
use beacon_node::beacon_chain::types::Uint256;
|
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("terminal-total-difficulty-override", Some("1337424242"))
|
.flag("terminal-total-difficulty-override", Some("1337424242"))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port();
|
||||||
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
||||||
assert_eq!(spec.terminal_total_difficulty, Uint256::from(1337424242))
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
// DEPRECATED. This flag is deprecated but should not cause a crash.
|
||||||
#[test]
|
#[test]
|
||||||
fn terminal_block_hash_and_activation_epoch_override_flags() {
|
fn terminal_block_hash_and_activation_epoch_override_flags() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("terminal-block-hash-epoch-override", Some("1337"))
|
.flag("terminal-block-hash-epoch-override", Some("1337"))
|
||||||
.flag(
|
|
||||||
"terminal-block-hash-override",
|
|
||||||
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
|
|
||||||
)
|
|
||||||
.run_with_zero_port()
|
|
||||||
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
||||||
assert_eq!(
|
|
||||||
spec.terminal_block_hash,
|
|
||||||
ExecutionBlockHash::from_str(
|
|
||||||
"0x4242424242424242424242424242424242424242424242424242424242424242"
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(spec.terminal_block_hash_activation_epoch, 1337);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn terminal_block_hash_missing_activation_epoch() {
|
|
||||||
CommandLineTest::new()
|
|
||||||
.flag(
|
.flag(
|
||||||
"terminal-block-hash-override",
|
"terminal-block-hash-override",
|
||||||
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
|
Some("0x4242424242424242424242424242424242424242424242424242424242424242"),
|
||||||
)
|
)
|
||||||
.run_with_zero_port();
|
.run_with_zero_port();
|
||||||
}
|
}
|
||||||
#[test]
|
// DEPRECATED. This flag is deprecated but should not cause a crash.
|
||||||
#[should_panic]
|
|
||||||
fn epoch_override_missing_terminal_block_hash() {
|
|
||||||
CommandLineTest::new()
|
|
||||||
.flag("terminal-block-hash-epoch-override", Some("1337"))
|
|
||||||
.run_with_zero_port();
|
|
||||||
}
|
|
||||||
#[test]
|
#[test]
|
||||||
fn safe_slots_to_import_optimistically_flag() {
|
fn safe_slots_to_import_optimistically_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("safe-slots-to-import-optimistically", Some("421337"))
|
.flag("safe-slots-to-import-optimistically", Some("421337"))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port();
|
||||||
.with_spec::<MainnetEthSpec, _>(|spec| {
|
|
||||||
assert_eq!(spec.safe_slots_to_import_optimistically, 421337)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests for Network flags.
|
// Tests for Network flags.
|
||||||
|
|||||||
@@ -140,11 +140,6 @@ impl<C> CompletedTest<C> {
|
|||||||
func(&self.config);
|
func(&self.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_spec<E: EthSpec, F: Fn(ChainSpec)>(self, func: F) {
|
|
||||||
let spec = ChainSpec::from_config::<E>(&self.chain_config).unwrap();
|
|
||||||
func(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_config_and_dir<F: Fn(&C, &TempDir)>(self, func: F) {
|
pub fn with_config_and_dir<F: Fn(&C, &TempDir)>(self, func: F) {
|
||||||
func(&self.config, &self.dir);
|
func(&self.config, &self.dir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ excluded_paths = [
|
|||||||
# Intentionally omitted, as per https://github.com/sigp/lighthouse/issues/1835
|
# Intentionally omitted, as per https://github.com/sigp/lighthouse/issues/1835
|
||||||
"tests/.*/.*/ssz_static/Eth1Block/",
|
"tests/.*/.*/ssz_static/Eth1Block/",
|
||||||
"tests/.*/.*/ssz_static/PowBlock/",
|
"tests/.*/.*/ssz_static/PowBlock/",
|
||||||
|
# We no longer implement merge logic.
|
||||||
|
"tests/.*/bellatrix/fork_choice/on_merge_block",
|
||||||
# light_client
|
# light_client
|
||||||
"tests/.*/.*/light_client/single_merkle_proof",
|
"tests/.*/.*/light_client/single_merkle_proof",
|
||||||
"tests/.*/.*/light_client/sync",
|
"tests/.*/.*/light_client/sync",
|
||||||
|
|||||||
@@ -627,8 +627,8 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||||
// Merge block tests are only enabled for Bellatrix.
|
// We no longer run on_merge_block tests since removing merge support.
|
||||||
if self.handler_name == "on_merge_block" && fork_name != ForkName::Bellatrix {
|
if self.handler_name == "on_merge_block" {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -826,12 +826,6 @@ fn fork_choice_on_block() {
|
|||||||
ForkChoiceHandler::<MainnetEthSpec>::new("on_block").run();
|
ForkChoiceHandler::<MainnetEthSpec>::new("on_block").run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn fork_choice_on_merge_block() {
|
|
||||||
ForkChoiceHandler::<MinimalEthSpec>::new("on_merge_block").run();
|
|
||||||
ForkChoiceHandler::<MainnetEthSpec>::new("on_merge_block").run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fork_choice_ex_ante() {
|
fn fork_choice_ex_ante() {
|
||||||
ForkChoiceHandler::<MinimalEthSpec>::new("ex_ante").run();
|
ForkChoiceHandler::<MinimalEthSpec>::new("ex_ante").run();
|
||||||
|
|||||||
Reference in New Issue
Block a user