Casual Alice Geth and moving towards testnet as a default provider process

pull/984/head
Kieran R. Prasch 2019-05-16 18:46:32 -06:00 committed by Kieran Prasch
parent 9330e69bee
commit e32aab17e4
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
4 changed files with 93 additions and 26 deletions

View File

@ -329,6 +329,17 @@ class NuCypherGethProcess(LoggingMixin, BaseGethProcess):
self.wait_for_rpc(timeout=timeout)
time.sleep(extra_delay)
def ensure_account_exists(self, password: str) -> str:
accounts = get_accounts(**self.geth_kwargs)
if not accounts:
account = create_new_account(password=password.encode(), **self.geth_kwargs)
else:
account = accounts[0]
checksum_address = to_checksum_address(account.decode())
assert is_checksum_address(checksum_address), f"GETH RETURNED INVALID ETH ADDRESS {checksum_address}"
return checksum_address
class NuCypherGethDevProcess(NuCypherGethProcess):
@ -414,13 +425,10 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
self.initialized = True
self.__process = NOT_RUNNING
super().__init__(geth_kwargs=geth_kwargs, *args, **kwargs) # Attaches self.geth_kwargs in super call
self.command = [*self.command, '--syncmode', 'fast']
def get_accounts(self):
accounts = get_accounts(**self.geth_kwargs)
return accounts
def initialize_blockchain(self, overwrite: bool = True) -> None:
log = Logger('nucypher-geth-init')
with open(self.GENESIS_SOURCE_FILEPATH, 'r') as file:
@ -435,21 +443,59 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
bootnodes_filepath = os.path.join(DEPLOY_DIR, 'static-nodes.json')
shutil.copy(bootnodes_filepath, os.path.join(self.data_dir))
def ensure_account_exists(self, password: str) -> str:
accounts = get_accounts(**self.geth_kwargs)
if not accounts:
account = create_new_account(password=password.encode(), **self.geth_kwargs)
class NuCypherGethGoerliProcess(NuCypherGethProcess):
IPC_PROTOCOL = 'file'
GENESIS_FILENAME = 'testnet_genesis.json'
GENESIS_SOURCE_FILEPATH = os.path.join(DEPLOY_DIR, GENESIS_FILENAME)
P2P_PORT = 30303
_CHAIN_NAME = 'goerli'
__CHAIN_ID = 5
def __init__(self,
config_root: str = None,
overrides: dict = None,
*args, **kwargs):
log = Logger('nucypher-geth-georli')
if overrides is None:
overrides = dict()
# Validate
invalid_override = f"You cannot specify `network_id` for a {self.__class__.__name__}"
if 'data_dir' in overrides:
raise ValueError(invalid_override)
if 'network_id' in overrides:
raise ValueError(invalid_override)
# Set the data dir
if config_root is None:
base_dir = os.path.join(DEFAULT_CONFIG_ROOT, '.ethereum')
else:
account = accounts[0]
base_dir = os.path.join(config_root, '.ethereum')
self.data_dir = get_chain_data_dir(base_dir=base_dir, name=self._CHAIN_NAME)
checksum_address = to_checksum_address(account.decode())
assert is_checksum_address(checksum_address), f"GETH RETURNED INVALID ETH ADDRESS {checksum_address}"
return checksum_address
# Hardcoded Geth CLI args for devnet child process ("light client")
ipc_path = os.path.join(self.data_dir, self.IPC_FILENAME)
geth_kwargs = {'port': str(self.P2P_PORT),
'verbosity': str(self.VERBOSITY),
'data_dir': self.data_dir,
'ipc_path': ipc_path,
'rpc_enabled': True,
'no_discover': False,
}
def start(self, *args, **kwargs):
# FIXME: Quick and Dirty
# Genesis & Blockchain Init
all_good = all((
not is_ropsten_chain(self.data_dir),
))
# Write static nodes file to data dir
bootnodes_filepath = os.path.join(DEPLOY_DIR, 'static-nodes.json')
shutil.copy(bootnodes_filepath, os.path.join(self.data_dir))
super().start()
if not all_good:
raise RuntimeError('Unintentional connection to Ropsten')
self.__process = NOT_RUNNING
super().__init__(geth_kwargs=geth_kwargs, *args, **kwargs) # Attaches self.geth_kwargs in super call
self.command = [*self.command, '--syncmode', 'fast', '--goerli']

View File

