Use Gossipsub 1.1 (#1516)
## Issue Addressed #1172 ## Proposed Changes * updates the libp2p dependency * small adaptions based on changes in libp2p * report not just valid messages but also invalid and distinguish between `IGNORE`d messages and `REJECT`ed messages Co-authored-by: Age Manning <Age@AgeManning.com>
This commit is contained in:
parent
b6340ec495
commit
c18d37c202
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -309,12 +309,6 @@ dependencies = [
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.12.3"
|
||||
@ -462,21 +456,6 @@ dependencies = [
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce4f9586c9a3151c4b49b19e82ba163dd073614dd057e53c969e1a4db5b52720"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
"crypto-mac 0.8.0",
|
||||
"digest 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
@ -2644,8 +2623,8 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
||||
|
||||
[[package]]
|
||||
name = "libp2p"
|
||||
version = "0.23.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
version = "0.25.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"bytes 0.5.6",
|
||||
@ -2662,7 +2641,7 @@ dependencies = [
|
||||
"libp2p-tcp",
|
||||
"libp2p-websocket",
|
||||
"multihash",
|
||||
"parity-multiaddr 0.9.1 (git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803)",
|
||||
"parity-multiaddr 0.9.1 (git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df)",
|
||||
"parking_lot 0.10.2",
|
||||
"pin-project",
|
||||
"smallvec 1.4.2",
|
||||
@ -2706,7 +2685,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-core"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"asn1_der",
|
||||
"bs58",
|
||||
@ -2719,8 +2698,8 @@ dependencies = [
|
||||
"libsecp256k1",
|
||||
"log 0.4.11",
|
||||
"multihash",
|
||||
"multistream-select 0.8.2 (git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803)",
|
||||
"parity-multiaddr 0.9.1 (git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803)",
|
||||
"multistream-select 0.8.2 (git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df)",
|
||||
"parity-multiaddr 0.9.1 (git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df)",
|
||||
"parking_lot 0.10.2",
|
||||
"pin-project",
|
||||
"prost",
|
||||
@ -2739,7 +2718,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-core-derive"
|
||||
version = "0.20.2"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
@ -2748,7 +2727,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-dns"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"futures 0.3.5",
|
||||
"libp2p-core 0.21.0",
|
||||
@ -2757,10 +2736,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libp2p-gossipsub"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"base64 0.11.0",
|
||||
"base64 0.12.3",
|
||||
"byteorder",
|
||||
"bytes 0.5.6",
|
||||
"fnv",
|
||||
@ -2773,16 +2752,16 @@ dependencies = [
|
||||
"prost",
|
||||
"prost-build",
|
||||
"rand 0.7.3",
|
||||
"sha2 0.8.2",
|
||||
"sha2 0.9.1",
|
||||
"smallvec 1.4.2",
|
||||
"unsigned-varint 0.4.0",
|
||||
"unsigned-varint 0.5.0",
|
||||
"wasm-timer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libp2p-identify"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"futures 0.3.5",
|
||||
"libp2p-core 0.21.0",
|
||||
@ -2797,7 +2776,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-mplex"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"fnv",
|
||||
@ -2812,7 +2791,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-noise"
|
||||
version = "0.23.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"curve25519-dalek 2.1.0",
|
||||
@ -2832,9 +2811,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libp2p-swarm"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"either",
|
||||
"futures 0.3.5",
|
||||
"libp2p-core 0.21.0",
|
||||
"log 0.4.11",
|
||||
@ -2847,7 +2827,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-tcp"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"futures 0.3.5",
|
||||
"futures-timer",
|
||||
@ -2862,7 +2842,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libp2p-websocket"
|
||||
version = "0.22.0"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"async-tls",
|
||||
"either",
|
||||
@ -3221,13 +3201,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "multihash"
|
||||
version = "0.11.3"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51cc1552a982658478dbc22eefb72bb1d4fd1161eb9818f7bbf4347443f07569"
|
||||
checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"blake2s_simd",
|
||||
"blake3",
|
||||
"digest 0.9.0",
|
||||
"sha-1 0.9.1",
|
||||
"sha2 0.9.1",
|
||||
@ -3244,7 +3223,7 @@ checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
|
||||
[[package]]
|
||||
name = "multistream-select"
|
||||
version = "0.8.2"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"futures 0.3.5",
|
||||
@ -3538,7 +3517,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-multiaddr"
|
||||
version = "0.9.1"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803#bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
source = "git+https://github.com/sigp/rust-libp2p?rev=d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df#d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bs58",
|
||||
@ -6033,6 +6012,10 @@ name = "unsigned-varint"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a98e44fc6af1e18c3a06666d829b4fd8d2714fb2dbffe8ab99d5dc7ea6baa628"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"futures_codec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
|
@ -41,7 +41,7 @@ rand = "0.7.3"
|
||||
[dependencies.libp2p]
|
||||
#version = "0.23.0"
|
||||
git = "https://github.com/sigp/rust-libp2p"
|
||||
rev = "bbf0cfbaff2f733b3ae7bfed3caba8b7ee542803"
|
||||
rev = "d0f9d6b9b3fef9616026f3ddf11d75fe9f7a41df"
|
||||
default-features = false
|
||||
features = ["websocket", "identify", "mplex", "noise", "gossipsub", "dns", "tcp-tokio"]
|
||||
|
||||
|
@ -131,8 +131,9 @@ impl<TSpec: EthSpec> ProtocolsHandler for DelegatingHandler<TSpec> {
|
||||
type InboundProtocol = DelegateInProto<TSpec>;
|
||||
type OutboundProtocol = DelegateOutProto<TSpec>;
|
||||
type OutboundOpenInfo = DelegateOutInfo<TSpec>;
|
||||
type InboundOpenInfo = ();
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, ()> {
|
||||
let gossip_proto = self.gossip_handler.listen_protocol();
|
||||
let rpc_proto = self.rpc_handler.listen_protocol();
|
||||
let identify_proto = self.identify_handler.listen_protocol();
|
||||
@ -147,24 +148,27 @@ impl<TSpec: EthSpec> ProtocolsHandler for DelegatingHandler<TSpec> {
|
||||
SelectUpgrade::new(rpc_proto.into_upgrade().1, identify_proto.into_upgrade().1),
|
||||
);
|
||||
|
||||
SubstreamProtocol::new(select).with_timeout(timeout)
|
||||
SubstreamProtocol::new(select, ()).with_timeout(timeout)
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
out: <Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Output,
|
||||
_info: Self::InboundOpenInfo,
|
||||
) {
|
||||
match out {
|
||||
// Gossipsub
|
||||
EitherOutput::First(out) => self.gossip_handler.inject_fully_negotiated_inbound(out),
|
||||
EitherOutput::First(out) => {
|
||||
self.gossip_handler.inject_fully_negotiated_inbound(out, ())
|
||||
}
|
||||
// RPC
|
||||
EitherOutput::Second(EitherOutput::First(out)) => {
|
||||
self.rpc_handler.inject_fully_negotiated_inbound(out)
|
||||
self.rpc_handler.inject_fully_negotiated_inbound(out, ())
|
||||
}
|
||||
// Identify
|
||||
EitherOutput::Second(EitherOutput::Second(out)) => {
|
||||
self.identify_handler.inject_fully_negotiated_inbound(out)
|
||||
}
|
||||
EitherOutput::Second(EitherOutput::Second(out)) => self
|
||||
.identify_handler
|
||||
.inject_fully_negotiated_inbound(out, ()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,10 +321,11 @@ impl<TSpec: EthSpec> ProtocolsHandler for DelegatingHandler<TSpec> {
|
||||
event,
|
||||
)));
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info }) => {
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol.map_upgrade(EitherUpgrade::A),
|
||||
info: EitherOutput::First(info),
|
||||
protocol: protocol
|
||||
.map_upgrade(EitherUpgrade::A)
|
||||
.map_info(EitherOutput::First),
|
||||
});
|
||||
}
|
||||
Poll::Pending => (),
|
||||
@ -333,10 +338,11 @@ impl<TSpec: EthSpec> ProtocolsHandler for DelegatingHandler<TSpec> {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(DelegateError::RPC(event)));
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info }) => {
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol.map_upgrade(|u| EitherUpgrade::B(EitherUpgrade::A(u))),
|
||||
info: EitherOutput::Second(EitherOutput::First(info)),
|
||||
protocol: protocol
|
||||
.map_upgrade(|u| EitherUpgrade::B(EitherUpgrade::A(u)))
|
||||
.map_info(|info| EitherOutput::Second(EitherOutput::First(info))),
|
||||
});
|
||||
}
|
||||
Poll::Pending => (),
|
||||
@ -351,10 +357,11 @@ impl<TSpec: EthSpec> ProtocolsHandler for DelegatingHandler<TSpec> {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(DelegateError::Identify(event)));
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () }) => {
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol.map_upgrade(|u| EitherUpgrade::B(EitherUpgrade::B(u))),
|
||||
info: EitherOutput::Second(EitherOutput::Second(())),
|
||||
protocol: protocol
|
||||
.map_upgrade(|u| EitherUpgrade::B(EitherUpgrade::B(u)))
|
||||
.map_info(|_| EitherOutput::Second(EitherOutput::Second(()))),
|
||||
});
|
||||
}
|
||||
Poll::Pending => (),
|
||||
|
@ -54,16 +54,18 @@ impl<TSpec: EthSpec> ProtocolsHandler for BehaviourHandler<TSpec> {
|
||||
type InboundProtocol = DelegateInProto<TSpec>;
|
||||
type OutboundProtocol = DelegateOutProto<TSpec>;
|
||||
type OutboundOpenInfo = DelegateOutInfo<TSpec>;
|
||||
type InboundOpenInfo = ();
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, ()> {
|
||||
self.delegate.listen_protocol()
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
out: <Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Output,
|
||||
_info: Self::InboundOpenInfo,
|
||||
) {
|
||||
self.delegate.inject_fully_negotiated_inbound(out)
|
||||
self.delegate.inject_fully_negotiated_inbound(out, ())
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_outbound(
|
||||
@ -127,11 +129,8 @@ impl<TSpec: EthSpec> ProtocolsHandler for BehaviourHandler<TSpec> {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(err)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(err))
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol,
|
||||
info,
|
||||
});
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol });
|
||||
}
|
||||
Poll::Pending => (),
|
||||
}
|
||||
|
@ -11,7 +11,10 @@ use libp2p::{
|
||||
identity::Keypair,
|
||||
Multiaddr,
|
||||
},
|
||||
gossipsub::{Gossipsub, GossipsubEvent, MessageAuthenticity, MessageId},
|
||||
gossipsub::{
|
||||
Gossipsub, GossipsubEvent, IdentTopic as Topic, MessageAcceptance, MessageAuthenticity,
|
||||
MessageId,
|
||||
},
|
||||
identify::{Identify, IdentifyEvent},
|
||||
swarm::{
|
||||
NetworkBehaviour, NetworkBehaviourAction as NBAction, NotifyHandler, PollParameters,
|
||||
@ -94,15 +97,19 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
|
||||
let meta_data = load_or_build_metadata(&net_conf.network_dir, &log);
|
||||
|
||||
// TODO: Until other clients support no author, we will use a 0 peer_id as our author.
|
||||
let message_author = PeerId::from_bytes(vec![0, 1, 0]).expect("Valid peer id");
|
||||
let gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, net_conf.gs_config.clone())
|
||||
.map_err(|e| format!("Could not construct gossipsub: {:?}", e))?;
|
||||
|
||||
// Temporarily disable scoring until parameters are tested.
|
||||
/*
|
||||
gossipsub
|
||||
.with_peer_score(PeerScoreParams::default(), PeerScoreThresholds::default())
|
||||
.expect("Valid score params and thresholds");
|
||||
*/
|
||||
|
||||
Ok(Behaviour {
|
||||
eth2_rpc: RPC::new(log.clone()),
|
||||
gossipsub: Gossipsub::new(
|
||||
MessageAuthenticity::Author(message_author),
|
||||
net_conf.gs_config.clone(),
|
||||
),
|
||||
gossipsub,
|
||||
identify,
|
||||
peer_manager: PeerManager::new(local_key, net_conf, network_globals.clone(), log)
|
||||
.await?,
|
||||
@ -147,6 +154,10 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
GossipEncoding::default(),
|
||||
self.enr_fork_id.fork_digest,
|
||||
);
|
||||
|
||||
// TODO: Implement scoring
|
||||
// let topic: Topic = gossip_topic.into();
|
||||
// self.gossipsub.set_topic_params(t.hash(), TopicScoreParams::default());
|
||||
self.subscribe(gossip_topic)
|
||||
}
|
||||
|
||||
@ -168,6 +179,12 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
GossipEncoding::default(),
|
||||
self.enr_fork_id.fork_digest,
|
||||
);
|
||||
// TODO: Implement scoring
|
||||
/*
|
||||
let t: Topic = topic.clone().into();
|
||||
self.gossipsub
|
||||
.set_topic_params(t.hash(), TopicScoreParams::default());
|
||||
*/
|
||||
self.subscribe(topic)
|
||||
}
|
||||
|
||||
@ -189,9 +206,18 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
.write()
|
||||
.insert(topic.clone());
|
||||
|
||||
let topic_str: String = topic.clone().into();
|
||||
debug!(self.log, "Subscribed to topic"; "topic" => topic_str);
|
||||
self.gossipsub.subscribe(topic.into())
|
||||
let topic: Topic = topic.into();
|
||||
|
||||
match self.gossipsub.subscribe(&topic) {
|
||||
Err(_) => {
|
||||
warn!(self.log, "Failed to subscribe to topic"; "topic" => topic.to_string());
|
||||
false
|
||||
}
|
||||
Ok(v) => {
|
||||
debug!(self.log, "Subscribed to topic"; "topic" => topic.to_string());
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsubscribe from a gossipsub topic.
|
||||
@ -201,8 +227,20 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
.gossipsub_subscriptions
|
||||
.write()
|
||||
.remove(&topic);
|
||||
|
||||
// unsubscribe from the topic
|
||||
self.gossipsub.unsubscribe(topic.into())
|
||||
let topic: Topic = topic.into();
|
||||
|
||||
match self.gossipsub.unsubscribe(&topic) {
|
||||
Err(_) => {
|
||||
warn!(self.log, "Failed to unsubscribe from topic"; "topic" => topic.to_string());
|
||||
false
|
||||
}
|
||||
Ok(v) => {
|
||||
debug!(self.log, "Unsubscribed to topic"; "topic" => topic.to_string());
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Publishes a list of messages on the pubsub (gossipsub) behaviour, choosing the encoding.
|
||||
@ -211,7 +249,7 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
for topic in message.topics(GossipEncoding::default(), self.enr_fork_id.fork_digest) {
|
||||
match message.encode(GossipEncoding::default()) {
|
||||
Ok(message_data) => {
|
||||
if let Err(e) = self.gossipsub.publish(&topic.into(), message_data) {
|
||||
if let Err(e) = self.gossipsub.publish(topic.into(), message_data) {
|
||||
slog::warn!(self.log, "Could not publish message"; "error" => format!("{:?}", e));
|
||||
}
|
||||
}
|
||||
@ -221,11 +259,21 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwards a message that is waiting in gossipsub's mcache. Messages are only propagated
|
||||
/// once validated by the beacon chain.
|
||||
pub fn validate_message(&mut self, propagation_source: &PeerId, message_id: MessageId) {
|
||||
self.gossipsub
|
||||
.validate_message(&message_id, propagation_source);
|
||||
/// Informs the gossipsub about the result of a message validation.
|
||||
/// If the message is valid it will get propagated by gossipsub.
|
||||
pub fn report_message_validation_result(
|
||||
&mut self,
|
||||
propagation_source: &PeerId,
|
||||
message_id: MessageId,
|
||||
validation_result: MessageAcceptance,
|
||||
) {
|
||||
if let Err(e) = self.gossipsub.report_message_validation_result(
|
||||
&message_id,
|
||||
propagation_source,
|
||||
validation_result,
|
||||
) {
|
||||
warn!(self.log, "Failed to report message validation"; "message_id" => message_id.to_string(), "peer_id" => propagation_source.to_string(), "error" => format!("{:?}", e));
|
||||
}
|
||||
}
|
||||
|
||||
/* Eth2 RPC behaviour functions */
|
||||
@ -392,11 +440,25 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
|
||||
fn on_gossip_event(&mut self, event: GossipsubEvent) {
|
||||
match event {
|
||||
GossipsubEvent::Message(propagation_source, id, gs_msg) => {
|
||||
GossipsubEvent::Message {
|
||||
propagation_source,
|
||||
message_id: id,
|
||||
message: gs_msg,
|
||||
} => {
|
||||
// Note: We are keeping track here of the peer that sent us the message, not the
|
||||
// peer that originally published the message.
|
||||
match PubsubMessage::decode(&gs_msg.topics, &gs_msg.data) {
|
||||
Err(e) => debug!(self.log, "Could not decode gossipsub message"; "error" => e),
|
||||
Err(e) => {
|
||||
debug!(self.log, "Could not decode gossipsub message"; "error" => e);
|
||||
//reject the message
|
||||
if let Err(e) = self.gossipsub.report_message_validation_result(
|
||||
&id,
|
||||
&propagation_source,
|
||||
MessageAcceptance::Reject,
|
||||
) {
|
||||
warn!(self.log, "Failed to report message validation"; "message_id" => id.to_string(), "peer_id" => propagation_source.to_string(), "error" => format!("{:?}", e));
|
||||
}
|
||||
}
|
||||
Ok(msg) => {
|
||||
// Notify the network
|
||||
self.add_event(BehaviourEvent::PubsubMessage {
|
||||
|
@ -99,8 +99,8 @@ impl Default for Config {
|
||||
let gs_config = GossipsubConfigBuilder::new()
|
||||
.max_transmit_size(GOSSIP_MAX_SIZE)
|
||||
.heartbeat_interval(Duration::from_millis(700))
|
||||
.mesh_n(6)
|
||||
.mesh_n_low(5)
|
||||
.mesh_n(8)
|
||||
.mesh_n_low(6)
|
||||
.mesh_n_high(12)
|
||||
.gossip_lazy(6)
|
||||
.fanout_ttl(Duration::from_secs(60))
|
||||
@ -111,7 +111,8 @@ impl Default for Config {
|
||||
// prevent duplicates for 550 heartbeats(700millis * 550) = 385 secs
|
||||
.duplicate_cache_time(Duration::from_secs(385))
|
||||
.message_id_fn(gossip_message_id)
|
||||
.build();
|
||||
.build()
|
||||
.expect("valid gossipsub configuration");
|
||||
|
||||
// discv5 configuration
|
||||
let discv5_config = Discv5ConfigBuilder::new()
|
||||
|
@ -19,7 +19,7 @@ pub use behaviour::{BehaviourEvent, PeerRequestId, Request, Response};
|
||||
pub use config::Config as NetworkConfig;
|
||||
pub use discovery::{CombinedKeyExt, EnrExt, Eth2Enr};
|
||||
pub use discv5;
|
||||
pub use libp2p::gossipsub::{MessageId, Topic, TopicHash};
|
||||
pub use libp2p::gossipsub::{MessageAcceptance, MessageId, Topic, TopicHash};
|
||||
pub use libp2p::{core::ConnectedPoint, PeerId, Swarm};
|
||||
pub use libp2p::{multiaddr, Multiaddr};
|
||||
pub use metrics::scrape_discovery_metrics;
|
||||
|
@ -81,7 +81,7 @@ where
|
||||
TSpec: EthSpec,
|
||||
{
|
||||
/// The upgrade for inbound substreams.
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>>,
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>, ()>,
|
||||
|
||||
/// Errors occurring on outbound and inbound connections queued for reporting back.
|
||||
pending_errors: Vec<HandlerErr>,
|
||||
@ -225,7 +225,10 @@ impl<TSpec> RPCHandler<TSpec>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
{
|
||||
pub fn new(listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>>, log: &slog::Logger) -> Self {
|
||||
pub fn new(
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>, ()>,
|
||||
log: &slog::Logger,
|
||||
) -> Self {
|
||||
RPCHandler {
|
||||
listen_protocol,
|
||||
pending_errors: Vec::new(),
|
||||
@ -249,7 +252,7 @@ where
|
||||
///
|
||||
/// > **Note**: If you modify the protocol, modifications will only applies to future inbound
|
||||
/// > substreams, not the ones already being negotiated.
|
||||
pub fn listen_protocol_ref(&self) -> &SubstreamProtocol<RPCProtocol<TSpec>> {
|
||||
pub fn listen_protocol_ref(&self) -> &SubstreamProtocol<RPCProtocol<TSpec>, ()> {
|
||||
&self.listen_protocol
|
||||
}
|
||||
|
||||
@ -257,7 +260,7 @@ where
|
||||
///
|
||||
/// > **Note**: If you modify the protocol, modifications will only apply to future inbound
|
||||
/// > substreams, not the ones already being negotiated.
|
||||
pub fn listen_protocol_mut(&mut self) -> &mut SubstreamProtocol<RPCProtocol<TSpec>> {
|
||||
pub fn listen_protocol_mut(&mut self) -> &mut SubstreamProtocol<RPCProtocol<TSpec>, ()> {
|
||||
&mut self.listen_protocol
|
||||
}
|
||||
|
||||
@ -344,14 +347,16 @@ where
|
||||
type InboundProtocol = RPCProtocol<TSpec>;
|
||||
type OutboundProtocol = RPCRequest<TSpec>;
|
||||
type OutboundOpenInfo = (RequestId, RPCRequest<TSpec>); // Keep track of the id and the request
|
||||
type InboundOpenInfo = ();
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, ()> {
|
||||
self.listen_protocol.clone()
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
substream: <Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Output,
|
||||
_info: Self::InboundOpenInfo,
|
||||
) {
|
||||
// only accept new peer requests when active
|
||||
if !matches!(self.state, HandlerState::Active) {
|
||||
@ -863,8 +868,7 @@ where
|
||||
let (id, req) = self.dial_queue.remove(0);
|
||||
self.dial_queue.shrink_to_fit();
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: SubstreamProtocol::new(req.clone()),
|
||||
info: (id, req),
|
||||
protocol: SubstreamProtocol::new(req.clone(), ()).map_info(|()| (id, req)),
|
||||
});
|
||||
}
|
||||
Poll::Pending
|
||||
|
@ -169,9 +169,12 @@ where
|
||||
|
||||
fn new_handler(&mut self) -> Self::ProtocolsHandler {
|
||||
RPCHandler::new(
|
||||
SubstreamProtocol::new(RPCProtocol {
|
||||
phantom: PhantomData,
|
||||
}),
|
||||
SubstreamProtocol::new(
|
||||
RPCProtocol {
|
||||
phantom: PhantomData,
|
||||
},
|
||||
(),
|
||||
),
|
||||
&self.log,
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use libp2p::gossipsub::Topic;
|
||||
use libp2p::gossipsub::IdentTopic as Topic;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use types::SubnetId;
|
||||
|
||||
@ -139,7 +139,7 @@ impl GossipTopic {
|
||||
|
||||
impl Into<Topic> for GossipTopic {
|
||||
fn into(self) -> Topic {
|
||||
Topic::new(self.into())
|
||||
Topic::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use std::time::Duration;
|
||||
use types::{EnrForkId, MinimalEthSpec};
|
||||
|
||||
type E = MinimalEthSpec;
|
||||
use libp2p::gossipsub::GossipsubConfigBuilder;
|
||||
use tempdir::TempDir;
|
||||
|
||||
pub struct Libp2pInstance(LibP2PService<E>, exit_future::Signal);
|
||||
@ -83,8 +84,11 @@ pub fn build_config(port: u16, mut boot_nodes: Vec<Enr>) -> NetworkConfig {
|
||||
config.boot_nodes_enr.append(&mut boot_nodes);
|
||||
config.network_dir = path.into_path();
|
||||
// Reduce gossipsub heartbeat parameters
|
||||
config.gs_config.heartbeat_initial_delay = Duration::from_millis(500);
|
||||
config.gs_config.heartbeat_interval = Duration::from_millis(500);
|
||||
config.gs_config = GossipsubConfigBuilder::from(config.gs_config)
|
||||
.heartbeat_initial_delay(Duration::from_millis(500))
|
||||
.heartbeat_interval(Duration::from_millis(500))
|
||||
.build()
|
||||
.unwrap();
|
||||
config
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use beacon_chain::{
|
||||
attestation_verification::Error as AttnError, observed_operations::ObservationOutcome,
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, ForkChoiceError,
|
||||
};
|
||||
use eth2_libp2p::{MessageId, PeerId};
|
||||
use eth2_libp2p::{MessageAcceptance, MessageId, PeerId};
|
||||
use slog::{crit, debug, error, info, trace, warn, Logger};
|
||||
use ssz::Encode;
|
||||
use std::sync::Arc;
|
||||
@ -51,6 +51,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
Err(e) => {
|
||||
self.handle_attestation_verification_failure(
|
||||
peer_id,
|
||||
message_id,
|
||||
beacon_block_root,
|
||||
"unaggregated",
|
||||
e,
|
||||
@ -61,7 +62,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
|
||||
// Indicate to the `Network` service that this message is valid and can be
|
||||
// propagated on the gossip network.
|
||||
self.propagate_gossip_message(message_id, peer_id.clone());
|
||||
self.propagate_validation_result(message_id, peer_id.clone(), MessageAcceptance::Accept);
|
||||
|
||||
if !should_import {
|
||||
return;
|
||||
@ -124,8 +125,10 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
{
|
||||
Ok(aggregate) => aggregate,
|
||||
Err(e) => {
|
||||
// Report the failure to gossipsub
|
||||
self.handle_attestation_verification_failure(
|
||||
peer_id,
|
||||
message_id,
|
||||
beacon_block_root,
|
||||
"aggregated",
|
||||
e,
|
||||
@ -136,7 +139,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
|
||||
// Indicate to the `Network` service that this message is valid and can be
|
||||
// propagated on the gossip network.
|
||||
self.propagate_gossip_message(message_id, peer_id.clone());
|
||||
self.propagate_validation_result(message_id, peer_id.clone(), MessageAcceptance::Accept);
|
||||
|
||||
metrics::inc_counter(&metrics::BEACON_PROCESSOR_AGGREGATED_ATTESTATION_VERIFIED_TOTAL);
|
||||
|
||||
@ -195,26 +198,43 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"slot" => verified_block.block.slot(),
|
||||
"hash" => verified_block.block_root.to_string()
|
||||
);
|
||||
self.propagate_gossip_message(message_id, peer_id.clone());
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Accept,
|
||||
);
|
||||
verified_block
|
||||
}
|
||||
Err(BlockError::ParentUnknown(block)) => {
|
||||
self.send_sync_message(SyncMessage::UnknownBlock(peer_id, block));
|
||||
return;
|
||||
}
|
||||
Err(BlockError::BlockIsAlreadyKnown) => {
|
||||
debug!(
|
||||
self.log,
|
||||
"Gossip block is already known";
|
||||
);
|
||||
Err(e @ BlockError::FutureSlot { .. })
|
||||
| Err(e @ BlockError::WouldRevertFinalizedSlot { .. })
|
||||
| Err(e @ BlockError::BlockIsAlreadyKnown)
|
||||
| Err(e @ BlockError::RepeatProposal { .. })
|
||||
| Err(e @ BlockError::NotFinalizedDescendant { .. })
|
||||
| Err(e @ BlockError::BeaconChainError(_)) => {
|
||||
warn!(self.log, "Could not verify block for gossip, ignoring the block";
|
||||
"error" => e.to_string());
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(
|
||||
self.log,
|
||||
"Could not verify block for gossip";
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
Err(e @ BlockError::StateRootMismatch { .. })
|
||||
| Err(e @ BlockError::IncorrectBlockProposer { .. })
|
||||
| Err(e @ BlockError::BlockSlotLimitReached)
|
||||
| Err(e @ BlockError::ProposalSignatureInvalid)
|
||||
| Err(e @ BlockError::NonLinearSlots)
|
||||
| Err(e @ BlockError::UnknownValidator(_))
|
||||
| Err(e @ BlockError::PerBlockProcessingError(_))
|
||||
| Err(e @ BlockError::NonLinearParentRoots)
|
||||
| Err(e @ BlockError::BlockIsNotLaterThanParent { .. })
|
||||
| Err(e @ BlockError::InvalidSignature)
|
||||
| Err(e @ BlockError::TooManySkippedSlots { .. })
|
||||
| Err(e @ BlockError::GenesisBlock) => {
|
||||
warn!(self.log, "Could not verify block for gossip, rejecting the block";
|
||||
"error" => e.to_string());
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Reject);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -290,6 +310,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
let exit = match self.chain.verify_voluntary_exit_for_gossip(voluntary_exit) {
|
||||
Ok(ObservationOutcome::New(exit)) => exit,
|
||||
Ok(ObservationOutcome::AlreadyKnown) => {
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
debug!(
|
||||
self.log,
|
||||
"Dropping exit for already exiting validator";
|
||||
@ -306,13 +331,16 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
// These errors occur due to a fault in the beacon chain. It is not necessarily
|
||||
// the fault on the peer.
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
metrics::inc_counter(&metrics::BEACON_PROCESSOR_EXIT_VERIFIED_TOTAL);
|
||||
|
||||
self.propagate_gossip_message(message_id, peer_id);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Accept);
|
||||
|
||||
self.chain.import_voluntary_exit(exit);
|
||||
debug!(self.log, "Successfully imported voluntary exit");
|
||||
@ -341,9 +369,12 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"validator_index" => validator_index,
|
||||
"peer" => peer_id.to_string()
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
// This is likely a fault with the beacon chain and not necessarily a
|
||||
// malicious message from the peer.
|
||||
debug!(
|
||||
self.log,
|
||||
"Dropping invalid proposer slashing";
|
||||
@ -351,13 +382,14 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
metrics::inc_counter(&metrics::BEACON_PROCESSOR_PROPOSER_SLASHING_VERIFIED_TOTAL);
|
||||
|
||||
self.propagate_gossip_message(message_id, peer_id);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Accept);
|
||||
|
||||
self.chain.import_proposer_slashing(slashing);
|
||||
debug!(self.log, "Successfully imported proposer slashing");
|
||||
@ -383,6 +415,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"reason" => "Slashings already known for all slashed validators",
|
||||
"peer" => peer_id.to_string()
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
@ -392,13 +425,14 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
metrics::inc_counter(&metrics::BEACON_PROCESSOR_ATTESTER_SLASHING_VERIFIED_TOTAL);
|
||||
|
||||
self.propagate_gossip_message(message_id, peer_id);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Accept);
|
||||
|
||||
if let Err(e) = self.chain.import_attester_slashing(slashing) {
|
||||
debug!(self.log, "Error importing attester slashing"; "error" => format!("{:?}", e));
|
||||
@ -441,11 +475,19 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
/// the gossip network.
|
||||
///
|
||||
/// Creates a log if there is an interal error.
|
||||
fn propagate_gossip_message(&self, message_id: MessageId, peer_id: PeerId) {
|
||||
/// Propagates the result of the validation fot the given message to the network. If the result
|
||||
/// is valid the message gets forwarded to other peers.
|
||||
fn propagate_validation_result(
|
||||
&self,
|
||||
message_id: MessageId,
|
||||
propagation_source: PeerId,
|
||||
validation_result: MessageAcceptance,
|
||||
) {
|
||||
self.network_tx
|
||||
.send(NetworkMessage::Validate {
|
||||
propagation_source: peer_id,
|
||||
.send(NetworkMessage::ValidationResult {
|
||||
propagation_source,
|
||||
message_id,
|
||||
validation_result,
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
warn!(
|
||||
@ -469,6 +511,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
pub fn handle_attestation_verification_failure(
|
||||
&self,
|
||||
peer_id: PeerId,
|
||||
message_id: MessageId,
|
||||
beacon_block_root: Hash256,
|
||||
attestation_type: &str,
|
||||
error: AttnError,
|
||||
@ -485,6 +528,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message, _only_ if we trust our own clock.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::InvalidSelectionProof { .. } | AttnError::InvalidSignature => {
|
||||
/*
|
||||
@ -492,6 +540,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::EmptyAggregationBitfield => {
|
||||
/*
|
||||
@ -500,10 +553,12 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
* Whilst we don't gossip this attestation, this act is **not** a clear
|
||||
* violation of the spec nor indication of fault.
|
||||
*
|
||||
* This may change soon. Reference:
|
||||
*
|
||||
* https://github.com/ethereum/eth2.0-specs/pull/1732
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::AggregatorPubkeyUnknown(_) => {
|
||||
/*
|
||||
@ -519,6 +574,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::AggregatorNotInCommittee { .. } => {
|
||||
/*
|
||||
@ -534,6 +594,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::AttestationAlreadyKnown { .. } => {
|
||||
/*
|
||||
@ -549,6 +614,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"block" => format!("{}", beacon_block_root),
|
||||
"type" => format!("{:?}", attestation_type),
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
AttnError::AggregatorAlreadyKnown(_) => {
|
||||
@ -565,6 +631,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"block" => format!("{}", beacon_block_root),
|
||||
"type" => format!("{:?}", attestation_type),
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
AttnError::PriorAttestationKnown { .. } => {
|
||||
@ -580,6 +647,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"block" => format!("{}", beacon_block_root),
|
||||
"type" => format!("{:?}", attestation_type),
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
AttnError::ValidatorIndexTooHigh(_) => {
|
||||
@ -589,6 +657,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::UnknownHeadBlock { beacon_block_root } => {
|
||||
// Note: its a little bit unclear as to whether or not this block is unknown or
|
||||
@ -605,7 +678,10 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
);
|
||||
// we don't know the block, get the sync manager to handle the block lookup
|
||||
self.sync_tx
|
||||
.send(SyncMessage::UnknownBlockHash(peer_id, *beacon_block_root))
|
||||
.send(SyncMessage::UnknownBlockHash(
|
||||
peer_id.clone(),
|
||||
*beacon_block_root,
|
||||
))
|
||||
.unwrap_or_else(|_| {
|
||||
warn!(
|
||||
self.log,
|
||||
@ -613,6 +689,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"msg" => "UnknownBlockHash"
|
||||
)
|
||||
});
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
return;
|
||||
}
|
||||
AttnError::UnknownTargetRoot(_) => {
|
||||
@ -632,6 +709,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::BadTargetEpoch => {
|
||||
/*
|
||||
@ -640,6 +722,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::NoCommitteeForSlotAndIndex { .. } => {
|
||||
/*
|
||||
@ -647,6 +734,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::NotExactlyOneAggregationBitSet(_) => {
|
||||
/*
|
||||
@ -654,6 +746,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::AttestsToFutureBlock { .. } => {
|
||||
/*
|
||||
@ -661,6 +758,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
|
||||
AttnError::InvalidSubnetId { received, expected } => {
|
||||
@ -672,7 +774,12 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"Received attestation on incorrect subnet";
|
||||
"expected" => format!("{:?}", expected),
|
||||
"received" => format!("{:?}", received),
|
||||
)
|
||||
);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::Invalid(_) => {
|
||||
/*
|
||||
@ -680,6 +787,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message.
|
||||
*/
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::TooManySkippedSlots {
|
||||
head_block_slot,
|
||||
@ -695,7 +807,14 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"Rejected long skip slot attestation";
|
||||
"head_block_slot" => head_block_slot,
|
||||
"attestation_slot" => attestation_slot,
|
||||
)
|
||||
);
|
||||
// In this case we wish to penalize gossipsub peers that do this to avoid future
|
||||
// attestations that have too many skip slots.
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
AttnError::BeaconChainError(e) => {
|
||||
/*
|
||||
@ -711,6 +830,11 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer_id" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e),
|
||||
);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,6 @@ use types::{
|
||||
SignedAggregateAndProof, SignedBeaconBlock, SignedVoluntaryExit, Slot, SubnetId,
|
||||
};
|
||||
|
||||
//TODO: Rate limit requests
|
||||
|
||||
/// If a block is more than `FUTURE_SLOT_TOLERANCE` slots ahead of our slot clock, we drop it.
|
||||
/// Otherwise we queue it.
|
||||
pub(crate) const FUTURE_SLOT_TOLERANCE: u64 = 1;
|
||||
|
@ -6,12 +6,12 @@ use crate::{
|
||||
};
|
||||
use crate::{error, metrics};
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use eth2_libp2p::Service as LibP2PService;
|
||||
use eth2_libp2p::{
|
||||
rpc::{GoodbyeReason, RPCResponseErrorCode, RequestId},
|
||||
Libp2pEvent, PeerAction, PeerRequestId, PubsubMessage, Request, Response,
|
||||
};
|
||||
use eth2_libp2p::{BehaviourEvent, MessageId, NetworkGlobals, PeerId};
|
||||
use eth2_libp2p::{MessageAcceptance, Service as LibP2PService};
|
||||
use futures::prelude::*;
|
||||
use rest_types::ValidatorSubscription;
|
||||
use slog::{debug, error, info, o, trace, warn};
|
||||
@ -55,11 +55,13 @@ pub enum NetworkMessage<T: EthSpec> {
|
||||
/// Publish a list of messages to the gossipsub protocol.
|
||||
Publish { messages: Vec<PubsubMessage<T>> },
|
||||
/// Validates a received gossipsub message. This will propagate the message on the network.
|
||||
Validate {
|
||||
ValidationResult {
|
||||
/// The peer that sent us the message. We don't send back to this peer.
|
||||
propagation_source: PeerId,
|
||||
/// The id of the message we are validating and propagating.
|
||||
message_id: MessageId,
|
||||
/// The result of the validation
|
||||
validation_result: MessageAcceptance,
|
||||
},
|
||||
/// Reports a peer to the peer manager for performing an action.
|
||||
ReportPeer { peer_id: PeerId, action: PeerAction },
|
||||
@ -216,9 +218,10 @@ fn spawn_service<T: BeaconChainTypes>(
|
||||
NetworkMessage::SendError{ peer_id, error, id, reason } => {
|
||||
service.libp2p.respond_with_error(peer_id, id, error, reason);
|
||||
}
|
||||
NetworkMessage::Validate {
|
||||
NetworkMessage::ValidationResult {
|
||||
propagation_source,
|
||||
message_id,
|
||||
validation_result,
|
||||
} => {
|
||||
trace!(service.log, "Propagating gossipsub message";
|
||||
"propagation_peer" => format!("{:?}", propagation_source),
|
||||
@ -227,7 +230,9 @@ fn spawn_service<T: BeaconChainTypes>(
|
||||
service
|
||||
.libp2p
|
||||
.swarm
|
||||
.validate_message(&propagation_source, message_id);
|
||||
.report_message_validation_result(
|
||||
&propagation_source, message_id, validation_result
|
||||
);
|
||||
}
|
||||
NetworkMessage::Publish { messages } => {
|
||||
let mut topic_kinds = Vec::new();
|
||||
|
@ -172,7 +172,7 @@ impl<T: BeaconChainTypes> RangeSync<T> {
|
||||
} else {
|
||||
// there is no finalized chain that matches this peer's last finalized target
|
||||
// create a new finalized chain
|
||||
debug!(self.log, "New finalized chain added to sync"; "peer_id" => format!("{:?}", peer_id), "start_epoch" => local_finalized_slot, "end_slot" => remote_finalized_slot, "finalized_root" => format!("{}", remote_info.finalized_root));
|
||||
debug!(self.log, "New finalized chain added to sync"; "peer_id" => format!("{:?}", peer_id), "start_slot" => local_finalized_slot, "end_slot" => remote_finalized_slot, "finalized_root" => format!("{}", remote_info.finalized_root));
|
||||
|
||||
self.chains.new_finalized_chain(
|
||||
local_info.finalized_epoch,
|
||||
|
Loading…
Reference in New Issue
Block a user