Added dispersal test
This commit is contained in:
parent
7e9a4955a2
commit
5a791079e2
|
@ -1,4 +1,5 @@
|
|||
from dataclasses import dataclass
|
||||
from hashlib import sha3_256
|
||||
from typing import List, Optional, Generator, Sequence
|
||||
|
||||
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
||||
|
@ -20,15 +21,15 @@ class Dispersal:
|
|||
self.settings = settings
|
||||
|
||||
def _prepare_data(self, encoded_data: EncodedData) -> Generator[DABlob, None, None]:
|
||||
assert len(encoded_data.row_commitments) == len(self.settings.nodes_ids)
|
||||
assert len(encoded_data.row_proofs) == len(self.settings.nodes_ids)
|
||||
assert len(encoded_data.column_commitments) == len(self.settings.nodes_ids)
|
||||
assert len(encoded_data.aggregated_column_proofs) == len(self.settings.nodes_ids)
|
||||
columns = encoded_data.extended_matrix.columns
|
||||
column_commitments = encoded_data.column_commitments
|
||||
row_commitments = encoded_data.row_commitments
|
||||
rows_proofs = encoded_data.row_proofs
|
||||
aggregated_column_commitment = encoded_data.aggregated_column_commitment
|
||||
aggregated_column_proofs = encoded_data.aggregated_column_proofs
|
||||
blobs_data = enumerate(zip(columns, column_commitments, rows_proofs, aggregated_column_proofs))
|
||||
blobs_data = enumerate(zip(columns, column_commitments, zip(*rows_proofs), aggregated_column_proofs))
|
||||
for index, (column, column_commitment, row_proofs, column_proof) in blobs_data:
|
||||
blob = DABlob(
|
||||
index,
|
||||
|
@ -41,7 +42,7 @@ class Dispersal:
|
|||
)
|
||||
yield blob
|
||||
|
||||
def _send_and_await_response(self, node: NodeId, encoded_data: EncodedData) -> Optional[Attestation]:
|
||||
def _send_and_await_response(self, node: NodeId, blob: DABlob) -> Optional[Attestation]:
|
||||
pass
|
||||
|
||||
def _build_certificate(self, encoded_data: EncodedData, attestations: Sequence[Attestation]) -> Certificate:
|
||||
|
@ -57,12 +58,20 @@ class Dispersal:
|
|||
def _verify_attestation(public_key: BLSPublickey, attested_message: bytes, attestation: Attestation) -> bool:
|
||||
return bls_pop.Verify(public_key, attested_message, attestation.signature)
|
||||
|
||||
@staticmethod
|
||||
def _build_attestation_message(encoded_data: EncodedData) -> bytes:
|
||||
hasher = sha3_256()
|
||||
hasher.update(bytes(encoded_data.aggregated_column_commitment))
|
||||
for c in encoded_data.row_commitments:
|
||||
hasher.update(bytes(c))
|
||||
return hasher.digest()
|
||||
|
||||
def disperse(self, encoded_data: EncodedData) -> Optional[Certificate]:
|
||||
attestations = []
|
||||
|
||||
for node, blob in zip(self.settings.nodes_ids, self._prepare_data(encoded_data)):
|
||||
attested_message = self._build_attestation_message(encoded_data)
|
||||
for node, pk, blob in zip(self.settings.nodes_ids, self.settings.nodes_pubkey, self._prepare_data(encoded_data)):
|
||||
if attestation := self._send_and_await_response(node, blob):
|
||||
if self._verify_attestation(attestation):
|
||||
if self._verify_attestation(pk, attested_message, attestation):
|
||||
attestations.append(attestation)
|
||||
if len(attestations) >= self.settings.threshold:
|
||||
return self._build_certificate(encoded_data, attestations)
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
from hashlib import sha3_256
|
||||
from unittest import TestCase
|
||||
|
||||
from .encoder import DAEncoderParams, DAEncoder
|
||||
from .test_encoder import TestEncoder
|
||||
|
||||
from da.common import NodeId, Attestation
|
||||
from da.dispersal import Dispersal, DABlob, EncodedData, DispersalSettings
|
||||
from da.dispersal import Dispersal, EncodedData, DispersalSettings
|
||||
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
||||
|
||||
from .verifier import DAVerifier, DABlob
|
||||
|
||||
|
||||
class TestDispersal(TestCase):
|
||||
def setUp(self):
|
||||
self.nodes_ids = [NodeId(x.to_bytes(length=32, byteorder='big')) for x in range(10)]
|
||||
self.secret_keys = list(range(1, 11))
|
||||
self.n_nodes = 16
|
||||
self.nodes_ids = [NodeId(x.to_bytes(length=32, byteorder='big')) for x in range(self.n_nodes)]
|
||||
self.secret_keys = list(range(1, self.n_nodes+1))
|
||||
self.public_keys = [bls_pop.SkToPk(sk) for sk in self.secret_keys]
|
||||
dispersal_settings = DispersalSettings(
|
||||
self.nodes_ids,
|
||||
self.public_keys,
|
||||
6
|
||||
self.n_nodes // 2 + 1
|
||||
)
|
||||
self.dispersal = Dispersal(dispersal_settings)
|
||||
self.encoder_test = TestEncoder()
|
||||
self.encoder_test.setUp()
|
||||
|
||||
def test_build_certificate_insufficient_attestations(self):
|
||||
with self.assertRaises(AssertionError):
|
||||
self.dispersal._build_certificate(None, [])
|
||||
|
||||
|
||||
def test_build_certificate_enough_attestations(self):
|
||||
mock_encoded_data = EncodedData(
|
||||
None, None, None, [], [], [], bytes(b"f"*48), []
|
||||
|
@ -38,11 +45,26 @@ class TestDispersal(TestCase):
|
|||
bls_pop.AggregateVerify(self.public_keys, [mock_message]*len(self.public_keys), certificate.aggregated_signatures)
|
||||
)
|
||||
|
||||
def test_prepare_data(self):
|
||||
pass
|
||||
|
||||
def test_verify_attestation(self):
|
||||
pass
|
||||
|
||||
def test_disperse(self):
|
||||
pass
|
||||
data = self.encoder_test.data
|
||||
encoding_params = DAEncoderParams(column_count=self.n_nodes // 2, bytes_per_field_element=32)
|
||||
encoded_data = DAEncoder(encoding_params).encode(data)
|
||||
|
||||
# mock send and await method with local verifiers
|
||||
def __send_and_await_response(node: NodeId, blob: DABlob):
|
||||
sk = self.secret_keys[int.from_bytes(node)]
|
||||
verifier = DAVerifier(sk)
|
||||
return verifier.verify(blob)
|
||||
# inject mock send and await method
|
||||
self.dispersal._send_and_await_response = __send_and_await_response
|
||||
|
||||
certificate = self.dispersal.disperse(encoded_data)
|
||||
self.assertIsNotNone(certificate)
|
||||
self.assertTrue(
|
||||
bls_pop.AggregateVerify(
|
||||
self.public_keys[:self.dispersal.settings.threshold],
|
||||
[self.dispersal._build_attestation_message(encoded_data)]*self.dispersal.settings.threshold,
|
||||
certificate.aggregated_signatures
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ class TestEncoder(TestCase):
|
|||
ROOTS_OF_UNITY
|
||||
)
|
||||
|
||||
|
||||
def test_chunkify(self):
|
||||
encoder_settings = DAEncoderParams(column_count=2, bytes_per_field_element=32)
|
||||
elements = 10
|
||||
|
|
Loading…
Reference in New Issue