diff --git a/cli/main.py b/cli/main.py index fbf861170..5944a5397 100755 --- a/cli/main.py +++ b/cli/main.py @@ -126,7 +126,7 @@ class NucypherClickConfig: if self.compile: click.confirm("Compile solidity source?", abort=True) self.blockchain = Blockchain.connect(provider_uri=self.provider_uri, - registry_filepath=self.registry_filepath, + registry_filepath=self.registry_filepath or self.node_configuration.registry_filepath, deployer=self.deployer, compile=self.compile) if self.poa: @@ -214,6 +214,7 @@ def cli(config, # Store config data config.verbose = verbose + config.dev = dev config.federated_only = federated_only config.config_root = config_root @@ -309,19 +310,22 @@ def accounts(config, action, checksum_address): # # Initialize # + config.get_node_configuration() if not config.federated_only: config.connect_to_blockchain() + config.connect_to_contracts() - def __collect_transfer_details(denomination: str): - destination = click.prompt("Enter destination checksum_address") - if not is_checksum_address(destination): - click.echo("{} is not a valid checksum checksum_address".format(destination)) - raise click.Abort() - amount = click.prompt("Enter amount of {} to transfer".format(denomination), type=int) - return destination, amount + if not checksum_address: + checksum_address = config.blockchain.interface.w3.eth.coinbase + click.echo("WARNING: No checksum address specified - Using the node's default account.") - config.connect_to_contracts() - config.get_node_configuration() + def __collect_transfer_details(denomination: str): + destination = click.prompt("Enter destination checksum_address") + if not is_checksum_address(destination): + click.echo("{} is not a valid checksum checksum_address".format(destination)) + raise click.Abort() + amount = click.prompt("Enter amount of {} to transfer".format(denomination), type=int) + return destination, amount # # Action Switch diff --git a/nucypher/blockchain/eth/interfaces.py b/nucypher/blockchain/eth/interfaces.py index 5ed32253a..bed973ce8 100644 --- a/nucypher/blockchain/eth/interfaces.py +++ b/nucypher/blockchain/eth/interfaces.py @@ -22,7 +22,6 @@ class BlockchainInterface: ethereum contracts with the given web3 provider backend. """ __default_timeout = 10 # seconds - __default_network = 'tester' # __default_transaction_gas_limit = 500000 # TODO: determine sensible limit and validate transactions class UnknownContract(Exception): @@ -32,7 +31,6 @@ class BlockchainInterface: pass def __init__(self, - network_name: str = None, provider_uri: str = None, providers: list = None, autoconnect: bool = True, @@ -44,33 +42,39 @@ class BlockchainInterface: A blockchain "network inerface"; The circumflex wraps entirely around the bounds of contract operations including compilation, deployment, and execution. + Filesystem Configuration Client Web3 Node + ================ ====================== =============== ===================== =========================== - Solidity Files -- SolidityCompiler --- --- HTTPProvider -- - | | | - | | -- External EVM (geth, etc.) - | - *BlockchainInterface* -- IPCProvider -- + Solidity Files -- SolidityCompiler --- --- HTTPProvider ------ ... + | | + | | + + *BlockchainInterface* -- IPCProvider ----- External EVM (geth, parity...) | | | | | | - Registry File -- ContractRegistry -- | ---- TestProvider -- EthereumTester + Registry File -- ContractRegistry --- | ---- TestProvider ----- EthereumTester | - | | + | | | - Pyevm (development chain) - Blockchain + PyEVM (Development Chain) + Runtime Files --- -------- Blockchain + | | + | | | - | + Key Files ------ NodeConfiguration -------- Agent ... (Contract API) - Agent ... (Contract API) + | | | + | | + | ---------- Actor ... (Blockchain-Character API) + | + | | - | - - Character / Actor + Configuration File Character ... (Public API) - The circumflex is the junction of the solidity compiler, a contract registry, and a collection of - web3 network __providers as a means of interfacing with the ethereum blockchain to execute + The BlockchainInterface is the junction of the solidity compiler, a contract registry, and a collection of + web3 network providers as a means of interfacing with the ethereum blockchain to execute or deploy contract code on the network. @@ -96,9 +100,6 @@ class BlockchainInterface: self.log = getLogger("blockchain-interface") # type: Logger - self.__network = network_name if network_name is not None else self.__default_network - self.timeout = timeout if timeout is not None else self.__default_timeout - # # Providers # @@ -106,6 +107,7 @@ class BlockchainInterface: self.w3 = constants.NO_BLOCKCHAIN_CONNECTION self.__providers = providers or constants.NO_BLOCKCHAIN_CONNECTION self.provider_uri = constants.NO_BLOCKCHAIN_CONNECTION + self.timeout = timeout if timeout is not None else self.__default_timeout if provider_uri and providers: raise self.InterfaceError("Pass a provider URI string, or a list of provider instances.") @@ -167,10 +169,6 @@ class BlockchainInterface: def providers(self) -> Tuple[Union[IPCProvider, WebsocketProvider, HTTPProvider], ...]: return tuple(self.__providers) - @property - def network(self) -> str: - return self.__network - @property def is_connected(self) -> bool: """ @@ -179,9 +177,9 @@ class BlockchainInterface: return self.w3.isConnected() @property - def version(self) -> str: + def node_version(self) -> str: """Return node version information""" - return self.w3.version.node + return self.w3.node_version.node def add_provider(self, provider: Union[IPCProvider, WebsocketProvider, HTTPProvider] = None, @@ -215,7 +213,7 @@ class BlockchainInterface: # w3.middleware_stack.inject(geth_poa_middleware, layer=0) else: - raise self.InterfaceError("{} is an ambiguous or unsupported blockchain provider URI".format(provider_uri)) + raise self.InterfaceError("{} is an invalid or unsupported blockchain provider URI".format(provider_uri)) # IPC elif uri_breakdown.scheme == 'ipc': diff --git a/nucypher/config/node.py b/nucypher/config/node.py index 1b96ca128..66751970d 100644 --- a/nucypher/config/node.py +++ b/nucypher/config/node.py @@ -260,17 +260,22 @@ class NodeConfiguration: output_filepath = output_filepath or self.registry_filepath source = source or self.REGISTRY_SOURCE - # Validate Registry - with open(source, 'r') as registry_file: - try: - json.loads(registry_file.read()) - except JSONDecodeError: - raise self.ConfigurationError("The registry source {} is not valid JSON".format(source)) - if not blank: + # Validate Registry + with open(source, 'r') as registry_file: + try: + json.loads(registry_file.read()) + except JSONDecodeError: + message = "The registry source {} is not valid JSON".format(source) + self.log.critical(message) + raise self.ConfigurationError(message) + else: + self.log.debug("Source registry {} is valid JSON".format(source)) + self.log.info("Copied contract registry from {}".format(source)) shutil.copyfile(src=source, dst=output_filepath) else: - open(output_filepath, '').close() # blank + self.log.warning("Writing blank registry") + open(output_filepath, 'w').close() # blank return output_filepath