added and implemented block time validation based on VDF time
This commit is contained in:
parent
3de5a46483
commit
2797334059
@ -0,0 +1,49 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
from kasten import Kasten, generator
|
||||||
|
from kasten.types import KastenPacked, KastenChecksum
|
||||||
|
from kasten.exceptions import InvalidID
|
||||||
|
|
||||||
|
from mimcvdf import vdf_create, vdf_verify
|
||||||
|
|
||||||
|
from onionrblocks.universalrules import check_block_sanity
|
||||||
|
|
||||||
|
class AnonVDFGenerator(generator.KastenBaseGenerator):
|
||||||
|
@classmethod
|
||||||
|
def get_ttl_seconds_per_rounds(cls, rounds: int):
|
||||||
|
# 8000 rounds = 1 second (2.8ghz python) = 1 hour storage
|
||||||
|
if rounds < 8000:
|
||||||
|
raise ValueError("Rounds must be at least 8000")
|
||||||
|
return (rounds / 8000) * 60
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate(
|
||||||
|
cls, packed_bytes: KastenPacked, rounds: int = 5000) -> Kasten:
|
||||||
|
return Kasten(
|
||||||
|
vdf_create(
|
||||||
|
packed_bytes,
|
||||||
|
rounds, dec=True
|
||||||
|
).to_bytes(
|
||||||
|
64, "big"), packed_bytes, cls, auto_check_generator=False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_id(
|
||||||
|
hash: KastenChecksum,
|
||||||
|
packed_bytes: KastenPacked, rounds=5000) -> None:
|
||||||
|
|
||||||
|
try:
|
||||||
|
hash = int.from_bytes(hash, byteorder="big")
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
if not vdf_verify(packed_bytes, hash, rounds):
|
||||||
|
raise InvalidID
|
||||||
|
|
||||||
|
test_obj = Kasten(
|
||||||
|
None, packed_bytes, None, auto_check_generator=False)
|
||||||
|
allowed_age_seconds = AnonVDFGenerator.get_ttl_seconds_per_rounds(
|
||||||
|
rounds)
|
||||||
|
if time.time() > test_obj.get_timestamp() + allowed_age_seconds:
|
||||||
|
raise ValueError(
|
||||||
|
f"Block rounds only vaild through {allowed_age_seconds}")
|
||||||
|
|
||||||
|
return None
|
@ -3,7 +3,6 @@ from kasten import Kasten
|
|||||||
from time import time
|
from time import time
|
||||||
from math import floor
|
from math import floor
|
||||||
|
|
||||||
MAX_AGE_SECONDS = 60 * 60 * 24 * 30
|
|
||||||
MAX_FUTURE_SKEW_SECONDS = 60 * 2
|
MAX_FUTURE_SKEW_SECONDS = 60 * 2
|
||||||
TOTAL_MAX_SIZE = 6 * (10**6)
|
TOTAL_MAX_SIZE = 6 * (10**6)
|
||||||
|
|
||||||
@ -12,9 +11,6 @@ class BlockRulesException(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BlockOutdated(BlockRulesException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class BlockExpired(Exception):
|
class BlockExpired(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -37,14 +33,12 @@ def check_block_sanity(raw_bytes):
|
|||||||
timestamp: int = floor(time())
|
timestamp: int = floor(time())
|
||||||
block_timestamp = kasten.get_timestamp()
|
block_timestamp = kasten.get_timestamp()
|
||||||
difference = timestamp - block_timestamp
|
difference = timestamp - block_timestamp
|
||||||
if difference > MAX_AGE_SECONDS:
|
|
||||||
raise BlockOutdated()
|
|
||||||
if difference < -MAX_FUTURE_SKEW_SECONDS:
|
if difference < -MAX_FUTURE_SKEW_SECONDS:
|
||||||
raise BlockFutureSkewedBeyondMax()
|
raise BlockFutureSkewedBeyondMax()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if timestamp < block_timestamp + kasten.get_metadata()[
|
if block_timestamp + kasten.get_metadata()['expire'] >= timestamp:
|
||||||
'expire']:
|
|
||||||
raise BlockExpired()
|
raise BlockExpired()
|
||||||
except (IndexError, TypeError):
|
except (IndexError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
33
tests/test_anonvdf.py
Normal file
33
tests/test_anonvdf.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import unittest
|
||||||
|
from onionrblocks.generators import anonvdf
|
||||||
|
import kasten
|
||||||
|
import mimcvdf
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
from math import floor
|
||||||
|
|
||||||
|
class TestAnonVDF(unittest.TestCase):
|
||||||
|
def test_vdf_create(self):
|
||||||
|
test_data = kasten.generator.pack.pack(b"test", "tst", 0)
|
||||||
|
test_vdf = mimcvdf.vdf_create(test_data, 1000)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
anonvdf.AnonVDFGenerator.generate(test_data, rounds=1000).get_packed(),
|
||||||
|
test_data
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_vdf_block_validate_ok_time(self):
|
||||||
|
rds = 8000
|
||||||
|
test_data = kasten.generator.pack.pack(b"test", "tst", 0)
|
||||||
|
test_id = mimcvdf.vdf_create(test_data, rds)
|
||||||
|
anonvdf.AnonVDFGenerator.validate_id(test_id, test_data, rounds=rds)
|
||||||
|
|
||||||
|
def test_vdf_block_validate_not_enough(self):
|
||||||
|
rds = 8000
|
||||||
|
t = floor(time()) - 60
|
||||||
|
test_data = kasten.generator.pack.pack(b"test", "tst", 0, timestamp=t)
|
||||||
|
test_id = mimcvdf.vdf_create(test_data, rds)
|
||||||
|
self.assertRaises(ValueError, anonvdf.AnonVDFGenerator.validate_id, test_id, test_data, rounds=rds)
|
||||||
|
|
||||||
|
|
||||||
|
unittest.main()
|
@ -13,12 +13,6 @@ class TestUniversalRules(unittest.TestCase):
|
|||||||
universalrules.BlockTooLarge,
|
universalrules.BlockTooLarge,
|
||||||
universalrules.check_block_sanity, packed)
|
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):
|
def test_block_future_skew_ok(self):
|
||||||
t = floor(time()) + 120
|
t = floor(time()) + 120
|
||||||
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t)
|
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t)
|
||||||
@ -32,14 +26,14 @@ class TestUniversalRules(unittest.TestCase):
|
|||||||
universalrules.check_block_sanity, packed)
|
universalrules.check_block_sanity, packed)
|
||||||
|
|
||||||
def test_block_not_expired(self):
|
def test_block_not_expired(self):
|
||||||
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, app_metadata={"expire": 10000})
|
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, app_metadata={"expire": 7})
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
universalrules.BlockExpired,
|
universalrules.BlockExpired,
|
||||||
universalrules.check_block_sanity, packed)
|
universalrules.check_block_sanity, packed)
|
||||||
|
|
||||||
def test_block_expired(self):
|
def test_block_expired(self):
|
||||||
t = floor(time()) - 6
|
t = floor(time()) - 6
|
||||||
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t, app_metadata={"expire": 5})
|
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t, app_metadata={"expire": 6})
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
universalrules.BlockExpired,
|
universalrules.BlockExpired,
|
||||||
universalrules.check_block_sanity, packed)
|
universalrules.check_block_sanity, packed)
|
||||||
|
Loading…
Reference in New Issue
Block a user