mirror of https://github.com/nucypher/nucypher.git
Restore nucypher status CLI: Error handling and console painting; implement worker-staker speration.
parent
785eb1e796
commit
73c6da3ffe
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue