mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 11:22:56 +00:00
Testnet compatible network upgrade (#587)
* Create libp2p instance * Change logger to stdlog * test_connection initial commit * Add gossipsub test * Delete tests in network crate * Add test module * Clean tests * Remove dependency on discovery * Working publish between 2 nodes TODO: Publish should be called just once * Working 2 peer gossipsub test with additional events * Cleanup test * Add rpc test * Star topology discovery WIP * build_nodes builds and connects n nodes. Increase nodes in gossipsub test * Add unsubscribe method and expose reference to gossipsub object for gossipsub tests * Add gossipsub message forwarding test * Fix gossipsub forward test * Test improvements * Remove discovery tests * Simplify gossipsub forward test topology * Add helper functions for topology building * Clean up tests * Update naming to new network spec * Correct ssz encoding of protocol names * Further additions to network upgrade * Initial network spec update WIP * Temp commit * Builds one side of the streamed RPC responses * Temporary commit * Propagates streaming changes up into message handler * Intermediate network update * Partial update in upgrading to the new network spec * Update dependencies, remove redundant deps * Correct sync manager for block stream handling * Re-write of RPC handler, improves efficiency and corrects bugs * Stream termination update * Completed refactor of rpc handler * Remove crates * Correct compile issues associated with test merge * Build basic tests and testing structure for eth2-libp2p * Enhance RPC tests and add logging * Complete RPC testing framework and STATUS test * Decoding bug fixes, log improvements, stream test * Clean up RPC handler logging * Decoder bug fix, empty block stream test * Add BlocksByRoot RPC test * Add Goodbye RPC test * Syncing and stream handling bug fixes and performance improvements * Applies discv5 bug fixes * Adds DHT IP filtering for lighthouse - currently disabled * Adds randomized network propagation as a CLI arg * Add disconnect functionality * Adds attestation handling and parent lookup * Adds RPC error handling for the sync manager * Allow parent's blocks to be already processed * Update github workflow * Adds reviewer suggestions
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::sync::MessageProcessor;
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use eth2_libp2p::{
|
||||
behaviour::PubsubMessage,
|
||||
rpc::{RPCError, RPCErrorResponse, RPCRequest, RPCResponse, RequestId},
|
||||
rpc::{RPCError, RPCErrorResponse, RPCRequest, RPCResponse, RequestId, ResponseTermination},
|
||||
PeerId, RPCEvent,
|
||||
};
|
||||
use futures::future::Future;
|
||||
@@ -115,9 +115,9 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
/// A new RPC request has been received from the network.
|
||||
fn handle_rpc_request(&mut self, peer_id: PeerId, request_id: RequestId, request: RPCRequest) {
|
||||
match request {
|
||||
RPCRequest::Hello(hello_message) => {
|
||||
RPCRequest::Status(status_message) => {
|
||||
self.message_processor
|
||||
.on_hello_request(peer_id, request_id, hello_message)
|
||||
.on_status_request(peer_id, request_id, status_message)
|
||||
}
|
||||
RPCRequest::Goodbye(goodbye_reason) => {
|
||||
debug!(
|
||||
@@ -127,12 +127,12 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
);
|
||||
self.message_processor.on_disconnect(peer_id);
|
||||
}
|
||||
RPCRequest::BeaconBlocks(request) => self
|
||||
RPCRequest::BlocksByRange(request) => self
|
||||
.message_processor
|
||||
.on_beacon_blocks_request(peer_id, request_id, request),
|
||||
RPCRequest::RecentBeaconBlocks(request) => self
|
||||
.on_blocks_by_range_request(peer_id, request_id, request),
|
||||
RPCRequest::BlocksByRoot(request) => self
|
||||
.message_processor
|
||||
.on_recent_beacon_blocks_request(peer_id, request_id, request),
|
||||
.on_blocks_by_root_request(peer_id, request_id, request),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,27 +147,30 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
// an error could have occurred.
|
||||
match error_response {
|
||||
RPCErrorResponse::InvalidRequest(error) => {
|
||||
warn!(self.log, "Peer indicated invalid request";"peer_id" => format!("{:?}", peer_id), "error" => error.as_string())
|
||||
warn!(self.log, "Peer indicated invalid request";"peer_id" => format!("{:?}", peer_id), "error" => error.as_string());
|
||||
self.handle_rpc_error(peer_id, request_id, RPCError::RPCErrorResponse);
|
||||
}
|
||||
RPCErrorResponse::ServerError(error) => {
|
||||
warn!(self.log, "Peer internal server error";"peer_id" => format!("{:?}", peer_id), "error" => error.as_string())
|
||||
warn!(self.log, "Peer internal server error";"peer_id" => format!("{:?}", peer_id), "error" => error.as_string());
|
||||
self.handle_rpc_error(peer_id, request_id, RPCError::RPCErrorResponse);
|
||||
}
|
||||
RPCErrorResponse::Unknown(error) => {
|
||||
warn!(self.log, "Unknown peer error";"peer" => format!("{:?}", peer_id), "error" => error.as_string())
|
||||
warn!(self.log, "Unknown peer error";"peer" => format!("{:?}", peer_id), "error" => error.as_string());
|
||||
self.handle_rpc_error(peer_id, request_id, RPCError::RPCErrorResponse);
|
||||
}
|
||||
RPCErrorResponse::Success(response) => {
|
||||
match response {
|
||||
RPCResponse::Hello(hello_message) => {
|
||||
RPCResponse::Status(status_message) => {
|
||||
self.message_processor
|
||||
.on_hello_response(peer_id, hello_message);
|
||||
.on_status_response(peer_id, status_message);
|
||||
}
|
||||
RPCResponse::BeaconBlocks(response) => {
|
||||
match self.decode_beacon_blocks(&response) {
|
||||
Ok(beacon_blocks) => {
|
||||
self.message_processor.on_beacon_blocks_response(
|
||||
RPCResponse::BlocksByRange(response) => {
|
||||
match self.decode_beacon_block(response) {
|
||||
Ok(beacon_block) => {
|
||||
self.message_processor.on_blocks_by_range_response(
|
||||
peer_id,
|
||||
request_id,
|
||||
beacon_blocks,
|
||||
Some(beacon_block),
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -176,13 +179,13 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
RPCResponse::RecentBeaconBlocks(response) => {
|
||||
match self.decode_beacon_blocks(&response) {
|
||||
Ok(beacon_blocks) => {
|
||||
self.message_processor.on_recent_beacon_blocks_response(
|
||||
RPCResponse::BlocksByRoot(response) => {
|
||||
match self.decode_beacon_block(response) {
|
||||
Ok(beacon_block) => {
|
||||
self.message_processor.on_blocks_by_root_response(
|
||||
peer_id,
|
||||
request_id,
|
||||
beacon_blocks,
|
||||
Some(beacon_block),
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -191,6 +194,22 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
RPCResponse::Goodbye => {
|
||||
// A goodbye was successfully sent, ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
RPCErrorResponse::StreamTermination(response_type) => {
|
||||
// have received a stream termination, notify the processing functions
|
||||
match response_type {
|
||||
ResponseTermination::BlocksByRange => {
|
||||
self.message_processor
|
||||
.on_blocks_by_range_response(peer_id, request_id, None);
|
||||
}
|
||||
ResponseTermination::BlocksByRoot => {
|
||||
self.message_processor
|
||||
.on_blocks_by_root_response(peer_id, request_id, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,8 +217,8 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
|
||||
/// Handle various RPC errors
|
||||
fn handle_rpc_error(&mut self, peer_id: PeerId, request_id: RequestId, error: RPCError) {
|
||||
//TODO: Handle error correctly
|
||||
warn!(self.log, "RPC Error"; "Peer" => format!("{:?}", peer_id), "request_id" => format!("{}", request_id), "Error" => format!("{:?}", error));
|
||||
self.message_processor.on_rpc_error(peer_id, request_id);
|
||||
}
|
||||
|
||||
/// Handle RPC messages
|
||||
@@ -338,16 +357,13 @@ impl<T: BeaconChainTypes> MessageHandler<T> {
|
||||
|
||||
/* Req/Resp Domain Decoding */
|
||||
|
||||
/// Verifies and decodes an ssz-encoded list of `BeaconBlock`s. This list may contain empty
|
||||
/// entries encoded with an SSZ NULL.
|
||||
fn decode_beacon_blocks(
|
||||
/// Verifies and decodes an ssz-encoded `BeaconBlock`. If `None` is passed, this represents a
|
||||
/// stream termination.
|
||||
fn decode_beacon_block(
|
||||
&self,
|
||||
beacon_blocks: &[u8],
|
||||
) -> Result<Vec<BeaconBlock<T::EthSpec>>, DecodeError> {
|
||||
if beacon_blocks.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
beacon_block: Vec<u8>,
|
||||
) -> Result<BeaconBlock<T::EthSpec>, DecodeError> {
|
||||
//TODO: Implement faster block verification before decoding entirely
|
||||
Vec::from_ssz_bytes(&beacon_blocks)
|
||||
BeaconBlock::from_ssz_bytes(&beacon_block)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user