mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 03:31:45 +00:00
Ensure difficulty/hash/epoch overrides change the ChainSpec (#2798)
* Unify loading of eth2_network_config * Apply overrides at lighthouse binary level * Remove duplicate override values * Add merge values to existing net configs * Make override flags global * Add merge fields to testing config * Add one to TTD * Fix failing engine tests * Fix test compile error * Remove TTD flags * Move get_eth2_network_config * Fix warn * Address review comments
This commit is contained in:
@@ -18,6 +18,7 @@ use tokio::{
|
||||
sync::{Mutex, MutexGuard},
|
||||
time::{sleep, sleep_until, Instant},
|
||||
};
|
||||
use types::ChainSpec;
|
||||
|
||||
pub use engine_api::{http::HttpJsonRpc, ExecutePayloadResponseStatus};
|
||||
|
||||
@@ -47,8 +48,6 @@ impl From<ApiError> for Error {
|
||||
|
||||
struct Inner {
|
||||
engines: Engines<HttpJsonRpc>,
|
||||
terminal_total_difficulty: Uint256,
|
||||
terminal_block_hash: Hash256,
|
||||
fee_recipient: Option<Address>,
|
||||
execution_blocks: Mutex<LruCache<Hash256, ExecutionBlock>>,
|
||||
executor: TaskExecutor,
|
||||
@@ -73,8 +72,6 @@ impl ExecutionLayer {
|
||||
/// Instantiate `Self` with `urls.len()` engines, all using the JSON-RPC via HTTP.
|
||||
pub fn from_urls(
|
||||
urls: Vec<SensitiveUrl>,
|
||||
terminal_total_difficulty: Uint256,
|
||||
terminal_block_hash: Hash256,
|
||||
fee_recipient: Option<Address>,
|
||||
executor: TaskExecutor,
|
||||
log: Logger,
|
||||
@@ -98,8 +95,6 @@ impl ExecutionLayer {
|
||||
latest_forkchoice_state: <_>::default(),
|
||||
log: log.clone(),
|
||||
},
|
||||
terminal_total_difficulty,
|
||||
terminal_block_hash,
|
||||
fee_recipient,
|
||||
execution_blocks: Mutex::new(LruCache::new(EXECUTION_BLOCKS_LRU_CACHE_SIZE)),
|
||||
executor,
|
||||
@@ -121,14 +116,6 @@ impl ExecutionLayer {
|
||||
&self.inner.executor
|
||||
}
|
||||
|
||||
fn terminal_total_difficulty(&self) -> Uint256 {
|
||||
self.inner.terminal_total_difficulty
|
||||
}
|
||||
|
||||
fn terminal_block_hash(&self) -> Hash256 {
|
||||
self.inner.terminal_block_hash
|
||||
}
|
||||
|
||||
fn fee_recipient(&self) -> Result<Address, Error> {
|
||||
self.inner
|
||||
.fee_recipient
|
||||
@@ -455,11 +442,14 @@ impl ExecutionLayer {
|
||||
/// `get_terminal_pow_block_hash`
|
||||
///
|
||||
/// https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/validator.md
|
||||
pub async fn get_terminal_pow_block_hash(&self) -> Result<Option<Hash256>, Error> {
|
||||
pub async fn get_terminal_pow_block_hash(
|
||||
&self,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<Hash256>, Error> {
|
||||
let hash_opt = self
|
||||
.engines()
|
||||
.first_success(|engine| async move {
|
||||
if self.terminal_block_hash() != Hash256::zero() {
|
||||
if spec.terminal_block_hash != Hash256::zero() {
|
||||
// Note: the specification is written such that if there are multiple blocks in
|
||||
// the PoW chain with the terminal block hash, then to select 0'th one.
|
||||
//
|
||||
@@ -468,11 +458,12 @@ impl ExecutionLayer {
|
||||
// hash. Such a scenario would be a devestating hash collision with external
|
||||
// implications far outweighing those here.
|
||||
Ok(self
|
||||
.get_pow_block(engine, self.terminal_block_hash())
|
||||
.get_pow_block(engine, spec.terminal_block_hash)
|
||||
.await?
|
||||
.map(|block| block.block_hash))
|
||||
} else {
|
||||
self.get_pow_block_hash_at_total_difficulty(engine).await
|
||||
self.get_pow_block_hash_at_total_difficulty(engine, spec)
|
||||
.await
|
||||
}
|
||||
})
|
||||
.await
|
||||
@@ -482,8 +473,8 @@ impl ExecutionLayer {
|
||||
info!(
|
||||
self.log(),
|
||||
"Found terminal block hash";
|
||||
"terminal_block_hash_override" => ?self.terminal_block_hash(),
|
||||
"terminal_total_difficulty" => ?self.terminal_total_difficulty(),
|
||||
"terminal_block_hash_override" => ?spec.terminal_block_hash,
|
||||
"terminal_total_difficulty" => ?spec.terminal_total_difficulty,
|
||||
"block_hash" => ?hash,
|
||||
);
|
||||
}
|
||||
@@ -503,6 +494,7 @@ impl ExecutionLayer {
|
||||
async fn get_pow_block_hash_at_total_difficulty(
|
||||
&self,
|
||||
engine: &Engine<HttpJsonRpc>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<Hash256>, ApiError> {
|
||||
let mut ttd_exceeding_block = None;
|
||||
let mut block = engine
|
||||
@@ -518,7 +510,7 @@ impl ExecutionLayer {
|
||||
//
|
||||
// https://github.com/ethereum/consensus-specs/issues/2636
|
||||
loop {
|
||||
if block.total_difficulty >= self.terminal_total_difficulty() {
|
||||
if block.total_difficulty >= spec.terminal_total_difficulty {
|
||||
ttd_exceeding_block = Some(block.block_hash);
|
||||
|
||||
// Try to prevent infinite loops.
|
||||
@@ -565,6 +557,7 @@ impl ExecutionLayer {
|
||||
pub async fn is_valid_terminal_pow_block_hash(
|
||||
&self,
|
||||
block_hash: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<bool>, Error> {
|
||||
let broadcast_results = self
|
||||
.engines()
|
||||
@@ -574,7 +567,7 @@ impl ExecutionLayer {
|
||||
self.get_pow_block(engine, pow_block.parent_hash).await?
|
||||
{
|
||||
return Ok(Some(
|
||||
self.is_valid_terminal_pow_block(pow_block, pow_parent),
|
||||
self.is_valid_terminal_pow_block(pow_block, pow_parent, spec),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -618,15 +611,19 @@ impl ExecutionLayer {
|
||||
/// This function should remain internal.
|
||||
///
|
||||
/// External users should use `self.is_valid_terminal_pow_block_hash`.
|
||||
fn is_valid_terminal_pow_block(&self, block: ExecutionBlock, parent: ExecutionBlock) -> bool {
|
||||
if block.block_hash == self.terminal_block_hash() {
|
||||
fn is_valid_terminal_pow_block(
|
||||
&self,
|
||||
block: ExecutionBlock,
|
||||
parent: ExecutionBlock,
|
||||
spec: &ChainSpec,
|
||||
) -> bool {
|
||||
if block.block_hash == spec.terminal_block_hash {
|
||||
return true;
|
||||
}
|
||||
|
||||
let is_total_difficulty_reached =
|
||||
block.total_difficulty >= self.terminal_total_difficulty();
|
||||
let is_total_difficulty_reached = block.total_difficulty >= spec.terminal_total_difficulty;
|
||||
let is_parent_total_difficulty_valid =
|
||||
parent.total_difficulty < self.terminal_total_difficulty();
|
||||
parent.total_difficulty < spec.terminal_total_difficulty;
|
||||
is_total_difficulty_reached && is_parent_total_difficulty_valid
|
||||
}
|
||||
|
||||
@@ -685,14 +682,14 @@ mod test {
|
||||
async fn finds_valid_terminal_block_hash() {
|
||||
MockExecutionLayer::default_params()
|
||||
.move_to_block_prior_to_terminal_block()
|
||||
.with_terminal_block(|el, _| async move {
|
||||
assert_eq!(el.get_terminal_pow_block_hash().await.unwrap(), None)
|
||||
.with_terminal_block(|spec, el, _| async move {
|
||||
assert_eq!(el.get_terminal_pow_block_hash(&spec).await.unwrap(), None)
|
||||
})
|
||||
.await
|
||||
.move_to_terminal_block()
|
||||
.with_terminal_block(|el, terminal_block| async move {
|
||||
.with_terminal_block(|spec, el, terminal_block| async move {
|
||||
assert_eq!(
|
||||
el.get_terminal_pow_block_hash().await.unwrap(),
|
||||
el.get_terminal_pow_block_hash(&spec).await.unwrap(),
|
||||
Some(terminal_block.unwrap().block_hash)
|
||||
)
|
||||
})
|
||||
@@ -703,9 +700,9 @@ mod test {
|
||||
async fn verifies_valid_terminal_block_hash() {
|
||||
MockExecutionLayer::default_params()
|
||||
.move_to_terminal_block()
|
||||
.with_terminal_block(|el, terminal_block| async move {
|
||||
.with_terminal_block(|spec, el, terminal_block| async move {
|
||||
assert_eq!(
|
||||
el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash)
|
||||
el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash, &spec)
|
||||
.await
|
||||
.unwrap(),
|
||||
Some(true)
|
||||
@@ -718,11 +715,11 @@ mod test {
|
||||
async fn rejects_invalid_terminal_block_hash() {
|
||||
MockExecutionLayer::default_params()
|
||||
.move_to_terminal_block()
|
||||
.with_terminal_block(|el, terminal_block| async move {
|
||||
.with_terminal_block(|spec, el, terminal_block| async move {
|
||||
let invalid_terminal_block = terminal_block.unwrap().parent_hash;
|
||||
|
||||
assert_eq!(
|
||||
el.is_valid_terminal_pow_block_hash(invalid_terminal_block)
|
||||
el.is_valid_terminal_pow_block_hash(invalid_terminal_block, &spec)
|
||||
.await
|
||||
.unwrap(),
|
||||
Some(false)
|
||||
@@ -735,11 +732,11 @@ mod test {
|
||||
async fn rejects_unknown_terminal_block_hash() {
|
||||
MockExecutionLayer::default_params()
|
||||
.move_to_terminal_block()
|
||||
.with_terminal_block(|el, _| async move {
|
||||
.with_terminal_block(|spec, el, _| async move {
|
||||
let missing_terminal_block = Hash256::repeat_byte(42);
|
||||
|
||||
assert_eq!(
|
||||
el.is_valid_terminal_pow_block_hash(missing_terminal_block)
|
||||
el.is_valid_terminal_pow_block_hash(missing_terminal_block, &spec)
|
||||
.await
|
||||
.unwrap(),
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user