Skip to content

Provide required info for nucypher-monitor without unnecessarily maturing sprouts#2709

Merged
derekpierre merged 6 commits intonucypher:mainfrom
fjarri:forever-young
Jun 7, 2021
Merged

Provide required info for nucypher-monitor without unnecessarily maturing sprouts#2709
derekpierre merged 6 commits intonucypher:mainfrom
fjarri:forever-young

Conversation

@fjarri
Copy link
Copy Markdown
Contributor

@fjarri fjarri commented May 20, 2021

Type of PR:

  • Bugfix

Required reviews:

  • 1

What this does:
Removes a mature() call that was introduced in 50da675 for the purposes of nucypher-monitor. The only thing it needs that a sprout doesn't have is rest_url, and we can provide that.

Additional changes were necessary to allow some tests to pass, since they now got a mix of Ursula and NodeSprout objects:

  • NodeSprout.__eq__ added (identical to Character.__eq__, comparing stamps)
  • NodeSprout.__hash__ was changed to conform to __eq__ (and to Character.__hash__), that is taking the hash of a stamp.

fjarri added a commit to fjarri/nucypher that referenced this pull request May 20, 2021
KPrasch
KPrasch previously approved these changes May 21, 2021
@KPrasch
Copy link
Copy Markdown
Member

KPrasch commented May 21, 2021

@fjarri
Copy link
Copy Markdown
Contributor Author

fjarri commented May 24, 2021

Some results from the failure investigation.

test_one_node_stores_a_bunch_of_others: started at commit 37929b3

In Learner.load_seednodes(), a sprout corresponding to the seed node from the test was created twice: once as maybe_sage_node, and the second time as seed_node (in the iteration over self._seed_nodes). Since NodeSprout did not have __eq__, these objects were treated as different ones by FleetSensor (record_node() puts new nodes in a set _nodes_to_add). Then, since sets are unordered, either of the two objects could end up in the actual fleet state during record_fleet_state().

On the other hand, node_storage.store_node_metadata() call had a different logic - since it did not accumulate changes and instead just saved the given one in the dictionary, the newer object always overwrote the older one.

Therefore, during the assertion in the test, where known_nodes is compared with the node_storage, two things could happen:

  • The seednode sprout never had mature() called on it. In that case the lists would differ, since two different sprout objects with the same checksum addresses were not considered equal.
  • The seednode sprout (the newer one) had mature() called on it. In that case, one would see an Ursula object in one list, and a NodeSprout in the other, and the test would fail just the same.

Solution to this may vary depending on what semantics exactly we want. Currently, I committed the following solution:

  • add NodeSprout.__eq__() (two sprouts are equal if their checksum addresses are equal)
  • force the replacement behavior of the older object with the newer one in FleetSensor.record_node(), to match that of the node storage.

This seems to fix the issue. Although perhaps it is not the best solution, since it does not fix the similarly looking failure in test_learner_uses_both_nodes_from_storage_and_fallback_nodes.

Why it appeared in this PR? node.mature() in FleetSensor which was removed in this PR converted the sprout into an Ursula, and two Ursulas with the same stamps are considered equal, so only the former possibility from the list above caused a test failure, making it much more rare.

To be continued.

(Edit) Damn, this change opened the hell's gate.

@fjarri fjarri changed the title Provide required info for nucypher-monitor without unnecessarily maturing sprouts [WIP] Provide required info for nucypher-monitor without unnecessarily maturing sprouts May 24, 2021
@fjarri
Copy link
Copy Markdown
Contributor Author

fjarri commented May 24, 2021

More investigation.

The introduction of NodeSprout.__eq__ in this PR broke logic in remember_node(). At the start there, we're comparing node == self, and if True, we don't remember the node. This worked because if node was a NodeSprout, it didn't have __eq__, and the Character.__eq__ (of self) was called, which only needed other.stamp. The initial version of NodeSprout.__eq__ I added only compared sprouts to sprouts, so it allowed node to remember itself in FleetSensor, causing test failures.

Additionally, sets of mixed Ursula and NodeSprout objects could not be compared in tests because even when a sprout and a full Ursula were equal, their hash() was different - sprouts used public_address, and Ursulas used stamp. Since the new NodeSprout.__eq__ uses stamp, it is logical to change NodeSprout.__hash__ to use it as well, because the assumption is that if two objects are equal, their hashes should be equal too.

@fjarri
Copy link
Copy Markdown
Contributor Author

fjarri commented May 24, 2021

The cli failure seems to be present in main as well

@fjarri fjarri changed the title [WIP] Provide required info for nucypher-monitor without unnecessarily maturing sprouts Provide required info for nucypher-monitor without unnecessarily maturing sprouts May 24, 2021
@fjarri fjarri requested a review from KPrasch May 24, 2021 22:00
@fjarri
Copy link
Copy Markdown
Contributor Author

fjarri commented May 25, 2021

The cli failure seems to be present in main as well

Ah, nevermind, it's the probationary period ending again.

@KPrasch KPrasch dismissed their stale review May 26, 2021 18:40

Opened hells gate.

Copy link
Copy Markdown
Member

@derekpierre derekpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎸

fjarri added a commit to fjarri/nucypher that referenced this pull request Jun 1, 2021
fjarri added a commit to fjarri/nucypher that referenced this pull request Jun 1, 2021
fjarri added 5 commits June 1, 2021 16:38
One ended up in FleetSensor, and the other in the node storage,
causing failure in `test_one_node_stores_a_bunch_of_others`
This way any comparison Union[NodeSprout, Character] == Union[NodeSprout, Character] works
This allows comparison of mixed Ursula/NodeSprout sets
fjarri added a commit to fjarri/nucypher that referenced this pull request Jun 2, 2021
Co-authored-by: KPrasch <kieranprasch@gmail.com>
@derekpierre derekpierre merged commit a9c7682 into nucypher:main Jun 7, 2021
@fjarri fjarri deleted the forever-young branch June 7, 2021 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants