Respond to RFCs for PR #2857

pull/2861/head
Kieran Prasch 2022-02-07 10:54:53 -08:00
parent 63621b1ef1
commit 419e649ec7
23 changed files with 112 additions and 109 deletions

View File

@ -1,2 +1 @@
Modifies Ursulas for usage as Operators on the Threshold Network's PRE Application.

View File

@ -28,7 +28,7 @@ from nucypher.blockchain.eth.token import TToken
class Economics:
_default_min_authorization = TToken(40_000, 'T').to_units()
_default_min_operator_seconds = 60 * 60 * 24 # one days in seconds
_default_min_operator_seconds = 60 * 60 * 24 # one day in seconds
# TODO: Reintroduce Adjudicator
# Slashing parameters

View File

@ -1126,10 +1126,13 @@ class Operator(BaseActor):
emitter.message(message, color='red')
raise self.ActorError(message)
ether_balance = client.get_balance(self.operator_address)
if ether_balance and (not funded):
funded, balance = True, Web3.fromWei(ether_balance, 'ether')
emitter.message(f"✓ Operator is funded with {balance} ETH", color='green')
if not funded:
# check for funds
ether_balance = client.get_balance(self.operator_address)
if ether_balance:
# funds found
funded, balance = True, Web3.fromWei(ether_balance, 'ether')
emitter.message(f"✓ Operator is funded with {balance} ETH", color='green')
if (not bonded) and (self.get_staking_provider_address() != NULL_ADDRESS):
bonded = True

View File

@ -47,21 +47,21 @@ from nucypher.utilities.logging import Logger
class ERC20:
"""
An amount of NuCypher tokens that doesn't hurt your eyes.
An amount of ERC20 tokens that doesn't hurt your eyes.
Wraps the eth_utils currency conversion methods.
The easiest way to use NU, is to pass an int, Decimal, or str, and denomination string:
The easiest way to use ERC20, is to pass an int, Decimal, or str, and denomination string:
Int: nu = NU(100, 'NU')
Int: nu = NU(15000000000000000000000, self._unit_name)
Int: t = T(100, 'T')
Int: t = T(15000000000000000000000, 'TuNits')
Decimal: nu = NU(Decimal('15042.445'), 'NU')
String: nu = NU('10002.302', 'NU')
Decimal: t = T(Decimal('15042.445'), 'T')
String: t = T('10002.302', 'T')
...or alternately...
Decimal: nu = NU.from_tokens(Decimal('100.50'))
Int: nu = NU.from_units(15000000000000000000000)
Decimal: t = T.from_tokens(Decimal('100.50'))
Int: t = T.from_units(15000000000000000000000)
Token quantity is stored internally as an int in the smallest denomination,
and all arithmetic operations use this value.
@ -572,6 +572,7 @@ def validate_increase(stake: Stake, amount: NU) -> None:
class WorkTrackerBase:
"""Baseclass for handling automated transaction tracking..."""
CLOCK = reactor
INTERVAL_FLOOR = 60 * 15 # fifteen minutes
@ -583,7 +584,7 @@ class WorkTrackerBase:
super().__init__(*args, **kwargs)
self.log = Logger('stake-tracker')
self.worker = worker
self.worker = worker # TODO: What to call the subject here? What is a work tracker without "work"?
self._tracking_task = task.LoopingCall(self._do_work)
self._tracking_task.clock = self.CLOCK
@ -759,7 +760,7 @@ class WorkTrackerBase:
Async working task for Ursula # TODO: Split into multiple async tasks
"""
self.log.info("doing work")
self.log.info(f"{self.__class__.__name__} is running. Advancing to next work cycle.") # TODO: What to call the verb the subject performs?
# Call once here, and inject later for temporal consistency
current_block_number = self.client.block_number
@ -770,6 +771,7 @@ class WorkTrackerBase:
# Commitment tracking
unmined_transactions = self.__track_pending_commitments()
if unmined_transactions:
self.log.info('Tracking pending transaction.')
self.__handle_replacement_commitment(current_block_number=current_block_number)
# while there are known pending transactions, remain in fast interval mode
self._tracking_task.interval = self.INTERVAL_FLOOR
@ -829,11 +831,11 @@ class WorkTracker(WorkTrackerBase):
return False
def _fire_commitment(self):
"""Makes an initial/replacement worker commitment transaction"""
"""Makes an initial/replacement operator commitment transaction"""
transacting_power = self.worker.transacting_power
with transacting_power:
txhash = self.worker.confirm_address(fire_and_forget=True) # < --- blockchain WRITE
self.log.info(f"Confirming worker address {self.worker.operator_address} with staking provider {self.worker.staking_provider_address} - TxHash: {txhash.hex()}")
self.log.info(f"Confirming operator address {self.worker.operator_address} with staking provider {self.worker.staking_provider_address} - TxHash: {txhash.hex()}")
return txhash

