From 3de5a464835d79a1c7288a9a17fcdc79072fa231 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 11 Dec 2020 04:18:03 +0000 Subject: [PATCH] work on adjusting tests --- onionrblocks/__init__.py | 4 -- onionrblocks/create.py | 50 ---------------------- onionrblocks/{types.py => customtypes.py} | 0 onionrblocks/generators/anonvdf.py | 0 onionrblocks/loadblockobject.py | 19 --------- onionrblocks/universalrules.py | 52 +++++++++++++++++++++++ requirements.in | 2 +- requirements.txt | 6 +-- tests/test_universal_rules.py | 47 ++++++++++++++++++++ tests/test_vdf_block.py | 24 ----------- 10 files changed, 103 insertions(+), 101 deletions(-) delete mode 100644 onionrblocks/create.py rename onionrblocks/{types.py => customtypes.py} (100%) create mode 100644 onionrblocks/generators/anonvdf.py delete mode 100644 onionrblocks/loadblockobject.py create mode 100644 onionrblocks/universalrules.py create mode 100644 tests/test_universal_rules.py delete mode 100644 tests/test_vdf_block.py diff --git a/onionrblocks/__init__.py b/onionrblocks/__init__.py index 8e95948..ff576a8 100644 --- a/onionrblocks/__init__.py +++ b/onionrblocks/__init__.py @@ -5,7 +5,3 @@ from binascii import hexlify import kasten -from .types import AnonymousVDFBlockResult -from .create import create_block_anonymous_vdf - - diff --git a/onionrblocks/create.py b/onionrblocks/create.py deleted file mode 100644 index 2824232..0000000 --- a/onionrblocks/create.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import Union -from time import time - -import kasten - -from .types import AnonymousVDFBlockResult - - -def __str_to_bytes(data: str): - try: - return data.encode('utf-8') - except AttributeError: - return data - - -def _packer(block_data: bytes, **kasten_header) -> kasten.main.KastenPacked: - def __get_optional(key, default): - try: - return kasten_header[key] - except KeyError: - return default - # Todo: validate length sanities - return kasten.generator.pack.pack( - block_data, - kasten_header['type'], - kasten_header['encrypt mode'], - __get_optional('signer', b''), - __get_optional('signature', b''), - __get_optional('metadata', None), - int(time()//60 * 60) - ) - -# Block creation functions handle calling the proof and compiling blocks -# They do not handle sigs or encryption (at least never directly) - - -def create_block_anonymous_vdf( - rounds: int, - block_data: Union[str, bytes], - **block_header) -> AnonymousVDFBlockResult: - block_data = __str_to_bytes(block_data) - # Block with anonymous VDF as proof - - packed: kasten.types.KastenPacked = _packer(block_data, **block_header) - kasten_result: kasten.Kasten = \ - kasten.generator.KastenMimcGenerator.generate(packed, rounds) - - return AnonymousVDFBlockResult( - kasten_result.id, - kasten_result.get_packed()) diff --git a/onionrblocks/types.py b/onionrblocks/customtypes.py similarity index 100% rename from onionrblocks/types.py rename to onionrblocks/customtypes.py diff --git a/onionrblocks/generators/anonvdf.py b/onionrblocks/generators/anonvdf.py new file mode 100644 index 0000000..e69de29 diff --git a/onionrblocks/loadblockobject.py b/onionrblocks/loadblockobject.py deleted file mode 100644 index ecac971..0000000 --- a/onionrblocks/loadblockobject.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Union - -from kasten.types import KastenPacked -from kasten import Kasten -from kasten.generator import KastenMimcGenerator - -from .types import DecChecksum, DecChecksumStr, HexChecksum - - -def load_anonymous_vdf_block( - expected_id: Union[DecChecksum, DecChecksumStr, HexChecksum], - raw_block: KastenPacked, - rounds: 'MimcRoundsInt') -> Kasten: - """Load a block created with the KastenMimcGenerator - - take expected checksum, bytes and rounds - - Throws kasten.generator.InvalidID if data does not match raw bytes""" - return Kasten(expected_id, raw_block, KastenMimcGenerator, *[rounds]) \ No newline at end of file diff --git a/onionrblocks/universalrules.py b/onionrblocks/universalrules.py new file mode 100644 index 0000000..54ad1f1 --- /dev/null +++ b/onionrblocks/universalrules.py @@ -0,0 +1,52 @@ +from kasten import Kasten + +from time import time +from math import floor + +MAX_AGE_SECONDS = 60 * 60 * 24 * 30 +MAX_FUTURE_SKEW_SECONDS = 60 * 2 +TOTAL_MAX_SIZE = 6 * (10**6) + + +class BlockRulesException(Exception): + pass + + +class BlockOutdated(BlockRulesException): + pass + +class BlockExpired(Exception): + pass + +class BlockFutureSkewedBeyondMax(BlockRulesException): + pass + + +class BlockTooLarge(BlockRulesException): + pass + + +def check_block_sanity(raw_bytes): + kasten: Kasten = Kasten(None, raw_bytes, None, auto_check_generator=False) + + # Ensure a block is not too large + if len(kasten.get_packed()) > TOTAL_MAX_SIZE: + raise BlockTooLarge() + + # Ensure block is not future-skewed or expired + timestamp: int = floor(time()) + block_timestamp = kasten.get_timestamp() + difference = timestamp - block_timestamp + if difference > MAX_AGE_SECONDS: + raise BlockOutdated() + if difference < -MAX_FUTURE_SKEW_SECONDS: + raise BlockFutureSkewedBeyondMax() + + try: + if timestamp < block_timestamp + kasten.get_metadata()[ + 'expire']: + raise BlockExpired() + except (IndexError, TypeError): + pass + + diff --git a/requirements.in b/requirements.in index 9ba2d81..9603b8e 100644 --- a/requirements.in +++ b/requirements.in @@ -1 +1 @@ -kasten==0.1.0 +kasten==1.0.0 diff --git a/requirements.txt b/requirements.txt index 312780f..644a269 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,9 +4,9 @@ # # pip-compile --generate-hashes requirements.in # -kasten==0.1.0 \ - --hash=sha256:21214afc1e61eb32bafdebbedc1856de973a0ac0798c1710787b889c7f9e9899 \ - --hash=sha256:a5d583f383778d256e56f69fa50c3c22e8fb1aa95923ff3d1c8f915e1235418e \ +kasten==1.0.0 \ + --hash=sha256:6da77272abbc139bc8e4d7a3c89512f708f5a1cafdabad36c12cd7466a5afe01 \ + --hash=sha256:bef1d048b507ef35b0b8a0baad0f56b843cded2818352ebe3e956ef4aeb28053 \ # via -r requirements.in mimcvdf==1.1.0 \ --hash=sha256:97a4ccdebb58352c64c268d2e57ef8817c9fe4ac3dcc922410bfcc72033f344a \ diff --git a/tests/test_universal_rules.py b/tests/test_universal_rules.py new file mode 100644 index 0000000..08740da --- /dev/null +++ b/tests/test_universal_rules.py @@ -0,0 +1,47 @@ +import unittest +from onionrblocks import universalrules +import kasten + +from time import time +from math import floor + +class TestUniversalRules(unittest.TestCase): + + def test_block_is_sane_max_size(self): + packed = kasten.generator.pack.pack(b"1"*6000000, b"tst", 0) + self.assertRaises( + universalrules.BlockTooLarge, + universalrules.check_block_sanity, packed) + + def test_block_too_old(self): + packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=1000) + self.assertRaises( + universalrules.BlockOutdated, + universalrules.check_block_sanity, packed) + + def test_block_future_skew_ok(self): + t = floor(time()) + 120 + packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t) + universalrules.check_block_sanity(packed) + + def test_block_future_skew_not_ok(self): + t = floor(time()) + 121 + packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t) + self.assertRaises( + universalrules.BlockFutureSkewedBeyondMax, + universalrules.check_block_sanity, packed) + + def test_block_not_expired(self): + packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, app_metadata={"expire": 10000}) + self.assertRaises( + universalrules.BlockExpired, + universalrules.check_block_sanity, packed) + + def test_block_expired(self): + t = floor(time()) - 6 + packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t, app_metadata={"expire": 5}) + self.assertRaises( + universalrules.BlockExpired, + universalrules.check_block_sanity, packed) + +unittest.main() \ No newline at end of file diff --git a/tests/test_vdf_block.py b/tests/test_vdf_block.py deleted file mode 100644 index 1b8dd88..0000000 --- a/tests/test_vdf_block.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -import binascii - -import kasten - -import onionrblocks - -class TestVDFBlock(unittest.TestCase): - - def test_vdf_create(self): - rounds = 10**4 - data = b'test data' - k = onionrblocks.create_block_anonymous_vdf(rounds, data, **{'type': 'test', 'encrypt mode': 0}) - raw = k.raw_bytes - id = int.from_bytes(k.dec_checksum, byteorder="big") - #print(id, raw) - print(id, raw) - kasten.generator.KastenMimcGenerator.validate_id(id, raw, rounds) - self.assertEqual(len(raw), 22) - - def test_vdf_auto_validate_loader - - -unittest.main() \ No newline at end of file