2023-04-14 15:25:54 +00:00
|
|
|
from collections import OrderedDict
|
|
|
|
from unittest.mock import Mock
|
|
|
|
|
2023-02-01 16:53:02 +00:00
|
|
|
import pytest
|
|
|
|
from eth_account import Account
|
2023-06-06 16:02:30 +00:00
|
|
|
from nucypher_core import SessionStaticSecret
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2024-01-29 00:05:46 +00:00
|
|
|
from nucypher.blockchain.eth.models import Coordinator
|
2023-04-16 19:59:28 +00:00
|
|
|
from tests.mock.coordinator import MockCoordinatorAgent
|
2023-04-17 23:44:26 +00:00
|
|
|
from tests.mock.interfaces import MockBlockchain
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-04-13 15:41:33 +00:00
|
|
|
DKG_SIZE = 4
|
|
|
|
|
2023-02-01 16:53:02 +00:00
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
2023-04-14 15:25:54 +00:00
|
|
|
def nodes_transacting_powers():
|
|
|
|
accounts = OrderedDict()
|
2023-04-13 15:41:33 +00:00
|
|
|
for _ in range(DKG_SIZE):
|
2023-02-01 16:53:02 +00:00
|
|
|
account = Account.create()
|
2023-04-14 15:25:54 +00:00
|
|
|
mock_transacting_power = Mock()
|
|
|
|
mock_transacting_power.account = account.address
|
|
|
|
accounts[account.address] = mock_transacting_power
|
2023-02-01 16:53:02 +00:00
|
|
|
return accounts
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
2023-04-16 19:59:28 +00:00
|
|
|
def coordinator():
|
|
|
|
return MockCoordinatorAgent(blockchain=MockBlockchain())
|
2023-02-01 16:53:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_mock_coordinator_creation(coordinator):
|
2024-01-29 17:19:56 +00:00
|
|
|
assert coordinator.number_of_rituals() == 0
|
2023-02-01 16:53:02 +00:00
|
|
|
|
|
|
|
|
2023-09-07 22:25:42 +00:00
|
|
|
def test_mock_coordinator_initiation(
|
|
|
|
mocker,
|
|
|
|
nodes_transacting_powers,
|
|
|
|
coordinator,
|
|
|
|
random_address,
|
|
|
|
get_random_checksum_address,
|
|
|
|
):
|
2024-01-29 17:19:56 +00:00
|
|
|
assert coordinator.number_of_rituals() == 0
|
2023-04-14 15:25:54 +00:00
|
|
|
mock_transacting_power = mocker.Mock()
|
|
|
|
mock_transacting_power.account = random_address
|
2023-05-03 17:55:25 +00:00
|
|
|
coordinator.initiate_ritual(
|
|
|
|
providers=list(nodes_transacting_powers.keys()),
|
2023-09-07 20:12:54 +00:00
|
|
|
authority=mock_transacting_power.account,
|
|
|
|
duration=1,
|
2023-09-07 22:25:42 +00:00
|
|
|
access_controller=get_random_checksum_address(),
|
2023-05-03 17:55:25 +00:00
|
|
|
transacting_power=mock_transacting_power,
|
|
|
|
)
|
2023-02-01 16:53:02 +00:00
|
|
|
assert coordinator.number_of_rituals() == 1
|
|
|
|
|
2024-01-29 17:19:56 +00:00
|
|
|
ritual = coordinator._rituals[0]
|
2023-04-13 15:41:33 +00:00
|
|
|
assert len(ritual.participants) == DKG_SIZE
|
2023-04-03 17:09:35 +00:00
|
|
|
for p in ritual.participants:
|
2023-02-01 16:53:02 +00:00
|
|
|
assert p.transcript == bytes()
|
|
|
|
|
2023-04-16 19:59:28 +00:00
|
|
|
assert len(coordinator.EVENTS) == 1
|
2023-04-03 17:09:35 +00:00
|
|
|
|
2023-04-16 19:59:28 +00:00
|
|
|
timestamp, signal = list(coordinator.EVENTS.items())[0]
|
2023-02-01 16:53:02 +00:00
|
|
|
signal_type, signal_data = signal
|
2023-04-21 17:43:56 +00:00
|
|
|
assert signal_type == MockCoordinatorAgent.Events.START_RITUAL
|
|
|
|
assert signal_data["ritual_id"] == 0
|
2023-09-07 20:08:22 +00:00
|
|
|
assert signal_data["authority"] == mock_transacting_power.account
|
2023-05-03 17:55:25 +00:00
|
|
|
assert set(signal_data["participants"]) == nodes_transacting_powers.keys()
|
2023-02-01 16:53:02 +00:00
|
|
|
|
|
|
|
|
2023-05-19 17:35:05 +00:00
|
|
|
def test_mock_coordinator_round_1(
|
|
|
|
nodes_transacting_powers, coordinator, random_transcript
|
|
|
|
):
|
2024-01-29 17:19:56 +00:00
|
|
|
ritual = coordinator._rituals[0]
|
2023-05-03 17:55:25 +00:00
|
|
|
assert (
|
|
|
|
coordinator.get_ritual_status(0)
|
2024-01-29 00:05:46 +00:00
|
|
|
== Coordinator.RitualStatus.DKG_AWAITING_TRANSCRIPTS
|
2023-05-03 17:55:25 +00:00
|
|
|
)
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-04-03 17:09:35 +00:00
|
|
|
for p in ritual.participants:
|
2023-02-01 16:53:02 +00:00
|
|
|
assert p.transcript == bytes()
|
|
|
|
|
2023-04-14 15:25:54 +00:00
|
|
|
for index, node_address in enumerate(nodes_transacting_powers):
|
2023-05-19 17:35:05 +00:00
|
|
|
transcript = random_transcript
|
2023-04-14 15:25:54 +00:00
|
|
|
|
2023-02-01 16:53:02 +00:00
|
|
|
coordinator.post_transcript(
|
|
|
|
ritual_id=0,
|
2023-04-14 15:25:54 +00:00
|
|
|
transcript=transcript,
|
|
|
|
transacting_power=nodes_transacting_powers[node_address]
|
2023-02-01 16:53:02 +00:00
|
|
|
)
|
|
|
|
|
2023-04-03 17:09:35 +00:00
|
|
|
performance = ritual.participants[index]
|
2023-05-19 17:35:05 +00:00
|
|
|
assert performance.transcript == bytes(transcript)
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-04-14 15:25:54 +00:00
|
|
|
if index == len(nodes_transacting_powers) - 1:
|
2023-04-16 19:59:28 +00:00
|
|
|
assert len(coordinator.EVENTS) == 2
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-04-16 19:59:28 +00:00
|
|
|
timestamp, signal = list(coordinator.EVENTS.items())[1]
|
2023-02-01 16:53:02 +00:00
|
|
|
signal_type, signal_data = signal
|
2023-04-16 19:59:28 +00:00
|
|
|
assert signal_type == MockCoordinatorAgent.Events.START_AGGREGATION_ROUND
|
2023-05-03 17:55:25 +00:00
|
|
|
assert signal_data["ritual_id"] == 0
|
2023-02-01 16:53:02 +00:00
|
|
|
|
|
|
|
|
2023-05-04 16:57:42 +00:00
|
|
|
def test_mock_coordinator_round_2(
|
2023-05-19 17:35:05 +00:00
|
|
|
nodes_transacting_powers,
|
|
|
|
coordinator,
|
|
|
|
aggregated_transcript,
|
|
|
|
dkg_public_key,
|
|
|
|
random_transcript,
|
2023-05-04 16:57:42 +00:00
|
|
|
):
|
2024-01-29 17:19:56 +00:00
|
|
|
ritual = coordinator._rituals[0]
|
2023-05-03 17:55:25 +00:00
|
|
|
assert (
|
|
|
|
coordinator.get_ritual_status(0)
|
2024-01-29 00:05:46 +00:00
|
|
|
== Coordinator.RitualStatus.DKG_AWAITING_AGGREGATIONS
|
2023-05-03 17:55:25 +00:00
|
|
|
)
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-04-03 17:09:35 +00:00
|
|
|
for p in ritual.participants:
|
2023-05-19 17:35:05 +00:00
|
|
|
assert p.transcript == bytes(random_transcript)
|
2023-02-01 16:53:02 +00:00
|
|
|
|
2023-05-30 20:13:19 +00:00
|
|
|
participant_public_keys = []
|
2023-04-14 15:25:54 +00:00
|
|
|
for index, node_address in enumerate(nodes_transacting_powers):
|
2023-06-06 16:02:30 +00:00
|
|
|
participant_public_key = SessionStaticSecret.random().public_key()
|
2023-04-03 17:09:35 +00:00
|
|
|
coordinator.post_aggregation(
|
2023-02-01 16:53:02 +00:00
|
|
|
ritual_id=0,
|
2023-04-14 15:25:54 +00:00
|
|
|
aggregated_transcript=aggregated_transcript,
|
2023-05-04 16:57:42 +00:00
|
|
|
public_key=dkg_public_key,
|
2023-05-30 20:13:19 +00:00
|
|
|
participant_public_key=participant_public_key,
|
2023-04-14 15:25:54 +00:00
|
|
|
transacting_power=nodes_transacting_powers[node_address]
|
2023-02-01 16:53:02 +00:00
|
|
|
)
|
2023-05-30 20:13:19 +00:00
|
|
|
participant_public_keys.append(participant_public_key)
|
2023-04-14 15:25:54 +00:00
|
|
|
if index == len(nodes_transacting_powers) - 1:
|
2023-04-16 19:59:28 +00:00
|
|
|
assert len(coordinator.EVENTS) == 2
|
|
|
|
|
2023-05-19 17:35:05 +00:00
|
|
|
assert ritual.aggregated_transcript == bytes(aggregated_transcript)
|
2023-05-04 16:57:42 +00:00
|
|
|
|
2023-05-06 17:15:48 +00:00
|
|
|
assert bytes(ritual.public_key) == bytes(dkg_public_key)
|
2023-05-16 15:18:33 +00:00
|
|
|
for index, p in enumerate(ritual.participants):
|
2023-04-21 13:49:44 +00:00
|
|
|
# unchanged
|
2023-05-19 17:35:05 +00:00
|
|
|
assert p.transcript == bytes(random_transcript)
|
|
|
|
assert p.transcript != bytes(aggregated_transcript)
|
2023-05-31 13:52:22 +00:00
|
|
|
assert p.decryption_request_static_key == bytes(participant_public_keys[index])
|
2023-04-13 15:41:33 +00:00
|
|
|
|
2023-04-21 13:49:44 +00:00
|
|
|
assert len(coordinator.EVENTS) == 2 # no additional event emitted here?
|
2024-01-29 00:05:46 +00:00
|
|
|
assert coordinator.get_ritual_status(0) == Coordinator.RitualStatus.ACTIVE
|