@ -2,7 +2,9 @@ import datetime
import click
import maya
from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION
from nucypher.blockchain.eth.clients import NuCypherGethGoerliProcess
from nucypher.characters.banners import ALICE_BANNER
from nucypher.characters.control.emitters import IPCStdoutEmitter
from nucypher.cli import actions, painting
@ -23,6 +25,7 @@ from nucypher.config.characters import AliceConfiguration
@click.option('--config-root', help="Custom configuration directory", type=click.Path())
@click.option('--config-file', help="Path to configuration file", type=EXISTING_READABLE_FILE)
@click.option('--provider-uri', help="Blockchain provider's URI", type=click.STRING)
@click.option('--geth', '-G', help="Run using the built-in geth node", is_flag=True)
@click.option('--no-registry', help="Skip importing the default contract registry", is_flag=True)
@click.option('--registry-filepath', help="Custom contract registry filepath", type=EXISTING_READABLE_FILE)
@click.option('--bob-encrypting-key', help="Bob's encrypting key as a hexideicmal string", type=click.STRING)
@ -30,6 +33,7 @@ from nucypher.config.characters import AliceConfiguration
@click.option('--label', help="The label for a policy", type=click.STRING)
@click.option('--m', help="M-Threshold KFrags", type=click.INT)
@click.option('--n', help="N-Total KFrags", type=click.INT)
@click.option('--value', help="M-Threshold KFrags", type=click.FLOAT)
@click.option('--dev', '-d', help="Enable development mode", is_flag=True)
@click.option('--force', help="Don't ask for confirmation", is_flag=True)
@click.option('--dry-run', '-x', help="Execute normally without actually starting the node", is_flag=True)
@ -47,6 +51,7 @@ def alice(click_config,
config_root,
config_file,
provider_uri,
geth,
no_registry,
registry_filepath,
dev,
@ -57,15 +62,25 @@ def alice(click_config,
label,
m,
n,
message_kit
):
value,
message_kit):
"""
Start and manage an "Alice" character.
"""
# Validate
if federated_only and geth:
raise click.BadOptionUsage(option_name="--geth", message="Federated only cannot be used with the --geth flag")
if not click_config.json_ipc and not click_config.quiet:
click.secho(ALICE_BANNER)
# Stage integrated ethereum node process
ETH_NODE = NO_BLOCKCHAIN_CONNECTION.bool_value(False)
if geth:
ETH_NODE = NuCypherGethGoerliProcess() # TODO: Only devnet for now
provider_uri = ETH_NODE.provider_uri
if action == 'init':
"""Create a brand-new persistent Alice"""
@ -83,6 +98,7 @@ def alice(click_config,
federated_only=federated_only,
download_registry=no_registry,
registry_filepath=registry_filepath,
provider_process=ETH_NODE,
provider_uri=provider_uri)
return painting.paint_new_installation_help(new_configuration=new_alice_config,
@ -96,6 +112,7 @@ def alice(click_config,
alice_config = AliceConfiguration(dev_mode=True,
network_middleware=click_config.middleware,
domains={network},
provider_process=ETH_NODE,
provider_uri=provider_uri,
federated_only=True)
@ -107,6 +124,7 @@ def alice(click_config,
network_middleware=click_config.middleware,
rest_port=discovery_port,
checksum_public_address=pay_with,
provider_process=ETH_NODE,
provider_uri=provider_uri)
except FileNotFoundError:
return actions.handle_missing_configuration_file(character_config_class=AliceConfiguration,
@ -175,6 +193,9 @@ def alice(click_config,
'expiration': (maya.now() + datetime.timedelta(days=3)).iso8601(), # TODO
}
if not ALICE.federated_only:
grant_request.update({'value': value})
return ALICE.controller.grant(request=grant_request)
elif action == "revoke":

View File

@ -23,7 +23,7 @@ import socket
from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION
from twisted.internet import stdio
from nucypher.blockchain.eth.clients import NuCypherGethDevnetProcess
from nucypher.blockchain.eth.clients import NuCypherGethDevnetProcess, NuCypherGethGoerliProcess
from nucypher.blockchain.eth.token import NU
from nucypher.characters.banners import URSULA_BANNER
from nucypher.cli import actions, painting
@ -136,10 +136,10 @@ def ursula(click_config,
# Boring Setup Stuff
#
# Stage integrated ethereum node process TODO: Only devnet for now
# Stage integrated ethereum node process
ETH_NODE = NO_BLOCKCHAIN_CONNECTION.bool_value(False)
if geth:
ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root)
ETH_NODE = NuCypherGethGoerliProcess() # TODO: Only devnet for now
provider_uri = ETH_NODE.provider_uri
if not click_config.json_ipc and not click_config.quiet:
@ -304,7 +304,7 @@ def ursula(click_config,
ursula_config.blockchain.interface.w3.geth.admin.addPeer(enode)
click.secho(f"Added ethereum peer {enode}")
else:
raise NotImplemented # TODO: other backends
raise NotImplementedError # TODO: other backends
#
# Produce

View File

@ -14,8 +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 datetime
import json
import os
from constant_sorrow.constants import (