-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce "default init" and "unload" methods for Ipv8Component #6402
Conversation
4f05665
to
fd8cf86
Compare
bc9b0b8
to
99beb20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
In my opinion this is good to merge as-is. However, I would urge you to consider implementing my one suggestion already in this PR.
ipv8 = self.ipv8 | ||
community = DiscoveryCommunity(self.peer, ipv8.endpoint, ipv8.network, max_peers=100) | ||
community.bootstrappers.append(self.make_bootstrapper()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: seems like you can replace this with self.initialise_community_by_default(community)
and also shed the ipv8.add_strategy(community, RandomWalk(community), 20)
.
Same for _init_dht_discovery_community
. Loses 2 LOC overall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Is 20 target peers is necessary for the RandomWalk strategy for DiscoveryCommunity?
Why I asking is because if I replace it by self.initialise_community_by_default(community)
, then target_peers
become max_peers-10 == 90
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Short answer: yes, 20 is a good idea.
Long answer: The DiscoveryCommunity is a meta-community that all peers join to quickly synchronize the other Communities they are a part of. This also forms a secondary bootstrap mechanism (which is why you generally don't want to deviate from the default parameterization of your Community and use a custom Network()
). Actively walking to some peers in the DiscoveryCommunity will allow you to get a little bit of diversity in your connections. However, walking to too many peers here will just give you a lot of peers you do not share Communities with. 20 seems to be a good number (also considering the network topologies of the other Communities this Community shares its peer pool with). You could even set this to 0. However, 90 may produce too many open connections if overlay identifiers start diverging in the network.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. What if we will rewrite initialise_community_by_default
this way:
def initialise_community_by_default(self, community, default_random_walk_max_peers=20):
community.bootstrappers.append(self.make_bootstrapper())
# Value of `target_peers` must not be equal to the value of `max_peers` for the community.
# This causes a deformed network topology and makes it harder for peers to connect to others.
# More information: https://github.com/Tribler/py-ipv8/issues/979#issuecomment-896643760
#
# Then:
# random_walk_max_peers should be less than community.max_peers:
random_walk_max_peers = min(default_random_walk_max_peers, community.max_peers - 10)
# random_walk_max_peers should be greater than 0
random_walk_max_peers = max(0, random_walk_max_peers)
self.ipv8.add_strategy(community, RandomWalk(community), random_walk_max_peers)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented
database = BandwidthDatabase(database_path, self._ipv8_component.peer.public_key.key_to_bin()) | ||
self.community = bandwidth_cls(self._ipv8_component.peer, | ||
self._ipv8_component.ipv8.endpoint, | ||
self._ipv8_component.ipv8.network, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought/nit: We're injecting self._ipv8_component.ipv8.network
as a dependency and then the component itself is overwriting its input with a Network()
of its own creation. We should, at some point (probably not this PR) move the Network()
overwrite to this file (same for PopularityCommunity
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, probably. For me purpose of overwriting a Network is unclear.
It is true for PopularityCommunity
and GigachannelCommunity
(as successors of RemoteQueryCommunity
)
cc: @ichorid
(I see it as out of the scope of this PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GigaChannelCommunity walks and deletes peers aggressively, so creates a separate Network instance to prevent interfering with other communities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for a "clean" Network()
is the introduction of bias through custom parameterization of Communities. If you bias your peer discovery mechanism, you get a self-reinforcing effect that essentially forces some peers out of your network. It is not a problem if one peer deviates, but if you force a default on the entire network you will start seeing this. We've learned this the hard way #2894 (comment) (yes, we sinkhole attacked our own network) Therefore, for every Community that uses custom walks (including peer removal) or custom parameterization, we use a new Network
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented here: #6408
# test dht disabled | ||
tribler_config.dht.enabled = True | ||
session = Session(tribler_config, [MasterKeyComponent(), RESTComponent(), Ipv8Component()]) | ||
with session: | ||
await session.start() | ||
|
||
comp = Ipv8Component.instance() | ||
assert comp.dht_discovery_community | ||
|
||
# test discovery_community enabled | ||
tribler_config.gui_test_mode = False | ||
tribler_config.discovery_community.enabled = True | ||
session = Session(tribler_config, [MasterKeyComponent(), RESTComponent(), Ipv8Component()]) | ||
with session: | ||
await session.start() | ||
|
||
comp = Ipv8Component.instance() | ||
assert comp._peer_discovery_community |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: This test now breaks with the Arrange/Act/Assert
pattern: what I see here is Arrange/Assert/Arrange/Assert/Arrange/Assert
. By splitting this code at the comments (turning # test dht disabled
into async def test_ipv8_component_dht_disabled()
and # test discovery_community enabled
into async def test_ipv8_component_discovery_enabled()
) you can follow the AAA pattern with very little effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree! Will implement it soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented
99beb20
to
8daf601
Compare
Kudos, SonarCloud Quality Gate passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Thanks for going out of your way to even implement the nit and optional suggestion. Looks good 👍
Based on #6396