Merge branch 'unstable' into vc-fallback

This commit is contained in:
Mac L
2023-11-02 16:27:14 +11:00
546 changed files with 32366 additions and 8974 deletions

View File

@@ -1,25 +0,0 @@
FROM rust:1.68.2-bullseye AS builder
RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake libclang-dev
COPY . lighthouse
# Build lighthouse directly with a cargo build command, bypassing the Makefile.
RUN cd lighthouse && LD_LIBRARY_PATH=/lighthouse/testing/antithesis/libvoidstar/ RUSTFLAGS="-Cpasses=sancov-module -Cllvm-args=-sanitizer-coverage-level=3 -Cllvm-args=-sanitizer-coverage-trace-pc-guard -Ccodegen-units=1 -Cdebuginfo=2 -L/lighthouse/testing/antithesis/libvoidstar/ -lvoidstar" cargo build --release --manifest-path lighthouse/Cargo.toml --target x86_64-unknown-linux-gnu --features modern --verbose --bin lighthouse
# build lcli binary directly with cargo install command, bypassing the makefile
RUN cargo install --path /lighthouse/lcli --force --locked
FROM ubuntu:latest
RUN apt-get update && apt-get -y upgrade && apt-get install -y --no-install-recommends \
libssl-dev \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# create and move the libvoidstar file
RUN mkdir libvoidstar
COPY --from=builder /lighthouse/testing/antithesis/libvoidstar/libvoidstar.so /usr/lib/libvoidstar.so
# set the env variable to avoid having to always set it
ENV LD_LIBRARY_PATH=/usr/lib
# move the lighthouse binary and lcli binary
COPY --from=builder /lighthouse/target/x86_64-unknown-linux-gnu/release/lighthouse /usr/local/bin/lighthouse
COPY --from=builder /lighthouse/target/release/lcli /usr/local/bin/lcli

View File

@@ -2,37 +2,41 @@
name = "ef_tests"
version = "0.2.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"
edition = { workspace = true }
[features]
# `ef_tests` feature must be enabled to actually run the tests
ef_tests = []
milagro = ["bls/milagro"]
fake_crypto = ["bls/fake_crypto"]
portable = ["beacon_chain/portable"]
[dependencies]
bls = { path = "../../crypto/bls", default-features = false }
compare_fields = { path = "../../common/compare_fields" }
compare_fields_derive = { path = "../../common/compare_fields_derive" }
derivative = "2.1.1"
ethereum-types = "0.14.1"
hex = "0.4.2"
rayon = "1.4.1"
serde = "1.0.116"
serde_derive = "1.0.116"
serde_repr = "0.1.6"
serde_yaml = "0.8.13"
ethereum_ssz = "0.5.0"
ethereum_ssz_derive = "0.5.0"
tree_hash = "0.5.0"
tree_hash_derive = "0.5.0"
cached_tree_hash = { path = "../../consensus/cached_tree_hash" }
state_processing = { path = "../../consensus/state_processing" }
swap_or_not_shuffle = { path = "../../consensus/swap_or_not_shuffle" }
types = { path = "../../consensus/types" }
snap = "1.0.1"
fs2 = "0.4.3"
beacon_chain = { path = "../../beacon_node/beacon_chain" }
store = { path = "../../beacon_node/store" }
fork_choice = { path = "../../consensus/fork_choice" }
execution_layer = { path = "../../beacon_node/execution_layer" }
bls = { workspace = true }
compare_fields = { workspace = true }
compare_fields_derive = { workspace = true }
derivative = { workspace = true }
ethereum-types = { workspace = true }
hex = { workspace = true }
kzg = { workspace = true }
rayon = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_repr = { workspace = true }
serde_yaml = { workspace = true }
eth2_network_config = { workspace = true }
ethereum_serde_utils = { workspace = true }
ethereum_ssz = { workspace = true }
ethereum_ssz_derive = { workspace = true }
tree_hash = { workspace = true }
tree_hash_derive = { workspace = true }
cached_tree_hash = { workspace = true }
state_processing = { workspace = true }
swap_or_not_shuffle = { workspace = true }
types = { workspace = true }
snap = { workspace = true }
fs2 = { workspace = true }
beacon_chain = { workspace = true }
store = { workspace = true }
fork_choice = { workspace = true }
execution_layer = { workspace = true }

View File

@@ -1,4 +1,4 @@
TESTS_TAG := v1.3.0-rc.4
TESTS_TAG := v1.4.0-beta.3
TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

View File

