Merge branch 'unstable' into deneb-free-blobs

# Conflicts:
#	.github/workflows/docker.yml
#	.github/workflows/local-testnet.yml
#	.github/workflows/test-suite.yml
#	Cargo.lock
#	Cargo.toml
#	beacon_node/beacon_chain/src/beacon_chain.rs
#	beacon_node/beacon_chain/src/builder.rs
#	beacon_node/beacon_chain/src/test_utils.rs
#	beacon_node/execution_layer/src/engine_api/json_structures.rs
#	beacon_node/network/src/beacon_processor/mod.rs
#	beacon_node/network/src/beacon_processor/worker/gossip_methods.rs
#	beacon_node/network/src/sync/backfill_sync/mod.rs
#	beacon_node/store/src/config.rs
#	beacon_node/store/src/hot_cold_store.rs
#	common/eth2_network_config/Cargo.toml
#	consensus/ssz/src/decode/impls.rs
#	consensus/ssz_derive/src/lib.rs
#	consensus/ssz_derive/tests/tests.rs
#	consensus/ssz_types/src/serde_utils/mod.rs
#	consensus/tree_hash/src/impls.rs
#	consensus/tree_hash/src/lib.rs
#	consensus/types/Cargo.toml
#	consensus/types/src/beacon_state.rs
#	consensus/types/src/chain_spec.rs
#	consensus/types/src/eth_spec.rs
#	consensus/types/src/fork_name.rs
#	lcli/Cargo.toml
#	lcli/src/main.rs
#	lcli/src/new_testnet.rs
#	scripts/local_testnet/el_bootnode.sh
#	scripts/local_testnet/genesis.json
#	scripts/local_testnet/geth.sh
#	scripts/local_testnet/setup.sh
#	scripts/local_testnet/start_local_testnet.sh
#	scripts/local_testnet/vars.env
#	scripts/tests/doppelganger_protection.sh
#	scripts/tests/genesis.json
#	scripts/tests/vars.env
#	testing/ef_tests/Cargo.toml
#	validator_client/src/block_service.rs
This commit is contained in:
Jimmy Chen
2023-05-30 11:26:33 +10:00
333 changed files with 5930 additions and 13386 deletions

View File

@@ -11,7 +11,7 @@ clap = "2.33.3"
hex = "0.4.2"
dirs = "3.0.1"
eth2_network_config = { path = "../eth2_network_config" }
eth2_ssz = "0.4.1"
ethereum_ssz = "0.5.0"
ethereum-types = "0.14.1"
serde = "1.0.116"
serde_json = "1.0.59"

View File

@@ -14,6 +14,6 @@ hex = "0.4.2"
[dependencies]
types = { path = "../../consensus/types"}
eth2_ssz = "0.4.1"
tree_hash = "0.4.1"
ethereum_ssz = "0.5.0"
tree_hash = "0.5.0"
ethabi = "16.0.0"

View File

@@ -13,15 +13,15 @@ types = { path = "../../consensus/types" }
reqwest = { version = "0.11.0", features = ["json","stream"] }
lighthouse_network = { path = "../../beacon_node/lighthouse_network" }
proto_array = { path = "../../consensus/proto_array", optional = true }
eth2_serde_utils = "0.1.1"
ethereum_serde_utils = "0.5.0"
eth2_keystore = { path = "../../crypto/eth2_keystore" }
libsecp256k1 = "0.7.0"
ring = "0.16.19"
bytes = "1.0.1"
account_utils = { path = "../../common/account_utils" }
sensitive_url = { path = "../../common/sensitive_url" }
eth2_ssz = "0.4.1"
eth2_ssz_derive = "0.3.1"
ethereum_ssz = "0.5.0"
ethereum_ssz_derive = "0.5.0"
futures-util = "0.3.8"
futures = "0.3.8"
store = { path = "../../beacon_node/store", optional = true }

View File

