mirror of https://github.com/nucypher/nucypher.git
262 lines
8.2 KiB
Python
262 lines
8.2 KiB
Python
|
|
|
|
import maya
|
|
import pytest
|
|
from eth_typing import ChecksumAddress
|
|
|
|
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
|
from nucypher.cli.commands.bond import bond, unbond
|
|
from nucypher.cli.literature import (
|
|
ALREADY_BONDED,
|
|
BONDING_TIME,
|
|
UNEXPECTED_HUMAN_OPERATOR,
|
|
)
|
|
from nucypher.config.constants import (
|
|
NUCYPHER_ENVVAR_STAKING_PROVIDER_ETH_PASSWORD,
|
|
TEMPORARY_DOMAIN,
|
|
)
|
|
from nucypher.crypto.powers import TransactingPower
|
|
from nucypher.types import StakingProviderInfo
|
|
from tests.constants import INSECURE_DEVELOPMENT_PASSWORD, TEST_ETH_PROVIDER_URI
|
|
|
|
cli_env = {NUCYPHER_ENVVAR_STAKING_PROVIDER_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
|
|
|
|
|
@pytest.fixture(scope='module', autouse=True)
|
|
def mock_transacting_power(module_mocker):
|
|
module_mocker.patch.object(TransactingPower, 'unlock')
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def operator_address(testerchain):
|
|
return testerchain.unassigned_accounts[1]
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
@pytest.mark.usefixtures('test_registry_source_manager', 'mock_contract_agency')
|
|
def staking_provider_address(testerchain):
|
|
return testerchain.unassigned_accounts[2]
|
|
|
|
|
|
def test_nucypher_bond_help(click_runner, testerchain):
|
|
command = '--help'
|
|
result = click_runner.invoke(bond, command, catch_exceptions=False)
|
|
assert result.exit_code == 0
|
|
|
|
|
|
def exec_bond(click_runner, operator_address: ChecksumAddress, staking_provider_address: ChecksumAddress):
|
|
command = ('--operator-address', operator_address,
|
|
'--staking-provider', staking_provider_address,
|
|
'--eth-provider', TEST_ETH_PROVIDER_URI,
|
|
'--network', TEMPORARY_DOMAIN,
|
|
'--signer', TEST_ETH_PROVIDER_URI,
|
|
'--force' # non-interactive only
|
|
)
|
|
result = click_runner.invoke(bond, command, catch_exceptions=False, env=cli_env)
|
|
return result
|
|
|
|
|
|
def exec_unbond(click_runner, staking_provider_address: ChecksumAddress):
|
|
command = ('--staking-provider', staking_provider_address,
|
|
'--eth-provider', TEST_ETH_PROVIDER_URI,
|
|
'--network', TEMPORARY_DOMAIN,
|
|
'--signer', TEST_ETH_PROVIDER_URI,
|
|
'--force' # non-interactive only
|
|
)
|
|
result = click_runner.invoke(unbond, command, catch_exceptions=False, env=cli_env)
|
|
return result
|
|
|
|
|
|
@pytest.mark.usefixtures(
|
|
"test_registry_source_manager", "mock_contract_agency", "patch_keystore"
|
|
)
|
|
def test_nucypher_bond_unauthorized(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
|
|
mock_application_agent.is_authorized.return_value = False
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=NULL_ADDRESS,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
assert result.exit_code == 1
|
|
error_message = f'{staking_provider_address} is not authorized'
|
|
assert error_message in result.output
|
|
|
|
|
|
@pytest.mark.usefixtures(
|
|
"test_registry_source_manager", "mock_contract_agency", "test_registry"
|
|
)
|
|
def test_nucypher_unexpected_beneficiary(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=NULL_ADDRESS,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
mock_application_agent.get_beneficiary.return_value = (
|
|
testerchain.unassigned_accounts[-1]
|
|
)
|
|
mock_application_agent.get_staking_provider_from_operator.return_value = (
|
|
NULL_ADDRESS
|
|
)
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
|
|
assert result.exit_code == 1
|
|
assert UNEXPECTED_HUMAN_OPERATOR in result.output
|
|
|
|
|
|
@pytest.mark.usefixtures(
|
|
"test_registry_source_manager", "mock_contract_agency", "test_registry"
|
|
)
|
|
def test_nucypher_bond(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=NULL_ADDRESS,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
mock_application_agent.get_beneficiary.return_value = NULL_ADDRESS
|
|
mock_application_agent.get_staking_provider_from_operator.return_value = NULL_ADDRESS
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
|
@pytest.mark.usefixtures("test_registry_source_manager", "mock_contract_agency")
|
|
def test_nucypher_unbond_operator(
|
|
click_runner,
|
|
testerchain,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
operator_address,
|
|
):
|
|
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=operator_address,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
|
|
mock_application_agent.get_staking_provider_from_operator.return_value = staking_provider_address
|
|
|
|
result = exec_unbond(click_runner=click_runner, staking_provider_address=staking_provider_address)
|
|
assert result.exit_code == 0
|
|
|
|
|
|
@pytest.mark.usefixtures("test_registry_source_manager", "mock_contract_agency")
|
|
def test_nucypher_rebond_too_soon(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
|
|
min_authorized_seconds = 5
|
|
now = testerchain.get_blocktime()
|
|
operator_start_timestamp = now
|
|
termination = operator_start_timestamp + min_authorized_seconds
|
|
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=operator_address,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=operator_start_timestamp
|
|
)
|
|
mock_application_agent.get_min_operator_seconds.return_value = min_authorized_seconds
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
assert result.exit_code == 1
|
|
error_message = BONDING_TIME.format(date=maya.MayaDT(termination))
|
|
assert error_message in result.output
|
|
|
|
|
|
@pytest.mark.usefixtures("test_registry_source_manager", "mock_contract_agency")
|
|
def test_nucypher_bond_already_claimed_operator(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=NULL_ADDRESS,
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
mock_application_agent.get_beneficiary.return_value = NULL_ADDRESS
|
|
mock_application_agent.get_operator_from_staking_provider.return_value = (
|
|
NULL_ADDRESS
|
|
)
|
|
mock_application_agent.get_staking_provider_from_operator.return_value = (
|
|
testerchain.unassigned_accounts[4]
|
|
)
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
assert result.exit_code == 1
|
|
|
|
|
|
@pytest.mark.usefixtures("test_registry_source_manager", "mock_contract_agency")
|
|
def test_nucypher_rebond_operator(
|
|
click_runner,
|
|
testerchain,
|
|
operator_address,
|
|
staking_provider_address,
|
|
mock_application_agent,
|
|
):
|
|
mock_application_agent.get_staking_provider_info.return_value = StakingProviderInfo(
|
|
operator=testerchain.unassigned_accounts[-1],
|
|
operator_confirmed=False,
|
|
operator_start_timestamp=1
|
|
)
|
|
mock_application_agent.get_beneficiary.return_value = NULL_ADDRESS
|
|
mock_application_agent.get_staking_provider_from_operator.return_value = NULL_ADDRESS
|
|
|
|
result = exec_bond(
|
|
click_runner=click_runner,
|
|
operator_address=operator_address,
|
|
staking_provider_address=staking_provider_address
|
|
)
|
|
assert result.exit_code == 0
|