View File

@ -310,6 +310,9 @@ class Alice(Character, BlockchainPolicyAuthor):
def _check_grant_requirements(self, policy):
"""Called immediately before granting."""
# TODO: Do not allow policies with an expiration beyond a node unbonding time.
# Policy Probationary Period
# TODO: Remove when the time is right.
# from nucypher.config.constants import END_OF_POLICIES_PROBATIONARY_PERIOD
# if policy.expiration > END_OF_POLICIES_PROBATIONARY_PERIOD:
@ -1121,13 +1124,13 @@ class Ursula(Teacher, Character, Operator):
network_middleware: RestMiddleware = None,
*args,
**kwargs
) -> 'Ursula':
) -> Union['Ursula', 'NodeSprout']:
if network_middleware is None:
network_middleware = RestMiddleware(registry=registry)
# Parse node URI
host, port, staker_address = parse_node_uri(seed_uri)
host, port, staking_provider_address = parse_node_uri(seed_uri)
# Fetch the hosts TLS certificate and read the common name
try:
@ -1153,11 +1156,11 @@ class Ursula(Teacher, Character, Operator):
)
# Check the node's stake (optional)
if minimum_stake > 0 and staker_address and not federated_only:
staking_agent = ContractAgency.get_agent(PREApplicationAgent, registry=registry)
seednode_stake = staking_agent.get_authorized_stake(staking_provider=staker_address)
if minimum_stake > 0 and staking_provider_address and not federated_only:
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=registry)
seednode_stake = application_agent.get_authorized_stake(staking_provider=staking_provider_address)
if seednode_stake < minimum_stake:
raise Learner.NotATeacher(f"{staker_address} is staking less than the specified minimum stake value ({minimum_stake}).")
raise Learner.NotATeacher(f"{staking_provider_address} is staking less than the specified minimum stake value ({minimum_stake}).")
# OK - everyone get out
temp_node_storage.forget()

View File

@ -212,8 +212,7 @@ class BlockchainPolicy(Policy):
def _make_reservoir(self, handpicked_addresses: List[ChecksumAddress]):
"""Returns a reservoir of staking nodes to create a decentralized policy."""
reservoir = make_decentralized_staking_provider_reservoir(application_agent=self.publisher.application_agent,
include_addresses=handpicked_addresses,
pagination_size=self.publisher.application_agent.get_staking_providers_population()) # TODO: Use another size?
include_addresses=handpicked_addresses)
return reservoir

View File

