mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 10:11:44 +00:00
Merge latest master in v0.2.0
This commit is contained in:
@@ -139,101 +139,125 @@ impl<T: EthSpec> ProductionValidatorClient<T> {
|
||||
}
|
||||
})
|
||||
})
|
||||
.and_then(move |(beacon_node, remote_eth2_config, genesis_time)| {
|
||||
let log = log_4.clone();
|
||||
.and_then(|(beacon_node, eth2_config, genesis_time)| {
|
||||
beacon_node
|
||||
.http
|
||||
.beacon()
|
||||
.get_genesis_validators_root()
|
||||
.map(move |genesis_validators_root| {
|
||||
(
|
||||
beacon_node,
|
||||
eth2_config,
|
||||
genesis_time,
|
||||
genesis_validators_root,
|
||||
)
|
||||
})
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Unable to read genesis validators root from beacon node: {:?}",
|
||||
e
|
||||
)
|
||||
})
|
||||
})
|
||||
.and_then(
|
||||
move |(beacon_node, remote_eth2_config, genesis_time, genesis_validators_root)| {
|
||||
let log = log_4.clone();
|
||||
|
||||
// Do not permit a connection to a beacon node using different spec constants.
|
||||
if context.eth2_config.spec_constants != remote_eth2_config.spec_constants {
|
||||
return Err(format!(
|
||||
"Beacon node is using an incompatible spec. Got {}, expected {}",
|
||||
remote_eth2_config.spec_constants, context.eth2_config.spec_constants
|
||||
));
|
||||
}
|
||||
// Do not permit a connection to a beacon node using different spec constants.
|
||||
if context.eth2_config.spec_constants != remote_eth2_config.spec_constants {
|
||||
return Err(format!(
|
||||
"Beacon node is using an incompatible spec. Got {}, expected {}",
|
||||
remote_eth2_config.spec_constants, context.eth2_config.spec_constants
|
||||
));
|
||||
}
|
||||
|
||||
// Note: here we just assume the spec variables of the remote node. This is very useful
|
||||
// for testnets, but perhaps a security issue when it comes to mainnet.
|
||||
//
|
||||
// A damaging attack would be for a beacon node to convince the validator client of a
|
||||
// different `SLOTS_PER_EPOCH` variable. This could result in slashable messages being
|
||||
// produced. We are safe from this because `SLOTS_PER_EPOCH` is a type-level constant
|
||||
// for Lighthouse.
|
||||
context.eth2_config = remote_eth2_config;
|
||||
// Note: here we just assume the spec variables of the remote node. This is very useful
|
||||
// for testnets, but perhaps a security issue when it comes to mainnet.
|
||||
//
|
||||
// A damaging attack would be for a beacon node to convince the validator client of a
|
||||
// different `SLOTS_PER_EPOCH` variable. This could result in slashable messages being
|
||||
// produced. We are safe from this because `SLOTS_PER_EPOCH` is a type-level constant
|
||||
// for Lighthouse.
|
||||
context.eth2_config = remote_eth2_config;
|
||||
|
||||
let slot_clock = SystemTimeSlotClock::new(
|
||||
context.eth2_config.spec.genesis_slot,
|
||||
Duration::from_secs(genesis_time),
|
||||
Duration::from_millis(context.eth2_config.spec.milliseconds_per_slot),
|
||||
);
|
||||
let slot_clock = SystemTimeSlotClock::new(
|
||||
context.eth2_config.spec.genesis_slot,
|
||||
Duration::from_secs(genesis_time),
|
||||
Duration::from_millis(context.eth2_config.spec.milliseconds_per_slot),
|
||||
);
|
||||
|
||||
let fork_service = ForkServiceBuilder::new()
|
||||
.slot_clock(slot_clock.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("fork".into()))
|
||||
.build()?;
|
||||
let fork_service = ForkServiceBuilder::new()
|
||||
.slot_clock(slot_clock.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("fork".into()))
|
||||
.build()?;
|
||||
|
||||
let validator_store: ValidatorStore<SystemTimeSlotClock, T> =
|
||||
match &config.key_source {
|
||||
// Load pre-existing validators from the data dir.
|
||||
//
|
||||
// Use the `account_manager` to generate these files.
|
||||
KeySource::Disk => ValidatorStore::load_from_disk(
|
||||
config.data_dir.clone(),
|
||||
context.eth2_config.spec.clone(),
|
||||
fork_service.clone(),
|
||||
log.clone(),
|
||||
)?,
|
||||
// Generate ephemeral insecure keypairs for testing purposes.
|
||||
//
|
||||
// Do not use in production.
|
||||
KeySource::InsecureKeypairs(indices) => {
|
||||
ValidatorStore::insecure_ephemeral_validators(
|
||||
&indices,
|
||||
let validator_store: ValidatorStore<SystemTimeSlotClock, T> =
|
||||
match &config.key_source {
|
||||
// Load pre-existing validators from the data dir.
|
||||
//
|
||||
// Use the `account_manager` to generate these files.
|
||||
KeySource::Disk => ValidatorStore::load_from_disk(
|
||||
config.data_dir.clone(),
|
||||
genesis_validators_root,
|
||||
context.eth2_config.spec.clone(),
|
||||
fork_service.clone(),
|
||||
log.clone(),
|
||||
)?
|
||||
}
|
||||
};
|
||||
)?,
|
||||
// Generate ephemeral insecure keypairs for testing purposes.
|
||||
//
|
||||
// Do not use in production.
|
||||
KeySource::InsecureKeypairs(indices) => {
|
||||
ValidatorStore::insecure_ephemeral_validators(
|
||||
&indices,
|
||||
genesis_validators_root,
|
||||
context.eth2_config.spec.clone(),
|
||||
fork_service.clone(),
|
||||
log.clone(),
|
||||
)?
|
||||
}
|
||||
};
|
||||
|
||||
info!(
|
||||
log,
|
||||
"Loaded validator keypair store";
|
||||
"voting_validators" => validator_store.num_voting_validators()
|
||||
);
|
||||
info!(
|
||||
log,
|
||||
"Loaded validator keypair store";
|
||||
"voting_validators" => validator_store.num_voting_validators()
|
||||
);
|
||||
|
||||
let duties_service = DutiesServiceBuilder::new()
|
||||
.slot_clock(slot_clock.clone())
|
||||
.validator_store(validator_store.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("duties".into()))
|
||||
.allow_unsynced_beacon_node(config.allow_unsynced_beacon_node)
|
||||
.build()?;
|
||||
let duties_service = DutiesServiceBuilder::new()
|
||||
.slot_clock(slot_clock.clone())
|
||||
.validator_store(validator_store.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("duties".into()))
|
||||
.allow_unsynced_beacon_node(config.allow_unsynced_beacon_node)
|
||||
.build()?;
|
||||
|
||||
let block_service = BlockServiceBuilder::new()
|
||||
.duties_service(duties_service.clone())
|
||||
.slot_clock(slot_clock.clone())
|
||||
.validator_store(validator_store.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("block".into()))
|
||||
.build()?;
|
||||
let block_service = BlockServiceBuilder::new()
|
||||
.duties_service(duties_service.clone())
|
||||
.slot_clock(slot_clock.clone())
|
||||
.validator_store(validator_store.clone())
|
||||
.beacon_node(beacon_node.clone())
|
||||
.runtime_context(context.service_context("block".into()))
|
||||
.build()?;
|
||||
|
||||
let attestation_service = AttestationServiceBuilder::new()
|
||||
.duties_service(duties_service.clone())
|
||||
.slot_clock(slot_clock)
|
||||
.validator_store(validator_store)
|
||||
.beacon_node(beacon_node)
|
||||
.runtime_context(context.service_context("attestation".into()))
|
||||
.build()?;
|
||||
let attestation_service = AttestationServiceBuilder::new()
|
||||
.duties_service(duties_service.clone())
|
||||
.slot_clock(slot_clock)
|
||||
.validator_store(validator_store)
|
||||
.beacon_node(beacon_node)
|
||||
.runtime_context(context.service_context("attestation".into()))
|
||||
.build()?;
|
||||
|
||||
Ok(Self {
|
||||
context,
|
||||
duties_service,
|
||||
fork_service,
|
||||
block_service,
|
||||
attestation_service,
|
||||
exit_signals: vec![],
|
||||
})
|
||||
})
|
||||
Ok(Self {
|
||||
context,
|
||||
duties_service,
|
||||
fork_service,
|
||||
block_service,
|
||||
attestation_service,
|
||||
exit_signals: vec![],
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn start_service(&mut self) -> Result<(), String> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use bls::get_withdrawal_credentials;
|
||||
use deposit_contract::eth1_tx_data;
|
||||
use deposit_contract::encode_eth1_tx_data;
|
||||
use hex;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -275,7 +275,7 @@ impl ValidatorDirectoryBuilder {
|
||||
|
||||
deposit_data.signature = deposit_data.create_signature(&voting_keypair.sk, &spec);
|
||||
|
||||
eth1_tx_data(&deposit_data)
|
||||
encode_eth1_tx_data(&deposit_data)
|
||||
.map_err(|e| format!("Unable to encode eth1 deposit tx data: {:?}", e))?
|
||||
};
|
||||
|
||||
|
||||
@@ -12,13 +12,14 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tempdir::TempDir;
|
||||
use types::{
|
||||
Attestation, BeaconBlock, ChainSpec, Domain, Epoch, EthSpec, Fork, PublicKey, SelectionProof,
|
||||
Signature, SignedAggregateAndProof, SignedBeaconBlock, SignedRoot, Slot,
|
||||
Attestation, BeaconBlock, ChainSpec, Domain, Epoch, EthSpec, Fork, Hash256, PublicKey,
|
||||
SelectionProof, Signature, SignedAggregateAndProof, SignedBeaconBlock, SignedRoot, Slot,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ValidatorStore<T, E: EthSpec> {
|
||||
validators: Arc<RwLock<HashMap<PublicKey, ValidatorDirectory>>>,
|
||||
genesis_validators_root: Hash256,
|
||||
spec: Arc<ChainSpec>,
|
||||
log: Logger,
|
||||
temp_dir: Option<Arc<TempDir>>,
|
||||
@@ -29,6 +30,7 @@ pub struct ValidatorStore<T, E: EthSpec> {
|
||||
impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
pub fn load_from_disk(
|
||||
base_dir: PathBuf,
|
||||
genesis_validators_root: Hash256,
|
||||
spec: ChainSpec,
|
||||
fork_service: ForkService<T, E>,
|
||||
log: Logger,
|
||||
@@ -66,6 +68,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
|
||||
Ok(Self {
|
||||
validators: Arc::new(RwLock::new(HashMap::from_par_iter(validator_key_values))),
|
||||
genesis_validators_root,
|
||||
spec: Arc::new(spec),
|
||||
log,
|
||||
temp_dir: None,
|
||||
@@ -76,6 +79,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
|
||||
pub fn insecure_ephemeral_validators(
|
||||
validator_indices: &[usize],
|
||||
genesis_validators_root: Hash256,
|
||||
spec: ChainSpec,
|
||||
fork_service: ForkService<T, E>,
|
||||
log: Logger,
|
||||
@@ -107,6 +111,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
|
||||
Ok(Self {
|
||||
validators: Arc::new(RwLock::new(HashMap::from_iter(validators))),
|
||||
genesis_validators_root,
|
||||
spec: Arc::new(spec),
|
||||
log,
|
||||
temp_dir: Some(Arc::new(temp_dir)),
|
||||
@@ -144,7 +149,12 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
.get(validator_pubkey)
|
||||
.and_then(|validator_dir| {
|
||||
let voting_keypair = validator_dir.voting_keypair.as_ref()?;
|
||||
let domain = self.spec.get_domain(epoch, Domain::Randao, &self.fork()?);
|
||||
let domain = self.spec.get_domain(
|
||||
epoch,
|
||||
Domain::Randao,
|
||||
&self.fork()?,
|
||||
self.genesis_validators_root,
|
||||
);
|
||||
let message = epoch.signing_root(domain);
|
||||
|
||||
Some(Signature::new(message.as_bytes(), &voting_keypair.sk))
|
||||
@@ -162,7 +172,12 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
.get(validator_pubkey)
|
||||
.and_then(|validator_dir| {
|
||||
let voting_keypair = validator_dir.voting_keypair.as_ref()?;
|
||||
Some(block.sign(&voting_keypair.sk, &self.fork()?, &self.spec))
|
||||
Some(block.sign(
|
||||
&voting_keypair.sk,
|
||||
&self.fork()?,
|
||||
self.genesis_validators_root,
|
||||
&self.spec,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -184,6 +199,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
&voting_keypair.sk,
|
||||
validator_committee_position,
|
||||
&self.fork()?,
|
||||
self.genesis_validators_root,
|
||||
&self.spec,
|
||||
)
|
||||
.map_err(|e| {
|
||||
@@ -217,6 +233,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
aggregate,
|
||||
&voting_keypair.sk,
|
||||
&self.fork()?,
|
||||
self.genesis_validators_root,
|
||||
&self.spec,
|
||||
))
|
||||
}
|
||||
@@ -235,6 +252,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
slot,
|
||||
&voting_keypair.sk,
|
||||
&self.fork()?,
|
||||
self.genesis_validators_root,
|
||||
&self.spec,
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user