From 4a6bca7da1c7fc3d9d21f0c9c8b854305da2db1b Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Wed, 20 May 2020 12:43:36 -0400
Subject: [PATCH] Move some of the spending implementation to a new module

---
 src/_zkapauthorizer/_plugin.py           | 25 +++++++-------
 src/_zkapauthorizer/spending.py          | 42 ++++++++++++++++++++++++
 src/_zkapauthorizer/tests/test_plugin.py |  2 +-
 3 files changed, 54 insertions(+), 15 deletions(-)
 create mode 100644 src/_zkapauthorizer/spending.py

diff --git a/src/_zkapauthorizer/_plugin.py b/src/_zkapauthorizer/_plugin.py
index 4e19a39..e653955 100644
--- a/src/_zkapauthorizer/_plugin.py
+++ b/src/_zkapauthorizer/_plugin.py
@@ -64,10 +64,6 @@ from .api import (
     ZKAPAuthorizerStorageClient,
 )
 
-from .eliot import (
-    GET_PASSES,
-)
-
 from .model import (
     VoucherStore,
 )
@@ -82,6 +78,10 @@ from .storage_common import (
 from .controller import (
     get_redeemer,
 )
+from .spending import (
+    SpendingController,
+)
+
 from .lease_maintenance import (
     SERVICE_NAME,
     lease_maintenance_service,
@@ -173,16 +173,13 @@ class ZKAPAuthorizer(object):
         """
         from twisted.internet import reactor
         redeemer = self._get_redeemer(node_config, announcement, reactor)
-        extract_unblinded_tokens = self._get_store(node_config).extract_unblinded_tokens
-        def get_passes(message, count):
-            unblinded_tokens = extract_unblinded_tokens(count)
-            passes = redeemer.tokens_to_passes(message, unblinded_tokens)
-            GET_PASSES.log(
-                message=message,
-                count=count,
-            )
-            return passes
-
+        store = self._get_store(node_config)
+        # XXX Need to ensure one of these per store
+        controller = SpendingController(
+            store.extract_unblinded_tokens,
+            redeemer.tokens_to_passes,
+        )
+        get_passes = controller.get
         return ZKAPAuthorizerStorageClient(
             get_configured_pass_value(node_config),
             get_rref,
diff --git a/src/_zkapauthorizer/spending.py b/src/_zkapauthorizer/spending.py
new file mode 100644
index 0000000..ac0353c
--- /dev/null
+++ b/src/_zkapauthorizer/spending.py
@@ -0,0 +1,42 @@
+# Copyright 2019 PrivateStorage.io, LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+A module for logic controlling the manner in which ZKAPs are spent.
+"""
+
+import attr
+
+from .eliot import (
+    GET_PASSES,
+)
+
+
+@attr.s
+class SpendingController(object):
+    """
+    A ``SpendingController`` gives out ZKAPs and arranges for re-spend
+    attempts when necessary.
+    """
+    extract_unblinded_tokens = attr.ib()
+    tokens_to_passes = attr.ib()
+
+    def get(self, message, num_passes):
+        unblinded_tokens = self.extract_unblinded_tokens(num_passes)
+        passes = self.tokens_to_passes(message, unblinded_tokens)
+        GET_PASSES.log(
+            message=message,
+            count=num_passes,
+        )
+        return passes
diff --git a/src/_zkapauthorizer/tests/test_plugin.py b/src/_zkapauthorizer/tests/test_plugin.py
index ebd7148..da72930 100644
--- a/src/_zkapauthorizer/tests/test_plugin.py
+++ b/src/_zkapauthorizer/tests/test_plugin.py
@@ -104,7 +104,7 @@ from twisted.plugins.zkapauthorizer import (
     storage_server,
 )
 
-from .._plugin import (
+from ..spending import (
     GET_PASSES,
 )
 
-- 
GitLab