mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 02:42:38 +00:00
Encode Execution Engine Client Version In Graffiti (#5290)
* Add `engine_clientVersionV1` structs * Implement `engine_clientVersionV1` * Update to latest spec changes * Implement GraffitiCalculator Service * Added Unit Tests for GraffitiCalculator * Address Mac's Comments * Remove need to use clap in beacon chain * Merge remote-tracking branch 'upstream/unstable' into el_client_version_graffiti * Merge branch 'unstable' into el_client_version_graffiti # Conflicts: # beacon_node/beacon_chain/Cargo.toml
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use crate::engines::ForkchoiceState;
|
||||
use crate::http::{
|
||||
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
|
||||
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
|
||||
ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V1,
|
||||
ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3,
|
||||
ENGINE_GET_CLIENT_VERSION_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
|
||||
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
|
||||
ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3,
|
||||
};
|
||||
use eth2::types::{
|
||||
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
|
||||
@@ -24,11 +24,11 @@ pub use types::{
|
||||
ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList,
|
||||
Withdrawal, Withdrawals,
|
||||
};
|
||||
|
||||
use types::{
|
||||
ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadMerge,
|
||||
KzgProofs,
|
||||
};
|
||||
use types::{Graffiti, GRAFFITI_BYTES_LEN};
|
||||
|
||||
pub mod auth;
|
||||
pub mod http;
|
||||
@@ -61,13 +61,13 @@ pub enum Error {
|
||||
ParentHashEqualsBlockHash(ExecutionBlockHash),
|
||||
PayloadIdUnavailable,
|
||||
TransitionConfigurationMismatch,
|
||||
PayloadConversionLogicFlaw,
|
||||
SszError(ssz_types::Error),
|
||||
DeserializeWithdrawals(ssz_types::Error),
|
||||
BuilderApi(builder_client::Error),
|
||||
IncorrectStateVariant,
|
||||
RequiredMethodUnsupported(&'static str),
|
||||
UnsupportedForkVariant(String),
|
||||
InvalidClientVersion(String),
|
||||
RlpDecoderError(rlp::DecoderError),
|
||||
}
|
||||
|
||||
@@ -652,6 +652,7 @@ pub struct EngineCapabilities {
|
||||
pub get_payload_v1: bool,
|
||||
pub get_payload_v2: bool,
|
||||
pub get_payload_v3: bool,
|
||||
pub get_client_version_v1: bool,
|
||||
}
|
||||
|
||||
impl EngineCapabilities {
|
||||
@@ -690,7 +691,141 @@ impl EngineCapabilities {
|
||||
if self.get_payload_v3 {
|
||||
response.push(ENGINE_GET_PAYLOAD_V3);
|
||||
}
|
||||
if self.get_client_version_v1 {
|
||||
response.push(ENGINE_GET_CLIENT_VERSION_V1);
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ClientCode {
|
||||
Besu,
|
||||
EtherumJS,
|
||||
Erigon,
|
||||
GoEthereum,
|
||||
Grandine,
|
||||
Lighthouse,
|
||||
Lodestar,
|
||||
Nethermind,
|
||||
Nimbus,
|
||||
Teku,
|
||||
Prysm,
|
||||
Reth,
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ClientCode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let s = match self {
|
||||
ClientCode::Besu => "BU",
|
||||
ClientCode::EtherumJS => "EJ",
|
||||
ClientCode::Erigon => "EG",
|
||||
ClientCode::GoEthereum => "GE",
|
||||
ClientCode::Grandine => "GR",
|
||||
ClientCode::Lighthouse => "LH",
|
||||
ClientCode::Lodestar => "LS",
|
||||
ClientCode::Nethermind => "NM",
|
||||
ClientCode::Nimbus => "NB",
|
||||
ClientCode::Teku => "TK",
|
||||
ClientCode::Prysm => "PM",
|
||||
ClientCode::Reth => "RH",
|
||||
ClientCode::Unknown(code) => code,
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for ClientCode {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(code: String) -> Result<Self, Self::Error> {
|
||||
match code.as_str() {
|
||||
"BU" => Ok(Self::Besu),
|
||||
"EJ" => Ok(Self::EtherumJS),
|
||||
"EG" => Ok(Self::Erigon),
|
||||
"GE" => Ok(Self::GoEthereum),
|
||||
"GR" => Ok(Self::Grandine),
|
||||
"LH" => Ok(Self::Lighthouse),
|
||||
"LS" => Ok(Self::Lodestar),
|
||||
"NM" => Ok(Self::Nethermind),
|
||||
"NB" => Ok(Self::Nimbus),
|
||||
"TK" => Ok(Self::Teku),
|
||||
"PM" => Ok(Self::Prysm),
|
||||
"RH" => Ok(Self::Reth),
|
||||
string => {
|
||||
if string.len() == 2 {
|
||||
Ok(Self::Unknown(code))
|
||||
} else {
|
||||
Err(format!("Invalid client code: {}", code))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CommitPrefix(pub String);
|
||||
|
||||
impl TryFrom<String> for CommitPrefix {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
// Check if the input starts with '0x' and strip it if it does
|
||||
let commit_prefix = value.strip_prefix("0x").unwrap_or(&value);
|
||||
|
||||
// Ensure length is exactly 8 characters after '0x' removal
|
||||
if commit_prefix.len() != 8 {
|
||||
return Err(
|
||||
"Input must be exactly 8 characters long (excluding any '0x' prefix)".to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure all characters are valid hex digits
|
||||
if commit_prefix.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
Ok(CommitPrefix(commit_prefix.to_lowercase()))
|
||||
} else {
|
||||
Err("Input must contain only hexadecimal characters".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CommitPrefix {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ClientVersionV1 {
|
||||
pub code: ClientCode,
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub commit: CommitPrefix,
|
||||
}
|
||||
|
||||
impl ClientVersionV1 {
|
||||
pub fn calculate_graffiti(&self, lighthouse_commit_prefix: CommitPrefix) -> Graffiti {
|
||||
let graffiti_string = format!(
|
||||
"{}{}LH{}",
|
||||
self.code,
|
||||
self.commit
|
||||
.0
|
||||
.get(..4)
|
||||
.map_or_else(|| self.commit.0.as_str(), |s| s)
|
||||
.to_lowercase(),
|
||||
lighthouse_commit_prefix
|
||||
.0
|
||||
.get(..4)
|
||||
.unwrap_or("0000")
|
||||
.to_lowercase(),
|
||||
);
|
||||
let mut graffiti_bytes = [0u8; GRAFFITI_BYTES_LEN];
|
||||
let bytes_to_copy = std::cmp::min(graffiti_string.len(), GRAFFITI_BYTES_LEN);
|
||||
graffiti_bytes[..bytes_to_copy]
|
||||
.copy_from_slice(&graffiti_string.as_bytes()[..bytes_to_copy]);
|
||||
|
||||
Graffiti::from(graffiti_bytes)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user