95c8e476bc
* Remove ping protocol * Initial renaming of network services * Correct rebasing relative to latest master * Start updating types * Adds HashMapDelay struct to utils * Initial network restructure * Network restructure. Adds new types for v0.2.0 * Removes build artefacts * Shift validation to beacon chain * Temporarily remove gossip validation This is to be updated to match current optimisation efforts. * Adds AggregateAndProof * Begin rebuilding pubsub encoding/decoding * Signature hacking * Shift gossipsup decoding into eth2_libp2p * Existing EF tests passing with fake_crypto * Shifts block encoding/decoding into RPC * Delete outdated API spec * All release tests passing bar genesis state parsing * Update and test YamlConfig * Update to spec v0.10 compatible BLS * Updates to BLS EF tests * Add EF test for AggregateVerify And delete unused hash2curve tests for uncompressed points * Update EF tests to v0.10.1 * Use optional block root correctly in block proc * Use genesis fork in deposit domain. All tests pass * Fast aggregate verify test * Update REST API docs * Fix unused import * Bump spec tags to v0.10.1 * Add `seconds_per_eth1_block` to chainspec * Update to timestamp based eth1 voting scheme * Return None from `get_votes_to_consider` if block cache is empty * Handle overflows in `is_candidate_block` * Revert to failing tests * Fix eth1 data sets test * Choose default vote according to spec * Fix collect_valid_votes tests * Fix `get_votes_to_consider` to choose all eligible blocks * Uncomment winning_vote tests * Add comments; remove unused code * Reduce seconds_per_eth1_block for simulation * Addressed review comments * Add test for default vote case * Fix logs * Remove unused functions * Meter default eth1 votes * Fix comments * Progress on attestation service * Address review comments; remove unused dependency * Initial work on removing libp2p lock * Add LRU caches to store (rollup) * Update attestation validation for DB changes (WIP) * Initial version of should_forward_block * Scaffold * Progress on attestation validation Also, consolidate prod+testing slot clocks so that they share much of the same implementation and can both handle sub-slot time changes. * Removes lock from libp2p service * Completed network lock removal * Finish(?) attestation processing * Correct network termination future * Add slot check to block check * Correct fmt issues * Remove Drop implementation for network service * Add first attempt at attestation proc. re-write * Add version 2 of attestation processing * Minor fixes * Add validator pubkey cache * Make get_indexed_attestation take a committee * Link signature processing into new attn verification * First working version * Ensure pubkey cache is updated * Add more metrics, slight optimizations * Clone committee cache during attestation processing * Update shuffling cache during block processing * Remove old commented-out code * Fix shuffling cache insert bug * Used indexed attestation in fork choice * Restructure attn processing, add metrics * Add more detailed metrics * Tidy, fix failing tests * Fix failing tests, tidy * Address reviewers suggestions * Disable/delete two outdated tests * Modification of validator for subscriptions * Add slot signing to validator client * Further progress on validation subscription * Adds necessary validator subscription functionality * Add new Pubkeys struct to signature_sets * Refactor with functional approach * Update beacon chain * Clean up validator <-> beacon node http types * Add aggregator status to ValidatorDuty * Impl Clone for manual slot clock * Fix minor errors * Further progress validator client subscription * Initial subscription and aggregation handling * Remove decompressed member from pubkey bytes * Progress to modifying val client for attestation aggregation * First draft of validator client upgrade for aggregate attestations * Add hashmap for indices lookup * Add state cache, remove store cache * Only build the head committee cache * Removes lock on a network channel * Partially implement beacon node subscription http api * Correct compilation issues * Change `get_attesting_indices` to use Vec * Fix failing test * Partial implementation of timer * Adds timer, removes exit_future, http api to op pool * Partial multiple aggregate attestation handling * Permits bulk messages accross gossipsub network channel * Correct compile issues * Improve gosispsub messaging and correct rest api helpers * Added global gossipsub subscriptions * Update validator subscriptions data structs * Tidy * Re-structure validator subscriptions * Initial handling of subscriptions * Re-structure network service * Add pubkey cache persistence file * Add more comments * Integrate persistence file into builder * Add pubkey cache tests * Add HashSetDelay and introduce into attestation service * Handles validator subscriptions * Add data_dir to beacon chain builder * Remove Option in pubkey cache persistence file * Ensure consistency between datadir/data_dir * Fix failing network test * Peer subnet discovery gets queued for future subscriptions * Reorganise attestation service functions * Initial wiring of attestation service * First draft of attestation service timing logic * Correct minor typos * Tidy * Fix todos * Improve tests * Add PeerInfo to connected peers mapping * Fix compile error * Fix compile error from merge * Split up block processing metrics * Tidy * Refactor get_pubkey_from_state * Remove commented-out code * Rename state_cache -> checkpoint_cache * Rename Checkpoint -> Snapshot * Tidy, add comments * Tidy up find_head function * Change some checkpoint -> snapshot * Add tests * Expose max_len * Remove dead code * Tidy * Fix bug * Add sync-speed metric * Add first attempt at VerifiableBlock * Start integrating into beacon chain * Integrate VerifiableBlock * Rename VerifableBlock -> PartialBlockVerification * Add start of typed methods * Add progress * Add further progress * Rename structs * Add full block verification to block_processing.rs * Further beacon chain integration * Update checks for gossip * Add todo * Start adding segement verification * Add passing chain segement test * Initial integration with batch sync * Minor changes * Tidy, add more error checking * Start adding chain_segment tests * Finish invalid signature tests * Include single and gossip verified blocks in tests * Add gossip verification tests * Start adding docs * Finish adding comments to block_processing.rs * Rename block_processing.rs -> block_verification * Start removing old block processing code * Fixes beacon_chain compilation * Fix project-wide compile errors * Remove old code * Correct code to pass all tests * Fix bug with beacon proposer index * Fix shim for BlockProcessingError * Only process one epoch at a time * Fix loop in chain segment processing * Correct tests from master merge * Add caching for state.eth1_data_votes * Add BeaconChain::validator_pubkey * Revert "Add caching for state.eth1_data_votes" This reverts commit cd73dcd6434fb8d8e6bf30c5356355598ea7b78e. Co-authored-by: Grant Wuerker <gwuerker@gmail.com> Co-authored-by: Michael Sproul <michael@sigmaprime.io> Co-authored-by: Michael Sproul <micsproul@gmail.com> Co-authored-by: pawan <pawandhananjay@gmail.com> Co-authored-by: Paul Hauner <paul@paulhauner.com>
176 lines
6.2 KiB
Rust
176 lines
6.2 KiB
Rust
#![cfg(test)]
|
|
use crate::behaviour::{Behaviour, BehaviourEvent};
|
|
use crate::multiaddr::Protocol;
|
|
use ::types::MinimalEthSpec;
|
|
use eth2_libp2p::*;
|
|
use futures::prelude::*;
|
|
use libp2p::core::identity::Keypair;
|
|
use libp2p::{
|
|
core,
|
|
core::{muxing::StreamMuxerBox, nodes::Substream, transport::boxed::Boxed},
|
|
secio, PeerId, Swarm, Transport,
|
|
};
|
|
use slog::{crit, debug, info, Level};
|
|
use std::io::{Error, ErrorKind};
|
|
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
use tokio::prelude::*;
|
|
|
|
type TSpec = MinimalEthSpec;
|
|
|
|
mod common;
|
|
|
|
type Libp2pStream = Boxed<(PeerId, StreamMuxerBox), Error>;
|
|
type Libp2pBehaviour = Behaviour<Substream<StreamMuxerBox>, TSpec>;
|
|
|
|
/// Build and return a eth2_libp2p Swarm with only secio support.
|
|
fn build_secio_swarm(
|
|
config: &NetworkConfig,
|
|
log: slog::Logger,
|
|
) -> error::Result<Swarm<Libp2pStream, Libp2pBehaviour>> {
|
|
let local_keypair = Keypair::generate_secp256k1();
|
|
let local_peer_id = PeerId::from(local_keypair.public());
|
|
|
|
let network_globals = Arc::new(NetworkGlobals::new(
|
|
local_peer_id.clone(),
|
|
config.libp2p_port,
|
|
config.discovery_port,
|
|
));
|
|
|
|
let mut swarm = {
|
|
// Set up the transport - tcp/ws with secio and mplex/yamux
|
|
let transport = build_secio_transport(local_keypair.clone());
|
|
// Lighthouse network behaviour
|
|
let behaviour = Behaviour::new(&local_keypair, config, network_globals.clone(), &log)?;
|
|
Swarm::new(transport, behaviour, local_peer_id.clone())
|
|
};
|
|
|
|
// listen on the specified address
|
|
let listen_multiaddr = {
|
|
let mut m = Multiaddr::from(config.listen_address);
|
|
m.push(Protocol::Tcp(config.libp2p_port));
|
|
m
|
|
};
|
|
|
|
match Swarm::listen_on(&mut swarm, listen_multiaddr.clone()) {
|
|
Ok(_) => {
|
|
let mut log_address = listen_multiaddr;
|
|
log_address.push(Protocol::P2p(local_peer_id.clone().into()));
|
|
info!(log, "Listening established"; "address" => format!("{}", log_address));
|
|
}
|
|
Err(err) => {
|
|
crit!(
|
|
log,
|
|
"Unable to listen on libp2p address";
|
|
"error" => format!("{:?}", err),
|
|
"listen_multiaddr" => format!("{}", listen_multiaddr),
|
|
);
|
|
return Err("Libp2p was unable to listen on the given listen address.".into());
|
|
}
|
|
};
|
|
|
|
// helper closure for dialing peers
|
|
let mut dial_addr = |multiaddr: &Multiaddr| {
|
|
match Swarm::dial_addr(&mut swarm, multiaddr.clone()) {
|
|
Ok(()) => debug!(log, "Dialing libp2p peer"; "address" => format!("{}", multiaddr)),
|
|
Err(err) => debug!(
|
|
log,
|
|
"Could not connect to peer"; "address" => format!("{}", multiaddr), "error" => format!("{:?}", err)
|
|
),
|
|
};
|
|
};
|
|
|
|
// attempt to connect to any specified boot-nodes
|
|
for bootnode_enr in &config.boot_nodes {
|
|
for multiaddr in &bootnode_enr.multiaddr() {
|
|
// ignore udp multiaddr if it exists
|
|
let components = multiaddr.iter().collect::<Vec<_>>();
|
|
if let Protocol::Udp(_) = components[1] {
|
|
continue;
|
|
}
|
|
dial_addr(multiaddr);
|
|
}
|
|
}
|
|
Ok(swarm)
|
|
}
|
|
|
|
/// Build a simple TCP transport with secio, mplex/yamux.
|
|
fn build_secio_transport(local_private_key: Keypair) -> Boxed<(PeerId, StreamMuxerBox), Error> {
|
|
let transport = libp2p::tcp::TcpConfig::new().nodelay(true);
|
|
transport
|
|
.upgrade(core::upgrade::Version::V1)
|
|
.authenticate(secio::SecioConfig::new(local_private_key))
|
|
.multiplex(core::upgrade::SelectUpgrade::new(
|
|
libp2p::yamux::Config::default(),
|
|
libp2p::mplex::MplexConfig::new(),
|
|
))
|
|
.map(|(peer, muxer), _| (peer, core::muxing::StreamMuxerBox::new(muxer)))
|
|
.timeout(Duration::from_secs(20))
|
|
.timeout(Duration::from_secs(20))
|
|
.map_err(|err| Error::new(ErrorKind::Other, err))
|
|
.boxed()
|
|
}
|
|
|
|
/// Test if the encryption falls back to secio if noise isn't available
|
|
#[test]
|
|
fn test_secio_noise_fallback() {
|
|
// set up the logging. The level and enabled logging or not
|
|
let log_level = Level::Trace;
|
|
let enable_logging = true;
|
|
|
|
let log = common::build_log(log_level, enable_logging);
|
|
|
|
let noisy_config = common::build_config(56010, vec![], None);
|
|
let mut noisy_node = Service::new(&noisy_config, log.clone())
|
|
.expect("should build a libp2p instance")
|
|
.1;
|
|
|
|
let secio_config = common::build_config(56011, vec![common::get_enr(&noisy_node)], None);
|
|
|
|
// Building a custom Libp2pService from outside the crate isn't possible because of
|
|
// private fields in the Libp2pService struct. A swarm is good enough for testing
|
|
// compatibility with secio.
|
|
let mut secio_swarm =
|
|
build_secio_swarm(&secio_config, log.clone()).expect("should build a secio swarm");
|
|
|
|
let secio_log = log.clone();
|
|
|
|
let noisy_future = future::poll_fn(move || -> Poll<bool, ()> {
|
|
loop {
|
|
match noisy_node.poll().unwrap() {
|
|
_ => return Ok(Async::NotReady),
|
|
}
|
|
}
|
|
});
|
|
|
|
let secio_future = future::poll_fn(move || -> Poll<bool, ()> {
|
|
loop {
|
|
match secio_swarm.poll().unwrap() {
|
|
Async::Ready(Some(BehaviourEvent::PeerDialed(peer_id))) => {
|
|
// secio node negotiated a secio transport with
|
|
// the noise compatible node
|
|
info!(secio_log, "Connected to peer {}", peer_id);
|
|
return Ok(Async::Ready(true));
|
|
}
|
|
_ => return Ok(Async::NotReady),
|
|
}
|
|
}
|
|
});
|
|
|
|
// execute the futures and check the result
|
|
let test_result = Arc::new(AtomicBool::new(false));
|
|
let error_result = test_result.clone();
|
|
let thread_result = test_result.clone();
|
|
tokio::run(
|
|
noisy_future
|
|
.select(secio_future)
|
|
.timeout(Duration::from_millis(1000))
|
|
.map_err(move |_| error_result.store(false, Relaxed))
|
|
.map(move |result| {
|
|
thread_result.store(result.0, Relaxed);
|
|
}),
|
|
);
|
|
assert!(test_result.load(Relaxed));
|
|
}
|