@ -14,6 +14,8 @@
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from pathlib import Path
from typing import List, NamedTuple, Optional, Sequence
@ -21,11 +23,10 @@ from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION, NO_CONTROL_PROTO
from eth_typing import ChecksumAddress
from eth_utils import to_checksum_address
from flask import request, Response
from nucypher_core import TreasureMap, RetrievalKit
from nucypher_core.umbral import PublicKey
from nucypher.blockchain.eth.agents import ContractAgency, StakingEscrowAgent, PREApplicationAgent
from nucypher.blockchain.eth.agents import ContractAgency, PREApplicationAgent
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import BaseContractRegistry, InMemoryContractRegistry
from nucypher.characters.lawful import Ursula
@ -116,7 +117,7 @@ the Pipe for nucypher network operations
quantity: int,
exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None,
include_ursulas: Optional[Sequence[ChecksumAddress]] = None) -> List[UrsulaInfo]:
reservoir = self._make_staker_reservoir(quantity, exclude_ursulas, include_ursulas)
reservoir = self._make_reservoir(quantity, exclude_ursulas, include_ursulas)
value_factory = PrefetchStrategy(reservoir, quantity)
def get_ursula_info(ursula_address) -> Porter.UrsulaInfo:
@ -165,10 +166,10 @@ the Pipe for nucypher network operations
return client.retrieve_cfrags(treasure_map, retrieval_kits,
alice_verifying_key, bob_encrypting_key, bob_verifying_key)
def _make_staker_reservoir(self,
quantity: int,
exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None,
include_ursulas: Optional[Sequence[ChecksumAddress]] = None):
def _make_reservoir(self,
quantity: int,
exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None,
include_ursulas: Optional[Sequence[ChecksumAddress]] = None):
if self.federated_only:
sample_size = quantity - (len(include_ursulas) if include_ursulas else 0)
if not self.block_until_number_of_known_nodes_is(sample_size,

View File

@ -134,8 +134,8 @@ class UrsulaInfoMetricsCollector(BaseMetricsCollector):
self.metrics["work_orders_gauge"].set(len(reencryption_requests))
if not self.ursula.federated_only:
staking_agent = ContractAgency.get_agent(PREApplicationAgent, registry=self.ursula.registry)
authorized = staking_agent.get_authorized_stake(staking_provider=self.ursula.checksum_address)
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=self.ursula.registry)
authorized = application_agent.get_authorized_stake(staking_provider=self.ursula.checksum_address)
decentralized_payload = {'provider': str(self.ursula.provider_uri),
'active_stake': str(authorized)}
base_payload.update(decentralized_payload)

View File

@ -50,7 +50,7 @@ def test_investigator_requests_slashing(testerchain,
application_economics,
mocker):
staker_account = testerchain.staker_account(0)
staker_account = testerchain.stake_provider_account(0)
worker_account = testerchain.ursula_account(0)
##### STAKING ESCROW STUFF #####

View File

