Dear Felix, Admit that ethereum nodes need to be started early

pull/1040/head
Kieran Prasch 2019-04-28 01:39:50 +03:00
parent 3d40e1cd1f
commit 600decc8b4
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
4 changed files with 48 additions and 15 deletions

View File

@ -2,6 +2,7 @@ import json
import os
from constant_sorrow.constants import NOT_RUNNING
from eth_utils import to_checksum_address, is_checksum_address
from geth import LoggingMixin
from geth.accounts import ensure_account_exists, get_accounts, create_new_account
from geth.chain import (
@ -22,7 +23,7 @@ NUCYPHER_CHAIN_IDS = {
class NuCypherGethProcess(BaseGethProcess, LoggingMixin):
IPC_PROTOCOL = 'ipc'
IPC_PROTOCOL = 'http'
IPC_FILENAME = 'geth.ipc'
VERBOSITY = 5
@ -33,16 +34,25 @@ class NuCypherGethProcess(BaseGethProcess, LoggingMixin):
self.log = Logger('nucypher-geth')
@property
def provider_uri(self, scheme: str = None):
def provider_uri(self, scheme: str = None) -> str:
if not scheme:
scheme = self.IPC_PROTOCOL
uri = f"{scheme}://{self.ipc_path}"
if scheme == 'file':
location = self.ipc_path
elif scheme in ('http', 'ws'):
location = f'{self.rpc_host}:{self.rpc_port}'
else:
raise ValueError(f'{scheme} is an unknown ethereum node IPC protocol.')
uri = f"{scheme}://{location}"
return uri
def start(self, timeout: int = 30):
self.log.info("STARTING GETH NOW")
super().start()
self.wait_for_ipc(timeout=timeout)
self.wait_for_ipc(timeout=timeout) # on for all nodes by default
if self.IPC_PROTOCOL == 'rpc':
self.wait_for_rpc(timeout=timeout)
class NuCypherGethDevProcess(NuCypherGethProcess):
@ -65,6 +75,7 @@ class NuCypherGethDevProcess(NuCypherGethProcess):
class NuCypherGethDevnetProcess(NuCypherGethProcess):
IPC_PROTOCOL = 'file'
GENESIS_FILENAME = 'testnet_genesis.json'
GENESIS_SOURCE_FILEPATH = os.path.join(DEPLOY_DIR, GENESIS_FILENAME)
@ -119,6 +130,15 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
super().__init__(geth_kwargs)
@classmethod
def get_accounts(cls, data_dir: str):
geth_kwargs = {'network_id': str(cls.__CHAIN_ID),
'port': str(cls.P2P_PORT),
'verbosity': str(cls.VERBOSITY),
'data_dir': data_dir}
accounts = get_accounts(**geth_kwargs)
return accounts
@classmethod
def initialize_blockchain(cls, geth_kwargs: dict, overwrite: bool = True) -> None:
log = Logger('nucypher-geth-init')
@ -126,11 +146,12 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
genesis_data = json.loads(file.read())
log.info(f"Read genesis file '{cls.GENESIS_SOURCE_FILEPATH}'")
genesis_data.update(dict(overwrite=overwrite))
log.info(f'Initializing new blockchain database and genesis block.')
initialize_chain(genesis_data, overwrite=overwrite, **geth_kwargs)
initialize_chain(genesis_data=genesis_data, **geth_kwargs)
@classmethod
def ensure_account_exists(cls, password: str, data_dir: str):
def ensure_account_exists(cls, password: str, data_dir: str) -> str:
geth_kwargs = {'network_id': str(cls.__CHAIN_ID),
'port': str(cls.P2P_PORT),
'verbosity': str(cls.VERBOSITY),
@ -141,4 +162,7 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
account = create_new_account(password=password.encode(), **geth_kwargs)
else:
account = accounts[0]
return account
checksum_address = to_checksum_address(account.decode())
assert is_checksum_address(checksum_address), f"GETH RETURNED INVALID ETH ADDRESS {checksum_address}"
return checksum_address

View File

@ -330,7 +330,7 @@ class BlockchainInterface:
# Built-In
# - IPC -
elif uri_breakdown.scheme == 'ipc':
elif uri_breakdown.scheme in ('ipc', 'file'):
# https://web3py.readthedocs.io/en/latest/providers.html#ipcprovider
provider = IPCProvider(ipc_path=uri_breakdown.path, timeout=self.timeout)

View File

@ -58,6 +58,12 @@ def felix(click_config,
if not click_config.quiet:
click.secho(FELIX_BANNER.format(checksum_address or ''))
ETH_NODE = None # TODO: Make constant
if geth:
ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root)
ETH_NODE.start()
provider_uri = ETH_NODE.provider_uri
if action == "init":
"""Create a brand-new Felix"""
@ -92,11 +98,6 @@ def felix(click_config,
# Domains -> bytes | or default
domains = [bytes(network, encoding='utf-8')] if network else None
ETH_NODE = None
if geth:
ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root)
ETH_NODE.start()
# Load Felix from Configuration File with overrides
try:
felix_config = FelixConfiguration.from_configuration_file(filepath=config_file,

View File

@ -37,6 +37,7 @@ from constant_sorrow.constants import (
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
from cryptography.x509 import Certificate
from eth_utils import to_checksum_address, is_checksum_address
from twisted.logger import Logger
from umbral.signing import Signature
@ -286,7 +287,7 @@ class NodeConfiguration(ABC):
def __write(self, password: str):
if not self.federated_only:
self.connect_to_blockchain()
self.connect_to_blockchain() # Needed for access to ethereum node addresses and NC key signing
_new_installation_path = self.initialize(password=password, download_registry=self.download_registry)
_configuration_filepath = self.to_configuration_file(filepath=self.config_file_location)
@ -634,11 +635,18 @@ class NodeConfiguration(ABC):
if not os.path.exists(data_dir):
os.mkdir(data_dir)
client_version = self.interface.w3.clientVersion
client_version = self.blockchain.interface.w3.clientVersion
if 'Geth' in client_version:
checksum_address = NuCypherGethDevnetProcess.ensure_account_exists(password=password,
data_dir=data_dir)
else:
raise RuntimeError("THIS IS A TEMPORARY DEBUGGING EXCEPTION") # TODO
# Addresses read from some node keyrings are *not* returned in checksum format.
checksum_address = to_checksum_address(checksum_address)
assert is_checksum_address(checksum_address), f"INVALID ETH ADDRESS {checksum_address}"
# Use explicit address
elif self.checksum_public_address:
checksum_address = self.checksum_public_address