From 4d65b1914d96993986f2e1df143649be39e6e149 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Thu, 19 Dec 2019 10:33:24 -0500
Subject: [PATCH] Fix the stat_shares interface and fix the tests and
 implementation

---
 src/_zkapauthorizer/foolscap.py                     | 9 ++++++++-
 src/_zkapauthorizer/lease_maintenance.py            | 7 ++++++-
 src/_zkapauthorizer/tests/test_lease_maintenance.py | 3 +--
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/_zkapauthorizer/foolscap.py b/src/_zkapauthorizer/foolscap.py
index f0137ac..3d69a53 100644
--- a/src/_zkapauthorizer/foolscap.py
+++ b/src/_zkapauthorizer/foolscap.py
@@ -175,9 +175,16 @@ class RIPrivacyPassAuthorizedStorageServer(RemoteInterface):
     ):
         """
         Get various metadata about shares in the given storage index or slot.
+
+        :return [{int: ShareStat}]: A list of share stats.  Dictionaries in
+            the list corresponds to the results for each storage index
+            requested by the ``storage_indexes_or_slots`` argument.  Items in
+            the dictionary give share stats for each share known to this
+            server to be associated with the corresponding storage index.
+            Keys are share numbers and values are the stats.
         """
         # Any() should be ShareStat but I don't know how to spell that.
-        return ListOf(ListOf(DictOf(int, Any())))
+        return ListOf(DictOf(int, Any()))
 
     slot_readv = RIStorageServer["slot_readv"]
 
diff --git a/src/_zkapauthorizer/lease_maintenance.py b/src/_zkapauthorizer/lease_maintenance.py
index 57b8624..4673a87 100644
--- a/src/_zkapauthorizer/lease_maintenance.py
+++ b/src/_zkapauthorizer/lease_maintenance.py
@@ -164,7 +164,12 @@ def renew_leases_on_server(
         been checked and any leases that need renewal have been renewed.
     """
     stats = yield server.stat_shares(storage_indexes)
-    for storage_index, stat in zip(storage_indexes, stats):
+    for storage_index, stat_dict in zip(storage_indexes, stats):
+        if not stat_dict:
+            # The server has no shares for this storage index.
+            continue
+        # All shares have the same lease information.
+        stat = stat_dict.popitem()[1]
         if needs_lease_renew(min_lease_remaining, stat, now):
             yield renew_lease(renewal_secret, storage_index, server)
 
diff --git a/src/_zkapauthorizer/tests/test_lease_maintenance.py b/src/_zkapauthorizer/tests/test_lease_maintenance.py
index bbd12c0..e30444b 100644
--- a/src/_zkapauthorizer/tests/test_lease_maintenance.py
+++ b/src/_zkapauthorizer/tests/test_lease_maintenance.py
@@ -132,10 +132,9 @@ class DummyStorageServer(object):
 
     def stat_shares(self, storage_indexes):
         return succeed(list(
-            self.buckets[idx]
+            {0: self.buckets[idx]} if idx in self.buckets else {}
             for idx
             in storage_indexes
-            if idx in self.buckets
         ))
 
     def get_lease_seed(self):
-- 
GitLab