From 326ff623d9b253864920531591d607efb94c87e0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Mon, 22 Nov 2021 10:50:20 -0500 Subject: [PATCH] Add a counter of valid spent passes on the storage server --- src/_zkapauthorizer/_storage_server.py | 16 ++++++- .../tests/test_storage_server.py | 46 ++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/_zkapauthorizer/_storage_server.py b/src/_zkapauthorizer/_storage_server.py index 38ba354..1c1488b 100644 --- a/src/_zkapauthorizer/_storage_server.py +++ b/src/_zkapauthorizer/_storage_server.py @@ -41,7 +41,7 @@ from attr.validators import instance_of, provides from challenge_bypass_ristretto import SigningKey, TokenPreimage, VerificationSignature from eliot import start_action from foolscap.api import Referenceable -from prometheus_client import CollectorRegistry +from prometheus_client import CollectorRegistry, Counter from twisted.internet.defer import Deferred from twisted.internet.interfaces import IReactorTime from twisted.python.reflect import namedAny @@ -172,11 +172,22 @@ class ZKAPAuthorizerStorageServer(Referenceable): _original = attr.ib(validator=provides(RIStorageServer)) _pass_value = pass_value_attribute() _signing_key = attr.ib(validator=instance_of(SigningKey)) - _registry = attr.ib(default=attr.Factory(CollectorRegistry)) + _registry = attr.ib( + default=attr.Factory(CollectorRegistry), + validator=attr.validators.instance_of(CollectorRegistry), + ) _clock = attr.ib( validator=provides(IReactorTime), default=attr.Factory(partial(namedAny, "twisted.internet.reactor")), ) + _metric_spending_successes = attr.ib(init=False) + + def __attrs_post_init__(self): + self._metric_spending_successes = Counter( + "zkapauthorizer_server_spending_successes", + "ZKAP Spending Successes Counter", + registry=self._registry, + ) def remote_get_version(self): """ @@ -204,6 +215,7 @@ class ZKAPAuthorizerStorageServer(Referenceable): passes, self._signing_key, ) + self._metric_spending_successes.inc(len(validation.valid)) # Note: The *allocate_buckets* protocol allows for some shares to # already exist on the server. When this is the case, the cost of the diff --git a/src/_zkapauthorizer/tests/test_storage_server.py b/src/_zkapauthorizer/tests/test_storage_server.py index cdff293..3e7ce1b 100644 --- a/src/_zkapauthorizer/tests/test_storage_server.py +++ b/src/_zkapauthorizer/tests/test_storage_server.py @@ -162,7 +162,7 @@ class PassValidationTests(TestCase): self.anonymous_storage_server, self.pass_value, self.signing_key, - self.clock, + clock=self.clock, ) def setup_example(self): @@ -559,3 +559,47 @@ class PassValidationTests(TestCase): actual_sizes, Equals(expected_sizes), ) + + @given( + storage_index=storage_indexes(), + renew_secret=lease_renew_secrets(), + cancel_secret=lease_cancel_secrets(), + sharenums=sharenum_sets(), + size=sizes(), + ) + def test_immutable_spending_metrics( + self, storage_index, renew_secret, cancel_secret, sharenums, size + ): + """ + When ZKAPs are spent to call *allocate_buckets* the number of passes spent is recorded as a metric. + """ + expected = required_passes( + self.storage_server._pass_value, [size] * len(sharenums) + ) + valid_passes = make_passes( + self.signing_key, + allocate_buckets_message(storage_index), + list(RandomToken.create() for i in range(expected)), + ) + + before_count = self.storage_server._metric_spending_successes._value.get() + alreadygot, allocated = self.storage_server.doRemoteCall( + "allocate_buckets", + (), + dict( + passes=valid_passes, + storage_index=storage_index, + renew_secret=renew_secret, + cancel_secret=cancel_secret, + sharenums=sharenums, + allocated_size=size, + canary=LocalReferenceable(None), + ), + ) + + after_count = self.storage_server._metric_spending_successes._value.get() + + self.assertThat( + after_count - before_count, + Equals(expected), + ) -- GitLab