diff --git a/nucypher/blockchain/eth/agents.py b/nucypher/blockchain/eth/agents.py index 7e849f6a8..759717f7b 100644 --- a/nucypher/blockchain/eth/agents.py +++ b/nucypher/blockchain/eth/agents.py @@ -187,18 +187,33 @@ class StakingEscrowAgent(EthereumContractAgent, metaclass=Agency): # StakingEscrow Contract API # - def get_all_locked_tokens(self, periods: int = 1) -> int: + def get_global_locked_tokens(self, at_period: int = None) -> int: """ - Returns the amount of tokens the staking escrow has locked. + Gets the number of locked tokens for *all* stakers that have + confirmed activity for the specified period. + + `at_period` values can be any valid period number past, present, or future: + + PAST - Calling this function with an `at_period` value in the past will return the number + of locked tokens whose worker activity was confirmed for that past period. + + PRESENT - This is the default value, when no `at_period` value is provided. + + FUTURE - Calling this function with an `at_period` value greater than + the current period + 1 (next period), will result in a zero return value + because activity cannot be confirmed beyond the next period. + + Returns an amount of NuNits. """ - if periods < 0: - raise ValueError(f"Periods value must not be negative, Got '{periods}'.") - return self.contract.functions.getAllLockedTokens(periods).call() + if at_period is None: + # Get the current period on-chain by default. + at_period = self.contract.functions.getCurrentPeriod().call() + return self.contract.functions.lockedPerPeriod(at_period).call() def get_locked_tokens(self, staker_address: str, periods: int = 0) -> int: """ - Returns the amount of tokens this staker has locked - for a given duration in periods measured from the current period forwards. + Returns the amount of tokens the specified staker has locked + for a given duration in periods measured starting from the current period. """ if periods < 0: raise ValueError(f"Periods value must not be negative, Got '{periods}'.") @@ -341,8 +356,10 @@ class StakingEscrowAgent(EthereumContractAgent, metaclass=Agency): def sample(self, quantity: int, duration: int, additional_ursulas: float = 1.7, attempts: int = 5) -> List[str]: """ Select n random Stakers, according to their stake distribution. + The returned addresses are shuffled, so one can request more than needed and throw away those which do not respond. + See full diagram here: https://github.com/nucypher/kms-whitepaper/blob/master/pdf/miners-ruler.pdf """ diff --git a/nucypher/blockchain/eth/clients.py b/nucypher/blockchain/eth/clients.py index 9dbb579e3..6bba81e21 100644 --- a/nucypher/blockchain/eth/clients.py +++ b/nucypher/blockchain/eth/clients.py @@ -353,16 +353,6 @@ class InfuraClient(Web3Client): return True -class InfuraClient(Web3Client): - - is_local = False - - def unlock_account(self, address, password): - return True - - def sync(self, *args, **kwargs): - return True - class EthereumTesterClient(Web3Client): is_local = True diff --git a/nucypher/blockchain/eth/providers.py b/nucypher/blockchain/eth/providers.py index 9e84476a6..66e0febe6 100644 --- a/nucypher/blockchain/eth/providers.py +++ b/nucypher/blockchain/eth/providers.py @@ -42,12 +42,12 @@ def _get_infura_provider(provider_uri): from web3.auto.infura.goerli import w3 except InfuraKeyNotFound: - raise ProviderError(f'{infura_envvar} must be provided in order to use an Infura Web3 provider.') + raise ProviderError(f'{infura_envvar} must be provided in order to use an Infura Web3 provider {provider_uri}.') # Verify Connection connected = w3.isConnected() if not connected: - raise ProviderError('Failed to connect to Infura node.') + raise ProviderError(f'Failed to connect to Infura node "{provider_uri}".') return w3.provider diff --git a/nucypher/cli/painting.py b/nucypher/cli/painting.py index 3a8f36f9f..bcbb8b9ed 100644 --- a/nucypher/cli/painting.py +++ b/nucypher/cli/painting.py @@ -31,6 +31,8 @@ from nucypher.blockchain.eth.utils import datetime_at_period from nucypher.blockchain.eth.utils import etherscan_url from nucypher.characters.banners import NUCYPHER_BANNER, NU_BANNER from nucypher.config.constants import SEEDNODES +from nucypher.blockchain.eth.token import NU +from web3 import Web3 def echo_version(ctx, param, value): @@ -181,7 +183,7 @@ def paint_contract_status(blockchain, emitter): contract_payload = f""" | NuCypher Contracts | -Chain .....................{blockchain.client.chain_name} +Chain .................... {blockchain.client.chain_name} Provider URI ............. {blockchain.provider_uri} Registry Path ............ {blockchain.registry.filepath} @@ -195,9 +197,9 @@ Adjudicator .............. {adjudicator_agent.contract_address} | Staking | Current Period ........... {staking_agent.get_current_period()} -Actively Staked Tokens.... {staking_agent.get_all_locked_tokens()} +Actively Staked Tokens ... {NU.from_nunits(staking_agent.get_global_locked_tokens())} Published Stakes ......... {staking_agent.get_staker_population()} -Gas Price ................ {blockchain.client.gas_price} +Gas Price ................ {Web3.fromWei(blockchain.client.gas_price, 'gwei')} Gwei """ emitter.echo(contract_payload) emitter.echo(network_payload)