mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-10 17:13:08 +00:00
First experiments
This commit is contained in:
parent
84130ba58a
commit
60a5dbfe26
31
da/subnetwork_assignment.py
Normal file
31
da/subnetwork_assignment.py
Normal file
@ -0,0 +1,31 @@
|
||||
from itertools import chain
|
||||
from math import ceil
|
||||
from typing import Generator, Set, TypeAlias
|
||||
from hashlib import blake2b
|
||||
import random
|
||||
from scipy.stats.qmc import Halton
|
||||
Id: TypeAlias = bytes
|
||||
|
||||
|
||||
def _lazy_recursive_hash(_id: Id, hasher=lambda x: blake2b(x).digest()) -> Generator[Id, None, None]:
|
||||
while True:
|
||||
_id = hasher(_id)
|
||||
yield _id
|
||||
|
||||
|
||||
def generate_distribution_set(_id: Id, set_size: int, modulus=4096, hasher=lambda x: blake2b(x).digest()) -> Set[int]:
|
||||
result_set = set()
|
||||
ids = _lazy_recursive_hash(_id)
|
||||
while len(result_set) < set_size:
|
||||
result_set.add(int.from_bytes(next(ids)) % modulus)
|
||||
return result_set
|
||||
|
||||
|
||||
def generate_distribution_set_v3(_id: Id, set_size: int, replication_factor: int, modulus=4096) -> Set[int]:
|
||||
halton = Halton(set_size*replication_factor, seed=int.from_bytes(_id))
|
||||
return set(chain.from_iterable(halton.integers(l_bounds=0, u_bounds=modulus, n=set_size*replication_factor)))
|
||||
|
||||
|
||||
def calculate_minimum_membership(network_size: int, number_of_nodes: int, replication_factor: int) -> int:
|
||||
return ceil(network_size / number_of_nodes) * replication_factor
|
||||
|
||||
59
da/test_subnetwork_assignment.py
Normal file
59
da/test_subnetwork_assignment.py
Normal file
@ -0,0 +1,59 @@
|
||||
from math import ceil, floor
|
||||
from typing import List
|
||||
from unittest import TestCase
|
||||
from .subnetwork_assignment import (
|
||||
generate_distribution_set,
|
||||
generate_distribution_set_v3,
|
||||
calculate_minimum_membership
|
||||
)
|
||||
from hashlib import blake2b, sha512
|
||||
from uuid import uuid4
|
||||
from itertools import chain
|
||||
|
||||
|
||||
SUBNETWORK_SIZE: int = 4096
|
||||
NODES_OVER_NETWORK_SIZE: List[float] = [0.1, 0.25, 0.5, 0.75, 1.0, 2.0, 10.0]
|
||||
HASHERS = [lambda x: sha512(x).digest()]
|
||||
|
||||
|
||||
class TestSubnetworkAssignment(TestCase):
|
||||
def test_no_subnetwork_empty(self):
|
||||
for hasher in HASHERS:
|
||||
for nodes_factor in reversed(NODES_OVER_NETWORK_SIZE):
|
||||
total_nodes = int(SUBNETWORK_SIZE * nodes_factor)
|
||||
nodes = [uuid4() for _ in range(total_nodes)]
|
||||
replication_factor = ceil(5/nodes_factor)
|
||||
minimum_membership = calculate_minimum_membership(SUBNETWORK_SIZE, total_nodes, replication_factor)
|
||||
subsets = set(
|
||||
chain.from_iterable(
|
||||
generate_distribution_set(
|
||||
blake2b(_id.bytes).digest(),
|
||||
minimum_membership,
|
||||
SUBNETWORK_SIZE,
|
||||
hasher=hasher
|
||||
)
|
||||
for _id in nodes
|
||||
)
|
||||
)
|
||||
print(f"Total nodes: {total_nodes}")
|
||||
self.assertGreater(len(subsets), floor(SUBNETWORK_SIZE*0.99))
|
||||
|
||||
def test_no_subnetwork_v3_empty(self):
|
||||
for nodes_factor in reversed(NODES_OVER_NETWORK_SIZE):
|
||||
total_nodes = int(SUBNETWORK_SIZE * nodes_factor)
|
||||
nodes = [uuid4() for _ in range(total_nodes)]
|
||||
replication_factor = ceil(3/nodes_factor)
|
||||
minimum_membership = calculate_minimum_membership(SUBNETWORK_SIZE, total_nodes, 1)
|
||||
subsets = set(
|
||||
chain.from_iterable(
|
||||
generate_distribution_set_v3(
|
||||
blake2b(_id.bytes).digest(),
|
||||
minimum_membership,
|
||||
replication_factor,
|
||||
SUBNETWORK_SIZE
|
||||
)
|
||||
for _id in nodes
|
||||
)
|
||||
)
|
||||
print(f"Total nodes: {total_nodes}")
|
||||
self.assertGreater(len(subsets), floor(SUBNETWORK_SIZE*0.99))
|
||||
Loading…
x
Reference in New Issue
Block a user