Skip to content

Commit 262e5f2

Browse files
committed
Merge remote-tracking branch 'origin/unstable' into tree-states
2 parents 6262be7 + 1be5253 commit 262e5f2

File tree

91 files changed

+2252
-651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+2252
-651
lines changed

Cargo.lock

Lines changed: 232 additions & 129 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ crossbeam-channel = "0.5.8"
107107
delay_map = "0.3"
108108
derivative = "2"
109109
dirs = "3"
110-
discv5 = { git="https://github.com/sigp/discv5", rev="dbb4a718cd32eaed8127c3c8241bfd0fde9eb908", features = ["libp2p"] }
110+
discv5 = { git="https://github.com/sigp/discv5", rev="e30a2c31b7ac0c57876458b971164654dfa4513b", features = ["libp2p"] }
111111
env_logger = "0.9"
112112
error-chain = "0.12"
113113
ethereum-types = "0.14"
@@ -163,6 +163,10 @@ tempfile = "3"
163163
tokio = { version = "1", features = ["rt-multi-thread", "sync", "signal"] }
164164
tokio-stream = { version = "0.1", features = ["sync"] }
165165
tokio-util = { version = "0.6", features = ["codec", "compat", "time"] }
166+
tracing-appender = "0.2"
167+
tracing-core = "0.1"
168+
tracing-log = "0.2"
169+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
166170
tree_hash = "0.5"
167171
tree_hash_derive = "0.5"
168172
url = "2"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ BUILD_PATH_AARCH64 = "target/$(AARCH64_TAG)/release"
1414
PINNED_NIGHTLY ?= nightly
1515
CLIPPY_PINNED_NIGHTLY=nightly-2022-05-19
1616

17-
# List of features to use when building natively. Can be overriden via the environment.
17+
# List of features to use when building natively. Can be overridden via the environment.
1818
# No jemalloc on Windows
1919
ifeq ($(OS),Windows_NT)
2020
FEATURES?=

account_manager/src/validator/import.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
284284
suggested_fee_recipient,
285285
None,
286286
None,
287+
None,
288+
None,
287289
)
288290
.map_err(|e| format!("Unable to create new validator definition: {:?}", e))?;
289291

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::eth1_finalization_cache::{Eth1FinalizationCache, Eth1FinalizationData
3030
use crate::events::ServerSentEventHandler;
3131
use crate::execution_payload::{get_execution_payload, NotifyExecutionLayer, PreparePayloadHandle};
3232
use crate::fork_choice_signal::{ForkChoiceSignalRx, ForkChoiceSignalTx, ForkChoiceWaitResult};
33-
use crate::head_tracker::HeadTracker;
33+
use crate::head_tracker::{HeadTracker, HeadTrackerReader, SszHeadTracker};
3434
use crate::historical_blocks::HistoricalBlockError;
3535
use crate::light_client_finality_update_verification::{
3636
Error as LightClientFinalityUpdateError, VerifiedLightClientFinalityUpdate,
@@ -604,38 +604,48 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
604604
let mut batch = vec![];
605605

606606
let _head_timer = metrics::start_timer(&metrics::PERSIST_HEAD);
607-
batch.push(self.persist_head_in_batch()?);
607+
608+
// Hold a lock to head_tracker until it has been persisted to disk. Otherwise there's a race
609+
// condition with the pruning thread which can result in a block present in the head tracker
610+
// but absent in the DB. This inconsistency halts pruning and dramastically increases disk
611+
// size. Ref: https://github.com/sigp/lighthouse/issues/4773
612+
let head_tracker = self.head_tracker.0.read();
613+
batch.push(self.persist_head_in_batch(&head_tracker)?);
608614

609615
let _fork_choice_timer = metrics::start_timer(&metrics::PERSIST_FORK_CHOICE);
610616
batch.push(self.persist_fork_choice_in_batch()?);
611617

612618
self.store.hot_db.do_atomically(batch)?;
619+
drop(head_tracker);
613620

614621
Ok(())
615622
}
616623

617624
/// Return a `PersistedBeaconChain` without reference to a `BeaconChain`.
618625
pub fn make_persisted_head(
619626
genesis_block_root: Hash256,
620-
head_tracker: &HeadTracker,
627+
head_tracker_reader: &HeadTrackerReader,
621628
) -> PersistedBeaconChain {
622629
PersistedBeaconChain {
623630
_canonical_head_block_root: DUMMY_CANONICAL_HEAD_BLOCK_ROOT,
624631
genesis_block_root,
625-
ssz_head_tracker: head_tracker.to_ssz_container(),
632+
ssz_head_tracker: SszHeadTracker::from_map(head_tracker_reader),
626633
}
627634
}
628635

629636
/// Return a database operation for writing the beacon chain head to disk.
630-
pub fn persist_head_in_batch(&self) -> Result<KeyValueStoreOp, DBError> {
631-
Self::persist_head_in_batch_standalone(self.genesis_block_root, &self.head_tracker)
637+
pub fn persist_head_in_batch(
638+
&self,
639+
head_tracker_reader: &HeadTrackerReader,
640+
) -> Result<KeyValueStoreOp, DBError> {
641+
Self::persist_head_in_batch_standalone(self.genesis_block_root, head_tracker_reader)
632642
}
633643

634644
pub fn persist_head_in_batch_standalone(
635645
genesis_block_root: Hash256,
636-
head_tracker: &HeadTracker,
646+
head_tracker_reader: &HeadTrackerReader,
637647
) -> Result<KeyValueStoreOp, DBError> {
638-
Self::make_persisted_head(genesis_block_root, head_tracker)
648+
Self::make_persisted_head(genesis_block_root, head_tracker_reader)
639649
.as_kv_store_op(BEACON_CHAIN_DB_KEY)
640650
}
641651

@@ -1327,6 +1337,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
13271337
self.head_tracker.heads()
13281338
}
13291339

1340+
/// Only used in tests.
13301341
pub fn knows_head(&self, block_hash: &SignedBeaconBlockHash) -> bool {
13311342
self.head_tracker.contains_head((*block_hash).into())
13321343
}

beacon_node/beacon_chain/src/block_verification.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ impl<T: BeaconChainTypes> IntoGossipVerifiedBlockContents<T> for PublishBlockReq
718718
Ok::<_, BlockContentsError<T::EthSpec>>(gossip_verified_blobs)
719719
})
720720
.transpose()?;
721-
let gossip_verified_block = GossipVerifiedBlock::new(Arc::new(block), chain)?;
721+
let gossip_verified_block = GossipVerifiedBlock::new(block, chain)?;
722722

