mirror of https://github.com/nucypher/nucypher.git
Dear Felix, Admit that ethereum nodes need to be started early
parent
3d40e1cd1f
commit
600decc8b4
|
@ -2,6 +2,7 @@ import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from constant_sorrow.constants import NOT_RUNNING
|
from constant_sorrow.constants import NOT_RUNNING
|
||||||
|
from eth_utils import to_checksum_address, is_checksum_address
|
||||||
from geth import LoggingMixin
|
from geth import LoggingMixin
|
||||||
from geth.accounts import ensure_account_exists, get_accounts, create_new_account
|
from geth.accounts import ensure_account_exists, get_accounts, create_new_account
|
||||||
from geth.chain import (
|
from geth.chain import (
|
||||||
|
@ -22,7 +23,7 @@ NUCYPHER_CHAIN_IDS = {
|
||||||
|
|
||||||
class NuCypherGethProcess(BaseGethProcess, LoggingMixin):
|
class NuCypherGethProcess(BaseGethProcess, LoggingMixin):
|
||||||
|
|
||||||
IPC_PROTOCOL = 'ipc'
|
IPC_PROTOCOL = 'http'
|
||||||
IPC_FILENAME = 'geth.ipc'
|
IPC_FILENAME = 'geth.ipc'
|
||||||
VERBOSITY = 5
|
VERBOSITY = 5
|
||||||
|
|
||||||
|
@ -33,16 +34,25 @@ class NuCypherGethProcess(BaseGethProcess, LoggingMixin):
|
||||||
self.log = Logger('nucypher-geth')
|
self.log = Logger('nucypher-geth')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def provider_uri(self, scheme: str = None):
|
def provider_uri(self, scheme: str = None) -> str:
|
||||||
if not scheme:
|
if not scheme:
|
||||||
scheme = self.IPC_PROTOCOL
|
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
|
return uri
|
||||||
|
|
||||||
def start(self, timeout: int = 30):
|
def start(self, timeout: int = 30):
|
||||||
self.log.info("STARTING GETH NOW")
|
self.log.info("STARTING GETH NOW")
|
||||||
super().start()
|
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):
|
class NuCypherGethDevProcess(NuCypherGethProcess):
|
||||||
|
@ -65,6 +75,7 @@ class NuCypherGethDevProcess(NuCypherGethProcess):
|
||||||
|
|
||||||
class NuCypherGethDevnetProcess(NuCypherGethProcess):
|
class NuCypherGethDevnetProcess(NuCypherGethProcess):
|
||||||
|
|
||||||
|
IPC_PROTOCOL = 'file'
|
||||||
GENESIS_FILENAME = 'testnet_genesis.json'
|
GENESIS_FILENAME = 'testnet_genesis.json'
|
||||||
GENESIS_SOURCE_FILEPATH = os.path.join(DEPLOY_DIR, GENESIS_FILENAME)
|
GENESIS_SOURCE_FILEPATH = os.path.join(DEPLOY_DIR, GENESIS_FILENAME)
|
||||||
|
|
||||||
|
@ -119,6 +130,15 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
|
||||||
|
|
||||||
super().__init__(geth_kwargs)
|
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
|
@classmethod
|
||||||
def initialize_blockchain(cls, geth_kwargs: dict, overwrite: bool = True) -> None:
|
def initialize_blockchain(cls, geth_kwargs: dict, overwrite: bool = True) -> None:
|
||||||
log = Logger('nucypher-geth-init')
|
log = Logger('nucypher-geth-init')
|
||||||
|
@ -126,11 +146,12 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
|
||||||
genesis_data = json.loads(file.read())
|
genesis_data = json.loads(file.read())
|
||||||
log.info(f"Read genesis file '{cls.GENESIS_SOURCE_FILEPATH}'")
|
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.')
|
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
|
@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),
|
geth_kwargs = {'network_id': str(cls.__CHAIN_ID),
|
||||||
'port': str(cls.P2P_PORT),
|
'port': str(cls.P2P_PORT),
|
||||||
'verbosity': str(cls.VERBOSITY),
|
'verbosity': str(cls.VERBOSITY),
|
||||||
|
@ -141,4 +162,7 @@ class NuCypherGethDevnetProcess(NuCypherGethProcess):
|
||||||
account = create_new_account(password=password.encode(), **geth_kwargs)
|
account = create_new_account(password=password.encode(), **geth_kwargs)
|
||||||
else:
|
else:
|
||||||
account = accounts[0]
|
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
|
||||||
|
|
|
@ -330,7 +330,7 @@ class BlockchainInterface:
|
||||||
# Built-In
|
# Built-In
|
||||||
|
|
||||||
# - IPC -
|
# - IPC -
|
||||||
elif uri_breakdown.scheme == 'ipc':
|
elif uri_breakdown.scheme in ('ipc', 'file'):
|
||||||
# https://web3py.readthedocs.io/en/latest/providers.html#ipcprovider
|
# https://web3py.readthedocs.io/en/latest/providers.html#ipcprovider
|
||||||
provider = IPCProvider(ipc_path=uri_breakdown.path, timeout=self.timeout)
|
provider = IPCProvider(ipc_path=uri_breakdown.path, timeout=self.timeout)
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,12 @@ def felix(click_config,
|
||||||
if not click_config.quiet:
|
if not click_config.quiet:
|
||||||
click.secho(FELIX_BANNER.format(checksum_address or ''))
|
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":
|
if action == "init":
|
||||||
"""Create a brand-new Felix"""
|
"""Create a brand-new Felix"""
|
||||||
|
|
||||||
|
@ -92,11 +98,6 @@ def felix(click_config,
|
||||||
# Domains -> bytes | or default
|
# Domains -> bytes | or default
|
||||||
domains = [bytes(network, encoding='utf-8')] if network else None
|
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
|
# Load Felix from Configuration File with overrides
|
||||||
try:
|
try:
|
||||||
felix_config = FelixConfiguration.from_configuration_file(filepath=config_file,
|
felix_config = FelixConfiguration.from_configuration_file(filepath=config_file,
|
||||||
|
|
|
@ -37,6 +37,7 @@ from constant_sorrow.constants import (
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
|
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
|
||||||
from cryptography.x509 import Certificate
|
from cryptography.x509 import Certificate
|
||||||
|
from eth_utils import to_checksum_address, is_checksum_address
|
||||||
from twisted.logger import Logger
|
from twisted.logger import Logger
|
||||||
from umbral.signing import Signature
|
from umbral.signing import Signature
|
||||||
|
|
||||||
|
@ -286,7 +287,7 @@ class NodeConfiguration(ABC):
|
||||||
|
|
||||||
def __write(self, password: str):
|
def __write(self, password: str):
|
||||||
if not self.federated_only:
|
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)
|
_new_installation_path = self.initialize(password=password, download_registry=self.download_registry)
|
||||||
_configuration_filepath = self.to_configuration_file(filepath=self.config_file_location)
|
_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):
|
if not os.path.exists(data_dir):
|
||||||
os.mkdir(data_dir)
|
os.mkdir(data_dir)
|
||||||
|
|
||||||
client_version = self.interface.w3.clientVersion
|
client_version = self.blockchain.interface.w3.clientVersion
|
||||||
if 'Geth' in client_version:
|
if 'Geth' in client_version:
|
||||||
checksum_address = NuCypherGethDevnetProcess.ensure_account_exists(password=password,
|
checksum_address = NuCypherGethDevnetProcess.ensure_account_exists(password=password,
|
||||||
data_dir=data_dir)
|
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
|
# Use explicit address
|
||||||
elif self.checksum_public_address:
|
elif self.checksum_public_address:
|
||||||
checksum_address = self.checksum_public_address
|
checksum_address = self.checksum_public_address
|
||||||
|
|
Loading…
Reference in New Issue