Merge branch 'master' into paul-sync

This commit is contained in:
Paul Hauner
2019-03-22 07:11:04 +11:00
62 changed files with 1506 additions and 1386 deletions

View File

@@ -82,7 +82,7 @@ where
let state_root = genesis_state.canonical_root();
state_store.put(&state_root, &ssz_encode(&genesis_state)[..])?;
let block_root = genesis_block.into_header().canonical_root();
let block_root = genesis_block.block_header().canonical_root();
block_store.put(&block_root, &ssz_encode(&genesis_block)[..])?;
let finalized_head = RwLock::new(CheckPoint::new(
@@ -189,7 +189,7 @@ where
pub fn advance_state(&self, slot: Slot) -> Result<(), SlotProcessingError> {
let state_slot = self.state.read().slot;
let latest_block_header = self.head().beacon_block.into_header();
let latest_block_header = self.head().beacon_block.block_header();
for _ in state_slot.as_u64()..slot.as_u64() {
per_slot_processing(&mut *self.state.write(), &latest_block_header, &self.spec)?;
@@ -246,7 +246,10 @@ where
/// Information is read from the present `beacon_state` shuffling, so only information from the
/// present and prior epoch is available.
pub fn block_proposer(&self, slot: Slot) -> Result<usize, BeaconStateError> {
trace!("BeaconChain::block_proposer: slot: {}", slot);
self.state
.write()
.build_epoch_cache(RelativeEpoch::Current, &self.spec)?;
let index = self.state.read().get_beacon_proposer_index(
slot,
RelativeEpoch::Current,
@@ -561,7 +564,7 @@ where
pub fn process_block(&self, block: BeaconBlock) -> Result<BlockProcessingOutcome, Error> {
debug!("Processing block with slot {}...", block.slot);
let block_root = block.into_header().canonical_root();
let block_root = block.block_header().canonical_root();
let present_slot = self.present_slot();
@@ -596,7 +599,7 @@ where
// Transition the parent state to the present slot.
let mut state = parent_state;
let previous_block_header = parent_block.into_header();
let previous_block_header = parent_block.block_header();
for _ in state.slot.as_u64()..present_slot.as_u64() {
if let Err(e) = per_slot_processing(&mut state, &previous_block_header, &self.spec) {
return Ok(BlockProcessingOutcome::InvalidBlock(
@@ -662,6 +665,8 @@ where
let mut state = self.state.read().clone();
state.build_epoch_cache(RelativeEpoch::Current, &self.spec)?;
trace!("Finding attestations for new block...");
let attestations = self

View File

@@ -28,6 +28,8 @@ pub enum BeaconChainError {
pub enum BlockProductionError {
UnableToGetBlockRootFromState,
BlockProcessingError(BlockProcessingError),
BeaconStateError(BeaconStateError),
}
easy_from_to!(BlockProcessingError, BlockProductionError);
easy_from_to!(BeaconStateError, BlockProductionError);

View File

@@ -9,6 +9,7 @@ test_cases:
deposits_for_chain_start: 1000
num_slots: 64
skip_slots: [2, 3]
persistent_committee_period: 0
deposits:
# At slot 1, create a new validator deposit of 5 ETH.
- slot: 1

View File

@@ -51,11 +51,24 @@ impl BeaconChainHarness {
let slot_clock = TestingSlotClock::new(spec.genesis_slot.as_u64());
let fork_choice = BitwiseLMDGhost::new(block_store.clone(), state_store.clone());
let (genesis_state, keypairs) = state_builder.build();
let (mut genesis_state, keypairs) = state_builder.build();
let mut genesis_block = BeaconBlock::empty(&spec);
genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root());
genesis_state
.build_epoch_cache(RelativeEpoch::Previous, &spec)
.unwrap();
genesis_state
.build_epoch_cache(RelativeEpoch::Current, &spec)
.unwrap();
genesis_state
.build_epoch_cache(RelativeEpoch::NextWithoutRegistryChange, &spec)
.unwrap();
genesis_state
.build_epoch_cache(RelativeEpoch::NextWithRegistryChange, &spec)
.unwrap();
// Create the Beacon Chain
let beacon_chain = Arc::new(
BeaconChain::from_genesis(
@@ -194,7 +207,6 @@ impl BeaconChainHarness {
self.increment_beacon_chain_slot();
// Produce a new block.
debug!("Producing block...");
let block = self.produce_block();
debug!("Submitting block for processing...");
match self.beacon_chain.process_block(block) {

View File

@@ -62,6 +62,10 @@ impl TestCase {
spec.slots_per_epoch = n;
}
if let Some(n) = self.config.persistent_committee_period {
spec.persistent_committee_period = n;
}
spec
}

View File

@@ -20,6 +20,8 @@ pub struct Config {
pub deposits_for_chain_start: usize,
/// Number of slots in an epoch.
pub slots_per_epoch: Option<u64>,
/// Affects the number of epochs a validator must be active before they can withdraw.
pub persistent_committee_period: Option<u64>,
/// Number of slots to build before ending execution.
pub num_slots: u64,
/// Number of slots that should be skipped due to inactive validator.
@@ -45,6 +47,7 @@ impl Config {
deposits_for_chain_start: as_usize(&yaml, "deposits_for_chain_start")
.expect("Must specify validator count"),
slots_per_epoch: as_u64(&yaml, "slots_per_epoch"),
persistent_committee_period: as_u64(&yaml, "persistent_committee_period"),
num_slots: as_u64(&yaml, "num_slots").expect("Must specify `config.num_slots`"),
skip_slots: as_vec_u64(yaml, "skip_slots"),
deposits: parse_deposits(&yaml),

View File

@@ -1,5 +1,5 @@
[package]
name = "libp2p"
name = "eth2-libp2p"
version = "0.1.0"
authors = ["Age Manning <Age@AgeManning.com>"]
edition = "2018"

View File

@@ -10,7 +10,7 @@ sloggers = "0.3.2"
[dependencies]
beacon_chain = { path = "../beacon_chain" }
libp2p = { path = "../libp2p" }
eth2-libp2p = { path = "../eth2-libp2p" }
version = { path = "../version" }
types = { path = "../../eth2/types" }
slog = "2.4.1"

View File

@@ -7,7 +7,7 @@ use beacon_chain::{
types::{BeaconState, ChainSpec},
CheckPoint,
};
use libp2p::HelloMessage;
use eth2_libp2p::HelloMessage;
use types::{Epoch, Hash256, Slot};
/// The network's API to the beacon chain.

View File

@@ -1,5 +1,5 @@
// generates error types
use libp2p;
use eth2_libp2p;
use error_chain::{
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed,
@@ -8,6 +8,6 @@ use error_chain::{
error_chain! {
links {
Libp2p(libp2p::error::Error, libp2p::error::ErrorKind);
Libp2p(eth2_libp2p::error::Error, eth2_libp2p::error::ErrorKind);
}
}

View File

@@ -5,5 +5,5 @@ pub mod message_handler;
pub mod service;
pub mod sync;
pub use libp2p::NetworkConfig;
pub use eth2_libp2p::NetworkConfig;
pub use service::Service;

View File

@@ -3,11 +3,11 @@ use crate::error;
use crate::service::{NetworkMessage, OutgoingMessage};
use crate::sync::SimpleSync;
use crossbeam_channel::{unbounded as channel, Sender};
use futures::future;
use libp2p::{
use eth2_libp2p::{
rpc::{RPCRequest, RPCResponse},
PeerId, RPCEvent,
};
use futures::future;
use slog::debug;
use slog::warn;
use std::collections::HashMap;

View File

@@ -3,20 +3,20 @@ use crate::error;
use crate::message_handler::{HandlerMessage, MessageHandler};
use crate::NetworkConfig;
use crossbeam_channel::{unbounded as channel, Sender, TryRecvError};
use eth2_libp2p::RPCEvent;
use eth2_libp2p::Service as LibP2PService;
use eth2_libp2p::{Libp2pEvent, PeerId};
use futures::prelude::*;
use futures::sync::oneshot;
use futures::Stream;
use libp2p::RPCEvent;
use libp2p::Service as LibP2PService;
use libp2p::{Libp2pEvent, PeerId};
use slog::{debug, info, o, trace};
use std::sync::Arc;
use tokio::runtime::TaskExecutor;
/// Service that handles communication between internal services and the libp2p network service.
/// Service that handles communication between internal services and the eth2_libp2p network service.
pub struct Service {
//libp2p_service: Arc<Mutex<LibP2PService>>,
libp2p_exit: oneshot::Sender<()>,
//eth2_libp2p_service: Arc<Mutex<LibP2PService>>,
eth2_libp2p_exit: oneshot::Sender<()>,
network_send: crossbeam_channel::Sender<NetworkMessage>,
//message_handler: MessageHandler,
//message_handler_send: Sender<HandlerMessage>,
@@ -40,20 +40,20 @@ impl Service {
message_handler_log,
)?;
// launch libp2p service
let libp2p_log = log.new(o!("Service" => "Libp2p"));
let libp2p_service = LibP2PService::new(config.clone(), libp2p_log)?;
// launch eth2_libp2p service
let eth2_libp2p_log = log.new(o!("Service" => "Libp2p"));
let eth2_libp2p_service = LibP2PService::new(config.clone(), eth2_libp2p_log)?;
// TODO: Spawn thread to handle libp2p messages and pass to message handler thread.
let libp2p_exit = spawn_service(
libp2p_service,
// TODO: Spawn thread to handle eth2_libp2p messages and pass to message handler thread.
let eth2_libp2p_exit = spawn_service(
eth2_libp2p_service,
network_recv,
message_handler_send,
executor,
log,
)?;
let network_service = Service {
libp2p_exit,
eth2_libp2p_exit,
network_send: network_send.clone(),
};
@@ -72,7 +72,7 @@ impl Service {
}
fn spawn_service(
libp2p_service: LibP2PService,
eth2_libp2p_service: LibP2PService,
network_recv: crossbeam_channel::Receiver<NetworkMessage>,
message_handler_send: crossbeam_channel::Sender<HandlerMessage>,
executor: &TaskExecutor,
@@ -83,7 +83,7 @@ fn spawn_service(
// spawn on the current executor
executor.spawn(
network_service(
libp2p_service,
eth2_libp2p_service,
network_recv,
message_handler_send,
log.clone(),
@@ -100,18 +100,18 @@ fn spawn_service(
}
fn network_service(
mut libp2p_service: LibP2PService,
mut eth2_libp2p_service: LibP2PService,
network_recv: crossbeam_channel::Receiver<NetworkMessage>,
message_handler_send: crossbeam_channel::Sender<HandlerMessage>,
log: slog::Logger,
) -> impl futures::Future<Item = (), Error = libp2p::error::Error> {
futures::future::poll_fn(move || -> Result<_, libp2p::error::Error> {
) -> impl futures::Future<Item = (), Error = eth2_libp2p::error::Error> {
futures::future::poll_fn(move || -> Result<_, eth2_libp2p::error::Error> {
// poll the swarm
loop {
match libp2p_service.poll() {
match eth2_libp2p_service.poll() {
Ok(Async::Ready(Some(Libp2pEvent::RPC(peer_id, rpc_event)))) => {
trace!(
libp2p_service.log,
eth2_libp2p_service.log,
"RPC Event: RPC message received: {:?}",
rpc_event
);
@@ -120,13 +120,13 @@ fn network_service(
.map_err(|_| "failed to send rpc to handler")?;
}
Ok(Async::Ready(Some(Libp2pEvent::PeerDialed(peer_id)))) => {
debug!(libp2p_service.log, "Peer Dialed: {:?}", peer_id);
debug!(eth2_libp2p_service.log, "Peer Dialed: {:?}", peer_id);
message_handler_send
.send(HandlerMessage::PeerDialed(peer_id))
.map_err(|_| "failed to send rpc to handler")?;
}
Ok(Async::Ready(Some(Libp2pEvent::Message(m)))) => debug!(
libp2p_service.log,
eth2_libp2p_service.log,
"Network Service: Message received: {}", m
),
_ => break,
@@ -143,7 +143,7 @@ fn network_service(
trace!(log, "Sending RPC Event: {:?}", rpc_event);
//TODO: Make swarm private
//TODO: Implement correct peer id topic message handling
libp2p_service.swarm.send_rpc(peer_id, rpc_event);
eth2_libp2p_service.swarm.send_rpc(peer_id, rpc_event);
}
OutgoingMessage::NotifierTest => {
debug!(log, "Received message from notifier");
@@ -152,7 +152,9 @@ fn network_service(
}
Err(TryRecvError::Empty) => break,
Err(TryRecvError::Disconnected) => {
return Err(libp2p::error::Error::from("Network channel disconnected"));
return Err(eth2_libp2p::error::Error::from(
"Network channel disconnected",
));
}
}
}
@@ -163,7 +165,7 @@ fn network_service(
/// Types of messages that the network service can receive.
#[derive(Debug, Clone)]
pub enum NetworkMessage {
/// Send a message to libp2p service.
/// Send a message to eth2_libp2p service.
//TODO: Define typing for messages across the wire
Send(PeerId, OutgoingMessage),
}

View File

@@ -2,9 +2,9 @@ use crate::beacon_chain::BeaconChain;
use crate::message_handler::NetworkContext;
use crate::service::NetworkMessage;
use crossbeam_channel::Sender;
use libp2p::rpc::methods::*;
use libp2p::rpc::{RPCRequest, RPCResponse};
use libp2p::PeerId;
use eth2_libp2p::rpc::methods::*;
use eth2_libp2p::rpc::{RPCRequest, RPCResponse};
use eth2_libp2p::PeerId;
use slog::{debug, o};
use std::collections::HashMap;
use std::sync::Arc;
@@ -51,6 +51,7 @@ impl PeerSyncInfo {
}
}
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum PeerStatus {
OnDifferentChain,
HigherFinalizedEpoch,
@@ -143,6 +144,12 @@ impl SimpleSync {
debug!(self.log, "Handshake successful. Peer: {:?}", peer_id);
self.known_peers.insert(peer_id.clone(), peer);
debug!(
self.log,
"Peer hello. Status: {:?}",
peer.status(&self.chain)
);
match peer.status(&self.chain) {
PeerStatus::OnDifferentChain => {
debug!(self.log, "Peer is on different chain. Peer: {:?}", peer_id);

View File

@@ -1,8 +1,8 @@
use beacon_chain::test_utils::TestingBeaconChainBuilder;
use crossbeam_channel::{unbounded, Receiver, Sender};
use libp2p::rpc::methods::*;
use libp2p::rpc::{HelloMessage, RPCMethod, RPCRequest, RPCResponse};
use libp2p::{PeerId, RPCEvent};
use crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender};
use eth2_libp2p::rpc::methods::*;
use eth2_libp2p::rpc::{RPCMethod, RPCRequest, RPCResponse};
use eth2_libp2p::{PeerId, RPCEvent};
use network::beacon_chain::BeaconChain as NetworkBeaconChain;
use network::message_handler::{HandlerMessage, MessageHandler};
use network::service::{NetworkMessage, OutgoingMessage};
@@ -43,15 +43,13 @@ impl SyncNode {
self.sender.send(message).unwrap();
}
fn recv(&self) -> NetworkMessage {
self.receiver
.recv_timeout(Duration::from_millis(500))
.unwrap()
fn recv(&self) -> Result<NetworkMessage, RecvTimeoutError> {
self.receiver.recv_timeout(Duration::from_millis(500))
}
fn recv_rpc_response(&self) -> RPCResponse {
let network_message = self.recv();
match network_message {
fn recv_rpc_response(&self) -> Result<RPCResponse, RecvTimeoutError> {
let network_message = self.recv()?;
Ok(match network_message {
NetworkMessage::Send(
_peer_id,
OutgoingMessage::RPC(RPCEvent::Response {
@@ -61,12 +59,12 @@ impl SyncNode {
}),
) => result,
_ => panic!("get_rpc_response failed! got {:?}", network_message),
}
})
}
fn recv_rpc_request(&self) -> RPCRequest {
let network_message = self.recv();
match network_message {
fn recv_rpc_request(&self) -> Result<RPCRequest, RecvTimeoutError> {
let network_message = self.recv()?;
Ok(match network_message {
NetworkMessage::Send(
_peer_id,
OutgoingMessage::RPC(RPCEvent::Request {
@@ -76,7 +74,7 @@ impl SyncNode {
}),
) => body,
_ => panic!("get_rpc_request failed! got {:?}", network_message),
}
})
}
}
@@ -126,7 +124,7 @@ impl SyncMaster {
let message = HandlerMessage::PeerDialed(self.peer_id.clone());
node.send(message);
let request = node.recv_rpc_request();
let request = node.recv_rpc_request().expect("No hello response");
match request {
RPCRequest::Hello(_hello) => {
@@ -151,7 +149,7 @@ impl SyncMaster {
}
fn assert_sent_block_root_request(node: &SyncNode, expected: BeaconBlockRootsRequest) {
let request = node.recv_rpc_request();
let request = node.recv_rpc_request().expect("No block root request");
match request {
RPCRequest::BeaconBlockRoots(response) => {