723723
Ok((gossip_verified_block, gossip_verified_blobs))
724724
}

beacon_node/beacon_chain/src/builder.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -833,20 +833,25 @@ where
833833
//
834834
// This *must* be stored before constructing the `BeaconChain`, so that its `Drop` instance
835835
// doesn't write a `PersistedBeaconChain` without the rest of the batch.
836-
self.pending_io_batch.push(BeaconChain::<
837-
Witness<TSlotClock, TEth1Backend, TEthSpec, THotStore, TColdStore>,
838-
>::persist_head_in_batch_standalone(
839-
genesis_block_root, &head_tracker
840-
).map_err(|e| format!("{:?}", e))?);
836+
let head_tracker_reader = head_tracker.0.read();
837+
self.pending_io_batch
838+
.push(BeaconChain::<
839+
Witness<TSlotClock, TEth1Backend, TEthSpec, THotStore, TColdStore>,
840+
>::persist_head_in_batch_standalone(
841+
genesis_block_root,
842+
&head_tracker_reader,
843+
)
844+
.map_err(|e| format!("{e:?}"))?);
841845
self.pending_io_batch.push(BeaconChain::<
842846
Witness<TSlotClock, TEth1Backend, TEthSpec, THotStore, TColdStore>,
843847
>::persist_fork_choice_in_batch_standalone(
844848
&fork_choice
845-
).map_err(|e| format!("{:?}", e))?);
849+
).map_err(|e| format!("{e:?}"))?);
846850
store
847851
.hot_db
848852
.do_atomically(self.pending_io_batch)
849853
.map_err(|e| format!("Error writing chain & metadata to disk: {:?}", e))?;
854+
drop(head_tracker_reader);
850855

851856
let genesis_validators_root = head_snapshot.beacon_state.genesis_validators_root();
852857
let genesis_time = head_snapshot.beacon_state.genesis_time();