@@ -6,32 +6,32 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct IdealAttestationRewards {
// Validator's effective balance in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub effective_balance: u64,
// Ideal attester's reward for head vote in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub head: u64,
// Ideal attester's reward for target vote in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub target: u64,
// Ideal attester's reward for source vote in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub source: u64,
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct TotalAttestationRewards {
// one entry for every validator based on their attestations in the epoch
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
// attester's reward for head vote in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub head: u64,
// attester's reward for target vote in gwei
#[serde(with = "eth2_serde_utils::quoted_i64")]
#[serde(with = "serde_utils::quoted_i64")]
pub target: i64,
// attester's reward for source vote in gwei
#[serde(with = "eth2_serde_utils::quoted_i64")]
#[serde(with = "serde_utils::quoted_i64")]
pub source: i64,
// TBD attester's inclusion_delay reward in gwei (phase0 only)
// pub inclusion_delay: u64,

View File

@@ -5,22 +5,22 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct StandardBlockReward {
// proposer of the block, the proposer index who receives these rewards
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub proposer_index: u64,
// total block reward in gwei,
// equal to attestations + sync_aggregate + proposer_slashings + attester_slashings
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub total: u64,
// block reward component due to included attestations in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub attestations: u64,
// block reward component due to included sync_aggregate in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub sync_aggregate: u64,
// block reward component due to included proposer_slashings in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub proposer_slashings: u64,
// block reward component due to included attester_slashings in gwei
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub attester_slashings: u64,
}

View File

@@ -5,9 +5,9 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct SyncCommitteeReward {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
// sync committee reward in gwei for the validator
#[serde(with = "eth2_serde_utils::quoted_i64")]
#[serde(with = "serde_utils::quoted_i64")]
pub reward: i64,
}

View File

@@ -57,7 +57,7 @@ pub fn parse_pubkey(secret: &str) -> Result<Option<PublicKey>, Error> {
&secret[SECRET_PREFIX.len()..]
};
eth2_serde_utils::hex::decode(secret)
serde_utils::hex::decode(secret)
.map_err(|e| Error::InvalidSecret(format!("invalid hex: {:?}", e)))
.and_then(|bytes| {
if bytes.len() != PK_LEN {
@@ -174,7 +174,7 @@ impl ValidatorClientHttpClient {
let message =
Message::parse_slice(digest(&SHA256, &body).as_ref()).expect("sha256 is 32 bytes");
eth2_serde_utils::hex::decode(&sig)
serde_utils::hex::decode(&sig)
.ok()
.and_then(|bytes| {
let sig = Signature::parse_der(&bytes).ok()?;

View File

@@ -13,7 +13,7 @@ pub struct GetFeeRecipientResponse {
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct GetGasLimitResponse {
pub pubkey: PublicKeyBytes,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub gas_limit: u64,
}
@@ -45,7 +45,7 @@ pub struct ImportKeystoresRequest {
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct KeystoreJsonStr(#[serde(with = "eth2_serde_utils::json_str")] pub Keystore);
pub struct KeystoreJsonStr(#[serde(with = "serde_utils::json_str")] pub Keystore);
impl std::ops::Deref for KeystoreJsonStr {
type Target = Keystore;
@@ -56,7 +56,7 @@ impl std::ops::Deref for KeystoreJsonStr {
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct InterchangeJsonStr(#[serde(with = "eth2_serde_utils::json_str")] pub Interchange);
pub struct InterchangeJsonStr(#[serde(with = "serde_utils::json_str")] pub Interchange);
#[derive(Debug, Deserialize, Serialize)]
pub struct ImportKeystoresResponse {
@@ -103,7 +103,7 @@ pub struct DeleteKeystoresRequest {
#[derive(Debug, Deserialize, Serialize)]
pub struct DeleteKeystoresResponse {
pub data: Vec<Status<DeleteKeystoreStatus>>,
#[serde(with = "eth2_serde_utils::json_str")]
#[serde(with = "serde_utils::json_str")]
pub slashing_protection: Interchange,
}

View File

@@ -32,14 +32,14 @@ pub struct ValidatorRequest {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub builder_proposals: Option<bool>,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub deposit_gwei: u64,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct CreateValidatorsMnemonicRequest {
pub mnemonic: ZeroizeString,
#[serde(with = "eth2_serde_utils::quoted_u32")]
#[serde(with = "serde_utils::quoted_u32")]
pub key_derivation_path_offset: u32,
pub validators: Vec<ValidatorRequest>,
}
@@ -62,7 +62,7 @@ pub struct CreatedValidator {
#[serde(skip_serializing_if = "Option::is_none")]
pub builder_proposals: Option<bool>,
pub eth1_deposit_tx_data: String,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub deposit_gwei: u64,
}
@@ -141,7 +141,7 @@ pub struct UpdateFeeRecipientRequest {
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct UpdateGasLimitRequest {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub gas_limit: u64,
}

View File

@@ -83,10 +83,10 @@ impl std::fmt::Display for EndpointVersion {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GenesisData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub genesis_time: u64,
pub genesis_validators_root: Hash256,
#[serde(with = "eth2_serde_utils::bytes_4_hex")]
#[serde(with = "serde_utils::bytes_4_hex")]
pub genesis_fork_version: [u8; 4],
}
@@ -317,9 +317,9 @@ impl fmt::Display for ValidatorId {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ValidatorData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub balance: u64,
pub status: ValidatorStatus,
pub validator: Validator,
@@ -327,9 +327,9 @@ pub struct ValidatorData {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ValidatorBalanceData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub balance: u64,
}
@@ -492,16 +492,16 @@ pub struct ValidatorsQuery {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CommitteeData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
pub slot: Slot,
#[serde(with = "eth2_serde_utils::quoted_u64_vec")]
#[serde(with = "serde_utils::quoted_u64_vec")]
pub validators: Vec<u64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SyncCommitteeByValidatorIndices {
#[serde(with = "eth2_serde_utils::quoted_u64_vec")]
#[serde(with = "serde_utils::quoted_u64_vec")]
pub validators: Vec<u64>,
pub validator_aggregates: Vec<SyncSubcommittee>,
}
@@ -514,7 +514,7 @@ pub struct RandaoMix {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SyncSubcommittee {
#[serde(with = "eth2_serde_utils::quoted_u64_vec")]
#[serde(with = "serde_utils::quoted_u64_vec")]
pub indices: Vec<u64>,
}
@@ -539,7 +539,7 @@ pub struct BlockHeaderData {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DepositContractData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub chain_id: u64,
pub address: Address,
}
@@ -563,7 +563,7 @@ pub struct IdentityData {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MetaData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub seq_number: u64,
pub attnets: String,
pub syncnets: String,
@@ -578,6 +578,7 @@ pub struct VersionData {
pub struct SyncingData {
pub is_syncing: bool,
pub is_optimistic: Option<bool>,
pub el_offline: Option<bool>,
pub head_slot: Slot,
pub sync_distance: Slot,
}
@@ -650,27 +651,27 @@ pub struct ValidatorBalancesQuery {
#[derive(Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ValidatorIndexData(#[serde(with = "eth2_serde_utils::quoted_u64_vec")] pub Vec<u64>);
pub struct ValidatorIndexData(#[serde(with = "serde_utils::quoted_u64_vec")] pub Vec<u64>);
/// Borrowed variant of `ValidatorIndexData`, for serializing/sending.
#[derive(Clone, Copy, Serialize)]
#[serde(transparent)]
pub struct ValidatorIndexDataRef<'a>(
#[serde(serialize_with = "eth2_serde_utils::quoted_u64_vec::serialize")] pub &'a [u64],
#[serde(serialize_with = "serde_utils::quoted_u64_vec::serialize")] pub &'a [u64],
);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AttesterData {
pub pubkey: PublicKeyBytes,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub committees_at_slot: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub committee_index: CommitteeIndex,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub committee_length: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_committee_index: u64,
pub slot: Slot,
}
@@ -678,7 +679,7 @@ pub struct AttesterData {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ProposerData {
pub pubkey: PublicKeyBytes,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
pub slot: Slot,
}
@@ -727,11 +728,11 @@ pub struct ValidatorAggregateAttestationQuery {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct BeaconCommitteeSubscription {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub validator_index: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub committee_index: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub committees_at_slot: u64,
pub slot: Slot,
pub is_aggregator: bool,
@@ -852,13 +853,13 @@ impl fmt::Display for PeerDirection {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PeerCount {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub connected: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub connecting: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub disconnected: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub disconnecting: u64,
}
@@ -893,7 +894,7 @@ pub struct SseHead {
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
pub struct SseChainReorg {
pub slot: Slot,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub depth: u64,
pub old_head_block: Hash256,
pub old_head_state: Hash256,
@@ -926,7 +927,7 @@ pub struct SseLateHead {
#[serde(untagged)]
pub struct SsePayloadAttributes {
#[superstruct(getter(copy))]
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub timestamp: u64,
#[superstruct(getter(copy))]
pub prev_randao: Hash256,
@@ -939,10 +940,10 @@ pub struct SsePayloadAttributes {
#[derive(PartialEq, Debug, Deserialize, Serialize, Clone)]
pub struct SseExtendedPayloadAttributesGeneric<T> {
pub proposal_slot: Slot,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub proposer_index: u64,
pub parent_block_root: Hash256,
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub parent_block_number: u64,
pub parent_block_hash: ExecutionBlockHash,
pub payload_attributes: T,
@@ -1206,13 +1207,13 @@ fn parse_accept(accept: &str) -> Result<Vec<Mime>, String> {
#[derive(Debug, Serialize, Deserialize)]
pub struct LivenessRequestData {
pub epoch: Epoch,
#[serde(with = "eth2_serde_utils::quoted_u64_vec")]
#[serde(with = "serde_utils::quoted_u64_vec")]
pub indices: Vec<u64>,
}
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct LivenessResponseData {
#[serde(with = "eth2_serde_utils::quoted_u64")]
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
pub epoch: Epoch,
pub is_live: bool,
@@ -1230,9 +1231,9 @@ pub struct ForkChoiceNode {
pub slot: Slot,
pub block_root: Hash256,
pub parent_root: Option<Hash256>,
pub justified_epoch: Option<Epoch>,
pub finalized_epoch: Option<Epoch>,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub justified_epoch: Epoch,
pub finalized_epoch: Epoch,
#[serde(with = "serde_utils::quoted_u64")]
pub weight: u64,
pub validity: Option<String>,
pub execution_block_hash: Option<Hash256>,

View File

@@ -9,7 +9,7 @@ edition = "2021"
[dependencies]
lazy_static = "1.4.0"
num-bigint = "0.4.2"
eth2_hashing = "0.3.0"
ethereum_hashing = "1.0.0-beta.2"
hex = "0.4.2"
serde_yaml = "0.8.13"
serde = "1.0.116"

View File

@@ -20,7 +20,7 @@
extern crate lazy_static;
use bls::{Keypair, PublicKey, SecretKey};
use eth2_hashing::hash;
use ethereum_hashing::hash;
use num_bigint::BigUint;
use serde_derive::{Deserialize, Serialize};
use std::convert::TryInto;

View File

@@ -18,6 +18,6 @@ serde_yaml = "0.8.13"
serde_json = "1.0.58"
types = { path = "../../consensus/types"}
kzg = { path = "../../crypto/kzg" }
eth2_ssz = "0.4.1"
ethereum_ssz = "0.5.0"
eth2_config = { path = "../eth2_config"}
discv5 = "0.2.2"

View File

@@ -1 +1,5 @@
# EF Team
- enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk
- enr:-KG4QE5OIg5ThTjkzrlVF32WT_-XT14WeJtIz2zoTqLLjQhYAmJlnk4ItSoH41_2x0RX0wTFIe5GgjRzU2u7Q1fN4vADhGV0aDKQqP7o7pAAAHAyAAAAAAAAAIJpZIJ2NIJpcISlFsStiXNlY3AyNTZrMaEC-Rrd_bBZwhKpXzFCrStKp1q_HmGOewxY3KwM8ofAj_ODdGNwgiMog3VkcIIjKA
# Teku team (Consensys)
- enr:-Ly4QFoZTWR8ulxGVsWydTNGdwEESueIdj-wB6UmmjUcm-AOPxnQi7wprzwcdo7-1jBW_JxELlUKJdJES8TDsbl1EdNlh2F0dG5ldHOI__78_v2bsV-EZXRoMpA2-lATkAAAcf__________gmlkgnY0gmlwhBLYJjGJc2VjcDI1NmsxoQI0gujXac9rMAb48NtMqtSTyHIeNYlpjkbYpWJw46PmYYhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA

View File

@@ -17,8 +17,8 @@ pub const VERSION: &str = git_version!(
// NOTE: using --match instead of --exclude for compatibility with old Git
"--match=thiswillnevermatchlol"
],
prefix = "Lighthouse/v4.1.0-",
fallback = "Lighthouse/v4.1.0"
prefix = "Lighthouse/v4.2.0-",
fallback = "Lighthouse/v4.2.0"
);
/// Returns `VERSION`, but with platform information appended to the end.

View File

@@ -10,6 +10,13 @@ test_logger = [] # Print log output to stderr when running tests instead of drop
[dependencies]
slog = "2.5.2"
slog-term = "2.6.0"
tokio = { version = "1.26.0", features = ["sync"] }
lighthouse_metrics = { path = "../lighthouse_metrics" }
lazy_static = "1.4.0"
sloggers = { version = "2.1.1", features = ["json"] }
slog-async = "2.7.0"
take_mut = "0.2.2"
parking_lot = "0.12.1"
serde = "1.0.153"
serde_json = "1.0.94"
chrono = "0.4.23"

View File

@@ -0,0 +1,309 @@
//! An object that can be used to pass through a channel and be cloned. It can therefore be used
//! via the broadcast channel.
use parking_lot::Mutex;
use serde::ser::SerializeMap;
use serde::serde_if_integer128;
use serde::Serialize;
use slog::{BorrowedKV, Key, Level, OwnedKVList, Record, RecordStatic, Serializer, SingleKV, KV};
use std::cell::RefCell;
use std::fmt;
use std::fmt::Write;
use std::sync::Arc;
use take_mut::take;
thread_local! {
static TL_BUF: RefCell<String> = RefCell::new(String::with_capacity(128))
}
/// Serialized record.
#[derive(Clone)]
pub struct AsyncRecord {
msg: String,
level: Level,
location: Box<slog::RecordLocation>,
tag: String,
logger_values: OwnedKVList,
kv: Arc<Mutex<dyn KV + Send>>,
}
impl AsyncRecord {
/// Serializes a `Record` and an `OwnedKVList`.
pub fn from(record: &Record, logger_values: &OwnedKVList) -> Self {
let mut ser = ToSendSerializer::new();
record
.kv()
.serialize(record, &mut ser)
.expect("`ToSendSerializer` can't fail");
AsyncRecord {
msg: fmt::format(*record.msg()),
level: record.level(),
location: Box::new(*record.location()),
tag: String::from(record.tag()),
logger_values: logger_values.clone(),
kv: Arc::new(Mutex::new(ser.finish())),
}
}
pub fn to_json_string(&self) -> Result<String, String> {
serde_json::to_string(&self).map_err(|e| format!("{:?}", e))
}
}
pub struct ToSendSerializer {
kv: Box<dyn KV + Send>,
}
impl ToSendSerializer {
fn new() -> Self {
ToSendSerializer { kv: Box::new(()) }
}
fn finish(self) -> Box<dyn KV + Send> {
self.kv
}
}
impl Serializer for ToSendSerializer {
fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_unit(&mut self, key: Key) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, ()))));
Ok(())
}
fn emit_none(&mut self, key: Key) -> slog::Result {
let val: Option<()> = None;
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_char(&mut self, key: Key, val: char) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
#[cfg(integer128)]
fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
#[cfg(integer128)]
fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result {
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_str(&mut self, key: Key, val: &str) -> slog::Result {
let val = val.to_owned();
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
let val = fmt::format(*val);
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
Ok(())
}
}
impl Serialize for AsyncRecord {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
// Get the current time
let dt = chrono::Local::now().format("%b %e %T").to_string();
let rs = RecordStatic {
location: &self.location,
level: self.level,
tag: &self.tag,
};
let mut map_serializer = SerdeSerializer::new(serializer)?;
// Serialize the time and log level first
map_serializer.serialize_entry("time", &dt)?;
map_serializer.serialize_entry("level", self.level.as_short_str())?;
let kv = self.kv.lock();
// Convoluted pattern to avoid binding `format_args!` to a temporary.
// See: https://stackoverflow.com/questions/56304313/cannot-use-format-args-due-to-temporary-value-is-freed-at-the-end-of-this-state
let mut f = |msg: std::fmt::Arguments| {
map_serializer.serialize_entry("msg", &msg.to_string())?;
let record = Record::new(&rs, &msg, BorrowedKV(&(*kv)));
self.logger_values
.serialize(&record, &mut map_serializer)
.map_err(serde::ser::Error::custom)?;
record
.kv()
.serialize(&record, &mut map_serializer)
.map_err(serde::ser::Error::custom)
};
f(format_args!("{}", self.msg))?;
map_serializer.end()
}
}
struct SerdeSerializer<S: serde::Serializer> {
/// Current state of map serializing: `serde::Serializer::MapState`
ser_map: S::SerializeMap,
}
impl<S: serde::Serializer> SerdeSerializer<S> {
fn new(ser: S) -> Result<Self, S::Error> {
let ser_map = ser.serialize_map(None)?;
Ok(SerdeSerializer { ser_map })
}
fn serialize_entry<K, V>(&mut self, key: K, value: V) -> Result<(), S::Error>
where
K: serde::Serialize,
V: serde::Serialize,
{
self.ser_map.serialize_entry(&key, &value)
}
/// Finish serialization, and return the serializer
fn end(self) -> Result<S::Ok, S::Error> {
self.ser_map.end()
}
}
// NOTE: This is borrowed from slog_json
macro_rules! impl_m(
($s:expr, $key:expr, $val:expr) => ({
let k_s: &str = $key.as_ref();
$s.ser_map.serialize_entry(k_s, $val)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("serde serialization error: {}", e)))?;
Ok(())
});
);
impl<S> slog::Serializer for SerdeSerializer<S>
where
S: serde::Serializer,
{
fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_unit(&mut self, key: Key) -> slog::Result {
impl_m!(self, key, &())
}
fn emit_char(&mut self, key: Key, val: char) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_none(&mut self, key: Key) -> slog::Result {
let val: Option<()> = None;
impl_m!(self, key, &val)
}
fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result {
impl_m!(self, key, &val)
}
serde_if_integer128! {
fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result {
impl_m!(self, key, &val)
}
}
fn emit_str(&mut self, key: Key, val: &str) -> slog::Result {
impl_m!(self, key, &val)
}
fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
TL_BUF.with(|buf| {
let mut buf = buf.borrow_mut();
buf.write_fmt(*val).unwrap();
let res = { || impl_m!(self, key, &*buf) }();
buf.clear();
res
})
}
}

View File

@@ -11,6 +11,10 @@ use std::time::{Duration, Instant};
pub const MAX_MESSAGE_WIDTH: usize = 40;
pub mod async_record;
mod sse_logging_components;
pub use sse_logging_components::SSELoggingComponents;
/// The minimum interval between log messages indicating that a queue is full.
const LOG_DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);

View File

@@ -0,0 +1,46 @@
//! This module provides an implementation of `slog::Drain` that optionally writes to a channel if
//! there are subscribers to a HTTP SSE stream.
use crate::async_record::AsyncRecord;
use slog::{Drain, OwnedKVList, Record};
use std::panic::AssertUnwindSafe;
use std::sync::Arc;
use tokio::sync::broadcast::Sender;
/// Default log level for SSE Events.
// NOTE: Made this a constant. Debug level seems to be pretty intense. Can make this
// configurable later if needed.
const LOG_LEVEL: slog::Level = slog::Level::Info;
/// The components required in the HTTP API task to receive logged events.
#[derive(Clone)]
pub struct SSELoggingComponents {
/// The channel to receive events from.
pub sender: Arc<AssertUnwindSafe<Sender<AsyncRecord>>>,
}
impl SSELoggingComponents {
/// Create a new SSE drain.
pub fn new(channel_size: usize) -> Self {
let (sender, _receiver) = tokio::sync::broadcast::channel(channel_size);
let sender = Arc::new(AssertUnwindSafe(sender));
SSELoggingComponents { sender }
}
}
impl Drain for SSELoggingComponents {
type Ok = ();
type Err = &'static str;
fn log(&self, record: &Record, logger_values: &OwnedKVList) -> Result<Self::Ok, Self::Err> {
if record.level().is_at_least(LOG_LEVEL) {
// Attempt to send the logs
match self.sender.send(AsyncRecord::from(record, logger_values)) {
Ok(_num_sent) => {} // Everything got sent
Err(_err) => {} // There are no subscribers, do nothing
}
}
Ok(())
}
}

View File

@@ -16,7 +16,7 @@ filesystem = { path = "../filesystem" }
types = { path = "../../consensus/types" }
rand = "0.8.5"
deposit_contract = { path = "../deposit_contract" }
tree_hash = "0.4.1"
tree_hash = "0.5.0"
hex = "0.4.2"
derivative = "2.1.1"
lockfile = { path = "../lockfile" }