mirror of https://github.com/nucypher/nucypher.git
Add account selection to collect-reward. Complete tests for stake via contract.
parent
8e2bb3e217
commit
d968cdd848
|
@ -827,8 +827,8 @@ class Staker(NucypherTokenActor):
|
||||||
"""Withdraw tokens rewarded for staking."""
|
"""Withdraw tokens rewarded for staking."""
|
||||||
if self.is_contract:
|
if self.is_contract:
|
||||||
reward_amount = self.staking_agent.calculate_staking_reward(staker_address=self.checksum_address)
|
reward_amount = self.staking_agent.calculate_staking_reward(staker_address=self.checksum_address)
|
||||||
self.log.debug(f"Withdrawing staking reward, {reward_amount}, to {self.checksum_address}")
|
self.log.debug(f"Withdrawing staking reward ({NU.from_nunits(reward_amount)}) to {self.checksum_address}")
|
||||||
receipt = self.preallocation_escrow_agent.withdraw_as_staker(amount=reward_amount)
|
receipt = self.preallocation_escrow_agent.withdraw_as_staker(value=reward_amount)
|
||||||
else:
|
else:
|
||||||
receipt = self.staking_agent.collect_staking_reward(staker_address=self.checksum_address)
|
receipt = self.staking_agent.collect_staking_reward(staker_address=self.checksum_address)
|
||||||
return receipt
|
return receipt
|
||||||
|
@ -838,7 +838,7 @@ class Staker(NucypherTokenActor):
|
||||||
def withdraw(self, amount: NU) -> str:
|
def withdraw(self, amount: NU) -> str:
|
||||||
"""Withdraw tokens (assuming they're unlocked)"""
|
"""Withdraw tokens (assuming they're unlocked)"""
|
||||||
if self.is_contract:
|
if self.is_contract:
|
||||||
receipt = self.preallocation_escrow_agent.withdraw_as_staker(amount=int(amount))
|
receipt = self.preallocation_escrow_agent.withdraw_as_staker(value=int(amount))
|
||||||
else:
|
else:
|
||||||
receipt = self.staking_agent.withdraw(staker_address=self.checksum_address,
|
receipt = self.staking_agent.withdraw(staker_address=self.checksum_address,
|
||||||
amount=int(amount))
|
amount=int(amount))
|
||||||
|
@ -861,7 +861,6 @@ class Worker(NucypherTokenActor):
|
||||||
work_tracker: WorkTracker = None,
|
work_tracker: WorkTracker = None,
|
||||||
worker_address: str = None,
|
worker_address: str = None,
|
||||||
start_working_now: bool = True,
|
start_working_now: bool = True,
|
||||||
confirm_now: bool = True,
|
|
||||||
check_active_worker: bool = True,
|
check_active_worker: bool = True,
|
||||||
*args, **kwargs):
|
*args, **kwargs):
|
||||||
|
|
||||||
|
|
|
@ -374,7 +374,8 @@ class StakingEscrowAgent(EthereumContractAgent):
|
||||||
def collect_staking_reward(self, staker_address: str):
|
def collect_staking_reward(self, staker_address: str):
|
||||||
"""Withdraw tokens rewarded for staking."""
|
"""Withdraw tokens rewarded for staking."""
|
||||||
reward_amount = self.calculate_staking_reward(staker_address=staker_address)
|
reward_amount = self.calculate_staking_reward(staker_address=staker_address)
|
||||||
self.log.debug(f"Withdrawing staking reward, {reward_amount}, to {staker_address}")
|
from nucypher.blockchain.eth.token import NU
|
||||||
|
self.log.debug(f"Withdrawing staking reward ({NU.from_nunits(reward_amount)}) to {staker_address}")
|
||||||
return self.withdraw(staker_address=staker_address, amount=reward_amount)
|
return self.withdraw(staker_address=staker_address, amount=reward_amount)
|
||||||
|
|
||||||
@validate_checksum_address
|
@validate_checksum_address
|
||||||
|
|
|
@ -796,6 +796,7 @@ class Ursula(Teacher, Character, Worker):
|
||||||
checksum_address: str = None, # Staker address
|
checksum_address: str = None, # Staker address
|
||||||
worker_address: str = None,
|
worker_address: str = None,
|
||||||
work_tracker: WorkTracker = None,
|
work_tracker: WorkTracker = None,
|
||||||
|
start_working_now: bool = True,
|
||||||
client_password: str = None,
|
client_password: str = None,
|
||||||
|
|
||||||
# Character
|
# Character
|
||||||
|
@ -856,7 +857,8 @@ class Ursula(Teacher, Character, Worker):
|
||||||
registry=self.registry,
|
registry=self.registry,
|
||||||
checksum_address=checksum_address,
|
checksum_address=checksum_address,
|
||||||
worker_address=worker_address,
|
worker_address=worker_address,
|
||||||
work_tracker=work_tracker)
|
work_tracker=work_tracker,
|
||||||
|
start_working_now=start_working_now)
|
||||||
|
|
||||||
#
|
#
|
||||||
# ProxyRESTServer and TLSHostingPower #
|
# ProxyRESTServer and TLSHostingPower #
|
||||||
|
|
|
@ -191,6 +191,7 @@ def stake(click_config,
|
||||||
return # Exit
|
return # Exit
|
||||||
|
|
||||||
elif action == 'accounts':
|
elif action == 'accounts':
|
||||||
|
# TODO: Order accounts like shown by blockchain.client.accounts
|
||||||
for address, balances in STAKEHOLDER.wallet.balances.items():
|
for address, balances in STAKEHOLDER.wallet.balances.items():
|
||||||
emitter.echo(f"{address} | {Web3.fromWei(balances['ETH'], 'ether')} ETH | {NU.from_nunits(balances['NU'])}")
|
emitter.echo(f"{address} | {Web3.fromWei(balances['ETH'], 'ether')} ETH | {NU.from_nunits(balances['NU'])}")
|
||||||
return # Exit
|
return # Exit
|
||||||
|
@ -420,16 +421,22 @@ def stake(click_config,
|
||||||
elif action == 'collect-reward':
|
elif action == 'collect-reward':
|
||||||
"""Withdraw staking reward to the specified wallet address"""
|
"""Withdraw staking reward to the specified wallet address"""
|
||||||
|
|
||||||
# TODO: Missing account selection
|
# Authenticate
|
||||||
|
client_account, staking_address = handle_client_account_for_staking(emitter=emitter,
|
||||||
|
stakeholder=STAKEHOLDER,
|
||||||
|
staking_address=staking_address,
|
||||||
|
is_preallocation_staker=is_preallocation_staker,
|
||||||
|
beneficiary_address=beneficiary_address,
|
||||||
|
force=force)
|
||||||
|
|
||||||
password = None
|
password = None
|
||||||
if not hw_wallet and not blockchain.client.is_local:
|
if not hw_wallet and not blockchain.client.is_local:
|
||||||
password = get_client_password(checksum_address=staking_address)
|
password = get_client_password(checksum_address=client_account)
|
||||||
|
|
||||||
if not staking_reward and not policy_reward:
|
if not staking_reward and not policy_reward:
|
||||||
raise click.BadArgumentUsage(f"Either --staking-reward or --policy-reward must be True to collect rewards.")
|
raise click.BadArgumentUsage(f"Either --staking-reward or --policy-reward must be True to collect rewards.")
|
||||||
|
|
||||||
STAKEHOLDER.assimilate(checksum_address=staking_address, password=password)
|
STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
|
||||||
if staking_reward:
|
if staking_reward:
|
||||||
# Note: Sending staking / inflation rewards to another account is not allowed.
|
# Note: Sending staking / inflation rewards to another account is not allowed.
|
||||||
staking_receipt = STAKEHOLDER.collect_staking_reward()
|
staking_receipt = STAKEHOLDER.collect_staking_reward()
|
||||||
|
|
|
@ -15,19 +15,33 @@ You should have received a copy of the GNU Affero General Public License
|
||||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
|
||||||
|
import maya
|
||||||
import pytest
|
import pytest
|
||||||
|
from twisted.logger import Logger
|
||||||
from web3 import Web3
|
from web3 import Web3
|
||||||
|
|
||||||
from nucypher.blockchain.eth.actors import Staker
|
from nucypher.blockchain.eth.actors import Staker
|
||||||
from nucypher.blockchain.eth.agents import StakingEscrowAgent, ContractAgency, PreallocationEscrowAgent, NucypherTokenAgent
|
from nucypher.blockchain.eth.agents import StakingEscrowAgent, ContractAgency, PreallocationEscrowAgent, NucypherTokenAgent
|
||||||
from nucypher.blockchain.eth.token import NU, Stake
|
from nucypher.blockchain.eth.token import NU, Stake, StakeList
|
||||||
|
from nucypher.characters.lawful import Enrico, Ursula
|
||||||
from nucypher.cli.main import nucypher_cli
|
from nucypher.cli.main import nucypher_cli
|
||||||
|
from nucypher.config.characters import UrsulaConfiguration
|
||||||
|
from nucypher.crypto.powers import TransactingPower
|
||||||
from nucypher.utilities.sandbox.constants import (
|
from nucypher.utilities.sandbox.constants import (
|
||||||
TEST_PROVIDER_URI,
|
TEST_PROVIDER_URI,
|
||||||
INSECURE_DEVELOPMENT_PASSWORD,
|
INSECURE_DEVELOPMENT_PASSWORD,
|
||||||
|
MOCK_IP_ADDRESS,
|
||||||
|
MOCK_URSULA_STARTING_PORT,
|
||||||
|
TEMPORARY_DOMAIN,
|
||||||
|
MOCK_KNOWN_URSULAS_CACHE,
|
||||||
|
select_test_port,
|
||||||
)
|
)
|
||||||
|
from nucypher.utilities.sandbox.middleware import MockRestMiddleware
|
||||||
|
|
||||||
#
|
#
|
||||||
# This test module is intended to mirror tests/cli/ursula/test_stakeholder_and_ursula.py,
|
# This test module is intended to mirror tests/cli/ursula/test_stakeholder_and_ursula.py,
|
||||||
|
@ -169,6 +183,68 @@ def test_stake_set_worker(click_runner,
|
||||||
assert staker.worker_address == manual_worker
|
assert staker.worker_address == manual_worker
|
||||||
|
|
||||||
|
|
||||||
|
def test_stake_detach_worker(click_runner,
|
||||||
|
testerchain,
|
||||||
|
token_economics,
|
||||||
|
beneficiary,
|
||||||
|
preallocation_escrow_agent,
|
||||||
|
mock_allocation_registry,
|
||||||
|
manual_worker,
|
||||||
|
test_registry,
|
||||||
|
stakeholder_configuration_file_location):
|
||||||
|
|
||||||
|
staker_address = preallocation_escrow_agent.principal_contract.address
|
||||||
|
|
||||||
|
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||||
|
assert manual_worker == staking_agent.get_worker_from_staker(staker_address=staker_address)
|
||||||
|
|
||||||
|
testerchain.time_travel(periods=token_economics.minimum_worker_periods)
|
||||||
|
|
||||||
|
init_args = ('stake', 'detach-worker',
|
||||||
|
'--config-file', stakeholder_configuration_file_location,
|
||||||
|
'--escrow',
|
||||||
|
'--beneficiary-address', beneficiary,
|
||||||
|
'--allocation-filepath', mock_allocation_registry.filepath,
|
||||||
|
'--force')
|
||||||
|
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
init_args,
|
||||||
|
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
staker = Staker(is_me=True,
|
||||||
|
checksum_address=beneficiary,
|
||||||
|
allocation_registry=mock_allocation_registry,
|
||||||
|
registry=test_registry)
|
||||||
|
|
||||||
|
assert not staker.worker_address
|
||||||
|
|
||||||
|
# Ok ok, let's set the worker again.
|
||||||
|
|
||||||
|
init_args = ('stake', 'set-worker',
|
||||||
|
'--config-file', stakeholder_configuration_file_location,
|
||||||
|
'--escrow',
|
||||||
|
'--beneficiary-address', beneficiary,
|
||||||
|
'--allocation-filepath', mock_allocation_registry.filepath,
|
||||||
|
'--worker-address', manual_worker,
|
||||||
|
'--force')
|
||||||
|
|
||||||
|
user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}'
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
init_args,
|
||||||
|
input=user_input,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
staker = Staker(is_me=True,
|
||||||
|
checksum_address=beneficiary,
|
||||||
|
allocation_registry=mock_allocation_registry,
|
||||||
|
registry=test_registry)
|
||||||
|
|
||||||
|
assert staker.worker_address == manual_worker
|
||||||
|
|
||||||
|
|
||||||
def test_stake_restake(click_runner,
|
def test_stake_restake(click_runner,
|
||||||
beneficiary,
|
beneficiary,
|
||||||
preallocation_escrow_agent,
|
preallocation_escrow_agent,
|
||||||
|
@ -253,3 +329,248 @@ def test_stake_restake(click_runner,
|
||||||
allocation_registry=mock_allocation_registry)
|
allocation_registry=mock_allocation_registry)
|
||||||
assert not staker.is_restaking
|
assert not staker.is_restaking
|
||||||
assert "Successfully disabled" in result.output
|
assert "Successfully disabled" in result.output
|
||||||
|
|
||||||
|
|
||||||
|
def test_ursula_init(click_runner,
|
||||||
|
custom_filepath,
|
||||||
|
mock_registry_filepath,
|
||||||
|
preallocation_escrow_agent,
|
||||||
|
manual_worker,
|
||||||
|
testerchain):
|
||||||
|
|
||||||
|
init_args = ('ursula', 'init',
|
||||||
|
'--poa',
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
|
'--staker-address', preallocation_escrow_agent.principal_contract.address,
|
||||||
|
'--worker-address', manual_worker,
|
||||||
|
'--config-root', custom_filepath,
|
||||||
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--registry-filepath', mock_registry_filepath,
|
||||||
|
'--rest-host', MOCK_IP_ADDRESS,
|
||||||
|
'--rest-port', MOCK_URSULA_STARTING_PORT)
|
||||||
|
|
||||||
|
user_input = '{password}\n{password}'.format(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
init_args,
|
||||||
|
input=user_input,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
# Files and Directories
|
||||||
|
assert os.path.isdir(custom_filepath), 'Configuration file does not exist'
|
||||||
|
assert os.path.isdir(os.path.join(custom_filepath, 'keyring')), 'Keyring does not exist'
|
||||||
|
assert os.path.isdir(os.path.join(custom_filepath, 'known_nodes')), 'known_nodes directory does not exist'
|
||||||
|
|
||||||
|
custom_config_filepath = os.path.join(custom_filepath, UrsulaConfiguration.generate_filename())
|
||||||
|
assert os.path.isfile(custom_config_filepath), 'Configuration file does not exist'
|
||||||
|
|
||||||
|
with open(custom_config_filepath, 'r') as config_file:
|
||||||
|
raw_config_data = config_file.read()
|
||||||
|
config_data = json.loads(raw_config_data)
|
||||||
|
assert config_data['provider_uri'] == TEST_PROVIDER_URI
|
||||||
|
assert config_data['worker_address'] == manual_worker
|
||||||
|
assert config_data['checksum_address'] == preallocation_escrow_agent.principal_contract.address
|
||||||
|
assert TEMPORARY_DOMAIN in config_data['domains']
|
||||||
|
|
||||||
|
|
||||||
|
def test_ursula_run(click_runner,
|
||||||
|
manual_worker,
|
||||||
|
custom_filepath,
|
||||||
|
testerchain):
|
||||||
|
|
||||||
|
custom_config_filepath = os.path.join(custom_filepath, UrsulaConfiguration.generate_filename())
|
||||||
|
|
||||||
|
# Now start running your Ursula!
|
||||||
|
init_args = ('ursula', 'run',
|
||||||
|
'--dry-run',
|
||||||
|
'--config-file', custom_config_filepath)
|
||||||
|
|
||||||
|
user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' * 2
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
init_args,
|
||||||
|
input=user_input,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_collect_rewards_integration(click_runner,
|
||||||
|
testerchain,
|
||||||
|
test_registry,
|
||||||
|
stakeholder_configuration_file_location,
|
||||||
|
blockchain_alice,
|
||||||
|
blockchain_bob,
|
||||||
|
random_policy_label,
|
||||||
|
beneficiary,
|
||||||
|
preallocation_escrow_agent,
|
||||||
|
mock_allocation_registry,
|
||||||
|
manual_worker,
|
||||||
|
token_economics,
|
||||||
|
stake_value,
|
||||||
|
policy_value,
|
||||||
|
policy_rate):
|
||||||
|
|
||||||
|
half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup
|
||||||
|
logger = Logger("Test-CLI") # Enter the Teacher's Logger, and
|
||||||
|
current_period = 0 # State the initial period for incrementing
|
||||||
|
|
||||||
|
staker_address = preallocation_escrow_agent.principal_contract.address
|
||||||
|
worker_address = manual_worker
|
||||||
|
|
||||||
|
# The staker is staking.
|
||||||
|
stakes = StakeList(registry=test_registry, checksum_address=staker_address)
|
||||||
|
stakes.refresh()
|
||||||
|
assert stakes
|
||||||
|
|
||||||
|
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||||
|
assert worker_address == staking_agent.get_worker_from_staker(staker_address=staker_address)
|
||||||
|
|
||||||
|
ursula_port = select_test_port()
|
||||||
|
ursula = Ursula(is_me=True,
|
||||||
|
checksum_address=staker_address,
|
||||||
|
worker_address=worker_address,
|
||||||
|
registry=test_registry,
|
||||||
|
rest_host='127.0.0.1',
|
||||||
|
rest_port=ursula_port,
|
||||||
|
start_working_now=False,
|
||||||
|
network_middleware=MockRestMiddleware())
|
||||||
|
|
||||||
|
MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula
|
||||||
|
assert ursula.worker_address == worker_address
|
||||||
|
assert ursula.checksum_address == staker_address
|
||||||
|
|
||||||
|
# Mock TransactingPower consumption (Worker-Ursula)
|
||||||
|
testerchain.transacting_power = TransactingPower(account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||||
|
testerchain.transacting_power.activate()
|
||||||
|
|
||||||
|
# Confirm for half the first stake duration
|
||||||
|
for _ in range(half_stake_time):
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
ursula.confirm_activity()
|
||||||
|
testerchain.time_travel(periods=1)
|
||||||
|
current_period += 1
|
||||||
|
|
||||||
|
# Alice creates a policy and grants Bob access
|
||||||
|
blockchain_alice.selection_buffer = 1
|
||||||
|
|
||||||
|
M, N = 1, 1
|
||||||
|
expiration = maya.now() + datetime.timedelta(days=3)
|
||||||
|
blockchain_policy = blockchain_alice.grant(bob=blockchain_bob,
|
||||||
|
label=random_policy_label,
|
||||||
|
m=M, n=N,
|
||||||
|
value=policy_value,
|
||||||
|
expiration=expiration,
|
||||||
|
handpicked_ursulas={ursula})
|
||||||
|
|
||||||
|
# Ensure that the handpicked Ursula was selected for the policy
|
||||||
|
arrangement = list(blockchain_policy._accepted_arrangements)[0]
|
||||||
|
assert arrangement.ursula == ursula
|
||||||
|
|
||||||
|
# Bob learns about the new staker and joins the policy
|
||||||
|
blockchain_bob.start_learning_loop()
|
||||||
|
blockchain_bob.remember_node(node=ursula)
|
||||||
|
blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp))
|
||||||
|
|
||||||
|
# Enrico Encrypts (of course)
|
||||||
|
enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key,
|
||||||
|
network_middleware=MockRestMiddleware())
|
||||||
|
|
||||||
|
verifying_key = blockchain_alice.stamp.as_umbral_pubkey()
|
||||||
|
|
||||||
|
for index in range(half_stake_time - 5):
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
ursula.confirm_activity()
|
||||||
|
|
||||||
|
# Encrypt
|
||||||
|
random_data = os.urandom(random.randrange(20, 100))
|
||||||
|
ciphertext, signature = enrico.encrypt_message(message=random_data)
|
||||||
|
|
||||||
|
# Decrypt
|
||||||
|
cleartexts = blockchain_bob.retrieve(message_kit=ciphertext,
|
||||||
|
data_source=enrico,
|
||||||
|
alice_verifying_key=verifying_key,
|
||||||
|
label=random_policy_label)
|
||||||
|
assert random_data == cleartexts[0]
|
||||||
|
|
||||||
|
# Ursula Staying online and the clock advancing
|
||||||
|
testerchain.time_travel(periods=1)
|
||||||
|
current_period += 1
|
||||||
|
|
||||||
|
# Finish the passage of time
|
||||||
|
for _ in range(5 - 1): # minus 1 because the first period was already confirmed in test_ursula_run
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
ursula.confirm_activity()
|
||||||
|
current_period += 1
|
||||||
|
testerchain.time_travel(periods=1)
|
||||||
|
|
||||||
|
#
|
||||||
|
# WHERES THE MONEY URSULA?? - Collecting Rewards
|
||||||
|
#
|
||||||
|
|
||||||
|
# The address the client wants Ursula to send policy rewards to
|
||||||
|
burner_wallet = testerchain.w3.eth.account.create(INSECURE_DEVELOPMENT_PASSWORD)
|
||||||
|
|
||||||
|
# The policy rewards wallet is initially empty, because it is freshly created
|
||||||
|
assert testerchain.client.get_balance(burner_wallet.address) == 0
|
||||||
|
|
||||||
|
# Rewards will be unlocked after the
|
||||||
|
# final confirmed period has passed (+1).
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
testerchain.time_travel(periods=1)
|
||||||
|
current_period += 1
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
|
||||||
|
# Since we are mocking the blockchain connection, manually consume the transacting power of the Beneficiary.
|
||||||
|
testerchain.transacting_power = TransactingPower(account=beneficiary,
|
||||||
|
password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||||
|
testerchain.transacting_power.activate()
|
||||||
|
|
||||||
|
# Collect Policy Reward
|
||||||
|
collection_args = ('stake', 'collect-reward',
|
||||||
|
'--mock-networking',
|
||||||
|
'--config-file', stakeholder_configuration_file_location,
|
||||||
|
'--policy-reward',
|
||||||
|
'--no-staking-reward',
|
||||||
|
'--withdraw-address', burner_wallet.address,
|
||||||
|
'--escrow',
|
||||||
|
'--beneficiary-address', beneficiary,
|
||||||
|
'--allocation-filepath', mock_allocation_registry.filepath,
|
||||||
|
'--force')
|
||||||
|
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
collection_args,
|
||||||
|
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
# Policy Reward
|
||||||
|
collected_policy_reward = testerchain.client.get_balance(burner_wallet.address)
|
||||||
|
expected_collection = policy_rate * 30
|
||||||
|
assert collected_policy_reward == expected_collection
|
||||||
|
|
||||||
|
#
|
||||||
|
# Collect Staking Reward
|
||||||
|
#
|
||||||
|
token_agent = ContractAgency.get_agent(agent_class=NucypherTokenAgent, registry=test_registry)
|
||||||
|
balance_before_collecting = token_agent.get_balance(address=staker_address)
|
||||||
|
|
||||||
|
collection_args = ('stake', 'collect-reward',
|
||||||
|
'--mock-networking',
|
||||||
|
'--config-file', stakeholder_configuration_file_location,
|
||||||
|
'--no-policy-reward',
|
||||||
|
'--staking-reward',
|
||||||
|
'--escrow',
|
||||||
|
'--beneficiary-address', beneficiary,
|
||||||
|
'--allocation-filepath', mock_allocation_registry.filepath,
|
||||||
|
'--force')
|
||||||
|
|
||||||
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
collection_args,
|
||||||
|
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||||
|
catch_exceptions=False)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
# The beneficiary has withdrawn her staking rewards, which are now in the staking contract
|
||||||
|
assert token_agent.get_balance(address=staker_address) >= balance_before_collecting
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -400,9 +400,8 @@ def test_collect_rewards_integration(click_runner,
|
||||||
verifying_key = blockchain_alice.stamp.as_umbral_pubkey()
|
verifying_key = blockchain_alice.stamp.as_umbral_pubkey()
|
||||||
|
|
||||||
for index in range(half_stake_time - 5):
|
for index in range(half_stake_time - 5):
|
||||||
ursula.confirm_activity()
|
|
||||||
|
|
||||||
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
ursula.confirm_activity()
|
||||||
|
|
||||||
# Encrypt
|
# Encrypt
|
||||||
random_data = os.urandom(random.randrange(20, 100))
|
random_data = os.urandom(random.randrange(20, 100))
|
||||||
|
@ -421,10 +420,10 @@ def test_collect_rewards_integration(click_runner,
|
||||||
|
|
||||||
# Finish the passage of time for the first Stake
|
# Finish the passage of time for the first Stake
|
||||||
for _ in range(5): # plus the extended periods from stake division
|
for _ in range(5): # plus the extended periods from stake division
|
||||||
ursula.confirm_activity()
|
|
||||||
current_period += 1
|
|
||||||
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
ursula.confirm_activity()
|
||||||
testerchain.time_travel(periods=1)
|
testerchain.time_travel(periods=1)
|
||||||
|
current_period += 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# WHERES THE MONEY URSULA?? - Collecting Rewards
|
# WHERES THE MONEY URSULA?? - Collecting Rewards
|
||||||
|
@ -438,6 +437,7 @@ def test_collect_rewards_integration(click_runner,
|
||||||
|
|
||||||
# Rewards will be unlocked after the
|
# Rewards will be unlocked after the
|
||||||
# final confirmed period has passed (+1).
|
# final confirmed period has passed (+1).
|
||||||
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
testerchain.time_travel(periods=1)
|
testerchain.time_travel(periods=1)
|
||||||
current_period += 1
|
current_period += 1
|
||||||
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
|
@ -479,14 +479,18 @@ def test_collect_rewards_integration(click_runner,
|
||||||
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||||
testerchain.time_travel(periods=1)
|
testerchain.time_travel(periods=1)
|
||||||
|
|
||||||
# Collect Inflation Reward
|
#
|
||||||
|
# Collect Staking Reward
|
||||||
|
#
|
||||||
|
|
||||||
|
balance_before_collecting = staker.token_agent.get_balance(address=staker_address)
|
||||||
|
|
||||||
collection_args = ('stake', 'collect-reward',
|
collection_args = ('stake', 'collect-reward',
|
||||||
'--mock-networking',
|
'--mock-networking',
|
||||||
'--config-file', stakeholder_configuration_file_location,
|
'--config-file', stakeholder_configuration_file_location,
|
||||||
'--no-policy-reward',
|
'--no-policy-reward',
|
||||||
'--staking-reward',
|
'--staking-reward',
|
||||||
'--staking-address', staker_address,
|
'--staking-address', staker_address,
|
||||||
'--withdraw-address', burner_wallet.address,
|
|
||||||
'--force')
|
'--force')
|
||||||
|
|
||||||
result = click_runner.invoke(nucypher_cli,
|
result = click_runner.invoke(nucypher_cli,
|
||||||
|
@ -495,8 +499,8 @@ def test_collect_rewards_integration(click_runner,
|
||||||
catch_exceptions=False)
|
catch_exceptions=False)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
# The burner wallet has the reward ethers
|
# The staker has withdrawn her staking rewards
|
||||||
assert staker.token_agent.get_balance(address=staker_address)
|
assert staker.token_agent.get_balance(address=staker_address) >= balance_before_collecting
|
||||||
|
|
||||||
|
|
||||||
def test_stake_detach_worker(click_runner,
|
def test_stake_detach_worker(click_runner,
|
||||||
|
|
Loading…
Reference in New Issue