From f59d3b5fcc351edf79e8388a047709580fd04a5c Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Thu, 22 Jul 2021 16:29:36 -0400
Subject: [PATCH] Move observed public key from voucher to redemption group

It is observed for each redemption group and it could vary for groups
belonging to a single voucher.
---
 src/_zkapauthorizer/model.py                  | 13 ++-----------
 src/_zkapauthorizer/schema.py                 | 19 ++++++++++++-------
 src/_zkapauthorizer/tests/strategies.py       |  1 -
 .../tests/test_client_resource.py             |  4 ----
 src/_zkapauthorizer/tests/test_controller.py  |  4 ----
 src/_zkapauthorizer/tests/test_model.py       |  1 -
 6 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/src/_zkapauthorizer/model.py b/src/_zkapauthorizer/model.py
index f10552f..3dc7beb 100644
--- a/src/_zkapauthorizer/model.py
+++ b/src/_zkapauthorizer/model.py
@@ -456,9 +456,9 @@ class VoucherStore(object):
 
         cursor.execute(
             """
-            INSERT INTO [redemption-groups] ([voucher], [spendable]) VALUES (?, ?)
+            INSERT INTO [redemption-groups] ([voucher], [public-key], [spendable]) VALUES (?, ?, ?)
             """,
-            (voucher, spendable),
+            (voucher, public_key, spendable),
         )
         group_id = cursor.lastrowid
 
@@ -469,7 +469,6 @@ class VoucherStore(object):
               , [token-count] = COALESCE([token-count], 0) + ?
               , [sequestered-count] = COALESCE([sequestered-count], 0) + ?
               , [finished] = ?
-              , [public-key] = ?
               , [counter] = [counter] + 1
             WHERE [number] = ?
             """,
@@ -478,7 +477,6 @@ class VoucherStore(object):
                 token_count_increase,
                 sequestered_count_increase,
                 self.now(),
-                public_key,
                 voucher,
             ),
         )
@@ -978,13 +976,9 @@ class Redeemed(object):
     :ivar datetime finished: The time when the redemption finished.
 
     :ivar int token_count: The number of tokens the voucher was redeemed for.
-
-    :ivar unicode public_key: The public part of the key used to sign the
-        tokens for this voucher.
     """
     finished = attr.ib(validator=attr.validators.instance_of(datetime))
     token_count = attr.ib(validator=attr.validators.instance_of((int, long)))
-    public_key = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(unicode)))
 
     def should_start_redemption(self):
         return False
@@ -994,7 +988,6 @@ class Redeemed(object):
             u"name": u"redeemed",
             u"finished": self.finished.isoformat(),
             u"token-count": self.token_count,
-            u"public-key": self.public_key,
         }
 
 
@@ -1117,7 +1110,6 @@ class Voucher(object):
                 return Redeemed(
                     parse_datetime(row[0], delimiter=u" "),
                     row[1],
-                    row[2],
                 )
             raise ValueError("Unknown voucher state {}".format(state))
 
