mirror of https://github.com/nucypher/nucypher.git
bugfix: always handle transaction hashes instead of transcripts for dkg tracking. Updates mocks to return txhash instead of receipt for transcript and aggregation posting.
parent
2a73c816be
commit
5f8d68fe08
|
@ -3,7 +3,7 @@ import random
|
|||
import time
|
||||
from collections import defaultdict
|
||||
from decimal import Decimal
|
||||
from typing import DefaultDict, Dict, List, Optional, Set, Union
|
||||
from typing import DefaultDict, Dict, List, Optional, Set, Tuple, Union
|
||||
|
||||
import maya
|
||||
from eth_typing import ChecksumAddress
|
||||
|
@ -26,6 +26,7 @@ from nucypher_core.ferveo import (
|
|||
Validator,
|
||||
)
|
||||
from web3 import HTTPProvider, Web3
|
||||
from web3.exceptions import TransactionNotFound
|
||||
from web3.types import TxReceipt
|
||||
|
||||
from nucypher.acumen.nicknames import Nickname
|
||||
|
@ -320,13 +321,10 @@ class Operator(BaseActor):
|
|||
return result
|
||||
|
||||
def publish_transcript(self, ritual_id: int, transcript: Transcript) -> HexBytes:
|
||||
"""Publish a transcript to publicly available storage."""
|
||||
# look up the node index for this node on the blockchain
|
||||
tx_hash = self.coordinator_agent.post_transcript(
|
||||
ritual_id=ritual_id,
|
||||
transcript=transcript,
|
||||
transacting_power=self.transacting_power,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
return tx_hash
|
||||
|
||||
|
@ -347,7 +345,6 @@ class Operator(BaseActor):
|
|||
public_key=public_key,
|
||||
participant_public_key=participant_public_key,
|
||||
transacting_power=self.transacting_power,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
return tx_hash
|
||||
|
||||
|
@ -436,9 +433,7 @@ class Operator(BaseActor):
|
|||
|
||||
# publish the transcript and store the receipt
|
||||
tx_hash = self.publish_transcript(ritual_id=ritual_id, transcript=transcript)
|
||||
self.dkg_storage.store_transcript_receipt(
|
||||
ritual_id=ritual_id, txhash_or_receipt=tx_hash
|
||||
)
|
||||
self.dkg_storage.store_transcript_txhash(ritual_id=ritual_id, txhash=tx_hash)
|
||||
|
||||
# logging
|
||||
arrival = ritual.total_transcripts + 1
|
||||
|
@ -504,9 +499,7 @@ class Operator(BaseActor):
|
|||
)
|
||||
|
||||
# store the receipt
|
||||
self.dkg_storage.store_aggregated_transcript_receipt(
|
||||
ritual_id=ritual_id, txhash_or_receipt=tx_hash
|
||||
)
|
||||
self.dkg_storage.store_aggregation_txhash(ritual_id=ritual_id, txhash=tx_hash)
|
||||
|
||||
# logging
|
||||
total = ritual.total_aggregations + 1
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
from collections import defaultdict
|
||||
from typing import Optional, Union
|
||||
from typing import Optional
|
||||
|
||||
from hexbytes import HexBytes
|
||||
from nucypher_core.ferveo import AggregatedTranscript, Transcript
|
||||
from web3.types import TxReceipt
|
||||
|
||||
|
||||
class DKGStorage:
|
||||
|
@ -19,19 +18,14 @@ class DKGStorage:
|
|||
data = self.data["transcripts"].get(ritual_id)
|
||||
if not data:
|
||||
return None
|
||||
|
||||
transcript = Transcript.from_bytes(data)
|
||||
return transcript
|
||||
|
||||
def store_transcript_receipt(
|
||||
self, ritual_id: int, txhash_or_receipt: Union[TxReceipt, HexBytes]
|
||||
) -> None:
|
||||
self.data["transcript_receipts"][ritual_id] = txhash_or_receipt
|
||||
def store_transcript_txhash(self, ritual_id: int, txhash: HexBytes) -> None:
|
||||
self.data["transcript_tx_hashes"][ritual_id] = txhash
|
||||
|
||||
def get_transcript_receipt(
|
||||
self, ritual_id: int
|
||||
) -> Optional[Union[TxReceipt, HexBytes]]:
|
||||
return self.data["transcript_receipts"].get(ritual_id)
|
||||
def get_transcript_txhash(self, ritual_id: int) -> Optional[HexBytes]:
|
||||
return self.data["transcript_tx_hashes"].get(ritual_id)
|
||||
|
||||
def store_aggregated_transcript(self, ritual_id: int, aggregated_transcript: AggregatedTranscript) -> None:
|
||||
self.data["aggregated_transcripts"][ritual_id] = bytes(aggregated_transcript)
|
||||
|
@ -46,15 +40,11 @@ class DKGStorage:
|
|||
aggregated_transcript = AggregatedTranscript.from_bytes(data)
|
||||
return aggregated_transcript
|
||||
|
||||
def store_aggregated_transcript_receipt(
|
||||
self, ritual_id: int, txhash_or_receipt: Union[TxReceipt, HexBytes]
|
||||
) -> None:
|
||||
self.data["aggregated_transcript_receipts"][ritual_id] = txhash_or_receipt
|
||||
def store_aggregation_txhash(self, ritual_id: int, txhash: HexBytes) -> None:
|
||||
self.data["aggregation_tx_hashes"][ritual_id] = txhash
|
||||
|
||||
def get_aggregated_transcript_receipt(
|
||||
self, ritual_id: int
|
||||
) -> Optional[Union[TxReceipt, HexBytes]]:
|
||||
return self.data["aggregated_transcript_receipts"].get(ritual_id)
|
||||
def get_aggregation_txhash(self, ritual_id: int) -> Optional[HexBytes]:
|
||||
return self.data["aggregation_tx_hashes"].get(ritual_id)
|
||||
|
||||
def store_public_key(self, ritual_id: int, public_key: bytes) -> None:
|
||||
self.data["public_keys"][ritual_id] = public_key
|
||||
|
|
|
@ -111,15 +111,16 @@ def test_initiate_ritual(
|
|||
assert ritual_dkg_key is None # no dkg key available until ritual is completed
|
||||
|
||||
|
||||
def test_post_transcript(agent, transcripts, transacting_powers):
|
||||
def test_post_transcript(agent, transcripts, transacting_powers, testerchain):
|
||||
ritual_id = agent.number_of_rituals() - 1
|
||||
for i, transacting_power in enumerate(transacting_powers):
|
||||
receipt = agent.post_transcript(
|
||||
txhash = agent.post_transcript(
|
||||
ritual_id=ritual_id,
|
||||
transcript=transcripts[i],
|
||||
transacting_power=transacting_power,
|
||||
)
|
||||
assert receipt["status"] == 1
|
||||
|
||||
receipt = testerchain.wait_for_receipt(txhash)
|
||||
post_transcript_events = (
|
||||
agent.contract.events.TranscriptPosted().process_receipt(receipt)
|
||||
)
|
||||
|
@ -141,13 +142,18 @@ def test_post_transcript(agent, transcripts, transacting_powers):
|
|||
|
||||
|
||||
def test_post_aggregation(
|
||||
agent, aggregated_transcript, dkg_public_key, transacting_powers, cohort
|
||||
agent,
|
||||
aggregated_transcript,
|
||||
dkg_public_key,
|
||||
transacting_powers,
|
||||
cohort,
|
||||
testerchain,
|
||||
):
|
||||
ritual_id = agent.number_of_rituals() - 1
|
||||
participant_public_keys = {}
|
||||
for i, transacting_power in enumerate(transacting_powers):
|
||||
participant_public_key = SessionStaticSecret.random().public_key()
|
||||
receipt = agent.post_aggregation(
|
||||
txhash = agent.post_aggregation(
|
||||
ritual_id=ritual_id,
|
||||
aggregated_transcript=aggregated_transcript,
|
||||
public_key=dkg_public_key,
|
||||
|
@ -155,8 +161,7 @@ def test_post_aggregation(
|
|||
transacting_power=transacting_power,
|
||||
)
|
||||
participant_public_keys[cohort[i]] = participant_public_key
|
||||
assert receipt["status"] == 1
|
||||
|
||||
receipt = testerchain.wait_for_receipt(txhash)
|
||||
post_aggregation_events = (
|
||||
agent.contract.events.AggregationPosted().process_receipt(receipt)
|
||||
)
|
||||
|
|
|
@ -122,7 +122,6 @@ class MockCoordinatorAgent(MockContractAgent):
|
|||
ritual_id: int,
|
||||
transcript: Transcript,
|
||||
transacting_power: TransactingPower,
|
||||
fire_and_forget: bool = False,
|
||||
) -> TxReceipt:
|
||||
ritual = self.rituals[ritual_id]
|
||||
operator_address = transacting_power.account
|
||||
|
@ -143,7 +142,7 @@ class MockCoordinatorAgent(MockContractAgent):
|
|||
p.provider for p in ritual.participants
|
||||
], # TODO This should not be
|
||||
)
|
||||
return self.blockchain.FAKE_RECEIPT
|
||||
return self.blockchain.FAKE_TX_HASH
|
||||
|
||||
def post_aggregation(
|
||||
self,
|
||||
|
@ -152,7 +151,6 @@ class MockCoordinatorAgent(MockContractAgent):
|
|||
public_key: DkgPublicKey,
|
||||
participant_public_key: SessionStaticKey,
|
||||
transacting_power: TransactingPower,
|
||||
fire_and_forget: bool = False,
|
||||
) -> TxReceipt:
|
||||
ritual = self.rituals[ritual_id]
|
||||
operator_address = transacting_power.account
|
||||
|
@ -179,10 +177,10 @@ class MockCoordinatorAgent(MockContractAgent):
|
|||
ritual.aggregation_mismatch = True
|
||||
# don't increment aggregations
|
||||
# TODO Emit EndRitual here?
|
||||
return self.blockchain.FAKE_RECEIPT
|
||||
return self.blockchain.FAKE_TX_HASH
|
||||
|
||||
ritual.total_aggregations += 1
|
||||
return self.blockchain.FAKE_RECEIPT
|
||||
return self.blockchain.FAKE_TX_HASH
|
||||
|
||||
def set_provider_public_key(
|
||||
self, public_key: FerveoPublicKey, transacting_power: TransactingPower
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import pytest
|
||||
from hexbytes import HexBytes
|
||||
|
||||
from nucypher.blockchain.eth.agents import CoordinatorAgent
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
|
@ -18,6 +19,8 @@ def agent(mock_contract_agency, ursulas) -> MockCoordinatorAgent:
|
|||
if ursula.checksum_address == provider:
|
||||
return ursula.public_keys(RitualisticPower)
|
||||
|
||||
coordinator_agent.post_transcript = lambda *args, **kwargs: HexBytes("deadbeef")
|
||||
coordinator_agent.post_aggregation = lambda *args, **kwargs: HexBytes("deadbeef")
|
||||
coordinator_agent.get_provider_public_key = mock_get_provider_public_key
|
||||
return coordinator_agent
|
||||
|
||||
|
@ -144,7 +147,7 @@ def test_perform_round_1(
|
|||
assert tx_hash is not None
|
||||
|
||||
# ensure tx hash is stored
|
||||
assert ursula.dkg_storage.get_transcript_receipt(ritual_id=0) == tx_hash
|
||||
assert ursula.dkg_storage.get_transcript_txhash(ritual_id=0) == tx_hash
|
||||
|
||||
# try again
|
||||
tx_hash = ursula.perform_round_1(
|
||||
|
@ -153,7 +156,7 @@ def test_perform_round_1(
|
|||
assert tx_hash is None # no execution since pending tx already present
|
||||
|
||||
# clear tx hash
|
||||
ursula.dkg_storage.store_transcript_receipt(ritual_id=0, txhash_or_receipt=None)
|
||||
ursula.dkg_storage.store_transcript_txhash(ritual_id=0, txhash=None)
|
||||
|
||||
# participant already posted transcript
|
||||
participant = agent.get_participant(
|
||||
|
@ -241,16 +244,14 @@ def test_perform_round_2(
|
|||
assert tx_hash is not None
|
||||
|
||||
# check tx hash
|
||||
assert ursula.dkg_storage.get_aggregated_transcript_receipt(ritual_id=0) == tx_hash
|
||||
assert ursula.dkg_storage.get_aggregation_txhash(ritual_id=0) == tx_hash
|
||||
|
||||
# try again
|
||||
tx_hash = ursula.perform_round_2(ritual_id=0, timestamp=0)
|
||||
assert tx_hash is None # no execution since pending tx already present
|
||||
|
||||
# clear tx hash
|
||||
ursula.dkg_storage.store_aggregated_transcript_receipt(
|
||||
ritual_id=0, txhash_or_receipt=None
|
||||
)
|
||||
ursula.dkg_storage.store_aggregation_txhash(ritual_id=0, txhash=None)
|
||||
|
||||
# participant already posted aggregated transcript
|
||||
participant = agent.get_participant(
|
||||
|
|
Loading…
Reference in New Issue