mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-25 15:51:34 +00:00
Add NetworkBehaviour::inject_replaced (#914)
* Add NetworkBehaviour::inject_replaced * Address style * Forgot to call set_disconnected * Also add incoming addresses to kbuckets
This commit is contained in:
@ -262,8 +262,7 @@ where TBehaviour: NetworkBehaviour,
|
|||||||
self.behaviour.inject_disconnected(&peer_id, endpoint);
|
self.behaviour.inject_disconnected(&peer_id, endpoint);
|
||||||
},
|
},
|
||||||
Async::Ready(RawSwarmEvent::Replaced { peer_id, closed_endpoint, endpoint }) => {
|
Async::Ready(RawSwarmEvent::Replaced { peer_id, closed_endpoint, endpoint }) => {
|
||||||
self.behaviour.inject_disconnected(&peer_id, closed_endpoint);
|
self.behaviour.inject_replaced(peer_id, closed_endpoint, endpoint);
|
||||||
self.behaviour.inject_connected(peer_id, endpoint);
|
|
||||||
},
|
},
|
||||||
Async::Ready(RawSwarmEvent::IncomingConnection(incoming)) => {
|
Async::Ready(RawSwarmEvent::IncomingConnection(incoming)) => {
|
||||||
let handler = self.behaviour.new_handler();
|
let handler = self.behaviour.new_handler();
|
||||||
@ -343,6 +342,12 @@ pub trait NetworkBehaviour {
|
|||||||
/// endpoint is the one we used to be connected to.
|
/// endpoint is the one we used to be connected to.
|
||||||
fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint);
|
fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint);
|
||||||
|
|
||||||
|
/// Indicates the behaviour that we replace the connection from the node with another.
|
||||||
|
fn inject_replaced(&mut self, peer_id: PeerId, closed_endpoint: ConnectedPoint, new_endpoint: ConnectedPoint) {
|
||||||
|
self.inject_disconnected(&peer_id, closed_endpoint);
|
||||||
|
self.inject_connected(peer_id, new_endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates the behaviour that the node with the given peer id has generated an event for
|
/// Indicates the behaviour that the node with the given peer id has generated an event for
|
||||||
/// us.
|
/// us.
|
||||||
///
|
///
|
||||||
|
@ -191,6 +191,32 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `inject_replaced()`.
|
||||||
|
let inject_replaced_stmts = {
|
||||||
|
let num_fields = data_struct.fields.iter().filter(|f| !is_ignored(f)).count();
|
||||||
|
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||||
|
if is_ignored(&field) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(if field_n == num_fields - 1 {
|
||||||
|
match field.ident {
|
||||||
|
Some(ref i) => quote!{ self.#i.inject_replaced(peer_id, closed_endpoint, new_endpoint); },
|
||||||
|
None => quote!{ self.#field_n.inject_replaced(peer_id, closed_endpoint, new_endpoint); },
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match field.ident {
|
||||||
|
Some(ref i) => quote!{
|
||||||
|
self.#i.inject_replaced(peer_id.clone(), closed_endpoint.clone(), new_endpoint.clone());
|
||||||
|
},
|
||||||
|
None => quote!{
|
||||||
|
self.#field_n.inject_replaced(peer_id.clone(), closed_endpoint.clone(), new_endpoint.clone());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_dial_failure()`.
|
// Build the list of statements to put in the body of `inject_dial_failure()`.
|
||||||
let inject_dial_failure_stmts = {
|
let inject_dial_failure_stmts = {
|
||||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||||
@ -367,6 +393,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
#(#inject_disconnected_stmts);*
|
#(#inject_disconnected_stmts);*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn inject_replaced(&mut self, peer_id: #peer_id, closed_endpoint: #connected_point, new_endpoint: #connected_point) {
|
||||||
|
#(#inject_replaced_stmts);*
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inject_dial_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) {
|
fn inject_dial_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) {
|
||||||
#(#inject_dial_failure_stmts);*
|
#(#inject_dial_failure_stmts);*
|
||||||
|
@ -291,7 +291,7 @@ where
|
|||||||
.unwrap_or_else(Vec::new)
|
.unwrap_or_else(Vec::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connected(&mut self, id: PeerId, _: ConnectedPoint) {
|
fn inject_connected(&mut self, id: PeerId, endpoint: ConnectedPoint) {
|
||||||
if let Some(pos) = self.pending_rpcs.iter().position(|(p, _)| p == &id) {
|
if let Some(pos) = self.pending_rpcs.iter().position(|(p, _)| p == &id) {
|
||||||
let (_, rpc) = self.pending_rpcs.remove(pos);
|
let (_, rpc) = self.pending_rpcs.remove(pos);
|
||||||
self.queued_events.push(NetworkBehaviourAction::SendEvent {
|
self.queued_events.push(NetworkBehaviourAction::SendEvent {
|
||||||
@ -309,6 +309,14 @@ where
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let ConnectedPoint::Dialer { address } = endpoint {
|
||||||
|
if let Some(list) = self.kbuckets.entry_mut(&id) {
|
||||||
|
if list.iter().all(|a| *a != address) {
|
||||||
|
list.push(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.connected_peers.insert(id);
|
self.connected_peers.insert(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +327,28 @@ where
|
|||||||
for (query, _, _) in self.active_queries.values_mut() {
|
for (query, _, _) in self.active_queries.values_mut() {
|
||||||
query.inject_rpc_error(id);
|
query.inject_rpc_error(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.kbuckets.set_disconnected(&id);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inject_replaced(&mut self, peer_id: PeerId, _: ConnectedPoint, new_endpoint: ConnectedPoint) {
|
||||||
|
// We need to re-send the active queries.
|
||||||
|
for (query_id, (query, _, _)) in self.active_queries.iter() {
|
||||||
|
if query.is_waiting(&peer_id) {
|
||||||
|
self.queued_events.push(NetworkBehaviourAction::SendEvent {
|
||||||
|
peer_id: peer_id.clone(),
|
||||||
|
event: query.target().to_rpc_request(*query_id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let ConnectedPoint::Dialer { address } = new_endpoint {
|
||||||
|
if let Some(list) = self.kbuckets.entry_mut(&peer_id) {
|
||||||
|
if list.iter().all(|a| *a != address) {
|
||||||
|
list.push(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_node_event(&mut self, source: PeerId, event: KademliaHandlerEvent<QueryId>) {
|
fn inject_node_event(&mut self, source: PeerId, event: KademliaHandlerEvent<QueryId>) {
|
||||||
|
@ -216,6 +216,33 @@ impl QueryState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if we are waiting for a query answer from that peer.
|
||||||
|
///
|
||||||
|
/// After `poll()` returned `SendRpc`, this function will return `true`.
|
||||||
|
pub fn is_waiting(&self, id: &PeerId) -> bool {
|
||||||
|
let state = self
|
||||||
|
.closest_peers
|
||||||
|
.iter()
|
||||||
|
.filter_map(
|
||||||
|
|(peer_id, state)| {
|
||||||
|
if peer_id == id {
|
||||||
|
Some(state)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.next();
|
||||||
|
|
||||||
|
match state {
|
||||||
|
Some(&QueryPeerState::InProgress(_)) => true,
|
||||||
|
Some(&QueryPeerState::NotContacted) => false,
|
||||||
|
Some(&QueryPeerState::Succeeded) => false,
|
||||||
|
Some(&QueryPeerState::Failed) => false,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// After `poll()` returned `SendRpc`, this function should be called if we were unable to
|
/// After `poll()` returned `SendRpc`, this function should be called if we were unable to
|
||||||
/// reach the peer, or if an error of some sort happened.
|
/// reach the peer, or if an error of some sort happened.
|
||||||
///
|
///
|
||||||
|
Reference in New Issue
Block a user