Refactor contract registry CLI integration testing to implement condensed Blockchain API.

pull/1029/head
Kieran Prasch 2019-06-19 11:41:05 -07:00 committed by David Núñez
parent b59d12d89c
commit 2ccc46b86a
3 changed files with 74 additions and 67 deletions

View File

@ -18,7 +18,7 @@ def test_geth_EIP_191_client_signature_integration(geth_dev_node):
blockchain = BlockchainInterface(provider_process=geth_dev_node, sync_now=False)
# Sign a message (RPC) and verify it.
etherbase = blockchain.accounts[0]
etherbase = blockchain.client.accounts[0]
stamp = b'STAMP-' + os.urandom(64)
signature = blockchain.client.sign_message(account=etherbase, message=stamp)
is_valid = verify_eip_191(address=etherbase,

View File

@ -75,11 +75,9 @@ def test_deploy_and_allocate(agency, user_escrow_proxy, token_economics):
for address, deployer in deployments.items():
assert deployer.deployer_address == origin
receipt = deployer.initial_deposit(value=allocation, duration=token_economics.maximum_locked_periods)
_deposit_receipt = deployer.initial_deposit(value=allocation, duration=token_economics.maximum_locked_periods)
beneficiary = random.choice(testerchain.unassigned_accounts)
assignment_txhash = deployer.assign_beneficiary(beneficiary)
receipt = testerchain.wait_for_receipt(txhash=assignment_txhash)
assert receipt['status'] == 1, "Transaction Rejected {}".format(assignment_txhash)
_assign_receipt = deployer.assign_beneficiary(beneficiary)
assert len(deposit_txhashes) == number_of_deployments == len(deployments)

View File

@ -11,8 +11,8 @@ from nucypher.blockchain.eth.agents import (
StakingEscrowAgent,
UserEscrowAgent,
PolicyAgent,
Agency)
from nucypher.blockchain.eth.interfaces import BlockchainInterface
Agency, AdjudicatorAgent)
from nucypher.blockchain.eth.interfaces import BlockchainInterface, BlockchainDeployerInterface
from nucypher.blockchain.eth.registry import AllocationRegistry, EthereumContractRegistry
from nucypher.cli.deploy import deploy
from nucypher.config.constants import DEFAULT_CONFIG_ROOT
@ -58,11 +58,12 @@ def geth_poa_devchain():
def test_nucypher_deploy_contracts(click_runner,
testerchain,
mock_primary_registry_filepath,
mock_allocation_infile,
token_economics):
Agency.clear()
#
# Setup
#
@ -108,10 +109,15 @@ def test_nucypher_deploy_contracts(click_runner,
# Read several records
token_record, escrow_record, dispatcher_record, *other_records = registry_data
registered_name, registered_address, registered_abi = token_record
token_agent = NucypherTokenAgent()
assert token_agent.contract_name == registered_name
assert token_agent.registry_contract_name == registered_name
assert token_agent.contract_address == registered_address
#
# Agency
#
token_agent = NucypherTokenAgent()
assert token_agent.contract_name == registered_name
assert token_agent.registry_contract_name == registered_name
assert token_agent.contract_address == registered_address
# Now show that we can use contract Agency and read from the blockchain
assert token_agent.get_balance() == 0
@ -120,29 +126,32 @@ def test_nucypher_deploy_contracts(click_runner,
# and at least the others can be instantiated
assert PolicyAgent()
# assert AdjudicatorAgent() # TODO
# assert AdjudicatorAgent(blockchain=testerchain) # TODO: #931
def test_upgrade_contracts(click_runner,
testerchain,
mock_primary_registry_filepath):
def test_upgrade_contracts(click_runner, mock_primary_registry_filepath):
#
# Setup
#
# testerchain = TesterBlockchain(eth_airdrop=True, free_transactions=True, registry=mock_temporary_registry)
# testerchain.transacting_power = BlockchainPower(client=testerchain.client)
# testerchain.deployer_address = testerchain.etherbase_account
# Simulate "Reconnection"
real_attach_provider = BlockchainDeployerInterface._attach_provider
cached_blockchain = BlockchainDeployerInterface.reconnect()
registry = cached_blockchain.registry
assert registry.filepath == mock_primary_registry_filepath
def attach_cached_provider(interface, *args, **kwargs):
cached_provider = cached_blockchain.provider
real_attach_provider(interface, provider=cached_provider)
BlockchainDeployerInterface._attach_provider = attach_cached_provider
# Check the existing state of the registry before the meat and potatoes
assert os.path.isfile(mock_primary_registry_filepath)
expected_registrations = 9
expected_enrollments = 9
with open(mock_primary_registry_filepath, 'r') as file:
raw_registry_data = file.read()
registry_data = json.loads(raw_registry_data)
assert len(registry_data) == expected_registrations
assert len(registry_data) == expected_enrollments
#
# Input Components
@ -211,7 +220,7 @@ def test_upgrade_contracts(click_runner,
# Mutate the version tracking
version_tracker[contract_name] += 1
expected_registrations += 1
expected_enrollments += 1
# Verify the registry is updated (Potatoes)
with open(mock_primary_registry_filepath, 'r') as file:
@ -219,26 +228,28 @@ def test_upgrade_contracts(click_runner,
# Read the registry file directly, bypassing its interfaces
raw_registry_data = file.read()
registry_data = json.loads(raw_registry_data)
assert len(registry_data) == expected_registrations
assert len(registry_data) == expected_enrollments, f'Unexpected number of enrollments for {contract_name}'
# Check that there is more than one entry, since we've deployed a "version 2"
expected_enrollments = current_version + 1
expected_contract_enrollments = current_version + 1
registered_names = [r[0] for r in registry_data]
enrollments = registered_names.count(contract_name)
contract_enrollments = registered_names.count(contract_name)
assert enrollments > 1, f"New contract is not enrolled in {MOCK_REGISTRY_FILEPATH}"
assert enrollments == expected_enrollments, f"Incorrect number of records enrolled for {contract_name}. " \
f"Expected {expected_enrollments} got {enrollments}."
assert contract_enrollments > 1, f"New contract is not enrolled in {MOCK_REGISTRY_FILEPATH}"
error = f"Incorrect number of records enrolled for {contract_name}. " \
f"Expected {expected_contract_enrollments} got {contract_enrollments}."
assert contract_enrollments == expected_contract_enrollments, error
# Ensure deployments are different addresses
records = testerchain.registry.search(contract_name=contract_name)
assert len(records) == expected_enrollments
cached_blockchain = BlockchainDeployerInterface.reconnect()
records = cached_blockchain.registry.search(contract_name=contract_name)
assert len(records) == contract_enrollments, error
old, new = records[-2:] # Get the last two entries
old_name, old_address, *abi = old # Previous version
new_name, new_address, *abi = new # New version
assert old_name == new_name # TODO: Inspect ABI?
assert old_name == new_name # TODO: Inspect ABI / Move to different test.
assert old_address != new_address
# Select proxy (Dispatcher vs Linker)
@ -248,20 +259,25 @@ def test_upgrade_contracts(click_runner,
proxy_name = 'Dispatcher'
# Ensure the proxy targets the new deployment
proxy = testerchain.get_proxy(target_address=new_address, proxy_name=proxy_name)
proxy = cached_blockchain.get_proxy(target_address=new_address, proxy_name=proxy_name)
targeted_address = proxy.functions.target().call()
assert targeted_address != old_address
assert targeted_address == new_address
def test_rollback(click_runner):
def test_rollback(click_runner, mock_primary_registry_filepath):
"""Roll 'em all back!"""
# Connect to the blockchain with a blank temporary file-based registry
mock_temporary_registry = EthereumContractRegistry(registry_filepath=MOCK_REGISTRY_FILEPATH)
testerchain = _TesterBlockchain(eth_airdrop=True, free_transactions=True, registry=mock_temporary_registry)
testerchain.transacting_power = BlockchainPower(client=testerchain.client)
testerchain.deployer_address = testerchain.etherbase_account
# Simulate "Reconnection"
real_attach_provider = BlockchainDeployerInterface._attach_provider
cached_blockchain = BlockchainDeployerInterface.reconnect()
registry = cached_blockchain.registry
assert registry.filepath == mock_primary_registry_filepath
def attach_cached_provider(interface, *args, **kwargs):
cached_provider = cached_blockchain.provider
real_attach_provider(interface, provider=cached_provider)
BlockchainDeployerInterface._attach_provider = attach_cached_provider
# Input Components
yes = 'Y\n'
@ -271,9 +287,9 @@ def test_rollback(click_runner):
rollback_secret = generate_insecure_secret()
user_input = '0\n' + yes + old_secret + rollback_secret + rollback_secret
contracts_to_rollback = ('StakingEscrow', # v4 -> v3
'PolicyManager', # v4 -> v3
'Adjudicator', # v4 -> v3
contracts_to_rollback = ('StakingEscrow', # v4 -> v3
'PolicyManager', # v4 -> v3
'Adjudicator', # v4 -> v3
)
# Execute Rollbacks
for contract_name in contracts_to_rollback:
@ -287,7 +303,8 @@ def test_rollback(click_runner):
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
assert result.exit_code == 0
records = testerchain.registry.search(contract_name=contract_name)
blockchain = BlockchainDeployerInterface.reconnect()
records = blockchain.registry.search(contract_name=contract_name)
assert len(records) == 4
*old_records, v3, v4 = records
@ -299,9 +316,9 @@ def test_rollback(click_runner):
# Ensure the proxy targets the rollback target (previous version)
with pytest.raises(BlockchainInterface.UnknownContract):
testerchain.get_proxy(target_address=current_target_address, proxy_name='Dispatcher')
blockchain.get_proxy(target_address=current_target_address, proxy_name='Dispatcher')
proxy = testerchain.get_proxy(target_address=rollback_target_address, proxy_name='Dispatcher')
proxy = blockchain.get_proxy(target_address=rollback_target_address, proxy_name='Dispatcher')
# Deeper - Ensure the proxy targets the old deployment on-chain
targeted_address = proxy.functions.target().call()
@ -315,26 +332,16 @@ def test_nucypher_deploy_allocation_contracts(click_runner,
mock_primary_registry_filepath,
mock_allocation_infile,
token_economics):
Agency.clear()
# Simulate "Reconnection"
real_attach_provider = BlockchainDeployerInterface._attach_provider
cached_blockchain = BlockchainDeployerInterface.reconnect()
registry = cached_blockchain.registry
assert registry.filepath == mock_primary_registry_filepath
if os.path.isfile(MOCK_ALLOCATION_REGISTRY_FILEPATH):
os.remove(MOCK_ALLOCATION_REGISTRY_FILEPATH)
assert not os.path.isfile(MOCK_ALLOCATION_REGISTRY_FILEPATH)
# We start with a blockchain node, and nothing else...
if os.path.isfile(mock_primary_registry_filepath):
os.remove(mock_primary_registry_filepath)
assert not os.path.isfile(mock_primary_registry_filepath)
command = ['contracts',
'--registry-outfile', mock_primary_registry_filepath,
'--provider-uri', TEST_PROVIDER_URI,
'--poa',
'--no-sync']
user_input = deploy_user_input
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
assert result.exit_code == 0
def attach_cached_provider(interface, *args, **kwargs):
cached_provider = cached_blockchain.provider
real_attach_provider(interface, provider=cached_provider)
BlockchainDeployerInterface._attach_provider = attach_cached_provider
#
# Main
@ -344,7 +351,7 @@ def test_nucypher_deploy_allocation_contracts(click_runner,
'--registry-infile', MOCK_REGISTRY_FILEPATH,
'--allocation-infile', mock_allocation_infile.filepath,
'--allocation-outfile', MOCK_ALLOCATION_REGISTRY_FILEPATH,
'--provider-uri', 'tester://pyevm',
'--provider-uri', TEST_PROVIDER_URI,
'--poa')
account_index = '0\n'
@ -361,7 +368,9 @@ def test_nucypher_deploy_allocation_contracts(click_runner,
# ensure that a pre-allocation recipient has the allocated token quantity.
beneficiary = testerchain.client.accounts[-1]
allocation_registry = AllocationRegistry(registry_filepath=MOCK_ALLOCATION_REGISTRY_FILEPATH)
user_escrow_agent = UserEscrowAgent(beneficiary=beneficiary, allocation_registry=allocation_registry)
user_escrow_agent = UserEscrowAgent(blockchain=cached_blockchain,
beneficiary=beneficiary,
allocation_registry=allocation_registry)
assert user_escrow_agent.unvested_tokens == token_economics.minimum_allowed_locked
#