diff --git a/nucypher/network/nodes.py b/nucypher/network/nodes.py index 65cf73654..3b6f2f67d 100644 --- a/nucypher/network/nodes.py +++ b/nucypher/network/nodes.py @@ -1382,6 +1382,7 @@ class Teacher: "last_seen": last_seen, "fleet_state": node.fleet_state_checksum or 'unknown', "fleet_state_icon": fleet_icon, + "domain": node.learning_domain, 'version': nucypher.__version__} return payload diff --git a/nucypher/network/server.py b/nucypher/network/server.py index cc83da811..a0d17530a 100644 --- a/nucypher/network/server.py +++ b/nucypher/network/server.py @@ -32,7 +32,6 @@ from web3.exceptions import TimeExhausted import nucypher from nucypher.crypto.api import InvalidNodeCertificate from nucypher.config.constants import MAX_UPLOAD_CONTENT_LENGTH -from nucypher.config.storages import ForgetfulNodeStorage from nucypher.crypto.keypairs import HostingKeypair from nucypher.crypto.kits import UmbralMessageKit from nucypher.crypto.powers import KeyPairBasedPower, PowerUpError @@ -103,9 +102,7 @@ def make_rest_app( return rest_app, datastore -def _make_rest_app(datastore: Datastore, this_node, serving_domain: str, log: Logger) -> Tuple[Flask, Datastore]: - - forgetful_node_storage = ForgetfulNodeStorage(federated_only=this_node.federated_only) # FIXME: Seems unused +def _make_rest_app(datastore: Datastore, this_node, serving_domain: str, log: Logger) -> Flask: from nucypher.characters.lawful import Alice, Ursula _alice_class = Alice @@ -180,8 +177,8 @@ def _make_rest_app(datastore: Datastore, this_node, serving_domain: str, log: Lo @rest_app.route('/node_metadata', methods=["POST"]) def node_metadata_exchange(): - # If these nodes already have the same fleet state, no exchange is necessary. + # If these nodes already have the same fleet state, no exchange is necessary. learner_fleet_state = request.args.get('fleet') if learner_fleet_state == this_node.known_nodes.checksum: log.debug("Learner already knew fleet state {}; doing nothing.".format(learner_fleet_state)) diff --git a/nucypher/network/templates/basic_status.j2 b/nucypher/network/templates/basic_status.j2 index 6e3f96f12..5c69ac163 100644 --- a/nucypher/network/templates/basic_status.j2 +++ b/nucypher/network/templates/basic_status.j2 @@ -107,7 +107,7 @@
({{ checksum_address }})
{{ this_node.nickname_icon }}

v{{ version }}

-

Domains: {% for domain in domains %}{{ domain }} {% endfor %}

+

Domain: {{ domain }}

Fleet State

diff --git a/nucypher/utilities/prometheus/collector.py b/nucypher/utilities/prometheus/collector.py index cc78fc31c..ad31fc7c7 100644 --- a/nucypher/utilities/prometheus/collector.py +++ b/nucypher/utilities/prometheus/collector.py @@ -99,17 +99,17 @@ class UrsulaInfoMetricsCollector(BaseMetricsCollector): "learning_status": Enum(f'{metrics_prefix}_node_discovery', 'Learning loop status', states=['starting', 'running', 'stopped'], registry=registry), "known_nodes_gauge": Gauge(f'{metrics_prefix}_known_nodes', - 'Number of currently known nodes', - registry=registry), + 'Number of currently known nodes', + registry=registry), "work_orders_gauge": Gauge(f'{metrics_prefix}_work_orders', - 'Number of accepted work orders', - registry=registry), + 'Number of accepted work orders', + registry=registry), "policies_held_gauge": Gauge(f'{metrics_prefix}_policies_held', - 'Policies held', - registry=registry), + 'Policies held', + registry=registry), "availability_score_gauge": Gauge(f'{metrics_prefix}_availability_score', - 'Availability score', - registry=registry), + 'Availability score', + registry=registry), } def _collect_internal(self) -> None: @@ -118,6 +118,8 @@ class UrsulaInfoMetricsCollector(BaseMetricsCollector): 'teacher_version': str(self.ursula.TEACHER_VERSION), 'host': str(self.ursula.rest_interface), 'domain': self.ursula.learning_domain, + 'nickname': self.ursula.nickname, + 'nickname_icon': self.ursula.nickname_icon, 'fleet_state': str(self.ursula.known_nodes.checksum), 'known_nodes': str(len(self.ursula.known_nodes)) } diff --git a/tests/integration/learning/test_fleet_state.py b/tests/integration/learning/test_fleet_state.py index ba9528b2e..97c5285b9 100644 --- a/tests/integration/learning/test_fleet_state.py +++ b/tests/integration/learning/test_fleet_state.py @@ -103,3 +103,25 @@ def test_state_is_recorded_after_learning(federated_ursulas, lonely_ursula_maker assert len(states[0].nodes) == 2 # The first fleet state is just us and the one about whom we learned, which is part of the fleet. assert len(states[1].nodes) == len(federated_ursulas) + 1 # When we ran learn_from_teacher_node, we also loaded the rest of the fleet. + + +def test_teacher_records_new_fleet_state_upon_hearing_about_new_node(federated_ursulas, lonely_ursula_maker): + _lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1) + lonely_learner = _lonely_ursula_maker().pop() + + some_ursula_in_the_fleet = list(federated_ursulas)[0] + lonely_learner.remember_node(some_ursula_in_the_fleet) + + + teacher_states_before = list(some_ursula_in_the_fleet.known_nodes.states.values()) + lonely_learner.learn_from_teacher_node() + teacher_states_after = list(some_ursula_in_the_fleet.known_nodes.states.values()) + + # We added one fleet state. + len(teacher_states_after) == len(teacher_states_before) + 1 + + # The current fleet state of the Teacher... + teacher_fleet_state_checksum = some_ursula_in_the_fleet.fleet_state_checksum + + # ...is the same as the learner, because both have learned about everybody at this point. + teacher_fleet_state_checksum in lonely_learner.known_nodes.states