diff --git a/src/_zkapauthorizer/_storage_server.py b/src/_zkapauthorizer/_storage_server.py index e17207a9dce75b8b0e102f3a5ac64cce5a742601..cd6a765434db2fee81e322c4fdf36400a61b3ca2 100644 --- a/src/_zkapauthorizer/_storage_server.py +++ b/src/_zkapauthorizer/_storage_server.py @@ -70,12 +70,18 @@ from allmydata.interfaces import ( from allmydata.storage.common import ( storage_index_to_dir, ) +from allmydata.util.base32 import ( + b2a, +) from challenge_bypass_ristretto import ( TokenPreimage, VerificationSignature, SigningKey, ) +from twisted.internet.defer import ( + Deferred, +) from twisted.python.reflect import ( namedAny, ) @@ -83,6 +89,10 @@ from twisted.internet.interfaces import ( IReactorTime, ) +from eliot import ( + start_action, +) + from .foolscap import ( ShareStat, RIPrivacyPassAuthorizedStorageServer, @@ -318,9 +328,13 @@ class ZKAPAuthorizerStorageServer(Referenceable): return self._original.remote_advise_corrupt_share(*a, **kw) def remote_share_sizes(self, storage_index_or_slot, sharenums): - return dict( - get_share_sizes(self._original, storage_index_or_slot, sharenums) - ) + with start_action( + action_type=u"zkapauthorizer:storage-server:remote:share-sizes", + storage_index_or_slot=storage_index_or_slot, + ): + return dict( + get_share_sizes(self._original, storage_index_or_slot, sharenums) + ) def remote_stat_shares(self, storage_indexes_or_slots): return list( @@ -345,6 +359,30 @@ class ZKAPAuthorizerStorageServer(Referenceable): data in already-allocated storage. These cases may not be the same from the perspective of pass validation. """ + with start_action( + action_type=u"zkapauthorizer:storage-server:remote:slot-testv-and-readv-and-writev", + storage_index=b2a(storage_index), + path=storage_index_to_dir(storage_index), + ): + result = self._slot_testv_and_readv_and_writev( + passes, + storage_index, + secrets, + tw_vectors, + r_vector, + ) + if isinstance(result, Deferred): + raise TypeError("_slot_testv_and_readv_and_writev returned Deferred") + return result + + def _slot_testv_and_readv_and_writev( + self, + passes, + storage_index, + secrets, + tw_vectors, + r_vector, + ): # Only writes to shares without an active lease will result in a lease # renewal. renew_leases = False diff --git a/src/_zkapauthorizer/eliot.py b/src/_zkapauthorizer/eliot.py index 0d52a6246685dcddcea498c421bea8b6d8e96591..1cd64008f3bfc1b1a8670d67c496660c4d8824f0 100644 --- a/src/_zkapauthorizer/eliot.py +++ b/src/_zkapauthorizer/eliot.py @@ -80,3 +80,33 @@ CALL_WITH_PASSES = ActionType( [], u"A storage operation is being started which may spend some passes.", ) + +CURRENT_SIZES = Field( + u"current_sizes", + dict, + u"A dictionary mapping the numbers of existing shares to their existing sizes.", +) + +TW_VECTORS_SUMMARY = Field( + u"tw_vectors_summary", + dict, + u"A dictionary mapping share numbers from tw_vectors to test and write vector summaries.", +) + +NEW_SIZES = Field( + u"new_sizes", + dict, + u"A dictionary like that of CURRENT_SIZES but for the sizes computed for the shares after applying tw_vectors.", +) + +NEW_PASSES = Field( + u"new_passes", + int, + u"The number of passes computed as being required for the change in size.", +) + +MUTABLE_PASSES_REQUIRED = MessageType( + u"zkapauthorizer:storage:mutable-passes-required", + [CURRENT_SIZES, TW_VECTORS_SUMMARY, NEW_SIZES, NEW_PASSES], + u"Some number of passes has been computed as the cost of updating a mutable.", +) diff --git a/src/_zkapauthorizer/storage_common.py b/src/_zkapauthorizer/storage_common.py index 80707f226b892c96cfa5fefd278e68b9146dc7e1..1f429dd50a924557d73950c458f071bd4e9f9721 100644 --- a/src/_zkapauthorizer/storage_common.py +++ b/src/_zkapauthorizer/storage_common.py @@ -30,6 +30,10 @@ from .validators import ( greater_than, ) +from .eliot import ( + MUTABLE_PASSES_REQUIRED, +) + @attr.s(frozen=True) class MorePassesRequired(Exception): """ @@ -180,8 +184,9 @@ def get_implied_data_length(data_vector, new_length): def get_required_new_passes_for_mutable_write(pass_value, current_sizes, tw_vectors): """ :param int pass_value: The value of a single pass in byte-months. + + :param current_sizes: """ - # print("get_required_new_passes_for_mutable_write({}, {})".format(current_sizes, summarize(tw_vectors))) current_passes = required_passes( pass_value, current_sizes.values(), @@ -204,16 +209,23 @@ def get_required_new_passes_for_mutable_write(pass_value, current_sizes, tw_vect ) required_new_passes = new_passes - current_passes - # print("Current sizes: {}".format(current_sizes)) - # print("Current passes: {}".format(current_passes)) - # print("New sizes: {}".format(new_sizes)) - # print("New passes: {}".format(new_passes)) + MUTABLE_PASSES_REQUIRED.log( + current_sizes=current_sizes, + tw_vectors_summary=summarize(tw_vectors), + current_passes=current_passes, + new_sizes=new_sizes, + new_passes=new_passes, + ) return required_new_passes def summarize(tw_vectors): return { sharenum: ( - test_vector, + list( + (offset, length, operator, len(specimen)) + for (offset, length, operator, specimen) + in test_vector + ), list( (offset, len(data)) for (offset, data)