Restore nucypher status CLI: Error handling and console painting; implement worker-staker speration.

pull/1071/head
Kieran Prasch 2019-06-12 12:08:41 -07:00
parent 785eb1e796
commit 73c6da3ffe
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
5 changed files with 68 additions and 64 deletions

View File

@ -14,6 +14,8 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import random
from typing import Generator, List, Tuple, Union
@ -185,6 +187,14 @@ class StakingEscrowAgent(EthereumContractAgent, metaclass=Agency):
# StakingEscrow Contract API
#
def get_all_locked_tokens(self, periods: int = 1) -> int:
"""
Returns the amount of tokens the staking escrow has locked.
"""
if periods < 0:
raise ValueError(f"Periods value must not be negative, Got '{periods}'.")
return self.contract.functions.getAllLockedTokens(periods).call()
def get_locked_tokens(self, staker_address: str, periods: int = 0) -> int:
"""
Returns the amount of tokens this staker has locked

View File

@ -30,10 +30,10 @@ def _get_websocket_provider(provider_uri):
return WebsocketProvider(endpoint_uri=provider_uri)
def _get_infura_provider(self):
def _get_infura_provider(provider_uri):
# https://web3py.readthedocs.io/en/latest/providers.html#infura-mainnet
uri_breakdown = urlparse(self.provider_uri)
uri_breakdown = urlparse(provider_uri)
infura_envvar = 'WEB3_INFURA_PROJECT_ID'
os.environ[infura_envvar] = os.environ.get(infura_envvar, uri_breakdown.netloc)
@ -42,12 +42,12 @@ def _get_infura_provider(self):
from web3.auto.infura.goerli import w3
except InfuraKeyNotFound:
raise self.InterfaceError(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.')
# Verify Connection
connected = w3.isConnected()
if not connected:
raise self.InterfaceError('Failed to connect to Infura node.')
raise ProviderError('Failed to connect to Infura node.')
return w3.provider

View File

@ -24,9 +24,11 @@ import click
import maya
from constant_sorrow.constants import NO_KNOWN_NODES
from nucypher.blockchain.eth.agents import NucypherTokenAgent, AdjudicatorAgent, PolicyManagerAgent, StakingEscrowAgent
from nucypher.blockchain.eth.constants import NUCYPHER_TOKEN_CONTRACT_NAME
from nucypher.blockchain.eth.interfaces import BlockchainInterface
from nucypher.blockchain.eth.utils import datetime_at_period, etherscan_url
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
@ -169,36 +171,35 @@ def paint_known_nodes(emitter, ursula) -> None:
emitter.echo(row_template.format(node.rest_url().ljust(20), node), color=color_index[node_type])
def paint_contract_status(emitter, ursula_config):
contract_payload = """
def paint_contract_status(blockchain, emitter):
| NuCypher ETH Contracts |
token_agent = NucypherTokenAgent(blockchain=blockchain)
staking_agent = StakingEscrowAgent(blockchain=blockchain)
policy_agent = PolicyManagerAgent(blockchain=blockchain)
adjudicator_agent = AdjudicatorAgent(blockchain=blockchain)
Provider URI ............. {provider_uri}
Registry Path ............ {registry_filepath}
contract_payload = f"""
| NuCypher Contracts |
NucypherToken ............ {token}
StakingEscrow ............ {escrow}
PolicyManager ............ {manager}
Chain .....................{blockchain.client.chain_name}
Provider URI ............. {blockchain.provider_uri}
Registry Path ............ {blockchain.registry.filepath}
""".format(provider_uri=ursula_config.blockchain.provider_uri,
registry_filepath=ursula_config.blockchain.registry.filepath,
token=ursula_config.token_agent.contract_address,
escrow=ursula_config.staking_agent.contract_address,
manager=ursula_config.policy_agent.contract_address,
period=ursula_config.staking_agent.get_current_period())
NucypherToken ............ {token_agent.contract_address}
StakingEscrow ............ {staking_agent.contract_address}
PolicyManager ............ {policy_agent.contract_address}
Adjudicator .............. {adjudicator_agent.contract_address}
"""
network_payload = f"""
| Staking |
Current Period ........... {staking_agent.get_current_period()}
Actively Staked Tokens.... {staking_agent.get_all_locked_tokens()}
Published Stakes ......... {staking_agent.get_staker_population()}
Gas Price ................ {blockchain.client.gas_price}
"""
emitter.echo(contract_payload)
network_payload = """
| Blockchain Network |
Current Period ........... {period}
Gas Price ................ {gas_price}
Active Staking Ursulas ... {ursulas}
""".format(period=ursula_config.staking_agent.get_current_period(),
gas_price=ursula_config.blockchain.client.gasPrice,
ursulas=ursula_config.staking_agent.get_staker_population())
emitter.echo(network_payload)

View File

@ -18,31 +18,40 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import click
from nucypher.blockchain.eth.interfaces import BlockchainInterface
from nucypher.characters.banners import NU_BANNER
from nucypher.cli.actions import get_provider_process
from nucypher.cli.config import nucypher_click_config
from nucypher.cli.painting import paint_known_nodes, paint_contract_status
from nucypher.cli.types import (
EXISTING_READABLE_FILE
)
from nucypher.config.characters import UrsulaConfiguration
from nucypher.cli.painting import paint_contract_status
@click.command()
@click.option('--config-file', help="Path to configuration file", type=EXISTING_READABLE_FILE)
@click.option('--poa', help="Inject POA middleware", is_flag=True, default=False)
@click.option('--sync/--no-sync', default=False)
@click.option('--geth', '-G', help="Run using the built-in geth node", is_flag=True)
@click.option('--provider', 'provider_uri', help="Blockchain provider's URI", type=click.STRING, default="auto://")
@nucypher_click_config
def status(click_config, config_file):
def status(click_config, provider_uri, sync, geth, poa):
"""
Echo a snapshot of live network metadata.
"""
#
# Initialize
#
ursula_config = UrsulaConfiguration.from_configuration_file(filepath=config_file)
if not ursula_config.federated_only:
ursula_config.get_blockchain_interface(provider_uri=ursula_config.provider_uri)
ursula_config.acquire_agency()
# Contracts
paint_contract_status(click_config.emitter, ursula_config=ursula_config, click_config=click_config)
emitter = click_config.emitter
click.clear()
emitter.banner(NU_BANNER)
emitter.echo(message="Reading Latest Chaindata...")
# Known Nodes
paint_known_nodes(emitter=click_config.emitter, ursula=ursula_config)
try:
ETH_NODE = None
if geth:
ETH_NODE = get_provider_process()
blockchain = BlockchainInterface(provider_uri=provider_uri, provider_process=ETH_NODE, poa=poa)
blockchain.connect(sync_now=sync, fetch_registry=True)
paint_contract_status(blockchain=blockchain, emitter=emitter)
return # Exit
except Exception as e:
if click_config.debug:
raise
click.secho(str(e), bold=True, fg='red')
return # Exit

View File

@ -180,22 +180,6 @@ def test_run_federated_ursula_from_config_file(custom_filepath, click_runner):
assert "'help' or '?'" in result.output
def test_empty_federated_status(click_runner, custom_filepath):
custom_config_filepath = os.path.join(custom_filepath, UrsulaConfiguration.generate_filename())
assert os.path.isfile(custom_config_filepath), 'Configuration file does not exist'
status_args = ('status', '--config-file', custom_config_filepath)
result = click_runner.invoke(nucypher_cli, status_args, catch_exceptions=True)
assert result.exit_code == 0
assert 'Federated Only' in result.output
heading = 'Known Nodes (connected 0 / seen 0)'
assert heading in result.output
assert 'password' not in result.output
def test_ursula_destroy_configuration(custom_filepath, click_runner):
preexisting_live_configuration = os.path.isdir(DEFAULT_CONFIG_ROOT)