@@ -41,8 +41,6 @@ excluded_paths = [
"tests/.*/.*/ssz_static/LightClientFinalityUpdate",
# LightClientHeader
"tests/.*/.*/ssz_static/LightClientHeader",
# Deneb (previously known as eip4844) tests are disabled for now.
"tests/.*/deneb",
# One of the EF researchers likes to pack the tarballs on a Mac
".*\.DS_Store.*",
# More Mac weirdness.
@@ -52,7 +50,8 @@ excluded_paths = [
# some bls tests are not included now
"bls12-381-tests/deserialization_G1",
"bls12-381-tests/deserialization_G2",
"bls12-381-tests/hash_to_G2"
"bls12-381-tests/hash_to_G2",
"tests/.*/eip6110"
]

View File

@@ -18,6 +18,12 @@ mod fork;
mod fork_choice;
mod genesis_initialization;
mod genesis_validity;
mod kzg_blob_to_kzg_commitment;
mod kzg_compute_blob_kzg_proof;
mod kzg_compute_kzg_proof;
mod kzg_verify_blob_kzg_proof;
mod kzg_verify_blob_kzg_proof_batch;
mod kzg_verify_kzg_proof;
mod merkle_proof_validity;
mod operations;
mod rewards;
@@ -42,6 +48,12 @@ pub use epoch_processing::*;
pub use fork::ForkTest;
pub use genesis_initialization::*;
pub use genesis_validity::*;
pub use kzg_blob_to_kzg_commitment::*;
pub use kzg_compute_blob_kzg_proof::*;
pub use kzg_compute_kzg_proof::*;
pub use kzg_verify_blob_kzg_proof::*;
pub use kzg_verify_blob_kzg_proof_batch::*;
pub use kzg_verify_kzg_proof::*;
pub use merkle_proof_validity::*;
pub use operations::*;
pub use rewards::RewardsTest;

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, Signature};
use serde_derive::Deserialize;
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct BlsAggregateSigs {

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use serde::Deserialize;
use types::Hash256;
#[derive(Debug, Clone, Deserialize)]

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{verify_signature_sets, BlsWrappedSignature, PublicKeyBytes, Signature, SignatureSet};
use serde_derive::Deserialize;
use serde::Deserialize;
use std::borrow::Cow;
use std::str::FromStr;
use types::Hash256;

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{AggregatePublicKey, PublicKeyBytes};
use serde_derive::Deserialize;
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct BlsEthAggregatePubkeys {

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use serde::Deserialize;
use std::convert::TryInto;
use types::Hash256;

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use serde::Deserialize;
use std::convert::TryInto;
use types::Hash256;

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::SecretKey;
use serde_derive::Deserialize;
use serde::Deserialize;
use types::Hash256;
#[derive(Debug, Clone, Deserialize)]

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{PublicKeyBytes, Signature, SignatureBytes};
use serde_derive::Deserialize;
use serde::Deserialize;
use std::convert::TryInto;
use types::Hash256;

View File

@@ -1,4 +1,4 @@
use serde_derive::Deserialize;
use serde::Deserialize;
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use std::convert::TryFrom;
@@ -64,8 +64,9 @@ pub fn previous_fork(fork_name: ForkName) -> ForkName {
match fork_name {
ForkName::Base => ForkName::Base,
ForkName::Altair => ForkName::Base,
ForkName::Merge => ForkName::Altair, // TODO: Check this when tests are released..
ForkName::Capella => ForkName::Merge, // TODO: Check this when tests are released..
ForkName::Merge => ForkName::Altair,
ForkName::Capella => ForkName::Merge,
ForkName::Deneb => ForkName::Capella,
}
}

View File

@@ -4,7 +4,7 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use crate::type_name;
use crate::type_name::TypeName;
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::per_epoch_processing::capella::process_historical_summaries_update;
use state_processing::per_epoch_processing::effective_balance_updates::process_effective_balance_updates;
use state_processing::per_epoch_processing::{
@@ -101,7 +101,10 @@ impl<E: EthSpec> EpochTransition<E> for JustificationAndFinalization {
justification_and_finalization_state.apply_changes_to_state(state);
Ok(())
}
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => {
let justification_and_finalization_state =
altair::process_justification_and_finalization(
state,
@@ -122,13 +125,14 @@ impl<E: EthSpec> EpochTransition<E> for RewardsAndPenalties {
validator_statuses.process_attestations(state)?;
base::process_rewards_and_penalties(state, &validator_statuses, spec)
}
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
altair::process_rewards_and_penalties(
state,
&altair::ParticipationCache::new(state, spec).unwrap(),
spec,
)
}
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => altair::process_rewards_and_penalties(
state,
&altair::ParticipationCache::new(state, spec).unwrap(),
spec,
),
}
}
}
@@ -151,7 +155,10 @@ impl<E: EthSpec> EpochTransition<E> for Slashings {
spec,
)?;
}
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => {
process_slashings(
state,
altair::ParticipationCache::new(state, spec)
@@ -203,7 +210,9 @@ impl<E: EthSpec> EpochTransition<E> for HistoricalRootsUpdate {
impl<E: EthSpec> EpochTransition<E> for HistoricalSummariesUpdate {
fn run(state: &mut BeaconState<E>, _spec: &ChainSpec) -> Result<(), EpochProcessingError> {
match state {
BeaconState::Capella(_) => process_historical_summaries_update(state),
BeaconState::Capella(_) | BeaconState::Deneb(_) => {
process_historical_summaries_update(state)
}
_ => Ok(()),
}
}
@@ -223,9 +232,10 @@ impl<E: EthSpec> EpochTransition<E> for SyncCommitteeUpdates {
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
match state {
BeaconState::Base(_) => Ok(()),
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
altair::process_sync_committee_updates(state, spec)
}
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => altair::process_sync_committee_updates(state, spec),
}
}
}
@@ -234,13 +244,14 @@ impl<E: EthSpec> EpochTransition<E> for InactivityUpdates {
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
match state {
BeaconState::Base(_) => Ok(()),
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
altair::process_inactivity_updates(
state,
&altair::ParticipationCache::new(state, spec).unwrap(),
spec,
)
}
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => altair::process_inactivity_updates(
state,
&altair::ParticipationCache::new(state, spec).unwrap(),
spec,
),
}
}
}
@@ -249,9 +260,10 @@ impl<E: EthSpec> EpochTransition<E> for ParticipationFlagUpdates {
fn run(state: &mut BeaconState<E>, _: &ChainSpec) -> Result<(), EpochProcessingError> {
match state {
BeaconState::Base(_) => Ok(()),
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
altair::process_participation_flag_updates(state)
}
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => altair::process_participation_flag_updates(state),
}
}
}
@@ -302,7 +314,7 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
T::name() != "participation_record_updates"
&& T::name() != "historical_summaries_update"
}
ForkName::Capella => {
ForkName::Capella | ForkName::Deneb => {
T::name() != "participation_record_updates"
&& T::name() != "historical_roots_update"
}

View File

@@ -2,8 +2,10 @@ use super::*;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::cases::common::previous_fork;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use state_processing::upgrade::{upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella};
use serde::Deserialize;
use state_processing::upgrade::{
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
};
use types::{BeaconState, ForkName};
#[derive(Debug, Clone, Default, Deserialize)]
@@ -62,6 +64,7 @@ impl<E: EthSpec> Case for ForkTest<E> {
ForkName::Altair => upgrade_to_altair(&mut result_state, spec).map(|_| result_state),
ForkName::Merge => upgrade_to_bellatrix(&mut result_state, spec).map(|_| result_state),
ForkName::Capella => upgrade_to_capella(&mut result_state, spec).map(|_| result_state),
ForkName::Deneb => upgrade_to_deneb(&mut result_state, spec).map(|_| result_state),
};
compare_beacon_state_results_without_caches(&mut result, &mut expected)

View File

@@ -6,8 +6,9 @@ use beacon_chain::{
attestation_verification::{
obtain_indexed_attestation_and_committees_per_slot, VerifiedAttestation,
},
blob_verification::GossipVerifiedBlob,
test_utils::{BeaconChainHarness, EphemeralHarnessType},
BeaconChainTypes, CachedHead, NotifyExecutionLayer,
AvailabilityProcessingStatus, BeaconChainTypes, CachedHead, ChainConfig, NotifyExecutionLayer,
};
use execution_layer::{json_structures::JsonPayloadStatusV1Status, PayloadStatusV1};
use serde::Deserialize;
@@ -17,9 +18,9 @@ use std::future::Future;
use std::sync::Arc;
use std::time::Duration;
use types::{
Attestation, AttesterSlashing, BeaconBlock, BeaconState, Checkpoint, EthSpec,
ExecutionBlockHash, ForkName, Hash256, IndexedAttestation, ProgressiveBalancesMode,
SignedBeaconBlock, Slot, Uint256,
Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlobSidecar, BlobsList, Checkpoint,
EthSpec, ExecutionBlockHash, ForkName, Hash256, IndexedAttestation, KzgProof,
ProgressiveBalancesMode, Signature, SignedBeaconBlock, SignedBlobSidecar, Slot, Uint256,
};
#[derive(Default, Debug, PartialEq, Clone, Deserialize, Decode)]
@@ -71,25 +72,27 @@ impl From<PayloadStatus> for PayloadStatusV1 {
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum Step<B, A, AS, P> {
pub enum Step<TBlock, TBlobs, TAttestation, TAttesterSlashing, TPowBlock> {
Tick {
tick: u64,
},
ValidBlock {
block: B,
block: TBlock,
},
MaybeValidBlock {
block: B,
block: TBlock,
blobs: Option<TBlobs>,
proofs: Option<Vec<KzgProof>>,
valid: bool,
},
Attestation {
attestation: A,
attestation: TAttestation,
},
AttesterSlashing {
attester_slashing: AS,
attester_slashing: TAttesterSlashing,
},
PowBlock {
pow_block: P,
pow_block: TPowBlock,
},
OnPayloadInfo {
block_hash: ExecutionBlockHash,
@@ -113,7 +116,9 @@ pub struct ForkChoiceTest<E: EthSpec> {
pub anchor_state: BeaconState<E>,
pub anchor_block: BeaconBlock<E>,
#[allow(clippy::type_complexity)]
pub steps: Vec<Step<SignedBeaconBlock<E>, Attestation<E>, AttesterSlashing<E>, PowBlock>>,
pub steps: Vec<
Step<SignedBeaconBlock<E>, BlobsList<E>, Attestation<E>, AttesterSlashing<E>, PowBlock>,
>,
}
impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
@@ -126,7 +131,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
.expect("path must be valid OsStr")
.to_string();
let spec = &testing_spec::<E>(fork_name);
let steps: Vec<Step<String, String, String, String>> =
let steps: Vec<Step<String, String, String, String, String>> =
yaml_decode_file(&path.join("steps.yaml"))?;
// Resolve the object names in `steps.yaml` into actual decoded block/attestation objects.
let steps = steps
@@ -139,11 +144,25 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
})
.map(|block| Step::ValidBlock { block })
}
Step::MaybeValidBlock { block, valid } => {
ssz_decode_file_with(&path.join(format!("{}.ssz_snappy", block)), |bytes| {
SignedBeaconBlock::from_ssz_bytes(bytes, spec)
Step::MaybeValidBlock {
block,
blobs,
proofs,
valid,
} => {
let block =
ssz_decode_file_with(&path.join(format!("{block}.ssz_snappy")), |bytes| {
SignedBeaconBlock::from_ssz_bytes(bytes, spec)
})?;
let blobs = blobs
.map(|blobs| ssz_decode_file(&path.join(format!("{blobs}.ssz_snappy"))))
.transpose()?;
Ok(Step::MaybeValidBlock {
block,
blobs,
proofs,
valid,
})
.map(|block| Step::MaybeValidBlock { block, valid })
}
Step::Attestation { attestation } => {
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attestation)))
@@ -204,10 +223,15 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
for step in &self.steps {
match step {
Step::Tick { tick } => tester.set_tick(*tick),
Step::ValidBlock { block } => tester.process_block(block.clone(), true)?,
Step::MaybeValidBlock { block, valid } => {
tester.process_block(block.clone(), *valid)?
Step::ValidBlock { block } => {
tester.process_block(block.clone(), None, None, true)?
}
Step::MaybeValidBlock {
block,
blobs,
proofs,
valid,
} => tester.process_block(block.clone(), blobs.clone(), proofs.clone(), *valid)?,
Step::Attestation { attestation } => tester.process_attestation(attestation)?,
Step::AttesterSlashing { attester_slashing } => {
tester.process_attester_slashing(attester_slashing)
@@ -300,9 +324,13 @@ impl<E: EthSpec> Tester<E> {
));
}
let harness = BeaconChainHarness::builder(E::default())
let harness = BeaconChainHarness::<EphemeralHarnessType<E>>::builder(E::default())
.spec(spec.clone())
.keypairs(vec![])
.chain_config(ChainConfig {
reconstruct_historic_states: true,
..ChainConfig::default()
})
.genesis_state_ephemeral_store(case.anchor_state.clone())
.mock_execution_layer()
.recalculate_fork_times_with_genesis(0)
@@ -376,16 +404,70 @@ impl<E: EthSpec> Tester<E> {
.unwrap();
}
pub fn process_block(&self, block: SignedBeaconBlock<E>, valid: bool) -> Result<(), Error> {
pub fn process_block(
&self,
block: SignedBeaconBlock<E>,
blobs: Option<BlobsList<E>>,
kzg_proofs: Option<Vec<KzgProof>>,
valid: bool,
) -> Result<(), Error> {
let block_root = block.canonical_root();
// Convert blobs and kzg_proofs into sidecars, then plumb them into the availability tracker
if let Some(blobs) = blobs.clone() {
let proofs = kzg_proofs.unwrap();
let commitments = block
.message()
.body()
.blob_kzg_commitments()
.unwrap()
.clone();
// Zipping will stop when any of the zipped lists runs out, which is what we want. Some
// of the tests don't provide enough proofs/blobs, and should fail the availability
// check.
for (i, ((blob, kzg_proof), kzg_commitment)) in blobs
.into_iter()
.zip(proofs)
.zip(commitments.into_iter())
.enumerate()
{
let signed_sidecar = SignedBlobSidecar {
message: Arc::new(BlobSidecar {
block_root,
index: i as u64,
slot: block.slot(),
block_parent_root: block.parent_root(),
proposer_index: block.message().proposer_index(),
blob,
kzg_commitment,
kzg_proof,
}),
signature: Signature::empty(),
_phantom: Default::default(),
};
let result = self.block_on_dangerous(
self.harness
.chain
.process_gossip_blob(GossipVerifiedBlob::__assumed_valid(signed_sidecar)),
)?;
if valid {
assert!(result.is_ok());
}
}
};
let block = Arc::new(block);
let result = self.block_on_dangerous(self.harness.chain.process_block(
block_root,
block.clone(),
NotifyExecutionLayer::Yes,
|| Ok(()),
))?;
if result.is_ok() != valid {
let result: Result<Result<Hash256, ()>, _> = self
.block_on_dangerous(self.harness.chain.process_block(
block_root,
block.clone(),
NotifyExecutionLayer::Yes,
|| Ok(()),
))?
.map(|avail: AvailabilityProcessingStatus| avail.try_into());
let success = result.as_ref().map_or(false, |inner| inner.is_ok());
if success != valid {
return Err(Error::DidntFail(format!(
"block with root {} was valid={} whilst test expects valid={}. result: {:?}",
block_root,
@@ -397,8 +479,8 @@ impl<E: EthSpec> Tester<E> {
// Apply invalid blocks directly against the fork choice `on_block` function. This ensures
// that the block is being rejected by `on_block`, not just some upstream block processing
// function.
if !valid {
// function. When blobs exist, we don't do this.
if !valid && blobs.is_none() {
// A missing parent block whilst `valid == false` means the test should pass.
if let Some(parent_block) = self
.harness

View File

@@ -1,7 +1,7 @@
use super::*;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::initialize_beacon_state_from_eth1;
use std::path::PathBuf;
use types::{BeaconState, Deposit, EthSpec, ExecutionPayloadHeader, ForkName, Hash256};

View File

@@ -1,6 +1,6 @@
use super::*;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::is_valid_genesis_state;
use std::path::Path;
use types::{BeaconState, EthSpec, ForkName};

View File

@@ -0,0 +1,47 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::blob_to_kzg_commitment;
use kzg::KzgCommitment;
use serde::Deserialize;
use std::marker::PhantomData;
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGBlobToKZGCommitmentInput {
pub blob: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGBlobToKZGCommitment<E: EthSpec> {
pub input: KZGBlobToKZGCommitmentInput,
pub output: Option<String>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGBlobToKZGCommitment<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGBlobToKZGCommitment<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let kzg = get_kzg()?;
let commitment = parse_blob::<E>(&self.input.blob).and_then(|blob| {
blob_to_kzg_commitment::<E>(&kzg, &blob).map_err(|e| {
Error::InternalError(format!("Failed to compute kzg commitment: {:?}", e))
})
});
let expected = self.output.as_ref().and_then(|s| parse_commitment(s).ok());
compare_result::<KzgCommitment, _>(&commitment, &expected)
}
}

View File

@@ -0,0 +1,52 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::compute_blob_kzg_proof;
use kzg::KzgProof;
use serde::Deserialize;
use std::marker::PhantomData;
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGComputeBlobKZGProofInput {
pub blob: String,
pub commitment: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGComputeBlobKZGProof<E: EthSpec> {
pub input: KZGComputeBlobKZGProofInput,
pub output: Option<String>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGComputeBlobKZGProof<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGComputeBlobKZGProof<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let parse_input = |input: &KZGComputeBlobKZGProofInput| -> Result<_, Error> {
let blob = parse_blob::<E>(&input.blob)?;
let commitment = parse_commitment(&input.commitment)?;
Ok((blob, commitment))
};
let kzg = get_kzg()?;
let proof = parse_input(&self.input).and_then(|(blob, commitment)| {
compute_blob_kzg_proof::<E>(&kzg, &blob, commitment)
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
});
let expected = self.output.as_ref().and_then(|s| parse_proof(s).ok());
compare_result::<KzgProof, _>(&proof, &expected)
}
}

View File

@@ -0,0 +1,62 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::compute_kzg_proof;
use kzg::KzgProof;
use serde::Deserialize;
use std::marker::PhantomData;
use std::str::FromStr;
use types::Hash256;
pub fn parse_point(point: &str) -> Result<Hash256, Error> {
Hash256::from_str(&point[2..])
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse point: {:?}", e)))
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGComputeKZGProofInput {
pub blob: String,
pub z: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGComputeKZGProof<E: EthSpec> {
pub input: KZGComputeKZGProofInput,
pub output: Option<(String, Hash256)>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGComputeKZGProof<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGComputeKZGProof<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let parse_input = |input: &KZGComputeKZGProofInput| -> Result<_, Error> {
let blob = parse_blob::<E>(&input.blob)?;
let z = parse_point(&input.z)?;
Ok((blob, z))
};
let kzg = get_kzg()?;
let proof = parse_input(&self.input).and_then(|(blob, z)| {
compute_kzg_proof::<E>(&kzg, &blob, z)
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
});
let expected = self
.output
.as_ref()
.and_then(|(s, z)| parse_proof(s).ok().map(|proof| (proof, *z)));
compare_result::<(KzgProof, Hash256), _>(&proof, &expected)
}
}

View File

@@ -0,0 +1,100 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::validate_blob;
use eth2_network_config::TRUSTED_SETUP_BYTES;
use kzg::{Kzg, KzgCommitment, KzgProof, TrustedSetup};
use serde::Deserialize;
use std::convert::TryInto;
use std::marker::PhantomData;
use types::Blob;
pub fn get_kzg() -> Result<Kzg, Error> {
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES)
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))?;
Kzg::new_from_trusted_setup(trusted_setup)
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))
}
pub fn parse_proof(proof: &str) -> Result<KzgProof, Error> {
hex::decode(strip_0x(proof)?)
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse proof: {:?}", e)))
.and_then(|bytes| {
bytes
.try_into()
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse proof: {:?}", e)))
})
.map(KzgProof)
}
pub fn parse_commitment(commitment: &str) -> Result<KzgCommitment, Error> {
hex::decode(strip_0x(commitment)?)
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse commitment: {:?}", e)))
.and_then(|bytes| {
bytes.try_into().map_err(|e| {
Error::FailedToParseTest(format!("Failed to parse commitment: {:?}", e))
})
})
.map(KzgCommitment)
}
pub fn parse_blob<E: EthSpec>(blob: &str) -> Result<Blob<E>, Error> {
hex::decode(strip_0x(blob)?)
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse blob: {:?}", e)))
.and_then(|bytes| {
Blob::<E>::new(bytes)
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse blob: {:?}", e)))
})
}
fn strip_0x(s: &str) -> Result<&str, Error> {
s.strip_prefix("0x").ok_or(Error::FailedToParseTest(format!(
"Hex is missing 0x prefix: {}",
s
)))
}
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGVerifyBlobKZGProofInput {
pub blob: String,
pub commitment: String,
pub proof: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGVerifyBlobKZGProof<E: EthSpec> {
pub input: KZGVerifyBlobKZGProofInput,
pub output: Option<bool>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGVerifyBlobKZGProof<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGVerifyBlobKZGProof<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let parse_input = |input: &KZGVerifyBlobKZGProofInput| -> Result<(Blob<E>, KzgCommitment, KzgProof), Error> {
let blob = parse_blob::<E>(&input.blob)?;
let commitment = parse_commitment(&input.commitment)?;
let proof = parse_proof(&input.proof)?;
Ok((blob, commitment, proof))
};
let kzg = get_kzg()?;
let result = parse_input(&self.input).and_then(|(blob, commitment, proof)| {
validate_blob::<E>(&kzg, &blob, commitment, proof)
.map_err(|e| Error::InternalError(format!("Failed to validate blob: {:?}", e)))
});
compare_result::<bool, _>(&result, &self.output)
}
}

View File

@@ -0,0 +1,63 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::validate_blobs;
use serde::Deserialize;
use std::marker::PhantomData;
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGVerifyBlobKZGProofBatchInput {
pub blobs: Vec<String>,
pub commitments: Vec<String>,
pub proofs: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGVerifyBlobKZGProofBatch<E: EthSpec> {
pub input: KZGVerifyBlobKZGProofBatchInput,
pub output: Option<bool>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGVerifyBlobKZGProofBatch<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGVerifyBlobKZGProofBatch<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let parse_input = |input: &KZGVerifyBlobKZGProofBatchInput| -> Result<_, Error> {
let blobs = input
.blobs
.iter()
.map(|s| parse_blob::<E>(s))
.collect::<Result<Vec<_>, _>>()?;
let commitments = input
.commitments
.iter()
.map(|s| parse_commitment(s))
.collect::<Result<Vec<_>, _>>()?;
let proofs = input
.proofs
.iter()
.map(|s| parse_proof(s))
.collect::<Result<Vec<_>, _>>()?;
Ok((commitments, blobs, proofs))
};
let kzg = get_kzg()?;
let result = parse_input(&self.input).and_then(|(commitments, blobs, proofs)| {
validate_blobs::<E>(&kzg, &commitments, blobs.iter().collect(), &proofs)
.map_err(|e| Error::InternalError(format!("Failed to validate blobs: {:?}", e)))
});
compare_result::<bool, _>(&result, &self.output)
}
}

View File

@@ -0,0 +1,53 @@
use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::verify_kzg_proof;
use serde::Deserialize;
use std::marker::PhantomData;
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGVerifyKZGProofInput {
pub commitment: String,
pub z: String,
pub y: String,
pub proof: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGVerifyKZGProof<E: EthSpec> {
pub input: KZGVerifyKZGProofInput,
pub output: Option<bool>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGVerifyKZGProof<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGVerifyKZGProof<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Deneb
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let parse_input = |input: &KZGVerifyKZGProofInput| -> Result<_, Error> {
let commitment = parse_commitment(&input.commitment)?;
let z = parse_point(&input.z)?;
let y = parse_point(&input.y)?;
let proof = parse_proof(&input.proof)?;
Ok((commitment, z, y, proof))
};
let kzg = get_kzg()?;
let result = parse_input(&self.input).and_then(|(commitment, z, y, proof)| {
verify_kzg_proof::<E>(&kzg, commitment, proof, z, y)
.map_err(|e| Error::InternalError(format!("Failed to validate proof: {:?}", e)))
});
compare_result::<bool, _>(&result, &self.output)
}
}

View File

@@ -1,6 +1,6 @@
use super::*;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use std::path::Path;
use tree_hash::Hash256;
use types::{BeaconState, EthSpec, ForkName};
@@ -51,13 +51,10 @@ impl<E: EthSpec> Case for MerkleProofValidity<E> {
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let mut state = self.state.clone();
state.initialize_tree_hash_cache();
let proof = match state.compute_merkle_proof(self.merkle_proof.leaf_index) {
Ok(proof) => proof,
Err(_) => {
return Err(Error::FailedToParseTest(
"Could not retrieve merkle proof".to_string(),
))
}
let Ok(proof) = state.compute_merkle_proof(self.merkle_proof.leaf_index) else {
return Err(Error::FailedToParseTest(
"Could not retrieve merkle proof".to_string(),
));
};
let proof_len = proof.len();
let branch_len = self.merkle_proof.branch.len();

View File

@@ -3,14 +3,15 @@ use crate::bls_setting::BlsSetting;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use crate::testing_spec;
use serde_derive::Deserialize;
use serde::Deserialize;
use ssz::Decode;
use state_processing::common::update_progressive_balances_cache::initialize_progressive_balances_cache;
use state_processing::{
per_block_processing::{
errors::BlockProcessingError,
process_block_header, process_execution_payload,
process_operations::{
altair, base, process_attester_slashings, process_bls_to_execution_changes,
altair_deneb, base, process_attester_slashings, process_bls_to_execution_changes,
process_deposits, process_exits, process_proposer_slashings,
},
process_sync_aggregate, process_withdrawals, VerifyBlockRoot, VerifySignatures,
@@ -20,7 +21,8 @@ use state_processing::{
use std::fmt::Debug;
use std::path::Path;
use types::{
Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit,
Attestation, AttesterSlashing, BeaconBlock, BeaconBlockBody, BeaconBlockBodyCapella,
BeaconBlockBodyDeneb, BeaconBlockBodyMerge, BeaconState, BlindedPayload, ChainSpec, Deposit,
EthSpec, ExecutionPayload, ForkName, FullPayload, ProposerSlashing, SignedBlsToExecutionChange,
SignedVoluntaryExit, SyncAggregate,
};
@@ -96,9 +98,19 @@ impl<E: EthSpec> Operation<E> for Attestation<E> {
&mut ctxt,
spec,
),
BeaconState::Altair(_) | BeaconState::Merge(_) | BeaconState::Capella(_) => {
BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_)
| BeaconState::Deneb(_) => {
initialize_progressive_balances_cache(state, None, spec)?;
altair::process_attestation(state, self, 0, &mut ctxt, VerifySignatures::True, spec)
altair_deneb::process_attestation(
state,
self,
0,
&mut ctxt,
VerifySignatures::True,
spec,
)
}
}
}
@@ -260,13 +272,13 @@ impl<E: EthSpec> Operation<E> for SyncAggregate<E> {
}
}
impl<E: EthSpec> Operation<E> for FullPayload<E> {
impl<E: EthSpec> Operation<E> for BeaconBlockBody<E, FullPayload<E>> {
fn handler_name() -> String {
"execution_payload".into()
}
fn filename() -> String {
"execution_payload.ssz_snappy".into()
"body.ssz_snappy".into()
}
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
@@ -275,9 +287,13 @@ impl<E: EthSpec> Operation<E> for FullPayload<E> {
fn decode(path: &Path, fork_name: ForkName, _spec: &ChainSpec) -> Result<Self, Error> {
ssz_decode_file_with(path, |bytes| {
ExecutionPayload::from_ssz_bytes(bytes, fork_name)
Ok(match fork_name {
ForkName::Merge => BeaconBlockBody::Merge(<_>::from_ssz_bytes(bytes)?),
ForkName::Capella => BeaconBlockBody::Capella(<_>::from_ssz_bytes(bytes)?),
ForkName::Deneb => BeaconBlockBody::Deneb(<_>::from_ssz_bytes(bytes)?),
_ => panic!(),
})
})
.map(Into::into)
}
fn apply_to(
@@ -297,13 +313,13 @@ impl<E: EthSpec> Operation<E> for FullPayload<E> {
}
}
}
impl<E: EthSpec> Operation<E> for BlindedPayload<E> {
impl<E: EthSpec> Operation<E> for BeaconBlockBody<E, BlindedPayload<E>> {
fn handler_name() -> String {
"execution_payload".into()
}
fn filename() -> String {
"execution_payload.ssz_snappy".into()
"body.ssz_snappy".into()
}
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
@@ -312,9 +328,22 @@ impl<E: EthSpec> Operation<E> for BlindedPayload<E> {
fn decode(path: &Path, fork_name: ForkName, _spec: &ChainSpec) -> Result<Self, Error> {
ssz_decode_file_with(path, |bytes| {
ExecutionPayload::from_ssz_bytes(bytes, fork_name)
Ok(match fork_name {
ForkName::Merge => {
let inner = <BeaconBlockBodyMerge<E, FullPayload<E>>>::from_ssz_bytes(bytes)?;
BeaconBlockBody::Merge(inner.clone_as_blinded())
}
ForkName::Capella => {
let inner = <BeaconBlockBodyCapella<E, FullPayload<E>>>::from_ssz_bytes(bytes)?;
BeaconBlockBody::Capella(inner.clone_as_blinded())
}
ForkName::Deneb => {
let inner = <BeaconBlockBodyDeneb<E, FullPayload<E>>>::from_ssz_bytes(bytes)?;
BeaconBlockBody::Deneb(inner.clone_as_blinded())
}
_ => panic!(),
})
})
.map(Into::into)
}
fn apply_to(

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result_detailed;
use crate::decode::{ssz_decode_file, ssz_decode_state, yaml_decode_file};
use compare_fields_derive::CompareFields;
use serde_derive::Deserialize;
use serde::Deserialize;
use ssz::four_byte_option_impl;
use ssz_derive::{Decode, Encode};
use state_processing::{

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::bls_setting::BlsSetting;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::{
per_block_processing, per_slot_processing, BlockProcessingError, BlockSignatureStrategy,
ConsensusContext, StateProcessingStrategy, VerifyBlockRoot,

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::bls_setting::BlsSetting;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::per_slot_processing;
use types::{BeaconState, EthSpec, ForkName};

View File

@@ -1,7 +1,7 @@
use super::*;
use crate::case_result::compare_result;
use crate::decode::yaml_decode_file;
use serde_derive::Deserialize;
use serde::Deserialize;
use std::marker::PhantomData;
use swap_or_not_shuffle::{compute_shuffled_index, shuffle_list};
use types::ForkName;

View File

@@ -4,8 +4,8 @@ use super::*;
use crate::cases::common::{SszStaticType, TestU128, TestU256};
use crate::cases::ssz_static::{check_serialization, check_tree_hash};
use crate::decode::{snappy_decode_file, yaml_decode_file};
use serde::Deserialize;
use serde::{de::Error as SerdeError, Deserializer};
use serde_derive::Deserialize;
use ssz_derive::{Decode, Encode};
use std::path::{Path, PathBuf};
use tree_hash_derive::TreeHash;

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use crate::cases::common::SszStaticType;
use crate::decode::{snappy_decode_file, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use ssz::Decode;
use tree_hash::TreeHash;
use types::{BeaconBlock, BeaconState, ForkName, Hash256, SignedBeaconBlock};

View File

@@ -1,7 +1,7 @@
use super::*;
use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use serde::Deserialize;
use state_processing::{
per_block_processing, state_advance::complete_state_advance, BlockSignatureStrategy,
ConsensusContext, StateProcessingStrategy, VerifyBlockRoot,
@@ -47,6 +47,12 @@ impl<E: EthSpec> LoadCase for TransitionTest<E> {
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
spec.capella_fork_epoch = Some(metadata.fork_epoch);
}
ForkName::Deneb => {
spec.altair_fork_epoch = Some(Epoch::new(0));
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
spec.capella_fork_epoch = Some(Epoch::new(0));
spec.deneb_fork_epoch = Some(metadata.fork_epoch);
}
}
// Load blocks

View File

@@ -210,10 +210,6 @@ impl<T, E> SszStaticHandler<T, E> {
Self::for_forks(vec![ForkName::Altair])
}
pub fn altair_and_later() -> Self {
Self::for_forks(ForkName::list_all()[1..].to_vec())
}
pub fn merge_only() -> Self {
Self::for_forks(vec![ForkName::Merge])
}
@@ -222,9 +218,21 @@ impl<T, E> SszStaticHandler<T, E> {
Self::for_forks(vec![ForkName::Capella])
}
pub fn deneb_only() -> Self {
Self::for_forks(vec![ForkName::Deneb])
}
pub fn altair_and_later() -> Self {
Self::for_forks(ForkName::list_all()[1..].to_vec())
}
pub fn merge_and_later() -> Self {
Self::for_forks(ForkName::list_all()[2..].to_vec())
}
pub fn capella_and_later() -> Self {
Self::for_forks(ForkName::list_all()[3..].to_vec())
}
}
/// Handler for SSZ types that implement `CachedTreeHash`.
@@ -629,6 +637,126 @@ impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGBlobToKZGCommitmentHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGBlobToKZGCommitmentHandler<E> {
type Case = cases::KZGBlobToKZGCommitment<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"blob_to_kzg_commitment".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGComputeBlobKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeBlobKZGProofHandler<E> {
type Case = cases::KZGComputeBlobKZGProof<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"compute_blob_kzg_proof".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGComputeKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeKZGProofHandler<E> {
type Case = cases::KZGComputeKZGProof<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"compute_kzg_proof".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGVerifyBlobKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofHandler<E> {
type Case = cases::KZGVerifyBlobKZGProof<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"verify_blob_kzg_proof".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGVerifyBlobKZGProofBatchHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofBatchHandler<E> {
type Case = cases::KZGVerifyBlobKZGProofBatch<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"verify_blob_kzg_proof_batch".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct KZGVerifyKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyKZGProofHandler<E> {
type Case = cases::KZGVerifyKZGProof<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"verify_kzg_proof".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct MerkleProofValidityHandler<E>(PhantomData<E>);
@@ -654,7 +782,7 @@ impl<E: EthSpec + TypeName> Handler for MerkleProofValidityHandler<E> {
// spec.
//
// https://github.com/sigp/lighthouse/issues/4022
&& fork_name != ForkName::Capella
&& fork_name != ForkName::Capella && fork_name != ForkName::Deneb
}
}

View File

@@ -1,4 +1,5 @@
//! Mapping from types to canonical string identifiers used in testing.
use types::blob_sidecar::BlobIdentifier;
use types::historical_summary::HistoricalSummary;
use types::*;
@@ -47,8 +48,11 @@ type_name_generic!(BeaconBlockBodyBase, "BeaconBlockBody");
type_name_generic!(BeaconBlockBodyAltair, "BeaconBlockBody");
type_name_generic!(BeaconBlockBodyMerge, "BeaconBlockBody");
type_name_generic!(BeaconBlockBodyCapella, "BeaconBlockBody");
type_name_generic!(BeaconBlockBodyDeneb, "BeaconBlockBody");
type_name!(BeaconBlockHeader);
type_name_generic!(BeaconState);
type_name!(BlobIdentifier);
type_name_generic!(BlobSidecar);
type_name!(Checkpoint);
type_name_generic!(ContributionAndProof);
type_name!(Deposit);
@@ -58,10 +62,12 @@ type_name!(Eth1Data);
type_name_generic!(ExecutionPayload);
type_name_generic!(ExecutionPayloadMerge, "ExecutionPayload");
type_name_generic!(ExecutionPayloadCapella, "ExecutionPayload");
type_name_generic!(ExecutionPayloadDeneb, "ExecutionPayload");
type_name_generic!(FullPayload, "ExecutionPayload");
type_name_generic!(ExecutionPayloadHeader);
type_name_generic!(ExecutionPayloadHeaderMerge, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderCapella, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderDeneb, "ExecutionPayloadHeader");
type_name_generic!(BlindedPayload, "ExecutionPayloadHeader");
type_name!(Fork);
type_name!(ForkData);
@@ -72,6 +78,7 @@ type_name!(ProposerSlashing);
type_name_generic!(SignedAggregateAndProof);
type_name_generic!(SignedBeaconBlock);
type_name!(SignedBeaconBlockHeader);
type_name_generic!(SignedBlobSidecar);
type_name_generic!(SignedContributionAndProof);
type_name!(SignedVoluntaryExit);
type_name!(SigningData);

View File

@@ -72,14 +72,14 @@ fn operations_sync_aggregate() {
#[test]
fn operations_execution_payload_full() {
OperationsHandler::<MinimalEthSpec, FullPayload<_>>::default().run();
OperationsHandler::<MainnetEthSpec, FullPayload<_>>::default().run();
OperationsHandler::<MinimalEthSpec, BeaconBlockBody<_, FullPayload<_>>>::default().run();
OperationsHandler::<MainnetEthSpec, BeaconBlockBody<_, FullPayload<_>>>::default().run();
}
#[test]
fn operations_execution_payload_blinded() {
OperationsHandler::<MinimalEthSpec, BlindedPayload<_>>::default().run();
OperationsHandler::<MainnetEthSpec, BlindedPayload<_>>::default().run();
OperationsHandler::<MinimalEthSpec, BeaconBlockBody<_, BlindedPayload<_>>>::default().run();
OperationsHandler::<MainnetEthSpec, BeaconBlockBody<_, BlindedPayload<_>>>::default().run();
}
#[test]
@@ -215,6 +215,7 @@ macro_rules! ssz_static_test_no_run {
#[cfg(feature = "fake_crypto")]
mod ssz_static {
use ef_tests::{Handler, SszStaticHandler, SszStaticTHCHandler, SszStaticWithSpecHandler};
use types::blob_sidecar::BlobIdentifier;
use types::historical_summary::HistoricalSummary;
use types::*;
@@ -267,6 +268,10 @@ mod ssz_static {
.run();
SszStaticHandler::<BeaconBlockBodyCapella<MainnetEthSpec>, MainnetEthSpec>::capella_only()
.run();
SszStaticHandler::<BeaconBlockBodyDeneb<MinimalEthSpec>, MinimalEthSpec>::deneb_only()
.run();
SszStaticHandler::<BeaconBlockBodyDeneb<MainnetEthSpec>, MainnetEthSpec>::deneb_only()
.run();
}
// Altair and later
@@ -327,6 +332,10 @@ mod ssz_static {
.run();
SszStaticHandler::<ExecutionPayloadCapella<MainnetEthSpec>, MainnetEthSpec>::capella_only()
.run();
SszStaticHandler::<ExecutionPayloadDeneb<MinimalEthSpec>, MinimalEthSpec>::deneb_only()
.run();
SszStaticHandler::<ExecutionPayloadDeneb<MainnetEthSpec>, MainnetEthSpec>::deneb_only()
.run();
}
#[test]
@@ -339,30 +348,52 @@ mod ssz_static {
::capella_only().run();
SszStaticHandler::<ExecutionPayloadHeaderCapella<MainnetEthSpec>, MainnetEthSpec>
::capella_only().run();
SszStaticHandler::<ExecutionPayloadHeaderDeneb<MinimalEthSpec>, MinimalEthSpec>
::deneb_only().run();
SszStaticHandler::<ExecutionPayloadHeaderDeneb<MainnetEthSpec>, MainnetEthSpec>
::deneb_only().run();
}
#[test]
fn withdrawal() {
SszStaticHandler::<Withdrawal, MinimalEthSpec>::capella_only().run();
SszStaticHandler::<Withdrawal, MainnetEthSpec>::capella_only().run();
SszStaticHandler::<Withdrawal, MinimalEthSpec>::capella_and_later().run();
SszStaticHandler::<Withdrawal, MainnetEthSpec>::capella_and_later().run();
}
#[test]
fn bls_to_execution_change() {
SszStaticHandler::<BlsToExecutionChange, MinimalEthSpec>::capella_only().run();
SszStaticHandler::<BlsToExecutionChange, MainnetEthSpec>::capella_only().run();
SszStaticHandler::<BlsToExecutionChange, MinimalEthSpec>::capella_and_later().run();
SszStaticHandler::<BlsToExecutionChange, MainnetEthSpec>::capella_and_later().run();
}
#[test]
fn signed_bls_to_execution_change() {
SszStaticHandler::<SignedBlsToExecutionChange, MinimalEthSpec>::capella_only().run();
SszStaticHandler::<SignedBlsToExecutionChange, MainnetEthSpec>::capella_only().run();
SszStaticHandler::<SignedBlsToExecutionChange, MinimalEthSpec>::capella_and_later().run();
SszStaticHandler::<SignedBlsToExecutionChange, MainnetEthSpec>::capella_and_later().run();
}
#[test]
fn blob_sidecar() {
SszStaticHandler::<BlobSidecar<MinimalEthSpec>, MinimalEthSpec>::deneb_only().run();
SszStaticHandler::<BlobSidecar<MainnetEthSpec>, MainnetEthSpec>::deneb_only().run();
}
#[test]
fn signed_blob_sidecar() {
SszStaticHandler::<SignedBlobSidecar<MinimalEthSpec>, MinimalEthSpec>::deneb_only().run();
SszStaticHandler::<SignedBlobSidecar<MainnetEthSpec>, MainnetEthSpec>::deneb_only().run();
}
#[test]
fn blob_identifier() {
SszStaticHandler::<BlobIdentifier, MinimalEthSpec>::deneb_only().run();
SszStaticHandler::<BlobIdentifier, MainnetEthSpec>::deneb_only().run();
}
#[test]
fn historical_summary() {
SszStaticHandler::<HistoricalSummary, MinimalEthSpec>::capella_only().run();
SszStaticHandler::<HistoricalSummary, MainnetEthSpec>::capella_only().run();
SszStaticHandler::<HistoricalSummary, MinimalEthSpec>::capella_and_later().run();
SszStaticHandler::<HistoricalSummary, MainnetEthSpec>::capella_and_later().run();
}
}
@@ -532,6 +563,36 @@ fn genesis_validity() {
// Note: there are no genesis validity tests for mainnet
}
#[test]
fn kzg_blob_to_kzg_commitment() {
KZGBlobToKZGCommitmentHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn kzg_compute_blob_kzg_proof() {
KZGComputeBlobKZGProofHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn kzg_compute_kzg_proof() {
KZGComputeKZGProofHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn kzg_verify_blob_kzg_proof() {
KZGVerifyBlobKZGProofHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn kzg_verify_blob_kzg_proof_batch() {
KZGVerifyBlobKZGProofBatchHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn kzg_verify_kzg_proof() {
KZGVerifyKZGProofHandler::<MainnetEthSpec>::default().run();
}
#[test]
fn merkle_proof_validity() {
MerkleProofValidityHandler::<MainnetEthSpec>::default().run();

View File

@@ -2,15 +2,15 @@
name = "eth1_test_rig"
version = "0.2.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"
edition = { workspace = true }
[dependencies]
tokio = { version = "1.14.0", features = ["time"] }
ethers-core = "1.0.2"
ethers-providers = "1.0.2"
tokio = { workspace = true }
ethers-core = { workspace = true }
ethers-providers = { workspace = true }
ethers-contract = "1.0.2"
types = { path = "../../consensus/types"}
serde_json = "1.0.58"
deposit_contract = { path = "../../common/deposit_contract"}
unused_port = { path = "../../common/unused_port" }
hex = "0.4.2"
types = { workspace = true }
serde_json = { workspace = true }
deposit_contract = { workspace = true }
unused_port = { workspace = true }
hex = { workspace = true }

View File

@@ -1,24 +1,27 @@
[package]
name = "execution_engine_integration"
version = "0.1.0"
edition = "2021"
edition = { workspace = true }
[dependencies]
tempfile = "3.1.0"
serde_json = "1.0.58"
task_executor = { path = "../../common/task_executor" }
tokio = { version = "1.14.0", features = ["rt-multi-thread", "macros"] }
futures = "0.3.7"
exit-future = "0.2.0"
environment = { path = "../../lighthouse/environment" }
execution_layer = { path = "../../beacon_node/execution_layer" }
sensitive_url = { path = "../../common/sensitive_url" }
types = { path = "../../consensus/types" }
unused_port = { path = "../../common/unused_port" }
ethers-core = "1.0.2"
ethers-providers = "1.0.2"
deposit_contract = { path = "../../common/deposit_contract" }
reqwest = { version = "0.11.0", features = ["json"] }
hex = "0.4.2"
fork_choice = { path = "../../consensus/fork_choice" }
logging = { path = "../../common/logging" }
tempfile = { workspace = true }
serde_json = { workspace = true }
task_executor = { workspace = true }
tokio = { workspace = true }
futures = { workspace = true }
exit-future = { workspace = true }
environment = { workspace = true }
execution_layer = { workspace = true }
sensitive_url = { workspace = true }
types = { workspace = true }
unused_port = { workspace = true }
ethers-core = { workspace = true }
ethers-providers = { workspace = true }
deposit_contract = { workspace = true }
reqwest = { workspace = true }
hex = { workspace = true }
fork_choice = { workspace = true }
logging = { workspace = true }
[features]
portable = ["types/portable"]

View File

@@ -1,5 +1,5 @@
test:
cargo run --release --locked
cargo run --release --locked --features "$(TEST_FEATURES)"
clean:
rm -rf execution_clients

View File

@@ -66,6 +66,7 @@ pub fn get_latest_release(repo_dir: &Path, branch_name: &str) -> Result<String,
Command::new("git")
.arg("fetch")
.arg("--tags")
.arg("--force")
.current_dir(repo_dir)
.output()
.map_err(|e| format!("Failed to fetch tags for {repo_dir:?}: Err: {e}"))?,

View File

@@ -18,11 +18,10 @@ pub fn geth_genesis_json() -> Value {
"muirGlacierBlock":0,
"berlinBlock":0,
"londonBlock":0,
"clique": {
"period": 5,
"epoch": 30000
},
"terminalTotalDifficulty":0
"mergeNetsplitBlock": 0,
"shanghaiTime": 0,
"terminalTotalDifficulty": 0,
"terminalTotalDifficultyPassed": true
},
"nonce":"0x42",
"timestamp":"0x0",
@@ -72,8 +71,10 @@ pub fn nethermind_genesis_json() -> Value {
"accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x1469ca",
"MergeForkIdTransition": "0x3e8",
"networkID": "0x00146A2E",
"MergeForkIdTransition": "0x0",
"maxCodeSize": "0x6000",
"maxCodeSizeTransition": "0x0",
"eip150Transition": "0x0",
"eip158Transition": "0x0",
"eip160Transition": "0x0",
@@ -101,7 +102,15 @@ pub fn nethermind_genesis_json() -> Value {
"eip1559Transition": "0x0",
"eip3198Transition": "0x0",
"eip3529Transition": "0x0",
"eip3541Transition": "0x0"
"eip3541Transition": "0x0",
"eip3540TransitionTimestamp": "0x0",
"eip3651TransitionTimestamp": "0x0",
"eip3670TransitionTimestamp": "0x0",
"eip3675TransitionTimestamp": "0x0",
"eip3855TransitionTimestamp": "0x0",
"eip3860TransitionTimestamp": "0x0",
"eip4895TransitionTimestamp": "0x0",
"terminalTotalDifficulty": "0x0"
},
"genesis": {
"seal": {
@@ -112,10 +121,10 @@ pub fn nethermind_genesis_json() -> Value {
},
"difficulty": "0x01",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x0",
"timestamp": "0x63585F88",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "",
"gasLimit": "0x1C9C380"
"gasLimit": "0x400000"
},
"accounts": {
"0x7b8C3a386C0eea54693fFB0DA17373ffC9228139": {
@@ -123,9 +132,9 @@ pub fn nethermind_genesis_json() -> Value {
},
"0xdA2DD7560DB7e212B945fC72cEB54B7D8C886D77": {
"balance": "10000000000000000000000000"
},
}
},
"nodes": []
}
}
)
}

View File

@@ -3,7 +3,7 @@ use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::geth_genesis_json;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use std::{env, fs::File};
use std::{env, fs};
use tempfile::TempDir;
use unused_port::unused_tcp4_port;
@@ -36,6 +36,13 @@ pub fn build(execution_clients_dir: &Path) {
});
}
pub fn clean(execution_clients_dir: &Path) {
let repo_dir = execution_clients_dir.join("go-ethereum");
if let Err(e) = fs::remove_dir_all(repo_dir) {
eprintln!("Error while deleting folder: {}", e);
}
}
/*
* Geth-specific Implementation for GenericExecutionEngine
*/
@@ -60,7 +67,7 @@ impl GenericExecutionEngine for GethEngine {
let datadir = TempDir::new().unwrap();
let genesis_json_path = datadir.path().join("genesis.json");
let mut file = File::create(&genesis_json_path).unwrap();
let mut file = fs::File::create(&genesis_json_path).unwrap();
let json = geth_genesis_json();
serde_json::to_writer(&mut file, &json).unwrap();

View File

@@ -1,3 +1,5 @@
#![recursion_limit = "256"] // for inline json
/// This binary runs integration tests between Lighthouse and execution engines.
///
/// It will first attempt to build any supported integration clients, then it will run tests.
@@ -31,6 +33,7 @@ fn test_geth() {
let test_dir = build_utils::prepare_dir();
geth::build(&test_dir);
TestRig::new(GethEngine).perform_tests_blocking();
geth::clean(&test_dir);
}
fn test_nethermind() {

View File

@@ -2,7 +2,7 @@ use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::nethermind_genesis_json;
use std::env;
use std::fs::File;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use tempfile::TempDir;
@@ -11,7 +11,7 @@ use unused_port::unused_tcp4_port;
/// We've pinned the Nethermind version since our method of using the `master` branch to
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
/// We should fix this so we always pull the latest version of Nethermind.
const NETHERMIND_BRANCH: &str = "release/1.18.2";
const NETHERMIND_BRANCH: &str = "release/1.21.0";
const NETHERMIND_REPO_URL: &str = "https://github.com/NethermindEth/nethermind";
fn build_result(repo_dir: &Path) -> Output {
@@ -47,6 +47,12 @@ pub fn build(execution_clients_dir: &Path) {
build_utils::check_command_output(build_result(&repo_dir), || {
format!("nethermind build failed using release {last_release}")
});
// Cleanup some disk space by removing nethermind's tests
let tests_dir = execution_clients_dir.join("nethermind/src/tests");
if let Err(e) = fs::remove_dir_all(tests_dir) {
eprintln!("Error while deleting folder: {}", e);
}
}
/*
@@ -68,7 +74,8 @@ impl NethermindEngine {
.join("bin")
.join("Release")
.join("net7.0")
.join("Nethermind.Runner")
.join("linux-x64")
.join("nethermind")
}
}
@@ -76,7 +83,7 @@ impl GenericExecutionEngine for NethermindEngine {
fn init_datadir() -> TempDir {
let datadir = TempDir::new().unwrap();
let genesis_json_path = datadir.path().join("genesis.json");
let mut file = File::create(genesis_json_path).unwrap();
let mut file = fs::File::create(genesis_json_path).unwrap();
let json = nethermind_genesis_json();
serde_json::to_writer(&mut file, &json).unwrap();
datadir

View File

@@ -18,7 +18,9 @@ use types::{
Address, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
ForkName, FullPayload, Hash256, MainnetEthSpec, PublicKeyBytes, Slot, Uint256,
};
const EXECUTION_ENGINE_START_TIMEOUT: Duration = Duration::from_secs(30);
const EXECUTION_ENGINE_START_TIMEOUT: Duration = Duration::from_secs(60);
const TEST_FORK: ForkName = ForkName::Capella;
struct ExecutionPair<E, T: EthSpec> {
/// The Lighthouse `ExecutionLayer` struct, connected to the `execution_engine` via HTTP.
@@ -110,7 +112,7 @@ impl<E: GenericExecutionEngine> TestRig<E> {
let (runtime_shutdown, exit) = exit_future::signal();
let (shutdown_tx, _) = futures::channel::mpsc::channel(1);
let executor = TaskExecutor::new(Arc::downgrade(&runtime), exit, log.clone(), shutdown_tx);
let mut spec = MainnetEthSpec::default_spec();
let mut spec = TEST_FORK.make_genesis_spec(MainnetEthSpec::default_spec());
spec.terminal_total_difficulty = Uint256::zero();
let fee_recipient = None;
@@ -269,8 +271,13 @@ impl<E: GenericExecutionEngine> TestRig<E> {
Slot::new(1), // Insert proposer for the next slot
head_root,
proposer_index,
// TODO: think about how to test different forks
PayloadAttributes::new(timestamp, prev_randao, Address::repeat_byte(42), None),
PayloadAttributes::new(
timestamp,
prev_randao,
Address::repeat_byte(42),
Some(vec![]),
None,
),
)
.await;
@@ -308,8 +315,13 @@ impl<E: GenericExecutionEngine> TestRig<E> {
.execution_layer
.get_suggested_fee_recipient(proposer_index)
.await;
let payload_attributes =
PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None);
let payload_attributes = PayloadAttributes::new(
timestamp,
prev_randao,
suggested_fee_recipient,
Some(vec![]),
None,
);
let valid_payload = self
.ee_a
.execution_layer
@@ -318,8 +330,7 @@ impl<E: GenericExecutionEngine> TestRig<E> {
&payload_attributes,
forkchoice_update_params,
builder_params,
// FIXME: think about how to test other forks
ForkName::Merge,
TEST_FORK,
&self.spec,
)
.await
@@ -358,10 +369,11 @@ impl<E: GenericExecutionEngine> TestRig<E> {
* Provide the valid payload back to the EE again.
*/
// TODO: again consider forks here
let status = self
.ee_a
.execution_layer
.notify_new_payload(&valid_payload)
.notify_new_payload(valid_payload.clone().try_into().unwrap())
.await
.unwrap();
assert_eq!(status, PayloadStatus::Valid);
@@ -409,12 +421,13 @@ impl<E: GenericExecutionEngine> TestRig<E> {
* Provide an invalidated payload to the EE.
*/
// TODO: again think about forks here
let mut invalid_payload = valid_payload.clone();
*invalid_payload.prev_randao_mut() = Hash256::from_low_u64_be(42);
let status = self
.ee_a
.execution_layer
.notify_new_payload(&invalid_payload)
.notify_new_payload(invalid_payload.try_into().unwrap())
.await
.unwrap();
assert!(matches!(
@@ -448,8 +461,13 @@ impl<E: GenericExecutionEngine> TestRig<E> {
.execution_layer
.get_suggested_fee_recipient(proposer_index)
.await;
let payload_attributes =
PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None);
let payload_attributes = PayloadAttributes::new(
timestamp,
prev_randao,
suggested_fee_recipient,
Some(vec![]),
None,
);
let second_payload = self
.ee_a
.execution_layer
@@ -458,8 +476,7 @@ impl<E: GenericExecutionEngine> TestRig<E> {
&payload_attributes,
forkchoice_update_params,
builder_params,
// FIXME: think about how to test other forks
ForkName::Merge,
TEST_FORK,
&self.spec,
)
.await
@@ -473,10 +490,11 @@ impl<E: GenericExecutionEngine> TestRig<E> {
* Provide the second payload back to the EE again.
*/
// TODO: again consider forks here
let status = self
.ee_a
.execution_layer
.notify_new_payload(&second_payload)
.notify_new_payload(second_payload.clone().try_into().unwrap())
.await
.unwrap();
assert_eq!(status, PayloadStatus::Valid);
@@ -489,11 +507,15 @@ impl<E: GenericExecutionEngine> TestRig<E> {
*/
let head_block_hash = valid_payload.block_hash();
let finalized_block_hash = ExecutionBlockHash::zero();
// TODO: think about how to handle different forks
// To save sending proposer preparation data, just set the fee recipient
// to the fee recipient configured for EE A.
let payload_attributes =
PayloadAttributes::new(timestamp, prev_randao, Address::repeat_byte(42), None);
let payload_attributes = PayloadAttributes::new(
timestamp,
prev_randao,
Address::repeat_byte(42),
Some(vec![]),
None,
);
let slot = Slot::new(42);
let head_block_root = Hash256::repeat_byte(100);
let validator_index = 0;
@@ -520,17 +542,14 @@ impl<E: GenericExecutionEngine> TestRig<E> {
*
* Provide the second payload, without providing the first.
*/
// TODO: again consider forks here
let status = self
.ee_b
.execution_layer
.notify_new_payload(&second_payload)
.notify_new_payload(second_payload.clone().try_into().unwrap())
.await
.unwrap();
// TODO: we should remove the `Accepted` status here once Geth fixes it
assert!(matches!(
status,
PayloadStatus::Syncing | PayloadStatus::Accepted
));
assert!(matches!(status, PayloadStatus::Syncing));
/*
* Execution Engine B:
@@ -561,10 +580,11 @@ impl<E: GenericExecutionEngine> TestRig<E> {
* Provide the first payload to the EE.
*/
// TODO: again consider forks here
let status = self
.ee_b
.execution_layer
.notify_new_payload(&valid_payload)
.notify_new_payload(valid_payload.clone().try_into().unwrap())
.await
.unwrap();
assert_eq!(status, PayloadStatus::Valid);
@@ -578,7 +598,7 @@ impl<E: GenericExecutionEngine> TestRig<E> {
let status = self
.ee_b
.execution_layer
.notify_new_payload(&second_payload)
.notify_new_payload(second_payload.clone().try_into().unwrap())
.await
.unwrap();
assert_eq!(status, PayloadStatus::Valid);
@@ -630,11 +650,13 @@ async fn check_payload_reconstruction<E: GenericExecutionEngine>(
.get_engine_capabilities(None)
.await
.unwrap();
assert!(
// if the engine doesn't have these capabilities, we need to update the client in our tests
capabilities.get_payload_bodies_by_hash_v1 && capabilities.get_payload_bodies_by_range_v1,
"Testing engine does not support payload bodies methods"
);
let mut bodies = ee
.execution_layer
.get_payload_bodies_by_hash(vec![payload.block_hash()])

View File

@@ -2,16 +2,16 @@
name = "node_test_rig"
version = "0.2.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"
edition = { workspace = true }
[dependencies]
environment = { path = "../../lighthouse/environment" }
beacon_node = { path = "../../beacon_node" }
types = { path = "../../consensus/types" }
tempfile = "3.1.0"
eth2 = { path = "../../common/eth2" }
validator_client = { path = "../../validator_client" }
validator_dir = { path = "../../common/validator_dir", features = ["insecure_keys"] }
sensitive_url = { path = "../../common/sensitive_url" }
execution_layer = { path = "../../beacon_node/execution_layer" }
tokio = { version = "1.14.0", features = ["time"] }
environment = { workspace = true }
beacon_node = { workspace = true }
types = { workspace = true }
tempfile = { workspace = true }
eth2 = { workspace = true }
validator_client = { workspace = true }
validator_dir = { workspace = true }
sensitive_url = { workspace = true }
execution_layer = { workspace = true }
tokio = { workspace = true }

View File

@@ -98,7 +98,7 @@ pub fn testing_client_config() -> ClientConfig {
// Setting ports to `0` means that the OS will choose some available port.
client_config
.network
.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 0, 0);
.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 0, 0, 0);
client_config.network.upnp_enabled = false;
client_config.http_api.enabled = true;
client_config.http_api.listen_port = 0;
@@ -115,6 +115,9 @@ pub fn testing_client_config() -> ClientConfig {
genesis_time: now,
};
// Simulator tests expect historic states to be available for post-run checks.
client_config.chain.reconstruct_historic_states = true;
// Specify a constant count of beacon processor workers. Having this number
// too low can cause annoying HTTP timeouts, especially on Github runners
// with 2 logical CPUs.
@@ -217,14 +220,13 @@ impl<E: EthSpec> LocalValidatorClient<E> {
config.validator_dir = files.validator_dir.path().into();
config.secrets_dir = files.secrets_dir.path().into();
ProductionValidatorClient::new(context, config)
let mut client = ProductionValidatorClient::new(context, config).await?;
client
.start_service()
.await
.map(move |mut client| {
client
.start_service()
.expect("should start validator services");
Self { client, files }
})
.expect("should start validator services");
Ok(Self { client, files })
}
}
@@ -248,7 +250,7 @@ impl<E: EthSpec> LocalExecutionNode<E> {
panic!("Failed to write jwt file {}", e);
}
Self {
server: MockServer::new_with_config(&context.executor.handle().unwrap(), config),
server: MockServer::new_with_config(&context.executor.handle().unwrap(), config, None),
datadir,
}
}

View File

@@ -2,20 +2,20 @@
name = "simulator"
version = "0.2.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"
edition = { workspace = true }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
node_test_rig = { path = "../node_test_rig" }
eth1 = {path = "../../beacon_node/eth1"}
execution_layer = {path = "../../beacon_node/execution_layer"}
types = { path = "../../consensus/types" }
parking_lot = "0.12.0"
futures = "0.3.7"
tokio = "1.14.0"
eth1_test_rig = { path = "../eth1_test_rig" }
env_logger = "0.9.0"
clap = "2.33.3"
rayon = "1.4.1"
eth1 = { workspace = true }
execution_layer = { workspace = true }
types = { workspace = true }
parking_lot = { workspace = true }
futures = { workspace = true }
tokio = { workspace = true }
eth1_test_rig = { workspace = true }
env_logger = { workspace = true }
clap = { workspace = true }
rayon = { workspace = true }
sensitive_url = { path = "../../common/sensitive_url" }

View File

@@ -14,6 +14,7 @@ use std::{sync::Arc, time::Duration};
use types::{Epoch, EthSpec};
const BOOTNODE_PORT: u16 = 42424;
const QUIC_PORT: u16 = 43424;
pub const INVALID_ADDRESS: &str = "http://127.0.0.1:42423";
pub const EXECUTION_PORT: u16 = 4000;
@@ -63,9 +64,10 @@ impl<E: EthSpec> LocalNetwork<E> {
std::net::Ipv4Addr::UNSPECIFIED,
BOOTNODE_PORT,
BOOTNODE_PORT,
QUIC_PORT,
);
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT);
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT);
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT.try_into().expect("non zero"));
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT.try_into().expect("non zero"));
beacon_config.network.discv5_config.table_filter = |_| true;
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
@@ -150,13 +152,16 @@ impl<E: EthSpec> LocalNetwork<E> {
.expect("bootnode must have a network"),
);
let count = (self.beacon_node_count() + self.proposer_node_count()) as u16;
let libp2p_tcp_port = BOOTNODE_PORT + count;
let discv5_port = BOOTNODE_PORT + count;
beacon_config.network.set_ipv4_listening_address(
std::net::Ipv4Addr::UNSPECIFIED,
BOOTNODE_PORT + count,
BOOTNODE_PORT + count,
libp2p_tcp_port,
discv5_port,
QUIC_PORT + count,
);
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT + count);
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT + count);
beacon_config.network.enr_udp4_port = Some(discv5_port.try_into().unwrap());
beacon_config.network.enr_tcp4_port = Some(libp2p_tcp_port.try_into().unwrap());
beacon_config.network.discv5_config.table_filter = |_| true;
beacon_config.network.proposer_only = is_proposer;
}

View File

@@ -2,14 +2,17 @@
name = "state_transition_vectors"
version = "0.1.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2021"
edition = { workspace = true }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
state_processing = { path = "../../consensus/state_processing" }
types = { path = "../../consensus/types" }
ethereum_ssz = "0.5.0"
beacon_chain = { path = "../../beacon_node/beacon_chain" }
lazy_static = "1.4.0"
tokio = { version = "1.14.0", features = ["rt-multi-thread"] }
state_processing = { workspace = true }
types = { workspace = true }
ethereum_ssz = { workspace = true }
beacon_chain = { workspace = true }
lazy_static = { workspace = true }
tokio = { workspace = true }
[features]
portable = ["beacon_chain/portable"]

View File

@@ -2,7 +2,7 @@ produce-vectors:
cargo run --release
test:
cargo test --release
cargo test --release --features "$(TEST_FEATURES)"
clean:
rm -r vectors/

View File

@@ -57,7 +57,7 @@ impl ExitTest {
block_modifier(&harness, block);
})
.await;
(signed_block, state)
(signed_block.0, state)
}
fn process(

View File

@@ -1,10 +1,10 @@
[package]
name = "test-test_logger"
version = "0.1.0"
edition = "2021"
edition = { workspace = true }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
logging = { path = "../../common/logging" }
slog = "2.7.0"
logging = { workspace = true }
slog = { workspace = true }

View File

@@ -1,31 +1,30 @@
[package]
name = "web3signer_tests"
version = "0.1.0"
edition = "2021"
edition = { workspace = true }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dev-dependencies]
eth2_keystore = { path = "../../crypto/eth2_keystore" }
types = { path = "../../consensus/types" }
tempfile = "3.1.0"
tokio = { version = "1.14.0", features = ["rt-multi-thread", "macros"] }
reqwest = { version = "0.11.0", features = ["json","stream"] }
url = "2.2.2"
validator_client = { path = "../../validator_client" }
slot_clock = { path = "../../common/slot_clock" }
futures = "0.3.7"
exit-future = "0.2.0"
task_executor = { path = "../../common/task_executor" }
environment = { path = "../../lighthouse/environment" }
account_utils = { path = "../../common/account_utils" }
serde = "1.0.116"
serde_derive = "1.0.116"
serde_yaml = "0.8.13"
eth2_network_config = { path = "../../common/eth2_network_config" }
serde_json = "1.0.58"
zip = "0.5.13"
lazy_static = "1.4.0"
parking_lot = "0.12.0"
eth2_keystore = { workspace = true }
types = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }
reqwest = { workspace = true }
url = { workspace = true }
validator_client = { workspace = true }
slot_clock = { workspace = true }
futures = { workspace = true }
exit-future = { workspace = true }
task_executor = { workspace = true }
environment = { workspace = true }
account_utils = { workspace = true }
serde = { workspace = true }
serde_yaml = { workspace = true }
eth2_network_config = { workspace = true }
serde_json = { workspace = true }
zip = { workspace = true }
lazy_static = { workspace = true }
parking_lot = { workspace = true }

View File

@@ -51,7 +51,7 @@ mod tests {
/// If the we are unable to reach the Web3Signer HTTP API within this time out then we will
/// assume it failed to start.
const UPCHECK_TIMEOUT: Duration = Duration::from_secs(20);
const UPCHECK_TIMEOUT: Duration = Duration::from_secs(30);
/// Set to `false` to send the Web3Signer logs to the console during tests. Logs are useful when
/// debugging.

View File

@@ -1,6 +1,6 @@
## TLS Testing Files
The files in this directory are used for testing TLS with web3signer. We store them in this
repository since the are not sensitive and it's simpler than regenerating them for each test.
repository since they are not sensitive and it's simpler than regenerating them for each test.
The files were generated using the `./generate.sh` script.

View File

@@ -1,7 +1,7 @@
#!/bin/bash
openssl req -x509 -sha256 -nodes -days 36500 -newkey rsa:4096 -keyout web3signer/key.key -out web3signer/cert.pem -config web3signer/config &&
openssl pkcs12 -export -out web3signer/key.p12 -inkey web3signer/key.key -in web3signer/cert.pem -password pass:$(cat web3signer/password.txt) &&
openssl pkcs12 -export -aes256 -out web3signer/key.p12 -inkey web3signer/key.key -in web3signer/cert.pem -password pass:$(cat web3signer/password.txt) &&
cp web3signer/cert.pem lighthouse/web3signer.pem &&
openssl req -x509 -sha256 -nodes -days 36500 -newkey rsa:4096 -keyout lighthouse/key.key -out lighthouse/cert.pem -config lighthouse/config &&
openssl pkcs12 -export -out lighthouse/key.p12 -inkey lighthouse/key.key -in lighthouse/cert.pem -password pass:$(cat lighthouse/password.txt) &&
openssl pkcs12 -export -aes256 -out lighthouse/key.p12 -inkey lighthouse/key.key -in lighthouse/cert.pem -password pass:$(cat lighthouse/password.txt) &&
openssl x509 -noout -fingerprint -sha256 -inform pem -in lighthouse/cert.pem | cut -b 20-| sed "s/^/lighthouse /" > web3signer/known_clients.txt

View File

@@ -1,32 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFmzCCA4OgAwIBAgIUXpTV/0rd/GAoCfCyzPOtwcb4t7YwDQYJKoZIhvcNAQEL
MIIFujCCA6KgAwIBAgIUXZijYo8W4/9dAq58ocFEbZDxohwwDQYJKoZIhvcNAQEL
BQAwazELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMREwDwYDVQQHDAhTb21lQ2l0
eTESMBAGA1UECgwJTXlDb21wYW55MRMwEQYDVQQLDApNeURpdmlzaW9uMRMwEQYD
VQQDDApsaWdodGhvdXNlMCAXDTIyMDUxMTEzNDEwOFoYDzIxMjIwNDE3MTM0MTA4
VQQDDApsaWdodGhvdXNlMCAXDTIzMDkyMDAyNTYzNloYDzIxMjMwODI3MDI1NjM2
WjBrMQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExETAPBgNVBAcMCFNvbWVDaXR5
MRIwEAYDVQQKDAlNeUNvbXBhbnkxEzARBgNVBAsMCk15RGl2aXNpb24xEzARBgNV
BAMMCmxpZ2h0aG91c2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0
HrD6fJGcqm8zwEs+Y+FGIpRYPyjdlugj3qqwvMSI9jeDW2fr1zUl/wIuf4o+O16P
XZitHgAyg3lph1x/kKL59c4rwWxUabSudAQZ6YCJHo4jWf3hR+UmMQEdNPgNrofv
vGCA7CjLPKZfW6pzZo9kvMwbgeRNuJCuKZ0v/p9Y/lOplj+TTBq16HMtsSarib3b
nKEaRdLCQgTJS3vwbtEiCC9BcZAkvs0fmVUIENRVeKGZIqcAdiOTUPvs4zctchzJ
MGG+TA2ckKIpGT0F4be8gy1uHyP0fncJAtNvkGRPmVQcNew/HIIkJjiJvmrwewn4
dYqYAe+aEL5AB4dZhlKjIPENfq38t7iY/aXV8COTQZGMEZ7Diext1JmEb34vEXgS
7Gk9ZSCp/1X+fk/wW4uQeRlGwblaRtRxBrfJWmEoQHohzyP4jog8dajSZTjUbsA+
HGaeZo1k3M0i3lxRBbLGamPODIO9CVGwKaiEJTy4bEpreM2tLR1rk5JECf46WPUR
SN6OdHrO5x38wzQlUv+Hb4vN4p0ZkiGJO62Duuw6hbGA6UIBffM20QuJUtz3Pa8D
un/NunIagmIL5KCsrDtZkt5wBsX3XU6OPdfZrfgOIXNfQmpbbeAUOok1NOgszXjP
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
-----END CERTIFICATE-----

View File

@@ -1,52 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC0HrD6fJGcqm8z
wEs+Y+FGIpRYPyjdlugj3qqwvMSI9jeDW2fr1zUl/wIuf4o+O16PXZitHgAyg3lp
h1x/kKL59c4rwWxUabSudAQZ6YCJHo4jWf3hR+UmMQEdNPgNrofvvGCA7CjLPKZf
W6pzZo9kvMwbgeRNuJCuKZ0v/p9Y/lOplj+TTBq16HMtsSarib3bnKEaRdLCQgTJ
S3vwbtEiCC9BcZAkvs0fmVUIENRVeKGZIqcAdiOTUPvs4zctchzJMGG+TA2ckKIp
GT0F4be8gy1uHyP0fncJAtNvkGRPmVQcNew/HIIkJjiJvmrwewn4dYqYAe+aEL5A
B4dZhlKjIPENfq38t7iY/aXV8COTQZGMEZ7Diext1JmEb34vEXgS7Gk9ZSCp/1X+
fk/wW4uQeRlGwblaRtRxBrfJWmEoQHohzyP4jog8dajSZTjUbsA+HGaeZo1k3M0i
3lxRBbLGamPODIO9CVGwKaiEJTy4bEpreM2tLR1rk5JECf46WPURSN6OdHrO5x38
wzQlUv+Hb4vN4p0ZkiGJO62Duuw6hbGA6UIBffM20QuJUtz3Pa8Dun/NunIagmIL
5KCsrDtZkt5wBsX3XU6OPdfZrfgOIXNfQmpbbeAUOok1NOgszXjPDKCsnxZZBtPh
XC1VnRkiWK50GNmWe8MLqXR/G12TXwIDAQABAoICAQCXUo2W856Vwy5HiQ7t7JWv
CZAdj3pyp7yBnilC8GQhONGsntdw8M2rDVG05Nusqs4nnheNoX3C8mfHO7x/Q3FY
lKTQZ+DuDhyIz9k+N8kP6ca6dnlvkao3asYn1n9rZyy3QUjGJyGilWKlDGroJsrj
dCX6GidHEH8kgruXPdB7wLdi62KgCjkKiK5zPbhiNwd1gGJsoyqMn1BMGQmYFlHG
yJ+C2Lij1lSYboZcj18EK6N/9vfc0GPU+R2dh8qseIkskWQcruJknbJO2vBEh7yI
OKCrOqhHWRQCUwh1WxabNRLP3JGM+BNx8VZgisRnIsdeoMl+KWo1wklDm8+fa9Tx
4xquIy+4PzmobWXiWBpirF7bTNhyZ4vIaMSTOP5TYiliom/hJtcpAwLf9eXxMfti
vRAogZEtr0eKTieH72dwsBVx6wNlxhazvD+ZKIq7OIzJRA6Do2H+BAmz/l4mgVR/
geL3u0fn0j/Y+8OyFE3P+8D/PqgPzLgTYa5QSp6JtHxNlVcmWefJiLtZDAJvPpeo
UVsA+E2BHsrGveLk15GF9F+vJ867qKT7luQac3zF7V0hE9pktUKM2gY+Jy455w5i
cMxyjt4RAKY8AHAmFvCRQHNdjU2o1UjVFgYsQTYsOdvAiyq0xEJFkbeR2Zxz2sJW
JWK+YlT+UEGDL5SCaXzP4QKCAQEA7gRAy/Xq0Fjq7UZvc7oJ62h6BmseFL9BuKlW
QmvVFAilYeQVejl/ubafyL4Z9ntEeCGTkv8H4DeALs9A/isFOcDxZDoelCETrSxI
CfXllob24276eTc5dBdHmofBjRgIbovnyuFRYzK5uDalVAxYsZPFOp9/qtGa25ex
uIcyJwX+ivqqtA9B5CHu7p/znNrp155xLwGpVczx4xGqjPPr5N2rwZFOXufGFULH
AKbJBSUxiMMJnb1rN8aIuTo/Utr3/i7hc7AUO3//qieyjLdXe8tESqgxzTNvfZk3
qYtPk4GSHql7Eesxg19fzVdG+LTnzfRKOfOtcZJPRFGGW29fjwKCAQEAwbqXsZvC
7AmmmeVVAPL7q5pXAxSEMK7VsJzPJ7G6MRQ37YjkNRcCf7SRQqNBGQubVkv3Qzvc
rmMhT9I5QfCR2JXQtrH1y09eS45T6NYbRkT6NA3E3XNmRIPO+wIeDV32v5jJwhIk
7ayuG2zBsAryxNvg3us3pWHeIQ45sX0JqNil6BTemYRBrCZmCRWHndl72zDbtR23
kVt9GKaycSPyCZQ7yE4ZWD2VsrbgEidVJEQagknsjQrldMO68GLbHCP2ZyrIUhKN
2eeuHJpZPz+pahQ55MAEvjIsJKPWsg8cut2Vo4sqgez+xiz0v/nWiPLtvxdN+DHP
tAVbrw+0NeqnMQKCAQB3GsO+DLpLNiOhRpzhAViTZ32glpu/8BEYMgzLQiCnXMg9
myAwQHOs4DlG//IICJkzsEGjzmEHj15iji3MwoRj6SwiZn8EyySIhN8rtNQFplYH
a3KFk9/5OukG6CYvz7Xwc6wzNts+U5TiHN5Ql7kOa47HjicZuLfQaTFy0JyFMJe2
vkcLwZLMcTqaSIpklJtt3Yhv6FnvaJYmdaGt1SXXKiIXw/m+via+XuMsbUmsfHc0
I709JRtxFrU2U3J6qL5ugNEqzhLhz2SFpkXP6rMpbIcpAM+jCrkg1bon6mGQw8b1
9wNx7Qqi3egX3jPSotxYkIVQSKMjcP6fhlhAixP7AoIBAH1ynKQwHurF3RIuxPqW
XY3jpZCjCm6T6GAzSpmDpvP9CbJRQKV4Pu//N0kVeiQDthUNoBHzg5WRL5MGqHkg
lPDRIpQLbQS4YnE+uus9KfA43mQyvlZAUerwB2nXFyrEu/GZuJxpL2yQszWjGVEr
5cTANT9kxWXcmACDu6xJMaYalGRSj0qNsBEP1GbxgB4hJOjtHHiNw77mpXz/BPHq
uuKlEIlGuXbAel19ul9HBQU07I2N3RYABlG0JStgeE4io35u38T1qtF+CusOr9gb
G1NLwal1Bh07VAZt6arnykzfC/UZOu9jTh96IQrnd5q65GUnbB/Z8Yu7JIGaA7Ie
PyECggEAPZlzqPCdNcmdoCSNIDCDYZBVf2xZX8591xdphMG59Jrckp5kl5LM5bjQ
tysj1LJpMK+l60b3r8BI8a4lvj+eBqwBUck82/IImTedE9/oLF3Z64kLd1tr3aGa
W5jLXjThFF20BqfD+YbmFVEdHTwN2L+4kN0VvP/6oLadxogTLwQruMFoPlsD4B19
HDcAKe6OnyWMer/X9nq9OY6GFGc4X6wHjJ8pj4aa4HE8VNNq40GMkRZOZaJvaPqh
orK9SC50qdJtrVQeD4fhfZMVzmRyE4RSSQBPfc9zq/sO/pjUfV9uK4c99FDbviIf
JAkxGuYLZeyrHEyeKLm7S77SLipKWg==
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
vc3Za4ClKSLmb3ZA9giTswYMev+3BQ==
-----END PRIVATE KEY-----

View File

@@ -1,32 +1,33 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@@ -1,32 +1,33 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@@ -1,52 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
/OsV3MTX1gCaTE9Q2GlZVybDh20ZvdBC/g==
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
oJ/aHbXf6PdOO9MYiI/es/dfKK8ywA==
-----END PRIVATE KEY-----

View File

@@ -1 +1 @@
lighthouse 1B:43:E1:58:26:7D:3F:70:BD:DA:32:E9:29:A5:A9:50:EA:B2:A8:C3:0C:82:BF:90:13:ED:5B:E0:7D:5B:0A:C0
lighthouse 02:D0:A8:C0:6A:59:90:40:54:67:D4:BD:AE:5A:D4:F5:14:A9:79:38:98:E0:62:93:C1:77:13:FC:B4:60:65:CE