upgrade libp2p to 0.50.0 (#12734)

* upgrade libp2p to 0.50.0

* on_swarm_event and on_connection_handler_event

* replace `Swarm::new` with `Swarm::with_threadpool_executor`

* on_swarm_event and on_connection_handler_event part 2

* on_swarm_event and on_connection_handler_event part 3

* on_swarm_event and on_connection_handler_event part 4

* update libp2p

* libp2p 0.50.0

* rename OutboundQueryCompleted to OutboundQueryProgressed

refs https://github.com/libp2p/rust-libp2p/pull/2712

* remove unused var

* accumulate outbound_query_records until query is finished

* format code

* use p_handler instead of new_handler

https://github.com/paritytech/substrate/pull/12734#discussion_r1027640610

* pass ListenFailure to kademlia

https://github.com/paritytech/substrate/pull/12734#discussion_r1034716664

* use tokio executor in tests

https://github.com/paritytech/substrate/pull/12734#discussion_r1039291776

* use chrono Local::now

instead of deprecated Local::today

* remove unused vars from request_responses tests

* attempt to fix pallet UI tests

* restart CI

* restart CI

* restart CI

* restart CI

* restart CI

* restart CI

* restart CI

* restart CI
This commit is contained in:
Anton
2023-01-05 16:03:41 +04:00
committed by GitHub
parent 428a42752a
commit f2dcd9520c
31 changed files with 3010 additions and 2042 deletions
+2061 -1000
View File
File diff suppressed because it is too large Load Diff
@@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features =
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.1" futures-timer = "3.0.1"
ip_network = "0.4.1" ip_network = "0.4.1"
libp2p = { version = "0.49.0", default-features = false, features = ["kad"] } libp2p = { version = "0.50.0", features = ["kad"] }
log = "0.4.17" log = "0.4.17"
prost = "0.11" prost = "0.11"
rand = "0.8.5" rand = "0.8.5"
+1 -1
View File
@@ -18,7 +18,7 @@ chrono = "0.4.10"
clap = { version = "4.0.9", features = ["derive", "string"] } clap = { version = "4.0.9", features = ["derive", "string"] }
fdlimit = "0.2.1" fdlimit = "0.2.1"
futures = "0.3.21" futures = "0.3.21"
libp2p = "0.49.0" libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
names = { version = "0.13.0", default-features = false } names = { version = "0.13.0", default-features = false }
parity-scale-codec = "3.0.0" parity-scale-codec = "3.0.0"
+1 -1
View File
@@ -228,7 +228,7 @@ impl<C: SubstrateCli> Runner<C> {
pub fn print_node_infos<C: SubstrateCli>(config: &Configuration) { pub fn print_node_infos<C: SubstrateCli>(config: &Configuration) {
info!("{}", C::impl_name()); info!("{}", C::impl_name());
info!("✌️ version {}", C::impl_version()); info!("✌️ version {}", C::impl_version());
info!("❤️ by {}, {}-{}", C::author(), C::copyright_start_year(), Local::today().year()); info!("❤️ by {}, {}-{}", C::author(), C::copyright_start_year(), Local::now().year());
info!("📋 Chain specification: {}", config.chain_spec.name()); info!("📋 Chain specification: {}", config.chain_spec.name());
info!("🏷 Node name: {}", config.network.node_name); info!("🏷 Node name: {}", config.network.node_name);
info!("👤 Role: {}", config.display_role()); info!("👤 Role: {}", config.display_role());
+1 -1
View File
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
async-trait = "0.1.57" async-trait = "0.1.57"
futures = { version = "0.3.21", features = ["thread-pool"] } futures = { version = "0.3.21", features = ["thread-pool"] }
futures-timer = "3.0.1" futures-timer = "3.0.1"
libp2p = { version = "0.49.0", default-features = false } libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
mockall = "0.11.2" mockall = "0.11.2"
parking_lot = "0.12.1" parking_lot = "0.12.1"
+1 -1
View File
@@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
ahash = "0.7.6" ahash = "0.7.6"
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.1" futures-timer = "3.0.1"
libp2p = { version = "0.49.0", default-features = false } libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
lru = "0.8.1" lru = "0.8.1"
tracing = "0.1.29" tracing = "0.1.29"
+1 -1
View File
@@ -25,7 +25,7 @@ fnv = "1.0.6"
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.2" futures-timer = "3.0.2"
ip_network = "0.4.1" ip_network = "0.4.1"
libp2p = { version = "0.49.0", features = ["dns", "identify", "kad", "mdns", "mplex", "noise", "ping", "tcp", "tokio", "yamux", "websocket"] } libp2p = { version = "0.50.0", features = ["dns", "identify", "kad", "macros", "mdns", "mplex", "noise", "ping", "tcp", "tokio", "yamux", "websocket"] }
log = "0.4.17" log = "0.4.17"
lru = "0.8.1" lru = "0.8.1"
parking_lot = "0.12.1" parking_lot = "0.12.1"
+1 -1
View File
@@ -18,7 +18,7 @@ prost-build = "0.11"
[dependencies] [dependencies]
cid = "0.8.6" cid = "0.8.6"
futures = "0.3.21" futures = "0.3.21"
libp2p = "0.49.0" libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
prost = "0.11" prost = "0.11"
thiserror = "1.0" thiserror = "1.0"
+1 -1
View File
@@ -24,7 +24,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", features = [
] } ] }
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.2" futures-timer = "3.0.2"
libp2p = { version = "0.49.0", features = [ "request-response", "kad" ] } libp2p = { version = "0.50.0", features = ["request-response", "kad"] }
linked_hash_set = "0.1.3" linked_hash_set = "0.1.3"
prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../../utils/prometheus" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../../utils/prometheus" }
smallvec = "1.8.0" smallvec = "1.8.0"
+1 -1
View File
@@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", features = [
"derive", "derive",
] } ] }
futures = "0.3.21" futures = "0.3.21"
libp2p = "0.49.0" libp2p = "0.50.0"
log = "0.4.16" log = "0.4.16"
prost = "0.11" prost = "0.11"
sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain" } sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain" }
+1 -1
View File
@@ -29,7 +29,7 @@ use libp2p::{
core::{Multiaddr, PeerId, PublicKey}, core::{Multiaddr, PeerId, PublicKey},
identify::Info as IdentifyInfo, identify::Info as IdentifyInfo,
kad::record, kad::record,
NetworkBehaviour, swarm::NetworkBehaviour,
}; };
use sc_network_common::{ use sc_network_common::{
+130 -146
View File
@@ -51,23 +51,23 @@ use futures::prelude::*;
use futures_timer::Delay; use futures_timer::Delay;
use ip_network::IpNetwork; use ip_network::IpNetwork;
use libp2p::{ use libp2p::{
core::{ core::{connection::ConnectionId, Multiaddr, PeerId, PublicKey},
connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId,
PublicKey,
},
kad::{ kad::{
handler::KademliaHandlerProto, handler::KademliaHandlerProto,
record::{ record::{
self, self,
store::{MemoryStore, RecordStore}, store::{MemoryStore, RecordStore},
}, },
GetClosestPeersError, Kademlia, KademliaBucketInserts, KademliaConfig, KademliaEvent, GetClosestPeersError, GetRecordOk, Kademlia, KademliaBucketInserts, KademliaConfig,
QueryId, QueryResult, Quorum, Record, KademliaEvent, QueryId, QueryResult, Quorum, Record,
}, },
mdns::{MdnsConfig, MdnsEvent, TokioMdns}, mdns::{self, tokio::Behaviour as TokioMdns},
multiaddr::Protocol, multiaddr::Protocol,
swarm::{ swarm::{
behaviour::toggle::{Toggle, ToggleIntoConnectionHandler}, behaviour::{
toggle::{Toggle, ToggleIntoConnectionHandler},
DialFailure, FromSwarm, NewExternalAddr,
},
ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour, ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour,
NetworkBehaviourAction, PollParameters, NetworkBehaviourAction, PollParameters,
}, },
@@ -78,7 +78,6 @@ use sp_core::hexdisplay::HexDisplay;
use std::{ use std::{
cmp, cmp,
collections::{HashMap, HashSet, VecDeque}, collections::{HashMap, HashSet, VecDeque},
io,
num::NonZeroUsize, num::NonZeroUsize,
task::{Context, Poll}, task::{Context, Poll},
time::Duration, time::Duration,
@@ -235,7 +234,7 @@ impl DiscoveryConfig {
allow_private_ipv4, allow_private_ipv4,
discovery_only_if_under_num, discovery_only_if_under_num,
mdns: if enable_mdns { mdns: if enable_mdns {
match TokioMdns::new(MdnsConfig::default()) { match TokioMdns::new(mdns::Config::default()) {
Ok(mdns) => Some(mdns), Ok(mdns) => Some(mdns),
Err(err) => { Err(err) => {
warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err); warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err);
@@ -250,6 +249,7 @@ impl DiscoveryConfig {
NonZeroUsize::new(MAX_KNOWN_EXTERNAL_ADDRESSES) NonZeroUsize::new(MAX_KNOWN_EXTERNAL_ADDRESSES)
.expect("value is a constant; constant is non-zero; qed."), .expect("value is a constant; constant is non-zero; qed."),
), ),
outbound_query_records: Vec::new(),
} }
} }
} }
@@ -287,6 +287,8 @@ pub struct DiscoveryBehaviour {
allow_non_globals_in_dht: bool, allow_non_globals_in_dht: bool,
/// A cache of discovered external addresses. Only used for logging purposes. /// A cache of discovered external addresses. Only used for logging purposes.
known_external_addresses: LruHashSet<Multiaddr>, known_external_addresses: LruHashSet<Multiaddr>,
/// A cache of outbound query records.
outbound_query_records: Vec<(record::Key, Vec<u8>)>,
} }
impl DiscoveryBehaviour { impl DiscoveryBehaviour {
@@ -367,7 +369,7 @@ impl DiscoveryBehaviour {
/// A corresponding `ValueFound` or `ValueNotFound` event will later be generated. /// A corresponding `ValueFound` or `ValueNotFound` event will later be generated.
pub fn get_value(&mut self, key: record::Key) { pub fn get_value(&mut self, key: record::Key) {
if let Some(k) = self.kademlia.as_mut() { if let Some(k) = self.kademlia.as_mut() {
k.get_record(key.clone(), Quorum::One); k.get_record(key.clone());
} }
} }
@@ -516,127 +518,84 @@ impl NetworkBehaviour for DiscoveryBehaviour {
list list
} }
fn inject_address_change( fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
&mut self, match event {
peer_id: &PeerId, FromSwarm::ConnectionEstablished(e) => {
connection_id: &ConnectionId, self.num_connections += 1;
old: &ConnectedPoint, self.kademlia.on_swarm_event(FromSwarm::ConnectionEstablished(e));
new: &ConnectedPoint, },
) { FromSwarm::ConnectionClosed(e) => {
self.kademlia.inject_address_change(peer_id, connection_id, old, new) self.num_connections -= 1;
} self.kademlia.on_swarm_event(FromSwarm::ConnectionClosed(e));
},
fn inject_connection_established( FromSwarm::DialFailure(e @ DialFailure { peer_id, error, .. }) => {
&mut self, if let Some(peer_id) = peer_id {
peer_id: &PeerId, if let DialError::Transport(errors) = error {
conn: &ConnectionId, if let Some(list) = self.ephemeral_addresses.get_mut(&peer_id) {
endpoint: &ConnectedPoint, for (addr, _error) in errors {
failed_addresses: Option<&Vec<Multiaddr>>, list.retain(|a| a != addr);
other_established: usize, }
) { }
self.num_connections += 1;
self.kademlia.inject_connection_established(
peer_id,
conn,
endpoint,
failed_addresses,
other_established,
)
}
fn inject_connection_closed(
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
remaining_established: usize,
) {
self.num_connections -= 1;
self.kademlia.inject_connection_closed(
peer_id,
conn,
endpoint,
handler,
remaining_established,
)
}
fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
handler: Self::ConnectionHandler,
error: &DialError,
) {
if let Some(peer_id) = peer_id {
if let DialError::Transport(errors) = error {
if let Some(list) = self.ephemeral_addresses.get_mut(&peer_id) {
for (addr, _error) in errors {
list.retain(|a| a != addr);
} }
} }
}
}
self.kademlia.inject_dial_failure(peer_id, handler, error) self.kademlia.on_swarm_event(FromSwarm::DialFailure(e));
},
FromSwarm::ListenerClosed(e) => {
self.kademlia.on_swarm_event(FromSwarm::ListenerClosed(e));
},
FromSwarm::ListenFailure(e) => {
self.kademlia.on_swarm_event(FromSwarm::ListenFailure(e));
},
FromSwarm::ListenerError(e) => {
self.kademlia.on_swarm_event(FromSwarm::ListenerError(e));
},
FromSwarm::ExpiredExternalAddr(e) => {
// We intentionally don't remove the element from `known_external_addresses` in
// order to not print the log line again.
self.kademlia.on_swarm_event(FromSwarm::ExpiredExternalAddr(e));
},
FromSwarm::NewListener(e) => {
self.kademlia.on_swarm_event(FromSwarm::NewListener(e));
},
FromSwarm::ExpiredListenAddr(e) => {
self.kademlia.on_swarm_event(FromSwarm::ExpiredListenAddr(e));
},
FromSwarm::NewExternalAddr(e @ NewExternalAddr { addr }) => {
let new_addr = addr.clone().with(Protocol::P2p(self.local_peer_id.into()));
if Self::can_add_to_dht(addr) {
// NOTE: we might re-discover the same address multiple times
// in which case we just want to refrain from logging.
if self.known_external_addresses.insert(new_addr.clone()) {
info!(
target: "sub-libp2p",
"🔍 Discovered new external address for our node: {}",
new_addr,
);
}
}
self.kademlia.on_swarm_event(FromSwarm::NewExternalAddr(e));
},
FromSwarm::AddressChange(e) => {
self.kademlia.on_swarm_event(FromSwarm::AddressChange(e));
},
FromSwarm::NewListenAddr(e) => {
self.kademlia.on_swarm_event(FromSwarm::NewListenAddr(e));
},
}
} }
fn inject_event( fn on_connection_handler_event(
&mut self, &mut self,
peer_id: PeerId, peer_id: PeerId,
connection: ConnectionId, connection_id: ConnectionId,
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent, event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
) { ) {
self.kademlia.inject_event(peer_id, connection, event) self.kademlia.on_connection_handler_event(peer_id, connection_id, event);
}
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
let new_addr = addr.clone().with(Protocol::P2p(self.local_peer_id.into()));
if Self::can_add_to_dht(addr) {
// NOTE: we might re-discover the same address multiple times
// in which case we just want to refrain from logging.
if self.known_external_addresses.insert(new_addr.clone()) {
info!(
target: "sub-libp2p",
"🔍 Discovered new external address for our node: {}",
new_addr,
);
}
}
self.kademlia.inject_new_external_addr(addr)
}
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
// We intentionally don't remove the element from `known_external_addresses` in order
// to not print the log line again.
self.kademlia.inject_expired_external_addr(addr)
}
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.kademlia.inject_expired_listen_addr(id, addr)
}
fn inject_new_listener(&mut self, id: ListenerId) {
self.kademlia.inject_new_listener(id)
}
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.kademlia.inject_new_listen_addr(id, addr)
}
fn inject_listen_failure(&mut self, _: &Multiaddr, _: &Multiaddr, _: Self::ConnectionHandler) {
// NetworkBehaviour::inject_listen_failure on Kademlia<MemoryStore> does nothing.
}
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
self.kademlia.inject_listener_error(id, err)
}
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
self.kademlia.inject_listener_closed(id, reason)
} }
fn poll( fn poll(
@@ -705,7 +664,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
KademliaEvent::InboundRequest { .. } => { KademliaEvent::InboundRequest { .. } => {
// We are not interested in this event at the moment. // We are not interested in this event at the moment.
}, },
KademliaEvent::OutboundQueryCompleted { KademliaEvent::OutboundQueryProgressed {
result: QueryResult::GetClosestPeers(res), result: QueryResult::GetClosestPeers(res),
.. ..
} => match res { } => match res {
@@ -730,24 +689,36 @@ impl NetworkBehaviour for DiscoveryBehaviour {
} }
}, },
}, },
KademliaEvent::OutboundQueryCompleted { KademliaEvent::OutboundQueryProgressed {
result: QueryResult::GetRecord(res), result: QueryResult::GetRecord(res),
stats, stats,
step,
.. ..
} => { } => {
let ev = match res { let ev = match res {
Ok(ok) => { Ok(ok) =>
let results = ok if let GetRecordOk::FoundRecord(r) = ok {
.records self.outbound_query_records
.into_iter() .push((r.record.key, r.record.value));
.map(|r| (r.record.key, r.record.value)) continue
.collect(); } else {
debug!(
DiscoveryOut::ValueFound( target: "sub-libp2p",
results, "Libp2p => Query progressed to {:?} step (last: {:?})",
stats.duration().unwrap_or_default(), step.count,
) step.last,
}, );
if step.last {
let records =
self.outbound_query_records.drain(..).collect();
DiscoveryOut::ValueFound(
records,
stats.duration().unwrap_or_default(),
)
} else {
continue
}
},
Err(e @ libp2p::kad::GetRecordError::NotFound { .. }) => { Err(e @ libp2p::kad::GetRecordError::NotFound { .. }) => {
trace!( trace!(
target: "sub-libp2p", target: "sub-libp2p",
@@ -773,7 +744,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
}; };
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)) return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev))
}, },
KademliaEvent::OutboundQueryCompleted { KademliaEvent::OutboundQueryProgressed {
result: QueryResult::PutRecord(res), result: QueryResult::PutRecord(res),
stats, stats,
.. ..
@@ -795,7 +766,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
}; };
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)) return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev))
}, },
KademliaEvent::OutboundQueryCompleted { KademliaEvent::OutboundQueryProgressed {
result: QueryResult::RepublishRecord(res), result: QueryResult::RepublishRecord(res),
.. ..
} => match res { } => match res {
@@ -811,7 +782,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
), ),
}, },
// We never start any other type of query. // We never start any other type of query.
KademliaEvent::OutboundQueryCompleted { result: e, .. } => { KademliaEvent::OutboundQueryProgressed { result: e, .. } => {
warn!(target: "sub-libp2p", "Libp2p => Unhandled Kademlia event: {:?}", e) warn!(target: "sub-libp2p", "Libp2p => Unhandled Kademlia event: {:?}", e)
}, },
}, },
@@ -841,7 +812,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
while let Poll::Ready(ev) = mdns.poll(cx, params) { while let Poll::Ready(ev) = mdns.poll(cx, params) {
match ev { match ev {
NetworkBehaviourAction::GenerateEvent(event) => match event { NetworkBehaviourAction::GenerateEvent(event) => match event {
MdnsEvent::Discovered(list) => { mdns::Event::Discovered(list) => {
if self.num_connections >= self.discovery_only_if_under_num { if self.num_connections >= self.discovery_only_if_under_num {
continue continue
} }
@@ -852,7 +823,7 @@ impl NetworkBehaviour for DiscoveryBehaviour {
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)) return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev))
} }
}, },
MdnsEvent::Expired(_) => {}, mdns::Event::Expired(_) => {},
}, },
NetworkBehaviourAction::Dial { .. } => { NetworkBehaviourAction::Dial { .. } => {
unreachable!("mDNS never dials!"); unreachable!("mDNS never dials!");
@@ -907,12 +878,19 @@ mod tests {
}, },
identity::{ed25519, Keypair}, identity::{ed25519, Keypair},
noise, noise,
swarm::{Swarm, SwarmEvent}, swarm::{Executor, Swarm, SwarmEvent},
yamux, Multiaddr, yamux, Multiaddr,
}; };
use sc_network_common::config::ProtocolId; use sc_network_common::config::ProtocolId;
use sp_core::hash::H256; use sp_core::hash::H256;
use std::{collections::HashSet, task::Poll}; use std::{collections::HashSet, pin::Pin, task::Poll};
struct TokioExecutor(tokio::runtime::Runtime);
impl Executor for TokioExecutor {
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
let _ = self.0.spawn(f);
}
}
#[test] #[test]
fn discovery_working() { fn discovery_working() {
@@ -949,7 +927,13 @@ mod tests {
config.finish() config.finish()
}; };
let mut swarm = Swarm::new(transport, behaviour, keypair.public().to_peer_id()); let runtime = tokio::runtime::Runtime::new().unwrap();
let mut swarm = Swarm::with_executor(
transport,
behaviour,
keypair.public().to_peer_id(),
TokioExecutor(runtime),
);
let listen_addr: Multiaddr = let listen_addr: Multiaddr =
format!("/memory/{}", rand::random::<u64>()).parse().unwrap(); format!("/memory/{}", rand::random::<u64>()).parse().unwrap();
+137 -158
View File
@@ -19,16 +19,17 @@
use fnv::FnvHashMap; use fnv::FnvHashMap;
use futures::prelude::*; use futures::prelude::*;
use libp2p::{ use libp2p::{
core::{ core::{connection::ConnectionId, either::EitherOutput, ConnectedPoint, PeerId, PublicKey},
connection::ConnectionId, either::EitherOutput, transport::ListenerId, ConnectedPoint,
PeerId, PublicKey,
},
identify::{ identify::{
Behaviour as Identify, Config as IdentifyConfig, Event as IdentifyEvent, Behaviour as Identify, Config as IdentifyConfig, Event as IdentifyEvent,
Info as IdentifyInfo, Info as IdentifyInfo,
}, },
ping::{Behaviour as Ping, Config as PingConfig, Event as PingEvent, Success as PingSuccess}, ping::{Behaviour as Ping, Config as PingConfig, Event as PingEvent, Success as PingSuccess},
swarm::{ swarm::{
behaviour::{
AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm,
ListenFailure,
},
ConnectionHandler, IntoConnectionHandler, IntoConnectionHandlerSelect, NetworkBehaviour, ConnectionHandler, IntoConnectionHandler, IntoConnectionHandlerSelect, NetworkBehaviour,
NetworkBehaviourAction, PollParameters, NetworkBehaviourAction, PollParameters,
}, },
@@ -39,7 +40,6 @@ use sc_network_common::utils::interval;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
collections::hash_map::Entry, collections::hash_map::Entry,
error, io,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
time::{Duration, Instant}, time::{Duration, Instant},
@@ -188,172 +188,151 @@ impl NetworkBehaviour for PeerInfoBehaviour {
list list
} }
fn inject_address_change( fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
&mut self, match event {
peer_id: &PeerId, FromSwarm::ConnectionEstablished(
conn: &ConnectionId, e @ ConnectionEstablished { peer_id, endpoint, .. },
old: &ConnectedPoint, ) => {
new: &ConnectedPoint, self.ping.on_swarm_event(FromSwarm::ConnectionEstablished(e));
) { self.identify.on_swarm_event(FromSwarm::ConnectionEstablished(e));
self.ping.inject_address_change(peer_id, conn, old, new);
self.identify.inject_address_change(peer_id, conn, old, new);
if let Some(entry) = self.nodes_info.get_mut(peer_id) { match self.nodes_info.entry(peer_id) {
if let Some(endpoint) = entry.endpoints.iter_mut().find(|e| e == &old) { Entry::Vacant(e) => {
*endpoint = new.clone(); e.insert(NodeInfo::new(endpoint.clone()));
} else { },
error!(target: "sub-libp2p", Entry::Occupied(e) => {
"Unknown address change for peer {:?} from {:?} to {:?}", peer_id, old, new); let e = e.into_mut();
} if e.info_expire.as_ref().map(|exp| *exp < Instant::now()).unwrap_or(false)
} else { {
error!(target: "sub-libp2p", e.client_version = None;
"Unknown peer {:?} to change address from {:?} to {:?}", peer_id, old, new); e.latest_ping = None;
} }
} e.info_expire = None;
e.endpoints.push(endpoint.clone());
fn inject_connection_established( },
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
failed_addresses: Option<&Vec<Multiaddr>>,
other_established: usize,
) {
self.ping.inject_connection_established(
peer_id,
conn,
endpoint,
failed_addresses,
other_established,
);
self.identify.inject_connection_established(
peer_id,
conn,
endpoint,
failed_addresses,
other_established,
);
match self.nodes_info.entry(*peer_id) {
Entry::Vacant(e) => {
e.insert(NodeInfo::new(endpoint.clone()));
},
Entry::Occupied(e) => {
let e = e.into_mut();
if e.info_expire.as_ref().map(|exp| *exp < Instant::now()).unwrap_or(false) {
e.client_version = None;
e.latest_ping = None;
} }
e.info_expire = None; },
e.endpoints.push(endpoint.clone()); FromSwarm::ConnectionClosed(ConnectionClosed {
peer_id,
connection_id,
endpoint,
handler,
remaining_established,
}) => {
let (ping_handler, identity_handler) = handler.into_inner();
self.ping.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
peer_id,
connection_id,
endpoint,
handler: ping_handler,
remaining_established,
}));
self.identify.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
peer_id,
connection_id,
endpoint,
handler: identity_handler,
remaining_established,
}));
if let Some(entry) = self.nodes_info.get_mut(&peer_id) {
if remaining_established == 0 {
entry.info_expire = Some(Instant::now() + CACHE_EXPIRE);
}
entry.endpoints.retain(|ep| ep != endpoint)
} else {
error!(target: "sub-libp2p",
"Unknown connection to {:?} closed: {:?}", peer_id, endpoint);
}
},
FromSwarm::DialFailure(DialFailure { peer_id, handler, error }) => {
let (ping_handler, identity_handler) = handler.into_inner();
self.ping.on_swarm_event(FromSwarm::DialFailure(DialFailure {
peer_id,
handler: ping_handler,
error,
}));
self.identify.on_swarm_event(FromSwarm::DialFailure(DialFailure {
peer_id,
handler: identity_handler,
error,
}));
},
FromSwarm::ListenerClosed(e) => {
self.ping.on_swarm_event(FromSwarm::ListenerClosed(e));
self.identify.on_swarm_event(FromSwarm::ListenerClosed(e));
},
FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, handler }) => {
let (ping_handler, identity_handler) = handler.into_inner();
self.ping.on_swarm_event(FromSwarm::ListenFailure(ListenFailure {
local_addr,
send_back_addr,
handler: ping_handler,
}));
self.identify.on_swarm_event(FromSwarm::ListenFailure(ListenFailure {
local_addr,
send_back_addr,
handler: identity_handler,
}));
},
FromSwarm::ListenerError(e) => {
self.ping.on_swarm_event(FromSwarm::ListenerError(e));
self.identify.on_swarm_event(FromSwarm::ListenerError(e));
},
FromSwarm::ExpiredExternalAddr(e) => {
self.ping.on_swarm_event(FromSwarm::ExpiredExternalAddr(e));
self.identify.on_swarm_event(FromSwarm::ExpiredExternalAddr(e));
},
FromSwarm::NewListener(e) => {
self.ping.on_swarm_event(FromSwarm::NewListener(e));
self.identify.on_swarm_event(FromSwarm::NewListener(e));
},
FromSwarm::ExpiredListenAddr(e) => {
self.ping.on_swarm_event(FromSwarm::ExpiredListenAddr(e));
self.identify.on_swarm_event(FromSwarm::ExpiredListenAddr(e));
},
FromSwarm::NewExternalAddr(e) => {
self.ping.on_swarm_event(FromSwarm::NewExternalAddr(e));
self.identify.on_swarm_event(FromSwarm::NewExternalAddr(e));
},
FromSwarm::AddressChange(e @ AddressChange { peer_id, old, new, .. }) => {
self.ping.on_swarm_event(FromSwarm::AddressChange(e));
self.identify.on_swarm_event(FromSwarm::AddressChange(e));
if let Some(entry) = self.nodes_info.get_mut(&peer_id) {
if let Some(endpoint) = entry.endpoints.iter_mut().find(|e| e == &old) {
*endpoint = new.clone();
} else {
error!(target: "sub-libp2p",
"Unknown address change for peer {:?} from {:?} to {:?}", peer_id, old, new);
}
} else {
error!(target: "sub-libp2p",
"Unknown peer {:?} to change address from {:?} to {:?}", peer_id, old, new);
}
},
FromSwarm::NewListenAddr(e) => {
self.ping.on_swarm_event(FromSwarm::NewListenAddr(e));
self.identify.on_swarm_event(FromSwarm::NewListenAddr(e));
}, },
} }
} }
fn inject_connection_closed( fn on_connection_handler_event(
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
remaining_established: usize,
) {
let (ping_handler, identity_handler) = handler.into_inner();
self.identify.inject_connection_closed(
peer_id,
conn,
endpoint,
identity_handler,
remaining_established,
);
self.ping.inject_connection_closed(
peer_id,
conn,
endpoint,
ping_handler,
remaining_established,
);
if let Some(entry) = self.nodes_info.get_mut(peer_id) {
if remaining_established == 0 {
entry.info_expire = Some(Instant::now() + CACHE_EXPIRE);
}
entry.endpoints.retain(|ep| ep != endpoint)
} else {
error!(target: "sub-libp2p",
"Unknown connection to {:?} closed: {:?}", peer_id, endpoint);
}
}
fn inject_event(
&mut self, &mut self,
peer_id: PeerId, peer_id: PeerId,
connection: ConnectionId, connection_id: ConnectionId,
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent, event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
) { ) {
match event { match event {
EitherOutput::First(event) => self.ping.inject_event(peer_id, connection, event), EitherOutput::First(event) =>
EitherOutput::Second(event) => self.identify.inject_event(peer_id, connection, event), self.ping.on_connection_handler_event(peer_id, connection_id, event),
EitherOutput::Second(event) =>
self.identify.on_connection_handler_event(peer_id, connection_id, event),
} }
} }
fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
handler: Self::ConnectionHandler,
error: &libp2p::swarm::DialError,
) {
let (ping_handler, identity_handler) = handler.into_inner();
self.identify.inject_dial_failure(peer_id, identity_handler, error);
self.ping.inject_dial_failure(peer_id, ping_handler, error);
}
fn inject_new_listener(&mut self, id: ListenerId) {
self.ping.inject_new_listener(id);
self.identify.inject_new_listener(id);
}
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.ping.inject_new_listen_addr(id, addr);
self.identify.inject_new_listen_addr(id, addr);
}
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.ping.inject_expired_listen_addr(id, addr);
self.identify.inject_expired_listen_addr(id, addr);
}
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
self.ping.inject_new_external_addr(addr);
self.identify.inject_new_external_addr(addr);
}
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
self.ping.inject_expired_external_addr(addr);
self.identify.inject_expired_external_addr(addr);
}
fn inject_listen_failure(
&mut self,
local_addr: &Multiaddr,
send_back_addr: &Multiaddr,
handler: Self::ConnectionHandler,
) {
let (ping_handler, identity_handler) = handler.into_inner();
self.identify
.inject_listen_failure(local_addr, send_back_addr, identity_handler);
self.ping.inject_listen_failure(local_addr, send_back_addr, ping_handler);
}
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn error::Error + 'static)) {
self.ping.inject_listener_error(id, err);
self.identify.inject_listener_error(id, err);
}
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
self.ping.inject_listener_closed(id, reason);
self.identify.inject_listener_closed(id, reason);
}
fn poll( fn poll(
&mut self, &mut self,
cx: &mut Context, cx: &mut Context,
+11 -77
View File
@@ -22,10 +22,10 @@ use bytes::Bytes;
use codec::{Decode, DecodeAll, Encode}; use codec::{Decode, DecodeAll, Encode};
use futures::prelude::*; use futures::prelude::*;
use libp2p::{ use libp2p::{
core::{connection::ConnectionId, transport::ListenerId, ConnectedPoint}, core::connection::ConnectionId,
swarm::{ swarm::{
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, behaviour::FromSwarm, ConnectionHandler, IntoConnectionHandler, NetworkBehaviour,
PollParameters, NetworkBehaviourAction, PollParameters,
}, },
Multiaddr, PeerId, Multiaddr, PeerId,
}; };
@@ -49,7 +49,7 @@ use sp_arithmetic::traits::SaturatedConversion;
use sp_runtime::traits::{Block as BlockT, CheckedSub, Header as HeaderT, NumberFor, Zero}; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header as HeaderT, NumberFor, Zero};
use std::{ use std::{
collections::{HashMap, HashSet, VecDeque}, collections::{HashMap, HashSet, VecDeque},
io, iter, iter,
num::NonZeroUsize, num::NonZeroUsize,
pin::Pin, pin::Pin,
sync::Arc, sync::Arc,
@@ -969,47 +969,18 @@ where
self.behaviour.addresses_of_peer(peer_id) self.behaviour.addresses_of_peer(peer_id)
} }
fn inject_connection_established( fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
&mut self, self.behaviour.on_swarm_event(event);
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
failed_addresses: Option<&Vec<Multiaddr>>,
other_established: usize,
) {
self.behaviour.inject_connection_established(
peer_id,
conn,
endpoint,
failed_addresses,
other_established,
)
} }
fn inject_connection_closed( fn on_connection_handler_event(
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
remaining_established: usize,
) {
self.behaviour.inject_connection_closed(
peer_id,
conn,
endpoint,
handler,
remaining_established,
)
}
fn inject_event(
&mut self, &mut self,
peer_id: PeerId, peer_id: PeerId,
connection: ConnectionId, connection_id: ConnectionId,
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent, event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
) { ) {
self.behaviour.inject_event(peer_id, connection, event) self.behaviour.on_connection_handler_event(peer_id, connection_id, event);
} }
fn poll( fn poll(
@@ -1245,41 +1216,4 @@ where
cx.waker().wake_by_ref(); cx.waker().wake_by_ref();
Poll::Pending Poll::Pending
} }
fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
handler: Self::ConnectionHandler,
error: &libp2p::swarm::DialError,
) {
self.behaviour.inject_dial_failure(peer_id, handler, error);
}
fn inject_new_listener(&mut self, id: ListenerId) {
self.behaviour.inject_new_listener(id)
}
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.behaviour.inject_new_listen_addr(id, addr)
}
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.behaviour.inject_expired_listen_addr(id, addr)
}
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
self.behaviour.inject_new_external_addr(addr)
}
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
self.behaviour.inject_expired_external_addr(addr)
}
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
self.behaviour.inject_listener_error(id, err);
}
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
self.behaviour.inject_listener_closed(id, reason);
}
} }
File diff suppressed because it is too large Load Diff
@@ -22,24 +22,28 @@ use crate::protocol::notifications::{Notifications, NotificationsOut, ProtocolCo
use futures::prelude::*; use futures::prelude::*;
use libp2p::{ use libp2p::{
core::{ core::{connection::ConnectionId, transport::MemoryTransport, upgrade},
connection::ConnectionId,
transport::{ListenerId, MemoryTransport},
upgrade, ConnectedPoint,
},
identity, noise, identity, noise,
swarm::{ swarm::{
ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour, behaviour::FromSwarm, ConnectionHandler, Executor, IntoConnectionHandler, NetworkBehaviour,
NetworkBehaviourAction, PollParameters, Swarm, SwarmEvent, NetworkBehaviourAction, PollParameters, Swarm, SwarmEvent,
}, },
yamux, Multiaddr, PeerId, Transport, yamux, Multiaddr, PeerId, Transport,
}; };
use std::{ use std::{
error, io, iter, iter,
pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
time::Duration, time::Duration,
}; };
struct TokioExecutor(tokio::runtime::Runtime);
impl Executor for TokioExecutor {
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
let _ = self.0.spawn(f);
}
}
/// Builds two nodes that have each other as bootstrap nodes. /// Builds two nodes that have each other as bootstrap nodes.
/// This is to be used only for testing, and a panic will happen if something goes wrong. /// This is to be used only for testing, and a panic will happen if something goes wrong.
fn build_nodes() -> (Swarm<CustomProtoWithAddr>, Swarm<CustomProtoWithAddr>) { fn build_nodes() -> (Swarm<CustomProtoWithAddr>, Swarm<CustomProtoWithAddr>) {
@@ -100,7 +104,13 @@ fn build_nodes() -> (Swarm<CustomProtoWithAddr>, Swarm<CustomProtoWithAddr>) {
.collect(), .collect(),
}; };
let mut swarm = Swarm::new(transport, behaviour, keypairs[index].public().to_peer_id()); let runtime = tokio::runtime::Runtime::new().unwrap();
let mut swarm = Swarm::with_executor(
transport,
behaviour,
keypairs[index].public().to_peer_id(),
TokioExecutor(runtime),
);
swarm.listen_on(addrs[index].clone()).unwrap(); swarm.listen_on(addrs[index].clone()).unwrap();
out.push(swarm); out.push(swarm);
} }
@@ -150,42 +160,18 @@ impl NetworkBehaviour for CustomProtoWithAddr {
list list
} }
fn inject_connection_established( fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
&mut self, self.inner.on_swarm_event(event);
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
failed_addresses: Option<&Vec<Multiaddr>>,
other_established: usize,
) {
self.inner.inject_connection_established(
peer_id,
conn,
endpoint,
failed_addresses,
other_established,
)
} }
fn inject_connection_closed( fn on_connection_handler_event(
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
remaining_established: usize,
) {
self.inner
.inject_connection_closed(peer_id, conn, endpoint, handler, remaining_established)
}
fn inject_event(
&mut self, &mut self,
peer_id: PeerId, peer_id: PeerId,
connection: ConnectionId, connection_id: ConnectionId,
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent, event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
) { ) {
self.inner.inject_event(peer_id, connection, event) self.inner.on_connection_handler_event(peer_id, connection_id, event);
} }
fn poll( fn poll(
@@ -195,43 +181,6 @@ impl NetworkBehaviour for CustomProtoWithAddr {
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> { ) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
self.inner.poll(cx, params) self.inner.poll(cx, params)
} }
fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
handler: Self::ConnectionHandler,
error: &DialError,
) {
self.inner.inject_dial_failure(peer_id, handler, error)
}
fn inject_new_listener(&mut self, id: ListenerId) {
self.inner.inject_new_listener(id)
}
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.inner.inject_new_listen_addr(id, addr)
}
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
self.inner.inject_expired_listen_addr(id, addr)
}
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
self.inner.inject_new_external_addr(addr)
}
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
self.inner.inject_expired_external_addr(addr)
}
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn error::Error + 'static)) {
self.inner.inject_listener_error(id, err);
}
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
self.inner.inject_listener_closed(id, reason);
}
} }
#[test] #[test]
+122 -108
View File
@@ -40,14 +40,16 @@ use futures::{
prelude::*, prelude::*,
}; };
use libp2p::{ use libp2p::{
core::{connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId}, core::{connection::ConnectionId, Multiaddr, PeerId},
request_response::{ request_response::{
handler::RequestResponseHandler, ProtocolSupport, RequestResponse, RequestResponseCodec, handler::RequestResponseHandler, ProtocolSupport, RequestResponse, RequestResponseCodec,
RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
}, },
swarm::{ swarm::{
handler::multi::MultiHandler, ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, behaviour::{ConnectionClosed, DialFailure, FromSwarm, ListenFailure},
NetworkBehaviourAction, PollParameters, handler::multi::MultiHandler,
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
PollParameters,
}, },
}; };
use sc_network_common::{ use sc_network_common::{
@@ -312,120 +314,119 @@ impl NetworkBehaviour for RequestResponsesBehaviour {
Vec::new() Vec::new()
} }
fn inject_connection_established( fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
&mut self, match event {
peer_id: &PeerId, FromSwarm::ConnectionEstablished(e) =>
conn: &ConnectionId, for (p, _) in self.protocols.values_mut() {
endpoint: &ConnectedPoint, NetworkBehaviour::on_swarm_event(p, FromSwarm::ConnectionEstablished(e));
failed_addresses: Option<&Vec<Multiaddr>>, },
other_established: usize, FromSwarm::ConnectionClosed(ConnectionClosed {
) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_connection_established(
p,
peer_id, peer_id,
conn, connection_id,
endpoint, endpoint,
failed_addresses, handler,
other_established, remaining_established,
) }) =>
for (p_name, p_handler) in handler.into_iter() {
if let Some((proto, _)) = self.protocols.get_mut(p_name.as_str()) {
proto.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
peer_id,
connection_id,
endpoint,
handler: p_handler,
remaining_established,
}));
} else {
log::error!(
target: "sub-libp2p",
"on_swarm_event/connection_closed: no request-response instance registered for protocol {:?}",
p_name,
)
}
},
FromSwarm::DialFailure(DialFailure { peer_id, error, handler }) =>
for (p_name, p_handler) in handler.into_iter() {
if let Some((proto, _)) = self.protocols.get_mut(p_name.as_str()) {
proto.on_swarm_event(FromSwarm::DialFailure(DialFailure {
peer_id,
handler: p_handler,
error,
}));
} else {
log::error!(
target: "sub-libp2p",
"on_swarm_event/dial_failure: no request-response instance registered for protocol {:?}",
p_name,
)
}
},
FromSwarm::ListenerClosed(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::ListenerClosed(e));
},
FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, handler }) =>
for (p_name, p_handler) in handler.into_iter() {
if let Some((proto, _)) = self.protocols.get_mut(p_name.as_str()) {
proto.on_swarm_event(FromSwarm::ListenFailure(ListenFailure {
local_addr,
send_back_addr,
handler: p_handler,
}));
} else {
log::error!(
target: "sub-libp2p",
"on_swarm_event/listen_failure: no request-response instance registered for protocol {:?}",
p_name,
)
}
},
FromSwarm::ListenerError(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::ListenerError(e));
},
FromSwarm::ExpiredExternalAddr(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::ExpiredExternalAddr(e));
},
FromSwarm::NewListener(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::NewListener(e));
},
FromSwarm::ExpiredListenAddr(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::ExpiredListenAddr(e));
},
FromSwarm::NewExternalAddr(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::NewExternalAddr(e));
},
FromSwarm::AddressChange(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::AddressChange(e));
},
FromSwarm::NewListenAddr(e) =>
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::on_swarm_event(p, FromSwarm::NewListenAddr(e));
},
} }
} }
fn inject_connection_closed( fn on_connection_handler_event(
&mut self,
peer_id: &PeerId,
conn: &ConnectionId,
endpoint: &ConnectedPoint,
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
remaining_established: usize,
) {
for (p_name, event) in handler.into_iter() {
if let Some((proto, _)) = self.protocols.get_mut(p_name.as_str()) {
proto.inject_connection_closed(
peer_id,
conn,
endpoint,
event,
remaining_established,
)
} else {
log::error!(
target: "sub-libp2p",
"inject_connection_closed: no request-response instance registered for protocol {:?}",
p_name,
)
}
}
}
fn inject_event(
&mut self, &mut self,
peer_id: PeerId, peer_id: PeerId,
connection: ConnectionId, connection_id: ConnectionId,
(p_name, event): <Self::ConnectionHandler as ConnectionHandler>::OutEvent, (p_name, event): <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
) { ) {
if let Some((proto, _)) = self.protocols.get_mut(&*p_name) { if let Some((proto, _)) = self.protocols.get_mut(&*p_name) {
return proto.inject_event(peer_id, connection, event) return proto.on_connection_handler_event(peer_id, connection_id, event)
} }
log::warn!(target: "sub-libp2p", log::warn!(
"inject_node_event: no request-response instance registered for protocol {:?}", target: "sub-libp2p",
p_name) "on_connection_handler_event: no request-response instance registered for protocol {:?}",
} p_name
);
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_new_external_addr(p, addr)
}
}
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_expired_external_addr(p, addr)
}
}
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_expired_listen_addr(p, id, addr)
}
}
fn inject_dial_failure(
&mut self,
peer_id: Option<PeerId>,
_: Self::ConnectionHandler,
error: &libp2p::swarm::DialError,
) {
for (p, _) in self.protocols.values_mut() {
let handler = p.new_handler();
NetworkBehaviour::inject_dial_failure(p, peer_id, handler, error)
}
}
fn inject_new_listener(&mut self, id: ListenerId) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_new_listener(p, id)
}
}
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_new_listen_addr(p, id, addr)
}
}
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_listener_error(p, id, err)
}
}
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
for (p, _) in self.protocols.values_mut() {
NetworkBehaviour::inject_listener_closed(p, id, reason)
}
} }
fn poll( fn poll(
@@ -919,12 +920,19 @@ mod tests {
}, },
identity::Keypair, identity::Keypair,
noise, noise,
swarm::{Swarm, SwarmEvent}, swarm::{Executor, Swarm, SwarmEvent},
Multiaddr, Multiaddr,
}; };
use sc_peerset::{Peerset, PeersetConfig, SetConfig}; use sc_peerset::{Peerset, PeersetConfig, SetConfig};
use std::{iter, time::Duration}; use std::{iter, time::Duration};
struct TokioExecutor(tokio::runtime::Runtime);
impl Executor for TokioExecutor {
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
let _ = self.0.spawn(f);
}
}
fn build_swarm( fn build_swarm(
list: impl Iterator<Item = ProtocolConfig>, list: impl Iterator<Item = ProtocolConfig>,
) -> (Swarm<RequestResponsesBehaviour>, Multiaddr, Peerset) { ) -> (Swarm<RequestResponsesBehaviour>, Multiaddr, Peerset) {
@@ -953,7 +961,13 @@ mod tests {
let behaviour = RequestResponsesBehaviour::new(list, handle).unwrap(); let behaviour = RequestResponsesBehaviour::new(list, handle).unwrap();
let mut swarm = Swarm::new(transport, behaviour, keypair.public().to_peer_id()); let runtime = tokio::runtime::Runtime::new().unwrap();
let mut swarm = Swarm::with_executor(
transport,
behaviour,
keypair.public().to_peer_id(),
TokioExecutor(runtime),
);
let listen_addr: Multiaddr = format!("/memory/{}", rand::random::<u64>()).parse().unwrap(); let listen_addr: Multiaddr = format!("/memory/{}", rand::random::<u64>()).parse().unwrap();
swarm.listen_on(listen_addr.clone()).unwrap(); swarm.listen_on(listen_addr.clone()).unwrap();
+17 -11
View File
@@ -40,13 +40,13 @@ use crate::{
use futures::{channel::oneshot, prelude::*}; use futures::{channel::oneshot, prelude::*};
use libp2p::{ use libp2p::{
core::{either::EitherError, upgrade, ConnectedPoint, Executor}, core::{either::EitherError, upgrade, ConnectedPoint},
identify::Info as IdentifyInfo, identify::Info as IdentifyInfo,
kad::record::Key as KademliaKey, kad::record::Key as KademliaKey,
multiaddr, multiaddr,
ping::Failure as PingFailure, ping::Failure as PingFailure,
swarm::{ swarm::{
AddressScore, ConnectionError, ConnectionLimits, DialError, NetworkBehaviour, AddressScore, ConnectionError, ConnectionLimits, DialError, Executor, NetworkBehaviour,
PendingConnectionError, Swarm, SwarmBuilder, SwarmEvent, PendingConnectionError, Swarm, SwarmBuilder, SwarmEvent,
}, },
Multiaddr, PeerId, Multiaddr, PeerId,
@@ -370,7 +370,21 @@ where
} }
}; };
let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id) let builder = {
struct SpawnImpl<F>(F);
impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for SpawnImpl<F> {
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
(self.0)(f)
}
}
SwarmBuilder::with_executor(
transport,
behaviour,
local_peer_id,
SpawnImpl(params.executor),
)
};
let builder = builder
.connection_limits( .connection_limits(
ConnectionLimits::default() ConnectionLimits::default()
.with_max_established_per_peer(Some(crate::MAX_CONNECTIONS_PER_PEER as u32)) .with_max_established_per_peer(Some(crate::MAX_CONNECTIONS_PER_PEER as u32))
@@ -383,14 +397,6 @@ where
.connection_event_buffer_size(1024) .connection_event_buffer_size(1024)
.max_negotiating_inbound_streams(2048); .max_negotiating_inbound_streams(2048);
struct SpawnImpl<F>(F);
impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for SpawnImpl<F> {
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
(self.0)(f)
}
}
builder = builder.executor(Box::new(SpawnImpl(params.executor)));
(builder.build(), bandwidth) (builder.build(), bandwidth)
}; };
+5 -5
View File
@@ -54,17 +54,17 @@ pub fn build_transport(
) -> (Boxed<(PeerId, StreamMuxerBox)>, Arc<BandwidthSinks>) { ) -> (Boxed<(PeerId, StreamMuxerBox)>, Arc<BandwidthSinks>) {
// Build the base layer of the transport. // Build the base layer of the transport.
let transport = if !memory_only { let transport = if !memory_only {
let tcp_config = tcp::GenTcpConfig::new().nodelay(true); let tcp_config = tcp::Config::new().nodelay(true);
let desktop_trans = tcp::TokioTcpTransport::new(tcp_config.clone()); let desktop_trans = tcp::tokio::Transport::new(tcp_config.clone());
let desktop_trans = websocket::WsConfig::new(desktop_trans) let desktop_trans = websocket::WsConfig::new(desktop_trans)
.or_transport(tcp::TokioTcpTransport::new(tcp_config.clone())); .or_transport(tcp::tokio::Transport::new(tcp_config.clone()));
let dns_init = dns::TokioDnsConfig::system(desktop_trans); let dns_init = dns::TokioDnsConfig::system(desktop_trans);
EitherTransport::Left(if let Ok(dns) = dns_init { EitherTransport::Left(if let Ok(dns) = dns_init {
EitherTransport::Left(dns) EitherTransport::Left(dns)
} else { } else {
let desktop_trans = tcp::TokioTcpTransport::new(tcp_config.clone()); let desktop_trans = tcp::tokio::Transport::new(tcp_config.clone());
let desktop_trans = websocket::WsConfig::new(desktop_trans) let desktop_trans = websocket::WsConfig::new(desktop_trans)
.or_transport(tcp::TokioTcpTransport::new(tcp_config)); .or_transport(tcp::tokio::Transport::new(tcp_config));
EitherTransport::Right(desktop_trans.map_err(dns::DnsErr::Transport)) EitherTransport::Right(desktop_trans.map_err(dns::DnsErr::Transport))
}) })
} else { } else {
+1 -1
View File
@@ -20,7 +20,7 @@ array-bytes = "4.1"
async-trait = "0.1.58" async-trait = "0.1.58"
codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] }
futures = "0.3.21" futures = "0.3.21"
libp2p = "0.49.0" libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
lru = "0.8.1" lru = "0.8.1"
mockall = "0.11.2" mockall = "0.11.2"
+1 -1
View File
@@ -17,7 +17,7 @@ tokio = "1.22.0"
async-trait = "0.1.57" async-trait = "0.1.57"
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.1" futures-timer = "3.0.1"
libp2p = { version = "0.49.0", default-features = false } libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
parking_lot = "0.12.1" parking_lot = "0.12.1"
rand = "0.8.5" rand = "0.8.5"
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
array-bytes = "4.1" array-bytes = "4.1"
codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] }
futures = "0.3.21" futures = "0.3.21"
libp2p = "0.49.0" libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
pin-project = "1.0.12" pin-project = "1.0.12"
prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../../utils/prometheus" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../../utils/prometheus" }
+1 -1
View File
@@ -21,7 +21,7 @@ futures = "0.3.21"
futures-timer = "3.0.2" futures-timer = "3.0.2"
hyper = { version = "0.14.16", features = ["stream", "http2"] } hyper = { version = "0.14.16", features = ["stream", "http2"] }
hyper-rustls = { version = "0.23.0", features = ["http2"] } hyper-rustls = { version = "0.23.0", features = ["http2"] }
libp2p = { version = "0.49.0", default-features = false } libp2p = "0.50.0"
num_cpus = "1.13" num_cpus = "1.13"
once_cell = "1.8" once_cell = "1.8"
parking_lot = "0.12.1" parking_lot = "0.12.1"
+1 -1
View File
@@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies] [dependencies]
futures = "0.3.21" futures = "0.3.21"
libp2p = { version = "0.49.0", default-features = false } libp2p = "0.50.0"
log = "0.4.17" log = "0.4.17"
serde_json = "1.0.85" serde_json = "1.0.85"
wasm-timer = "0.2" wasm-timer = "0.2"
+1 -1
View File
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies] [dependencies]
chrono = "0.4.19" chrono = "0.4.19"
futures = "0.3.21" futures = "0.3.21"
libp2p = { version = "0.49.0", default-features = false, features = ["dns", "tcp", "tokio", "wasm-ext", "websocket"] } libp2p = { version = "0.50.0", features = ["dns", "tcp", "tokio", "wasm-ext", "websocket"] }
log = "0.4.17" log = "0.4.17"
parking_lot = "0.12.1" parking_lot = "0.12.1"
pin-project = "1.0.12" pin-project = "1.0.12"
+1 -1
View File
@@ -30,7 +30,7 @@ const CONNECT_TIMEOUT: Duration = Duration::from_secs(20);
pub(crate) fn initialize_transport() -> Result<WsTrans, io::Error> { pub(crate) fn initialize_transport() -> Result<WsTrans, io::Error> {
let transport = { let transport = {
let tcp_transport = libp2p::tcp::TokioTcpTransport::new(libp2p::tcp::GenTcpConfig::new()); let tcp_transport = libp2p::tcp::tokio::Transport::new(libp2p::tcp::Config::new());
let inner = libp2p::dns::TokioDnsConfig::system(tcp_transport)?; let inner = libp2p::dns::TokioDnsConfig::system(tcp_transport)?;
libp2p::websocket::framed::WsConfig::new(inner).and_then(|connec, _| { libp2p::websocket::framed::WsConfig::new(inner).and_then(|connec, _| {
let connec = connec let connec = connec
@@ -26,5 +26,5 @@ error[E0277]: the trait bound `Vec<u8>: MaxEncodedLen` is not satisfied
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7)
and 79 others and $N others
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageMyStorage<T>, Vec<u8>>` to implement `StorageInfoTrait` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageMyStorage<T>, Vec<u8>>` to implement `StorageInfoTrait`
@@ -28,7 +28,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>> <&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
<&[(T,)] as EncodeLike<LinkedList<LikeT>>> <&[(T,)] as EncodeLike<LinkedList<LikeT>>>
<&[T] as EncodeLike<Vec<U>>> <&[T] as EncodeLike<Vec<U>>>
and 281 others and $N others
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `PartialStorageInfoTrait` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `PartialStorageInfoTrait`
@@ -48,7 +48,7 @@ error[E0277]: the trait bound `Bar: WrapperTypeEncode` is not satisfied
Rc<T> Rc<T>
Vec<T> Vec<T>
bytes::bytes::Bytes bytes::bytes::Bytes
and 3 others and $N others
= note: required for `Bar` to implement `Encode` = note: required for `Bar` to implement `Encode`
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
@@ -69,7 +69,7 @@ error[E0277]: the trait bound `Bar: TypeInfo` is not satisfied
(A, B, C, D) (A, B, C, D)
(A, B, C, D, E) (A, B, C, D, E)
(A, B, C, D, E, F) (A, B, C, D, E, F)
and 163 others and $N others
= note: required for `Bar` to implement `StaticTypeInfo` = note: required for `Bar` to implement `StaticTypeInfo`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder`
@@ -103,7 +103,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>> <&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
<&[(T,)] as EncodeLike<LinkedList<LikeT>>> <&[(T,)] as EncodeLike<LinkedList<LikeT>>>
<&[T] as EncodeLike<Vec<U>>> <&[T] as EncodeLike<Vec<U>>>
and 281 others and $N others
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder`
@@ -123,7 +123,7 @@ error[E0277]: the trait bound `Bar: WrapperTypeEncode` is not satisfied
Rc<T> Rc<T>
Vec<T> Vec<T>
bytes::bytes::Bytes bytes::bytes::Bytes
and 3 others and $N others
= note: required for `Bar` to implement `Encode` = note: required for `Bar` to implement `Encode`
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
@@ -28,7 +28,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>> <&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
<&[(T,)] as EncodeLike<LinkedList<LikeT>>> <&[(T,)] as EncodeLike<LinkedList<LikeT>>>
<&[T] as EncodeLike<Vec<U>>> <&[T] as EncodeLike<Vec<U>>>
and 281 others and $N others
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `PartialStorageInfoTrait` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `PartialStorageInfoTrait`
@@ -48,7 +48,7 @@ error[E0277]: the trait bound `Bar: WrapperTypeEncode` is not satisfied
Rc<T> Rc<T>
Vec<T> Vec<T>
bytes::bytes::Bytes bytes::bytes::Bytes
and 3 others and $N others
= note: required for `Bar` to implement `Encode` = note: required for `Bar` to implement `Encode`
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
@@ -69,7 +69,7 @@ error[E0277]: the trait bound `Bar: TypeInfo` is not satisfied
(A, B, C, D) (A, B, C, D)
(A, B, C, D, E) (A, B, C, D, E)
(A, B, C, D, E, F) (A, B, C, D, E, F)
and 163 others and $N others
= note: required for `Bar` to implement `StaticTypeInfo` = note: required for `Bar` to implement `StaticTypeInfo`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder`
@@ -103,7 +103,7 @@ error[E0277]: the trait bound `Bar: EncodeLike` is not satisfied
<&[(T,)] as EncodeLike<BinaryHeap<LikeT>>> <&[(T,)] as EncodeLike<BinaryHeap<LikeT>>>
<&[(T,)] as EncodeLike<LinkedList<LikeT>>> <&[(T,)] as EncodeLike<LinkedList<LikeT>>>
<&[T] as EncodeLike<Vec<U>>> <&[T] as EncodeLike<Vec<U>>>
and 281 others and $N others
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageEntryMetadataBuilder`
@@ -123,7 +123,7 @@ error[E0277]: the trait bound `Bar: WrapperTypeEncode` is not satisfied
Rc<T> Rc<T>
Vec<T> Vec<T>
bytes::bytes::Bytes bytes::bytes::Bytes
and 3 others and $N others
= note: required for `Bar` to implement `Encode` = note: required for `Bar` to implement `Encode`
= note: required for `Bar` to implement `FullEncode` = note: required for `Bar` to implement `FullEncode`
= note: required for `Bar` to implement `FullCodec` = note: required for `Bar` to implement `FullCodec`
@@ -13,5 +13,5 @@ error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7)
and 79 others and $N others
= note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageInfoTrait` = note: required for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>` to implement `StorageInfoTrait`
@@ -13,6 +13,6 @@ error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6)
(TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7)
and 79 others and $N others
= note: required for `Key<frame_support::Twox64Concat, Bar>` to implement `KeyGeneratorMaxEncodedLen` = note: required for `Key<frame_support::Twox64Concat, Bar>` to implement `KeyGeneratorMaxEncodedLen`
= note: required for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, Key<frame_support::Twox64Concat, Bar>, u32>` to implement `StorageInfoTrait` = note: required for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, Key<frame_support::Twox64Concat, Bar>, u32>` to implement `StorageInfoTrait`