From f07f2979ce1bb203142bf8cb56a8470053922a2e Mon Sep 17 00:00:00 2001 From: Kieran Prasch Date: Fri, 14 Dec 2018 17:36:48 -0800 Subject: [PATCH 1/2] Provide simple way to start testing nucypher on pyevm with TeserBlockchain classmethods --- .gitignore | 5 +-- nucypher/utilities/sandbox/blockchain.py | 39 ++++++++++++++-- tests/metrics/estimate_gas.py | 57 +++++------------------- 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/.gitignore b/.gitignore index 392a7854b..95eb1ac46 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,4 @@ variables*.yml *ansible/*.retry *ansible/inventory/* .env -examples/heartbeat_demo/*.json -examples/heartbeat_demo/*.msgpack -examples/heartbeat_demo/doctor-files/ -examples/heartbeat_demo/alicia-files/ +/tests/metrics/results/ diff --git a/nucypher/utilities/sandbox/blockchain.py b/nucypher/utilities/sandbox/blockchain.py index 9182f1c03..5a59e83e5 100644 --- a/nucypher/utilities/sandbox/blockchain.py +++ b/nucypher/utilities/sandbox/blockchain.py @@ -14,10 +14,20 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with nucypher. If not, see . """ +import os + from twisted.logger import Logger from constant_sorrow.constants import NO_BLOCKCHAIN_AVAILABLE -from typing import List +from typing import List, Tuple + +from nucypher.blockchain.eth.actors import Deployer +from nucypher.blockchain.eth.agents import NucypherTokenAgent, MinerAgent, PolicyAgent +from nucypher.blockchain.eth.constants import DISPATCHER_SECRET_LENGTH +from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface +from nucypher.blockchain.eth.registry import InMemoryEthereumContractRegistry +from nucypher.blockchain.eth.sol.compile import SolidityCompiler +from nucypher.config.constants import CONTRACT_ROOT from umbral.keys import UmbralPrivateKey from web3.middleware import geth_poa_middleware @@ -48,10 +58,12 @@ class TesterBlockchain(Blockchain): Blockchain subclass with additional test utility methods and options. """ + _PROVIDER_URI = 'tester://pyevm' _instance = NO_BLOCKCHAIN_AVAILABLE _test_account_cache = list() + _default_test_accounts = 10 - def __init__(self, test_accounts=None, poa=True, airdrop=True, *args, **kwargs): + def __init__(self, test_accounts=_default_test_accounts, poa=True, airdrop=True, *args, **kwargs): super().__init__(*args, **kwargs) self.log = Logger("test-blockchain") # type: Logger @@ -91,7 +103,7 @@ class TesterBlockchain(Blockchain): address = self.interface.w3.personal.importRawKey(private_key=umbral_priv_key.to_bytes(), passphrase=insecure_password) - assert self.interface.unlock_account(address, password=insecure_password, duration=None), 'Failed to unlock {}'.format(address) + assert self.interface.unlock_account(address, password=insecure_password), 'Failed to unlock {}'.format(address) addresses.append(address) self._test_account_cache.append(address) self.log.info('Generated new insecure account {}'.format(address)) @@ -143,3 +155,24 @@ class TesterBlockchain(Blockchain): self.interface.w3.eth.web3.testing.timeTravel(timestamp=end_timestamp) self.interface.w3.eth.web3.testing.mine(1) self.log.info("Time traveled to {}".format(end_timestamp)) + + @classmethod + def connect(cls, *args, **kwargs) -> 'TesterBlockchain': + solidity_compiler = SolidityCompiler(test_contract_dir=CONTRACT_ROOT) + memory_registry = InMemoryEthereumContractRegistry() + interface = BlockchainDeployerInterface(provider_uri=cls._PROVIDER_URI, compiler=solidity_compiler, registry=memory_registry) + testerchain = TesterBlockchain(interface=interface, test_accounts=cls._default_test_accounts, airdrop=False) + return testerchain + + @classmethod + def bootstrap_network(cls) -> Tuple['TesterBlockchain', List[str]]: + + def __deploy_contracts(testerchain: TesterBlockchain) -> None: + origin = testerchain.interface.w3.eth.accounts[0] + deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True) + _txhashes, _agents = deployer.deploy_network_contracts(miner_secret=os.urandom(DISPATCHER_SECRET_LENGTH), + policy_secret=os.urandom(DISPATCHER_SECRET_LENGTH)) + + testerchain = cls.connect() + __deploy_contracts(testerchain=testerchain) + return testerchain, testerchain.interface.w3.eth.accounts diff --git a/tests/metrics/estimate_gas.py b/tests/metrics/estimate_gas.py index 8343c2a75..9e82b4d3b 100755 --- a/tests/metrics/estimate_gas.py +++ b/tests/metrics/estimate_gas.py @@ -115,43 +115,6 @@ class AnalyzeGas: globalLogPublisher.addObserver(json_observer) globalLogPublisher.addObserver(self) - def connect_to_blockchain(self) -> TesterBlockchain: - print("Deploying Blockchain...") - - solidity_compiler = SolidityCompiler(test_contract_dir=self.CONTRACT_DIR) - memory_registry = InMemoryEthereumContractRegistry() - interface = BlockchainDeployerInterface(provider_uri=self.PROVIDER_URI, compiler=solidity_compiler, - registry=memory_registry) - - testerchain = TesterBlockchain(interface=interface, test_accounts=self.TEST_ACCOUNTS, airdrop=False) - return testerchain - - @staticmethod - def deploy_contracts(testerchain: TesterBlockchain) -> None: - print("Deploying Contracts...") - - origin = testerchain.interface.w3.eth.accounts[0] - deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True) - _txhashes, _agents = deployer.deploy_network_contracts(miner_secret=os.urandom(DISPATCHER_SECRET_LENGTH), - policy_secret=os.urandom(DISPATCHER_SECRET_LENGTH)) - - @staticmethod - def connect_to_contracts(testerchain: TesterBlockchain) -> Tuple[NucypherTokenAgent, MinerAgent, PolicyAgent]: - print("Connecting...") - - token_agent = NucypherTokenAgent(blockchain=testerchain) - miner_agent = MinerAgent(blockchain=testerchain) - policy_agent = PolicyAgent(blockchain=testerchain) - - return token_agent, miner_agent, policy_agent - - def bootstrap_network(self) -> Tuple[TesterBlockchain, List[str]]: - print("Bootstrapping testing network...") - - testerchain = self.connect_to_blockchain() - self.deploy_contracts(testerchain=testerchain) - return testerchain, testerchain.interface.w3.eth.accounts - def estimate_gas(analyzer: AnalyzeGas = None) -> None: """ @@ -165,25 +128,29 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None: # # Setup # + if AnalyzeGas is None: analyzer = AnalyzeGas() - # Logger log = Logger(AnalyzeGas.LOG_NAME) # Blockchain - testerchain, accounts = analyzer.bootstrap_network() + testerchain, accounts = TesterBlockchain.bootstrap_network() web3 = testerchain.interface.w3 - # Contracts - token_agent, miner_agent, policy_agent = analyzer.connect_to_contracts(testerchain=testerchain) - token_functions = token_agent.contract.functions - miner_functions = miner_agent.contract.functions - policy_functions = policy_agent.contract.functions - # Accounts origin, ursula1, ursula2, ursula3, alice1, *everyone_else = testerchain.interface.w3.eth.accounts + # Contracts + token_agent = NucypherTokenAgent(blockchain=testerchain) + miner_agent = MinerAgent(blockchain=testerchain) + policy_agent = PolicyAgent(blockchain=testerchain) + + # Contract Callers + token_functions = token_agent.contract.functions + miner_functions = miner_agent.contract.functions + policy_functions = policy_agent.contract.functions + analyzer.start_collection() print("********* Estimating Gas *********") From 1755a35fdc2d8fd2318a8c73129394615999ae2c Mon Sep 17 00:00:00 2001 From: Kieran Prasch Date: Tue, 18 Dec 2018 10:31:41 -0800 Subject: [PATCH 2/2] Respond to RFCs in PR #617 --- .gitignore | 4 +++ nucypher/blockchain/eth/chains.py | 2 ++ nucypher/utilities/sandbox/blockchain.py | 42 ++++++++++++++---------- tests/metrics/estimate_gas.py | 4 +-- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 95eb1ac46..691b0a403 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,10 @@ chains .ethash nucypher_cli/examples/examples-runtime-cruft/* nucypher_cli/examples/finnegans-wake.txt +examples/heartbeat_demo/*.json +examples/heartbeat_demo/*.msgpack +examples/heartbeat_demo/doctor-files/ +examples/heartbeat_demo/alicia-files/ mypy_reports/ reports/ test-* diff --git a/nucypher/blockchain/eth/chains.py b/nucypher/blockchain/eth/chains.py index 388857e02..f4610f0c3 100644 --- a/nucypher/blockchain/eth/chains.py +++ b/nucypher/blockchain/eth/chains.py @@ -14,6 +14,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with nucypher. If not, see . """ + + from twisted.logger import Logger from web3.middleware import geth_poa_middleware diff --git a/nucypher/utilities/sandbox/blockchain.py b/nucypher/utilities/sandbox/blockchain.py index 5a59e83e5..35ef625e8 100644 --- a/nucypher/utilities/sandbox/blockchain.py +++ b/nucypher/utilities/sandbox/blockchain.py @@ -14,15 +14,18 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with nucypher. If not, see . """ + + import os +from functools import partial from twisted.logger import Logger from constant_sorrow.constants import NO_BLOCKCHAIN_AVAILABLE -from typing import List, Tuple +from typing import List, Tuple, Dict from nucypher.blockchain.eth.actors import Deployer -from nucypher.blockchain.eth.agents import NucypherTokenAgent, MinerAgent, PolicyAgent +from nucypher.blockchain.eth.agents import NucypherTokenAgent, MinerAgent, PolicyAgent, EthereumContractAgent from nucypher.blockchain.eth.constants import DISPATCHER_SECRET_LENGTH from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface from nucypher.blockchain.eth.registry import InMemoryEthereumContractRegistry @@ -63,7 +66,10 @@ class TesterBlockchain(Blockchain): _test_account_cache = list() _default_test_accounts = 10 - def __init__(self, test_accounts=_default_test_accounts, poa=True, airdrop=True, *args, **kwargs): + def __init__(self, test_accounts=None, poa=True, airdrop=False, *args, **kwargs): + if test_accounts is None: + test_accounts = self._default_test_accounts + super().__init__(*args, **kwargs) self.log = Logger("test-blockchain") # type: Logger @@ -103,7 +109,7 @@ class TesterBlockchain(Blockchain): address = self.interface.w3.personal.importRawKey(private_key=umbral_priv_key.to_bytes(), passphrase=insecure_password) - assert self.interface.unlock_account(address, password=insecure_password), 'Failed to unlock {}'.format(address) + assert self.interface.unlock_account(address, password=insecure_password, duration=None), 'Failed to unlock {}'.format(address) addresses.append(address) self._test_account_cache.append(address) self.log.info('Generated new insecure account {}'.format(address)) @@ -158,21 +164,21 @@ class TesterBlockchain(Blockchain): @classmethod def connect(cls, *args, **kwargs) -> 'TesterBlockchain': - solidity_compiler = SolidityCompiler(test_contract_dir=CONTRACT_ROOT) - memory_registry = InMemoryEthereumContractRegistry() - interface = BlockchainDeployerInterface(provider_uri=cls._PROVIDER_URI, compiler=solidity_compiler, registry=memory_registry) - testerchain = TesterBlockchain(interface=interface, test_accounts=cls._default_test_accounts, airdrop=False) + interface = BlockchainDeployerInterface(provider_uri=cls._PROVIDER_URI, + compiler=SolidityCompiler(test_contract_dir=CONTRACT_ROOT), + registry=InMemoryEthereumContractRegistry()) + + testerchain = TesterBlockchain(interface=interface, *args, **kwargs) return testerchain @classmethod - def bootstrap_network(cls) -> Tuple['TesterBlockchain', List[str]]: - - def __deploy_contracts(testerchain: TesterBlockchain) -> None: - origin = testerchain.interface.w3.eth.accounts[0] - deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True) - _txhashes, _agents = deployer.deploy_network_contracts(miner_secret=os.urandom(DISPATCHER_SECRET_LENGTH), - policy_secret=os.urandom(DISPATCHER_SECRET_LENGTH)) - + def bootstrap_network(cls) -> Tuple['TesterBlockchain', Dict[str, EthereumContractAgent]]: testerchain = cls.connect() - __deploy_contracts(testerchain=testerchain) - return testerchain, testerchain.interface.w3.eth.accounts + + origin = testerchain.interface.w3.eth.accounts[0] + deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True) + + random_deployment_secret = partial(os.urandom, DISPATCHER_SECRET_LENGTH) + _txhashes, agents = deployer.deploy_network_contracts(miner_secret=random_deployment_secret(), + policy_secret=random_deployment_secret()) + return testerchain, agents diff --git a/tests/metrics/estimate_gas.py b/tests/metrics/estimate_gas.py index 9e82b4d3b..bcc7306ce 100755 --- a/tests/metrics/estimate_gas.py +++ b/tests/metrics/estimate_gas.py @@ -129,13 +129,13 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None: # Setup # - if AnalyzeGas is None: + if analyzer is None: analyzer = AnalyzeGas() log = Logger(AnalyzeGas.LOG_NAME) # Blockchain - testerchain, accounts = TesterBlockchain.bootstrap_network() + testerchain, agents = TesterBlockchain.bootstrap_network() web3 = testerchain.interface.w3 # Accounts