diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 467ebe7c1e6199366594768bcb4a246091157651..3c8030a2583f5458fb102726a83a6be2d501c049 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -71,5 +71,5 @@ nixpkgs We pin to a nixos channel release, which isn't directly supported by niv (`issue <https://github.com/nmattia/niv/issues/225>`_). Thus, the pin needs to be update manually. -To do this, copy the ``url`` and ``sha256`` values from PrivateStorageio's `nixpkgs-2105.json <https://whetstone.privatestorage.io/privatestorage/PrivateStorageio/-/blob/develop/nixpkgs-2105.json>`_ into the ``release2015`` entry in ``nix/sources.json``. +To do this, copy the ``url`` and ``sha256`` values from PrivateStorageio's `nixpkgs-2105.json <https://whetstone.privatestorage.io/privatestorage/PrivateStorageio/-/blob/develop/nixpkgs-2105.json>`_ into the ``release2105`` entry in ``nix/sources.json``. When this is deployed as part of Privatestorageio, we use the value pinned there, rather than the pin in this repository. diff --git a/default.nix b/default.nix index 7f9b277c7290c3a277c7f80ff194ddabbb32c00b..e2b8e609769c6f559bf77fbbe28beee11ae53d58 100644 --- a/default.nix +++ b/default.nix @@ -1,7 +1,7 @@ let sources = import nix/sources.nix; in -{ pkgs ? import sources.release2015 {} +{ pkgs ? import sources.release2105 {} , pypiData ? sources.pypi-deps-db , mach-nix ? import sources.mach-nix { inherit pkgs pypiData; } , tahoe-lafs-source ? "tahoe-lafs" @@ -30,13 +30,25 @@ in traceback2 = "wheel"; # - Incorrectly merged extras - https://github.com/DavHau/mach-nix/pull/334 tqdm = "wheel"; + + # The version of Klein we get doesn't need / can't have the patch that + # comes from the nixpkgs derivation mach-nix picks up from 21.05. + klein = "wheel"; }; in rec { tahoe-lafs = mach-nix.buildPythonPackage rec { inherit python providers; name = "tahoe-lafs"; - version = "1.16.post999"; + # We add `.post999` here so that we don't accidentally *exactly* match + # the upstream Tahoe-LAFS version. This avoids the misleading + # circumstance where the version in the Nix packaging *looks* like a + # real upstream Tahoe-LAFS revision but we have forgotten to update it + # so it is the *wrong* real upstream Tahoe-LAFS revision. Hopefully + # the `.post999` looks weird enough that if someone really cares about + # the version in use they will notice it and go searching for what's + # going on and discover the real version specified by `src` below. + version = "1.17.0.post999"; # See https://github.com/DavHau/mach-nix/issues/190 requirementsExtra = '' pyrsistent < 0.17 diff --git a/nix/sources.json b/nix/sources.json index 9ce1d8e0cf1793a5db2e50d82e8758ec645578e7..fdde626e48c8f4c98f24532a65da6829345b6f6e 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -35,7 +35,7 @@ "url": "https://github.com/DavHau/pypi-deps-db/archive/96d01556b4597c022647acbf8c3b58d2a99bc963.tar.gz", "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" }, - "release2015": { + "release2105": { "sha256": "112drvixj81vscj8cncmks311rk2ik5gydpd03d3r0yc939zjskg", "type": "tarball", "url": "https://releases.nixos.org/nixos/21.05/nixos-21.05.3740.ce7a1190a0f/nixexprs.tar.xz", @@ -47,10 +47,10 @@ "homepage": "https://tahoe-lafs.org/", "owner": "tahoe-lafs", "repo": "tahoe-lafs", - "rev": "d3c6f58a8ded7db3324ef97c47f5c1921c3d58b7", - "sha256": "18zr6l53r32pigymsnv10m67kgf981bxl8c3rjhv5bikfnf986q8", + "rev": "tahoe-lafs-1.17.0", + "sha256": "0vjq7g1lfjd16y0iwnfsccp5k3q3av7wllkyqbsyd877a29nibzi", "type": "tarball", - "url": "https://github.com/tahoe-lafs/tahoe-lafs/archive/d3c6f58a8ded7db3324ef97c47f5c1921c3d58b7.tar.gz", + "url": "https://github.com/tahoe-lafs/tahoe-lafs/archive/tahoe-lafs-1.17.0.tar.gz", "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" } } diff --git a/setup.cfg b/setup.cfg index c1c6250091326d2793a6d2d3ed9843dcde0b0578..6d39a54cf210521314307ad39114e59389be8e12 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,13 +40,8 @@ install_requires = # The pip resolver sometimes finds treq's dependencies first and these are # incompatible with Tahoe-LAFS'. So duplicate them here (the ones that # have been observed to cause problems). - Twisted[tls,conch]>=18.4.0 - - # Lease renewal changes aren't available from a release of Tahoe yet. - # Note "Public index servers SHOULD NOT allow the use of direct references - # in uploaded distributions." - # https://www.python.org/dev/peps/pep-0440/#direct-references - tahoe-lafs @ https://github.com/tahoe-lafs/tahoe-lafs/archive/d3c6f58a8ded7db3324ef97c47f5c1921c3d58b7.zip + Twisted[tls,conch] >= 19.10.0 + tahoe-lafs >=1.17,<1.18 treq pyutil prometheus-client diff --git a/shell.nix b/shell.nix index f34fcf949ca84d7b092cf06761aae4f03db8df51..0f661ebc3692fbf6bfe199abc0cbd8fbd6feaa8e 100644 --- a/shell.nix +++ b/shell.nix @@ -1,7 +1,7 @@ let sources = import nix/sources.nix; in -{ pkgs ? import sources.release2015 {} +{ pkgs ? import sources.release2105 {} , tahoe-lafs-source ? "tahoe-lafs" }: let diff --git a/src/_zkapauthorizer/_storage_server.py b/src/_zkapauthorizer/_storage_server.py index 5fdf3e473b27086abd680481b736ecd9888695f4..809b385118b2a2f27c32e623c5d97bea2b8fc3be 100644 --- a/src/_zkapauthorizer/_storage_server.py +++ b/src/_zkapauthorizer/_storage_server.py @@ -33,7 +33,9 @@ from struct import calcsize, unpack import attr from allmydata.interfaces import RIStorageServer, TestAndWriteVectorsForShares from allmydata.storage.common import storage_index_to_dir +from allmydata.storage.immutable import ShareFile from allmydata.storage.lease import LeaseInfo +from allmydata.storage.mutable import MutableShareFile from allmydata.storage.server import StorageServer from allmydata.storage.shares import get_share_file from allmydata.util.base32 import b2a @@ -721,7 +723,7 @@ def get_storage_index_share_size(sharepath): # From src/allmydata/storage/immutable.py # # The share file has the following layout: - # 0x00: share file version number, four bytes, current version is 1 + # 0x00: share file version number, four bytes, current version is 2 # 0x04: share data length, four bytes big-endian = A # See Footnote 1 below. # 0x08: number of leases, four bytes big-endian # 0x0c: beginning of share data (see immutable.layout.WriteBucketProxy) @@ -756,12 +758,14 @@ def get_storage_index_share_size(sharepath): version, _, number_of_leases = unpack(header_format, header) - if version != 1: - raise ValueError( - "Cannot interpret version {} share file.".format(version), - ) + if version in (1, 2): + # Version 1 and 2 don't differ in a way that changes the size + # calculation. + return share_file_size - header_size - (number_of_leases * (4 + 32 + 32 + 4)) - return share_file_size - header_size - (number_of_leases * (4 + 32 + 32 + 4)) + raise ValueError( + "Cannot interpret version {} share file.".format(version), + ) def stat_bucket(storage_server, storage_index, sharepath): @@ -824,10 +828,16 @@ def get_stat(sharepath): # Figure out if it is a storage index or a slot. with open(sharepath, "rb") as share_file: magic = share_file.read(32) - if magic == "Tahoe mutable container v1\n" + "\x75\x09\x44\x03\x8e": + if len(magic) < 32: + # Tahoe could check for this. + # https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3853 + raise ValueError("Share file has short header") + if ShareFile.is_valid_header(magic): + return stat_bucket + elif MutableShareFile.is_valid_header(magic): return stat_slot else: - return stat_bucket + raise ValueError("Cannot interpret share header {!r}".format(magic)) def add_leases_for_writev(storage_server, storage_index, secrets, tw_vectors, now): @@ -847,6 +857,7 @@ def add_leases_for_writev(storage_server, storage_index, secrets, tw_vectors, no (write_enabler, renew_secret, cancel_secret) = secrets share = get_share_file(sharepath) share.add_or_renew_lease( + storage_server.get_available_space(), LeaseInfo( owner_num=1, renew_secret=renew_secret, diff --git a/src/_zkapauthorizer/tests/fixtures.py b/src/_zkapauthorizer/tests/fixtures.py index 3a4e4155fb8cbf4f19c36bd6f0e29c22b2ad79bc..e017eadd6b42f10f6f4255caf5c110d64cfca7de 100644 --- a/src/_zkapauthorizer/tests/fixtures.py +++ b/src/_zkapauthorizer/tests/fixtures.py @@ -21,7 +21,6 @@ from __future__ import absolute_import from base64 import b64encode import attr -from allmydata import __version__ as allmydata_version from allmydata.storage.server import StorageServer from fixtures import Fixture, TempDir from twisted.internet.task import Clock @@ -51,18 +50,10 @@ class AnonymousStorageServer(Fixture): def _setUp(self): self.tempdir = FilePath(self.useFixture(TempDir()).join(b"storage")) - if allmydata_version >= "1.16.": - # This version of Tahoe adds a new StorageServer argument for - # controlling time. - timeargs = {"get_current_time": self.clock.seconds} - else: - # Older versions just use time.time() and there's not much we can - # do _here_. Code somewhere else will have to monkey-patch that - # to control things. - timeargs = {} - self.storage_server = StorageServer( - self.tempdir.asBytesMode().path, b"x" * 20, **timeargs + self.tempdir.asBytesMode().path, + b"x" * 20, + clock=self.clock, ) diff --git a/src/_zkapauthorizer/tests/test_storage_protocol.py b/src/_zkapauthorizer/tests/test_storage_protocol.py index a5b642997cb07c01ced81c33090f59713ef9f34e..89654633b6b9176ec98fb71492571b0467eb42b7 100644 --- a/src/_zkapauthorizer/tests/test_storage_protocol.py +++ b/src/_zkapauthorizer/tests/test_storage_protocol.py @@ -21,7 +21,6 @@ from __future__ import absolute_import from allmydata.storage.common import storage_index_to_dir from allmydata.storage.shares import get_share_file from challenge_bypass_ristretto import PublicKey, random_signing_key -from fixtures import MonkeyPatch from foolscap.referenceable import LocalReferenceable from hypothesis import assume, given from hypothesis.strategies import data as data_strategy @@ -540,33 +539,22 @@ class ShareTests(TestCase): self.clock.advance(when) - # anonymous_storage_server uses time.time() before Tahoe-LAFS 1.16, - # unfortunately. For Tahoe-LAFS 1.16, AnonymousStorageServer will - # glue self.clock in for us. For older versions we still need this - # monkey-patching. - # - # And useFixture does not interact very well with Hypothesis. - patch = MonkeyPatch("time.time", self.clock.seconds) - try: - patch.setUp() - # Create a share we can toy with. - write_shares( - self.anonymous_storage_server, + # Create a share we can toy with. + write_shares( + self.anonymous_storage_server, + storage_index, + {sharenum}, + size, + canary=self.canary, + ) + # Perhaps put some more leases on it. Leases might impact our + # ability to determine share data size. + for renew_secret in leases: + self.anonymous_storage_server.remote_add_lease( storage_index, - {sharenum}, - size, - canary=self.canary, + renew_secret, + cancel_secret, ) - # Perhaps put some more leases on it. Leases might impact our - # ability to determine share data size. - for renew_secret in leases: - self.anonymous_storage_server.remote_add_lease( - storage_index, - renew_secret, - cancel_secret, - ) - finally: - patch.cleanUp() expected = [ { @@ -629,7 +617,7 @@ class ShareTests(TestCase): If a share file with an unexpected version is found, ``stat_shares`` declines to offer a result (by raising ``ValueError``). """ - assume(version != 1) + assume(version not in (1, 2)) sharedir = FilePath(self.anonymous_storage_server.sharedir).preauthChild( # storage_index_to_dir likes to return multiple segments @@ -771,23 +759,18 @@ class ShareTests(TestCase): """ self.clock.advance(when) - patch = MonkeyPatch("time.time", self.clock.seconds) - try: - patch.setUp() - # Create a share we can toy with. - wrote, read = extract_result( - self.client.slot_testv_and_readv_and_writev( - storage_index, - secrets=secrets, - tw_vectors={ - k: v.for_call() - for (k, v) in test_and_write_vectors_for_shares.items() - }, - r_vector=[], - ), - ) - finally: - patch.cleanUp() + # Create a share we can toy with. + wrote, read = extract_result( + self.client.slot_testv_and_readv_and_writev( + storage_index, + secrets=secrets, + tw_vectors={ + k: v.for_call() + for (k, v) in test_and_write_vectors_for_shares.items() + }, + r_vector=[], + ), + ) self.assertThat( wrote, Equals(True), @@ -1052,20 +1035,14 @@ class ShareTests(TestCase): r_vector=[], ) - patch = MonkeyPatch("time.time", self.clock.seconds) - try: - patch.setUp() - - # Create a share we can toy with. - self.assertThat(write(), is_successful_write()) + # Create a share we can toy with. + self.assertThat(write(), is_successful_write()) - # Advance time by more than a lease period so the lease is no - # longer valid. - self.clock.advance(self.server.LEASE_PERIOD.total_seconds() + 1) + # Advance time by more than a lease period so the lease is no + # longer valid. + self.clock.advance(self.server.LEASE_PERIOD.total_seconds() + 1) - self.assertThat(write(), is_successful_write()) - finally: - patch.cleanUp() + self.assertThat(write(), is_successful_write()) # The spent passes have been reported to the spending service. self.assertThat( diff --git a/tests.nix b/tests.nix index 7023c06a296dfd5be2cb3468c789d7038ac25add..c985ce0f41b39c886b67788243835d2ee8605808 100644 --- a/tests.nix +++ b/tests.nix @@ -1,7 +1,7 @@ let sources = import nix/sources.nix; in -{ pkgs ? import sources.release2015 {} +{ pkgs ? import sources.release2105 {} , pypiData ? sources.pypi-deps-db , mach-nix ? import sources.mach-nix { inherit pkgs pypiData; } , tahoe-lafs-source ? "tahoe-lafs" @@ -20,7 +20,7 @@ in inherit (pkgs) lib; inherit (privatestorage) zkapauthorizer; hypothesisProfile' = if hypothesisProfile == null then "default" else hypothesisProfile; - defaultTrialArgs = [ "--rterrors" ] ++ (lib.optional (! collectCoverage) "--jobs=$NIX_BUILD_CORES"); + defaultTrialArgs = [ "--rterrors" ] ++ (lib.optional (! collectCoverage) "--jobs=$(($NIX_BUILD_CORES > 8 ? 8 : $NIX_BUILD_CORES))"); trialArgs' = if trialArgs == null then defaultTrialArgs else trialArgs; extraTrialArgs = builtins.concatStringsSep " " trialArgs'; testSuite' = if testSuite == null then "_zkapauthorizer" else testSuite;