beacon_node/beacon_chain/src/capella_readiness.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//! Provides tools for checking if a node is ready for the Capella upgrade and following merge
2-
//! transition.
1+
//! Provides tools for checking if a node is ready for the Capella upgrade.
32
43
use crate::{BeaconChain, BeaconChainTypes};
54
use execution_layer::http::{

beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ mod test {
952952
};
953953

954954
let availability_pending_block = AvailabilityPendingExecutedBlock {
955-
block: Arc::new(block),
955+
block,
956956
import_data,
957957
payload_verification_outcome,
958958
};
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//! Provides tools for checking if a node is ready for the Deneb upgrade.
2+
3+
use crate::{BeaconChain, BeaconChainTypes};
4+
use execution_layer::http::{
5+
ENGINE_FORKCHOICE_UPDATED_V3, ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V3,
6+
};
7+
use serde::{Deserialize, Serialize};
8+
use std::fmt;
9+
use std::time::Duration;
10+
use types::*;
11+
12+
/// The time before the Deneb fork when we will start issuing warnings about preparation.
13+
use super::merge_readiness::SECONDS_IN_A_WEEK;
14+
pub const DENEB_READINESS_PREPARATION_SECONDS: u64 = SECONDS_IN_A_WEEK * 2;
15+
pub const ENGINE_CAPABILITIES_REFRESH_INTERVAL: u64 = 300;
16+
17+
#[derive(Debug, Serialize, Deserialize)]
18+
#[serde(rename_all = "snake_case")]
19+
#[serde(tag = "type")]
20+
pub enum DenebReadiness {
21+
/// The execution engine is deneb-enabled (as far as we can tell)
22+
Ready,
23+
/// We are connected to an execution engine which doesn't support the V3 engine api methods
24+
V3MethodsNotSupported { error: String },
25+
/// The transition configuration with the EL failed, there might be a problem with
26+
/// connectivity, authentication or a difference in configuration.
27+
ExchangeCapabilitiesFailed { error: String },
28+
/// The user has not configured an execution endpoint
29+
NoExecutionEndpoint,
30+
}
31+
32+
impl fmt::Display for DenebReadiness {
33+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34+
match self {
35+
DenebReadiness::Ready => {
36+
write!(f, "This node appears ready for Deneb.")
37+
}
38+
DenebReadiness::ExchangeCapabilitiesFailed { error } => write!(
39+
f,
40+
"Could not exchange capabilities with the \
41+
execution endpoint: {}",
42+
error
43+
),
44+
DenebReadiness::NoExecutionEndpoint => write!(
45+
f,
46+
"The --execution-endpoint flag is not specified, this is a \
47+
requirement post-merge"
48+
),
49+
DenebReadiness::V3MethodsNotSupported { error } => write!(
50+
f,
51+
"Execution endpoint does not support Deneb methods: {}",
52+
error
53+
),
54+
}
55+
}
56+
}
57+
58+
impl<T: BeaconChainTypes> BeaconChain<T> {
59+
/// Returns `true` if deneb epoch is set and Deneb fork has occurred or will
60+
/// occur within `DENEB_READINESS_PREPARATION_SECONDS`
61+
pub fn is_time_to_prepare_for_deneb(&self, current_slot: Slot) -> bool {
62+
if let Some(deneb_epoch) = self.spec.deneb_fork_epoch {
63+
let deneb_slot = deneb_epoch.start_slot(T::EthSpec::slots_per_epoch());
64+
let deneb_readiness_preparation_slots =
65+
DENEB_READINESS_PREPARATION_SECONDS / self.spec.seconds_per_slot;
66+
// Return `true` if Deneb has happened or is within the preparation time.
67+
current_slot + deneb_readiness_preparation_slots > deneb_slot
68+
} else {
69+
// The Deneb fork epoch has not been defined yet, no need to prepare.
70+
false
71+
}
72+
}
73+
74+
/// Attempts to connect to the EL and confirm that it is ready for capella.
75+
pub async fn check_deneb_readiness(&self) -> DenebReadiness {
76+
if let Some(el) = self.execution_layer.as_ref() {
77+
match el
78+
.get_engine_capabilities(Some(Duration::from_secs(
79+
ENGINE_CAPABILITIES_REFRESH_INTERVAL,
80+
)))
81+
.await
82+
{
83+
Err(e) => {
84+
// The EL was either unreachable or responded with an error
85+
DenebReadiness::ExchangeCapabilitiesFailed {
86+
error: format!("{:?}", e),
87+
}
88+
}
89+
Ok(capabilities) => {
90+
let mut missing_methods = String::from("Required Methods Unsupported:");
91+
let mut all_good = true;
92+
if !capabilities.get_payload_v3 {
93+
missing_methods.push(' ');
94+
missing_methods.push_str(ENGINE_GET_PAYLOAD_V3);
95+
all_good = false;
96+
}
97+
if !capabilities.forkchoice_updated_v3 {
98+
missing_methods.push(' ');
99+
missing_methods.push_str(ENGINE_FORKCHOICE_UPDATED_V3);
100+
all_good = false;
101+
}
102+
if !capabilities.new_payload_v3 {
103+
missing_methods.push(' ');
104+
missing_methods.push_str(ENGINE_NEW_PAYLOAD_V3);
105+
all_good = false;
106+
}
107+
108+
if all_good {
109+
DenebReadiness::Ready
110+
} else {
111+
DenebReadiness::V3MethodsNotSupported {
112+
error: missing_methods,
113+
}
114+
}
115+
}
116+
}
117+
} else {
118+
DenebReadiness::NoExecutionEndpoint
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)