Skip to content

Commit d26e04a

Browse files
authored
feat(kad): report automatic changes to kad mode
Previously, the kademlia protocol would only log changes to the internal mode. With this patch, we now also emit an event which allows users to code against the internal state of the kademlia protocol. Fixes #4310. Pull-Request: #4503.
1 parent eb8fffa commit d26e04a

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

protocols/kad/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 0.45.0 - unreleased
22

3+
- Emit `ModeChanged` event whenever we automatically reconfigure the mode.
4+
See [PR 4503](https://github.com/libp2p/rust-libp2p/pull/4503).
35

46
## 0.44.6
57

protocols/kad/src/behaviour.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,8 @@ where
10481048
}
10491049

10501050
fn determine_mode_from_external_addresses(&mut self) {
1051+
let old_mode = self.mode;
1052+
10511053
self.mode = match (self.external_addresses.as_slice(), self.mode) {
10521054
([], Mode::Server) => {
10531055
log::debug!("Switching to client-mode because we no longer have any confirmed external addresses");
@@ -1082,6 +1084,13 @@ where
10821084
};
10831085

10841086
self.reconfigure_mode();
1087+
1088+
if old_mode != self.mode {
1089+
self.queued_events
1090+
.push_back(ToSwarm::GenerateEvent(Event::ModeChanged {
1091+
new_mode: self.mode,
1092+
}));
1093+
}
10851094
}
10861095

10871096
/// Processes discovered peers from a successful request in an iterative `Query`.
@@ -2673,6 +2682,12 @@ pub enum Event {
26732682
/// See [`Behaviour::kbucket`] for insight into the contents of
26742683
/// the k-bucket of `peer`.
26752684
PendingRoutablePeer { peer: PeerId, address: Multiaddr },
2685+
2686+
/// This peer's mode has been updated automatically.
2687+
///
2688+
/// This happens in response to an external
2689+
/// address being added or removed.
2690+
ModeChanged { new_mode: Mode },
26762691
}
26772692

26782693
/// Information about progress events.

protocols/kad/src/behaviour/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ fn exceed_jobs_max_queries() {
10591059
result: QueryResult::GetClosestPeers(Ok(r)),
10601060
..
10611061
}) => break assert!(r.peers.is_empty()),
1062+
SwarmEvent::Behaviour(Event::ModeChanged { .. }) => {}
10621063
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {e:?}"),
10631064
_ => {}
10641065
}
@@ -1382,6 +1383,7 @@ fn get_providers_single() {
13821383
result: QueryResult::StartProviding(Ok(_)),
13831384
..
13841385
}) => {}
1386+
SwarmEvent::Behaviour(Event::ModeChanged { .. }) => {}
13851387
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {e:?}"),
13861388
_ => {}
13871389
}

protocols/kad/tests/client_mode.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,24 @@ async fn adding_an_external_addresses_activates_server_mode_on_existing_connecti
8282
// Remove memory address to simulate a server that doesn't know its external address.
8383
server.remove_external_address(&memory_addr);
8484
client.dial(memory_addr.clone()).unwrap();
85-
// Do the usual identify send/receive dance.
85+
// Do the usual identify send/receive dance. This triggers a mode change to Mode::Client.
8686
match libp2p_swarm_test::drive(&mut client, &mut server).await {
87-
([Identify(_), Identify(_)], [Identify(_), Identify(_)]) => {}
87+
([Identify(_), Identify(_)], [Kad(ModeChanged { new_mode }), Identify(_), Identify(_)]) => {
88+
assert_eq!(new_mode, Mode::Client);
89+
}
8890
other => panic!("Unexpected events: {other:?}"),
8991
}
9092

9193
// Server learns its external address (this could be through AutoNAT or some other mechanism).
9294
server.add_external_address(memory_addr);
9395

94-
// The server reconfigured its connection to the client to be in server mode, pushes that information to client which as a result updates its routing table.
96+
// The server reconfigured its connection to the client to be in server mode, pushes that information to client which as a result updates its routing table and triggers a mode change to Mode::Server.
9597
match libp2p_swarm_test::drive(&mut client, &mut server).await {
9698
(
9799
[Identify(identify::Event::Received { .. }), Kad(RoutingUpdated { peer: peer1, .. })],
98-
[Identify(identify::Event::Pushed { .. })],
100+
[Kad(ModeChanged { new_mode }), Identify(identify::Event::Pushed { .. })],
99101
) => {
102+
assert_eq!(new_mode, Mode::Server);
100103
assert_eq!(peer1, server_peer_id);
101104
}
102105
other => panic!("Unexpected events: {other:?}"),

0 commit comments

Comments
 (0)