@ -18,6 +18,7 @@
import pytest
import pytest_twisted
from constant_sorrow.constants import MOCK_DB
from twisted.internet import threads
from twisted.internet.task import Clock
from web3.middleware.simulate_unmined_transaction import unmined_receipt_simulator_middleware
@ -26,11 +27,10 @@ from nucypher.blockchain.eth.actors import Operator
from nucypher.blockchain.eth.agents import ContractAgency, PREApplicationAgent
from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.blockchain.eth.token import NU, WorkTracker
from nucypher.blockchain.eth.token import NU
from nucypher.crypto.powers import TransactingPower
from nucypher.utilities.logging import Logger
from tests.utils.ursula import make_decentralized_ursulas, start_pytest_ursula_services
from constant_sorrow.constants import MOCK_DB
logger = Logger("test-operator")
@ -42,13 +42,13 @@ def log(message):
@pytest.mark.skip()
@pytest_twisted.inlineCallbacks
def test_worker_auto_commitments(mocker,
testerchain,
test_registry,
staker,
agency,
application_economics,
ursula_decentralized_test_config):
def test_work_tracker(mocker,
testerchain,
test_registry,
staker,
agency,
application_economics,
ursula_decentralized_test_config):
staker.initialize_stake(amount=NU(application_economics.min_authorization, 'NuNit'),
lock_periods=int(application_economics.min_operator_seconds))
@ -182,12 +182,12 @@ def test_worker_auto_commitments(mocker,
yield d
def test_ursula_contract_interaction_methods(ursula_decentralized_test_config,
testerchain,
threshold_staking,
agency,
application_economics,
test_registry):
def test_ursula_operator_confirmation(ursula_decentralized_test_config,
testerchain,
threshold_staking,
agency,
application_economics,
test_registry):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
creator, staking_provider, operator_address, *everyone_else = testerchain.client.accounts
min_authorization = application_economics.min_authorization
@ -229,13 +229,13 @@ def test_ursula_contract_interaction_methods(ursula_decentralized_test_config,
@pytest_twisted.inlineCallbacks
def test_integration_of_ursula_contract_interaction(mocker,
ursula_decentralized_test_config,
testerchain,
threshold_staking,
agency,
application_economics,
test_registry):
def test_ursula_operator_confirmation_autopilot(mocker,
ursula_decentralized_test_config,
testerchain,
threshold_staking,
agency,
application_economics,
test_registry):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
creator, staking_provider, operator, staking_provider2, operator2, *everyone_else = testerchain.client.accounts
min_authorization = application_economics.min_authorization

View File

@ -55,7 +55,7 @@ def test_adjudicator_slashes(agency,
test_registry,
mocker):
staker_account = testerchain.staker_account(0)
staker_account = testerchain.stake_provider_account(0)
worker_account = testerchain.ursula_account(0)
##### STAKING ESCROW STUFF #####

View File

@ -15,21 +15,17 @@
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
from decimal import Decimal, InvalidOperation
from nucypher.blockchain.eth.agents import StakingEscrowAgent, ContractAgency, PREApplicationAgent
from nucypher.blockchain.eth.token import NU
from nucypher.blockchain.eth.agents import ContractAgency, PREApplicationAgent
def test_get_agent_with_different_registries(application_economics, agency, test_registry, agency_local_registry):
# Get agents using same registry instance
staking_agent_1 = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
staking_agent_2 = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
assert staking_agent_2.registry_str == staking_agent_1.registry_str == str(test_registry)
assert staking_agent_2 is staking_agent_1
application_agent_1 = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
application_agent_2 = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
assert application_agent_2.registry_str == application_agent_1.registry_str == str(test_registry)
assert application_agent_2 is application_agent_1
# Same content but different classes of registries
staking_agent_2 = ContractAgency.get_agent(PREApplicationAgent, registry=agency_local_registry)
assert staking_agent_2.registry_str == str(test_registry)
assert staking_agent_2 is staking_agent_1
application_agent_2 = ContractAgency.get_agent(PREApplicationAgent, registry=agency_local_registry)
assert application_agent_2.registry_str == str(test_registry)
assert application_agent_2 is application_agent_1

View File

@ -44,9 +44,9 @@ def test_get_min_seconds(agency, test_registry, application_economics):
assert result == application_economics.min_operator_seconds
def test_authorized_tokens(testerchain, agency, application_economics, test_registry, stakers):
def test_authorized_tokens(testerchain, agency, application_economics, test_registry, staking_providers):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
provider_account = stakers[0]
provider_account = staking_providers[0]
authorized_amount = application_agent.get_authorized_stake(staking_provider=provider_account)
assert authorized_amount >= application_economics.min_authorization
@ -82,19 +82,19 @@ def test_staking_providers_and_operators_relationships(testerchain,
assert NULL_ADDRESS == application_agent.get_staking_provider_from_operator(operator_address=random_address)
def test_get_staker_population(agency, stakers, test_registry):
def test_get_staker_population(agency, staking_providers, test_registry):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
# Apart from all the providers in the fixture, we also added a new provider above
assert application_agent.get_staking_providers_population() == len(stakers) + 1
assert application_agent.get_staking_providers_population() == len(staking_providers) + 1
def test_get_swarm(agency, stakers, test_registry):
def test_get_swarm(agency, staking_providers, test_registry):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
swarm = application_agent.swarm()
swarm_addresses = list(swarm)
assert len(swarm_addresses) == len(stakers) + 1
assert len(swarm_addresses) == len(staking_providers) + 1
# Grab a staker address from the swarm
provider_addr = swarm_addresses[0]
@ -102,7 +102,7 @@ def test_get_swarm(agency, stakers, test_registry):
assert is_address(provider_addr)
@pytest.mark.usefixtures("stakers")
@pytest.mark.usefixtures("staking_providers")
def test_sample_staking_providers(agency, test_registry):
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)

View File

@ -35,7 +35,7 @@ def test_sampling_distribution(testerchain, test_registry, threshold_staking, ap
# setup
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
stake_provider_accounts = testerchain.stakers_accounts
stake_provider_accounts = testerchain.stake_providers_accounts
amount = application_economics.min_authorization
all_locked_tokens = len(stake_provider_accounts) * amount

View File

@ -125,11 +125,11 @@ def test_stakers_and_workers_relationships(testerchain, agency, test_registry):
@pytest.mark.skip()
def test_get_staker_population(agency, stakers, test_registry):
def test_get_staker_population(agency, staking_providers, test_registry):
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
# Apart from all the stakers in the fixture, we also added a new staker above
assert staking_agent.get_staker_population() == len(stakers) + 1
assert staking_agent.get_staker_population() == len(staking_providers) + 1
@pytest.mark.skip()

View File

@ -69,8 +69,8 @@ def test_testerchain_creation(testerchain, another_testerchain):
bob = chain.bob_account
assert bob == chain.client.accounts[2]
stakers = [chain.staker_account(i) for i in range(NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS)]
assert stakers == chain.stakers_accounts
stakers = [chain.stake_provider_account(i) for i in range(NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS)]
assert stakers == chain.stake_providers_accounts
ursulas = [chain.ursula_account(i) for i in range(NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS)]
assert ursulas == chain.ursulas_accounts

View File

@ -100,8 +100,8 @@ def test_stake_equality(application_economics, get_random_checksum_address, mock
@pytest.mark.skip()
def test_stake_integration(stakers):
staker = list(stakers)[1]
def test_stake_integration(staking_providers):
staker = list(staking_providers)[1]
stakes = staker.stakes
assert stakes

View File

@ -29,12 +29,12 @@ from tests.utils.ursula import make_decentralized_ursulas
@pytest.mark.usefixtures("blockchain_ursulas")
def test_stakers_bond_to_ursulas(testerchain, test_registry, stakers, ursula_decentralized_test_config):
def test_stakers_bond_to_ursulas(testerchain, test_registry, staking_providers, ursula_decentralized_test_config):
ursulas = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
stakers_addresses=testerchain.stakers_accounts,
stakers_addresses=testerchain.stake_providers_accounts,
workers_addresses=testerchain.ursulas_accounts)
assert len(ursulas) == len(stakers)
assert len(ursulas) == len(staking_providers)
for ursula in ursulas:
ursula.validate_worker(registry=test_registry)
assert ursula.verified_worker

View File

@ -62,7 +62,7 @@ def test_nucypher_status_network(click_runner, testerchain, agency_local_registr
@pytest.mark.skip()
def test_nucypher_status_stakers(click_runner, agency_local_registry, stakers):
def test_nucypher_status_stakers(click_runner, agency_local_registry, staking_providers):
# Get all stakers info
stakers_command = ('stakers',
@ -77,11 +77,11 @@ def test_nucypher_status_stakers(click_runner, agency_local_registry, stakers):
# TODO: Use regex matching instead of this
assert re.search(f"^Current period: {staking_agent.get_current_period()}", result.output, re.MULTILINE)
for staker in stakers:
for staker in staking_providers:
assert re.search(f"^{staker.checksum_address}", result.output, re.MULTILINE)
# Get info of only one staker
some_dude = random.choice(stakers)
some_dude = random.choice(staking_providers)
staking_address = some_dude.checksum_address
stakers_command = ('stakers', '--staking-address', staking_address,
'--registry-filepath', str(agency_local_registry.filepath.absolute()),
@ -105,7 +105,7 @@ def test_nucypher_status_stakers(click_runner, agency_local_registry, stakers):
@pytest.mark.skip()
def test_nucypher_status_fee_range(click_runner, agency_local_registry, stakers):
def test_nucypher_status_fee_range(click_runner, agency_local_registry, staking_providers):
# Get information about global fee range (minimum rate, default rate, maximum rate)
stakers_command = ('fee-range',
@ -122,7 +122,7 @@ def test_nucypher_status_fee_range(click_runner, agency_local_registry, stakers)
@pytest.mark.skip()
def test_nucypher_status_locked_tokens(click_runner, testerchain, agency_local_registry, stakers):
def test_nucypher_status_locked_tokens(click_runner, testerchain, agency_local_registry, staking_providers):
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry)
# All workers make a commitment
@ -151,7 +151,7 @@ def test_nucypher_status_locked_tokens(click_runner, testerchain, agency_local_r
@pytest.mark.skip()
def test_nucypher_status_events(click_runner, testerchain, agency_local_registry, stakers, temp_dir_path):
def test_nucypher_status_events(click_runner, testerchain, agency_local_registry, staking_providers, temp_dir_path):
# All workers make a commitment
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry)
starting_block_number = testerchain.get_block_number()
@ -174,11 +174,11 @@ def test_nucypher_status_events(click_runner, testerchain, agency_local_registry
'--contract-name', 'StakingEscrow',
'--from-block', starting_block_number)
result = click_runner.invoke(status, status_command, catch_exceptions=False)
for staker in stakers:
for staker in staking_providers:
assert re.search(f'staker: {staker.checksum_address}, period: {committed_period}', result.output, re.MULTILINE)
# event filter output
first_staker = stakers[0]
first_staker = staking_providers[0]
filter_status_command = ('events',
'--provider', TEST_PROVIDER_URI,
'--network', TEMPORARY_DOMAIN,
@ -188,7 +188,7 @@ def test_nucypher_status_events(click_runner, testerchain, agency_local_registry
'--event-filter', f'staker={first_staker.checksum_address}')
result = click_runner.invoke(status, filter_status_command, catch_exceptions=False)
assert re.search(f'staker: {first_staker.checksum_address}, period: {committed_period}', result.output, re.MULTILINE)
for staker in stakers:
for staker in staking_providers:
if staker != first_staker:
assert not re.search(f'staker: {staker.checksum_address}', result.output, re.MULTILINE), result.output

View File

@ -81,7 +81,7 @@ def mock_funded_account_password_keystore(tmp_path_factory, testerchain, thresho
def test_ursula_and_local_keystore_signer_integration(click_runner,
tmp_path,
stakers,
staking_providers,
stake_value,
application_economics,
mocker,

View File

@ -95,8 +95,8 @@ def test_blockchain_metrics_collector(testerchain):
@pytest.mark.skip()
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
def test_staker_metrics_collector(test_registry, stakers):
staker = random.choice(stakers)
def test_staker_metrics_collector(test_registry, staking_providers):
staker = random.choice(staking_providers)
collector = StakerMetricsCollector(domain=staker.network,
staker_address=staker.checksum_address,
contract_registry=test_registry)

View File

@ -613,12 +613,12 @@ def threshold_staking(deploy_contract):
@pytest.fixture(scope="module")
def stakers(testerchain, agency, test_registry, threshold_staking):
def staking_providers(testerchain, agency, test_registry, threshold_staking):
pre_application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=test_registry)
blockchain = pre_application_agent.blockchain
staking_providers = list()
for provider_address, operator_address in zip(blockchain.stakers_accounts, blockchain.ursulas_accounts):
for provider_address, operator_address in zip(blockchain.stake_providers_accounts, blockchain.ursulas_accounts):
provider_power = TransactingPower(account=provider_address, signer=Web3Signer(testerchain.client))
provider_power.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
@ -651,14 +651,14 @@ def stakers(testerchain, agency, test_registry, threshold_staking):
@pytest.fixture(scope="module")
def blockchain_ursulas(testerchain, stakers, ursula_decentralized_test_config):
def blockchain_ursulas(testerchain, staking_providers, ursula_decentralized_test_config):
if MOCK_KNOWN_URSULAS_CACHE:
# TODO: Is this a safe assumption / test behaviour?
# raise RuntimeError("Ursulas cache was unclear at fixture loading time. Did you use one of the ursula maker functions without cleaning up?")
MOCK_KNOWN_URSULAS_CACHE.clear()
_ursulas = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
stakers_addresses=testerchain.stakers_accounts,
stakers_addresses=testerchain.stake_providers_accounts,
workers_addresses=testerchain.ursulas_accounts)
for u in _ursulas:
u.synchronous_query_timeout = .01 # We expect to never have to wait for content that is actually on-chain during tests.

View File

@ -263,9 +263,9 @@ class TesterBlockchain(BlockchainDeployerInterface):
raise ValueError(f"Ursula index must be lower than {NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS}")
return self.client.accounts[index + self._FIRST_URSULA]
def staker_account(self, index):
def stake_provider_account(self, index):
if index not in self.__STAKERS_RANGE:
raise ValueError(f"Staker index must be lower than {NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS}")
raise ValueError(f"Stake provider index must be lower than {NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS}")
return self.client.accounts[index + self._FIRST_STAKER]
@property
@ -273,13 +273,13 @@ class TesterBlockchain(BlockchainDeployerInterface):
return list(self.ursula_account(i) for i in self.__WORKERS_RANGE)
@property
def stakers_accounts(self):
return list(self.staker_account(i) for i in self.__STAKERS_RANGE)
def stake_providers_accounts(self):
return list(self.stake_provider_account(i) for i in self.__STAKERS_RANGE)
@property
def unassigned_accounts(self):
special_accounts = [self.etherbase_account, self.alice_account, self.bob_account]
assigned_accounts = set(self.stakers_accounts + self.ursulas_accounts + special_accounts)
assigned_accounts = set(self.stake_providers_accounts + self.ursulas_accounts + special_accounts)
accounts = set(self.client.accounts)
return list(accounts.difference(assigned_accounts))