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 math import floor
|
||||
|
||||
MAX_AGE_SECONDS = 60 * 60 * 24 * 30
|
||||
MAX_FUTURE_SKEW_SECONDS = 60 * 2
|
||||
TOTAL_MAX_SIZE = 6 * (10**6)
|
||||
|
||||
@ -12,9 +11,6 @@ class BlockRulesException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class BlockOutdated(BlockRulesException):
|
||||
pass
|
||||
|
||||
class BlockExpired(Exception):
|
||||
pass
|
||||
|
||||
@ -37,14 +33,12 @@ def check_block_sanity(raw_bytes):
|
||||
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']:
|
||||
if block_timestamp + kasten.get_metadata()['expire'] >= timestamp:
|
||||
raise BlockExpired()
|
||||
except (IndexError, TypeError):
|
||||
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.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)
|
||||
@ -32,14 +26,14 @@ class TestUniversalRules(unittest.TestCase):
|
||||
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})
|
||||
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, app_metadata={"expire": 7})
|
||||
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})
|
||||
packed = kasten.generator.pack.pack(b"1"*10, b"tst", 0, timestamp=t, app_metadata={"expire": 6})
|
||||
self.assertRaises(
|
||||
universalrules.BlockExpired,
|
||||
universalrules.check_block_sanity, packed)
|
||||
|
Loading…
Reference in New Issue
Block a user