@@ -1161,7 +1153,6 @@ class Voucher(object):
             state = Redeemed(
                 finished=parse_datetime(state_json[u"finished"]),
                 token_count=state_json[u"token-count"],
-                public_key=state_json[u"public-key"],
             )
         elif state_name == u"unpaid":
             state = Unpaid(
diff --git a/src/_zkapauthorizer/schema.py b/src/_zkapauthorizer/schema.py
index 2d66273..24c402b 100644
--- a/src/_zkapauthorizer/schema.py
+++ b/src/_zkapauthorizer/schema.py
@@ -128,6 +128,8 @@ _UPGRADES = {
 
     1: [
         """
+        -- Incorrectly track a single public-key for all.  Later version of
+        -- the schema moves this elsewhere.
         ALTER TABLE [vouchers] ADD COLUMN [public-key] text
         """,
     ],
@@ -169,10 +171,6 @@ _UPGRADES = {
     ],
 
     5: [
-        """
-        ALTER TABLE [vouchers] ADD COLUMN [sequestered-count] integer NOT NULL DEFAULT 0
-        """,
-
         """
         -- Create a table where rows represent a single group of unblinded
         -- tokens all redeemed together.  Some number of these rows represent
@@ -186,13 +184,20 @@ _UPGRADES = {
 
             -- A flag indicating whether these tokens can be spent or if
             -- they're being held for further inspection.
-            [spendable] integer
+            [spendable] integer,
+
+            -- The public key seen when redeeming this group.
+            [public-key] text
         )
         """,
 
         """
-        INSERT INTO [redemption-groups] ([voucher], [spendable])
-            SELECT DISTINCT([number]), 1 FROM [vouchers] WHERE [state] = "redeemed"
+        INSERT INTO [redemption-groups] ([voucher], [public-key], [spendable])
+            SELECT DISTINCT([number]), [public-key], 1 FROM [vouchers] WHERE [state] = "redeemed"
+        """,
+
+        """
+        ALTER TABLE [vouchers] ADD COLUMN [sequestered-count] integer NOT NULL DEFAULT 0
         """,
 
         """
diff --git a/src/_zkapauthorizer/tests/strategies.py b/src/_zkapauthorizer/tests/strategies.py
index 2a8590e..818a350 100644
--- a/src/_zkapauthorizer/tests/strategies.py
+++ b/src/_zkapauthorizer/tests/strategies.py
@@ -434,7 +434,6 @@ def redeemed_states():
         Redeemed,
         finished=datetimes(),
         token_count=one_of(integers(min_value=1)),
-        public_key=dummy_ristretto_keys(),
     )
 
 
diff --git a/src/_zkapauthorizer/tests/test_client_resource.py b/src/_zkapauthorizer/tests/test_client_resource.py
index 2bee0fb..5bee598 100644
--- a/src/_zkapauthorizer/tests/test_client_resource.py
+++ b/src/_zkapauthorizer/tests/test_client_resource.py
@@ -1161,7 +1161,6 @@ class VoucherTests(TestCase):
         are included in a json-encoded response body.
         """
         count = get_token_count("privatestorageio-zkapauthz-v1", config)
-        public_key = get_dummyredeemer_public_key("privatestorageio-zkapauthz-v1", config)
         return self._test_get_known_voucher(
             config,
             api_auth_token,
@@ -1174,7 +1173,6 @@ class VoucherTests(TestCase):
                 state=Equals(Redeemed(
                     finished=now,
                     token_count=count,
-                    public_key=public_key,
                 )),
             ),
         )
@@ -1340,7 +1338,6 @@ class VoucherTests(TestCase):
         vouchers.
         """
         count = get_token_count("privatestorageio-zkapauthz-v1", config)
-        public_key = get_dummyredeemer_public_key("privatestorageio-zkapauthz-v1", config)
         return self._test_list_vouchers(
             config,
             api_auth_token,
@@ -1355,7 +1352,6 @@ class VoucherTests(TestCase):
                         state=Redeemed(
                             finished=now,
                             token_count=count,
-                            public_key=public_key,
                         ),
                     ).marshal()
                     for voucher
diff --git a/src/_zkapauthorizer/tests/test_controller.py b/src/_zkapauthorizer/tests/test_controller.py
index be05ec1..cf7726f 100644
--- a/src/_zkapauthorizer/tests/test_controller.py
+++ b/src/_zkapauthorizer/tests/test_controller.py
@@ -138,7 +138,6 @@ from .strategies import (
     voucher_counters,
     redemption_group_counts,
     dummy_ristretto_keys,
-    token_counts,
     clocks,
 )
 from .matchers import (
@@ -407,7 +406,6 @@ class PaymentControllerTests(TestCase):
                 model_Redeemed(
                     finished=now,
                     token_count=num_tokens,
-                    public_key=public_key,
                 ),
             ),
         )
@@ -468,7 +466,6 @@ class PaymentControllerTests(TestCase):
             Equals(model_Redeemed(
                 finished=now,
                 token_count=100,
-                public_key=public_key,
             )),
         )
 
@@ -708,7 +705,6 @@ class PaymentControllerTests(TestCase):
                     model_Redeemed(
                         finished=datetime_now(),
                         token_count=allowed_token_count,
-                        public_key=all_public_keys[-1],
                     ),
                 ),
             ),
diff --git a/src/_zkapauthorizer/tests/test_model.py b/src/_zkapauthorizer/tests/test_model.py
index 3ff7b56..5af0027 100644
--- a/src/_zkapauthorizer/tests/test_model.py
+++ b/src/_zkapauthorizer/tests/test_model.py
@@ -807,7 +807,6 @@ class UnblindedTokenStoreTests(TestCase):
                 state=Equals(Redeemed(
                     finished=now,
                     token_count=num_tokens,
-                    public_key=public_key,
                 )),
             ),
         )
-- 
GitLab