bump version with improved vdf metric
This commit is contained in:
parent
36d3e308af
commit
c4f349eedf
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
This project uses Semantic Versioning
|
This project uses Semantic Versioning
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
* Bumped minimum VDF rounds to C implementation benchmark
|
||||||
|
* VDF ttl now uses metric based on disk+transfer prices
|
||||||
|
* Typo correction
|
||||||
|
* Enforce universalrules when checking either generators
|
||||||
|
* Added missing pynacl dependency
|
||||||
|
|
||||||
## 0.0.0
|
## 0.0.0
|
||||||
|
|
||||||
Initial release
|
Initial release
|
||||||
|
@ -4,4 +4,4 @@ from binascii import hexlify
|
|||||||
|
|
||||||
import kasten
|
import kasten
|
||||||
|
|
||||||
|
from . import generators
|
||||||
|
@ -10,16 +10,25 @@ from onionrblocks.universalrules import check_block_sanity
|
|||||||
|
|
||||||
class AnonVDFGenerator(generator.KastenBaseGenerator):
|
class AnonVDFGenerator(generator.KastenBaseGenerator):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_ttl_seconds_per_rounds(cls, rounds: int):
|
def get_ttl_seconds_per_rounds(cls, rounds: int, size_bytes: int):
|
||||||
# 8000 rounds = 1 second (2.8ghz python) = 1 hour storage
|
# 90000 rounds = 1 second (2.8ghz C) = 1 hour storage of 1 MB storage
|
||||||
if rounds < 8000:
|
# jan 2021 disk price metric = 0.000017 USD per MB
|
||||||
|
# mobile MB transfer US/Canada = 0.0125 USD
|
||||||
|
# Max cost of block storage + American mobile data transfer = 0.0751 USD
|
||||||
|
|
||||||
|
base = 90000
|
||||||
|
per_byte = 1000
|
||||||
|
minimum = base + (per_byte * size_bytes)
|
||||||
|
if rounds < minimum:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Rounds must be at least 8000")
|
"Must be at least " + str(minimum) + " for " + str(size_bytes))
|
||||||
return (rounds / 8000) * 60
|
|
||||||
|
return (rounds / minimum) * 60
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate(
|
def generate(
|
||||||
cls, packed_bytes: KastenPacked, rounds: int = 5000) -> Kasten:
|
cls, packed_bytes: KastenPacked, rounds: int = 90000) -> Kasten:
|
||||||
|
check_block_sanity(packed_bytes)
|
||||||
return Kasten(
|
return Kasten(
|
||||||
vdf_create(
|
vdf_create(
|
||||||
packed_bytes,
|
packed_bytes,
|
||||||
@ -30,7 +39,9 @@ class AnonVDFGenerator(generator.KastenBaseGenerator):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_id(
|
def validate_id(
|
||||||
hash: KastenChecksum,
|
hash: KastenChecksum,
|
||||||
packed_bytes: KastenPacked, rounds=5000) -> None:
|
packed_bytes: KastenPacked, rounds=90000) -> None:
|
||||||
|
|
||||||
|
check_block_sanity(packed_bytes)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hash = int.from_bytes(hash, byteorder="big")
|
hash = int.from_bytes(hash, byteorder="big")
|
||||||
@ -42,9 +53,9 @@ class AnonVDFGenerator(generator.KastenBaseGenerator):
|
|||||||
test_obj = Kasten(
|
test_obj = Kasten(
|
||||||
None, packed_bytes, None, auto_check_generator=False)
|
None, packed_bytes, None, auto_check_generator=False)
|
||||||
allowed_age_seconds = AnonVDFGenerator.get_ttl_seconds_per_rounds(
|
allowed_age_seconds = AnonVDFGenerator.get_ttl_seconds_per_rounds(
|
||||||
rounds)
|
rounds, len(packed_bytes))
|
||||||
if time.time() > test_obj.get_timestamp() + allowed_age_seconds:
|
if time.time() > test_obj.get_timestamp() + allowed_age_seconds:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Block rounds only vaild through {allowed_age_seconds}")
|
f"Block rounds only valid through {allowed_age_seconds}")
|
||||||
|
|
||||||
return None
|
return None
|
@ -8,6 +8,7 @@ from kasten.exceptions import InvalidID
|
|||||||
from kasten.types import KastenPacked, KastenChecksum
|
from kasten.types import KastenPacked, KastenChecksum
|
||||||
|
|
||||||
from onionrblocks.customtypes import RawEd25519PrivateKey, RawEd25519PublicKey
|
from onionrblocks.customtypes import RawEd25519PrivateKey, RawEd25519PublicKey
|
||||||
|
from onionrblocks.universalrules import check_block_sanity
|
||||||
|
|
||||||
class Signed(generator.KastenBaseGenerator):
|
class Signed(generator.KastenBaseGenerator):
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ class Signed(generator.KastenBaseGenerator):
|
|||||||
hash: KastenChecksum,
|
hash: KastenChecksum,
|
||||||
packed_bytes: KastenPacked,
|
packed_bytes: KastenPacked,
|
||||||
verify_key: Union[VerifyKey, RawEd25519PublicKey]) -> None:
|
verify_key: Union[VerifyKey, RawEd25519PublicKey]) -> None:
|
||||||
|
check_block_sanity(packed_bytes)
|
||||||
# Hash is 64 bytes message then 32 bytes of the hash of the packed_bytes
|
# Hash is 64 bytes message then 32 bytes of the hash of the packed_bytes
|
||||||
if len(hash) != 86:
|
if len(hash) != 86:
|
||||||
raise InvalidID("Block not have proper signature length")
|
raise InvalidID("Block not have proper signature length")
|
||||||
|
4
setup.py
4
setup.py
@ -1,13 +1,13 @@
|
|||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
setup(name='onionrblocks',
|
setup(name='onionrblocks',
|
||||||
version='0.0.2',
|
version='1.0.0',
|
||||||
description='Onionr message format',
|
description='Onionr message format',
|
||||||
author='Kevin Froman',
|
author='Kevin Froman',
|
||||||
author_email='beardog@mailbox.org',
|
author_email='beardog@mailbox.org',
|
||||||
url='',
|
url='',
|
||||||
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
|
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
|
||||||
install_requires=['kasten>=2.0.1'],
|
install_requires=['kasten>=2.0.1', 'pynacl>=1.4.0'],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||||
|
@ -19,17 +19,30 @@ class TestAnonVDF(unittest.TestCase):
|
|||||||
self.assertEqual(generated.id, int(test_vdf).to_bytes(64, byteorder="big"))
|
self.assertEqual(generated.id, int(test_vdf).to_bytes(64, byteorder="big"))
|
||||||
|
|
||||||
def test_vdf_block_validate_ok_time(self):
|
def test_vdf_block_validate_ok_time(self):
|
||||||
rds = 8000
|
rds = 90000
|
||||||
test_data = kasten.generator.pack.pack(b"test", "tst", 0)
|
test_data = kasten.generator.pack.pack(b"test", "tst", 0)
|
||||||
|
rds += len(test_data) * 1000
|
||||||
test_id = mimcvdf.vdf_create(test_data, rds)
|
test_id = mimcvdf.vdf_create(test_data, rds)
|
||||||
anonvdf.AnonVDFGenerator.validate_id(test_id, test_data, rounds=rds)
|
anonvdf.AnonVDFGenerator.validate_id(test_id, test_data, rounds=rds)
|
||||||
|
|
||||||
def test_vdf_block_validate_not_enough(self):
|
def test_vdf_block_validate_not_enough(self):
|
||||||
rds = 8000
|
rds = 90000
|
||||||
t = floor(time()) - 60
|
t = floor(time()) - 60
|
||||||
test_data = kasten.generator.pack.pack(b"test", "tst", 0, timestamp=t)
|
test_data = kasten.generator.pack.pack(b"test", "tst", 0, timestamp=t)
|
||||||
test_id = mimcvdf.vdf_create(test_data, rds)
|
test_id = mimcvdf.vdf_create(test_data, rds)
|
||||||
self.assertRaises(ValueError, anonvdf.AnonVDFGenerator.validate_id, test_id, test_data, rounds=rds)
|
self.assertRaises(ValueError, anonvdf.AnonVDFGenerator.validate_id, test_id, test_data, rounds=rds)
|
||||||
|
|
||||||
|
def test_vdf_incermental(self):
|
||||||
|
last = 1
|
||||||
|
for i in range(1, 20):
|
||||||
|
t = time()
|
||||||
|
rds = 90000
|
||||||
|
test_data = kasten.generator.pack.pack(b"test" * i, "tst", 0)
|
||||||
|
rds += len(test_data) * 1000
|
||||||
|
test_id = mimcvdf.vdf_create(test_data, rds)
|
||||||
|
anonvdf.AnonVDFGenerator.validate_id(test_id, test_data, rounds=rds)
|
||||||
|
newT = time()
|
||||||
|
self.assertGreater(newT - t, last)
|
||||||
|
|
||||||
|
|
||||||
unittest.main()
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user