Fixes staking and locking client methods, concise test narrative for miners.

pull/270/head
Kieran Prasch 2018-05-09 18:11:53 -07:00 committed by Kieran R Prasch
parent 9972063ef1
commit e6f212a1cc
2 changed files with 36 additions and 74 deletions

View File

@ -152,14 +152,15 @@ class Miner(TokenActor):
def collect_staking_reward(self) -> str:
"""Withdraw tokens rewarded for staking."""
token_amount_bytes = self.miner_agent.contract.functions.getMinerInfo(self.miner_agent.MinerInfo.VALUE.value,
self.address, 0).call()
token_amount_bytes = self.miner_agent.contract.functions.minerInfo(self.address).call()[0]
token_amount = self.blockchain.provider.w3.toInt(token_amount_bytes)
token_amount = self.blockchain._chain.web3.toInt(token_amount_bytes)
collection_txhash = self.miner_agent.contract.functions.withdraw(token_amount).transact({'from': self.address})
# reward_amount = TODO
self.blockchain.wait_for_receipt(collection_txhash)
self._transactions.append((datetime.utcnow(), collection_txhash))
reward_txhash = self.miner_agent.contract.functions.withdraw(token_amount).transact({'from': self.address})
return collection_txhash
def __validate_stake(self, amount: int, periods: int) -> bool:
@ -171,7 +172,7 @@ class Miner(TokenActor):
else:
return True
def stake(self, amount, locktime, entire_balance=False):
def stake(self, amount, periods, entire_balance=False):
"""
High level staking method for Miners.
"""
@ -182,9 +183,9 @@ class Miner(TokenActor):
raise self.StakingError("Specify an amount or entire balance, not both")
if entire_balance is True:
balance_bytes = self.miner_agent.contract.functions.getMinerInfo(self.miner_agent.MinerInfo.VALUE.value,
self.address, 0).call()
amount = self.blockchain._chain.web3.toInt(balance_bytes)
amount = self.miner_agent.contract.functions.getMinerInfo(self.miner_agent.MinerInfo.VALUE.value,
self.address, 0).call()
amount = self.blockchain.provider.w3.toInt(amount)
assert self.__validate_stake(amount=amount, periods=periods)

View File

@ -5,92 +5,53 @@ from nucypher.blockchain.eth.actors import Miner
from nucypher.blockchain.eth.agents import MinerAgent
@pytest.mark.skip("Last 5 stubborn blockchain tests.")
def test_miner_locking_tokens(chain, token_agent, mock_token_deployer, mock_miner_agent):
@pytest.fixture(scope='module')
def miner(chain, mock_token_agent, mock_miner_agent):
mock_token_agent.token_airdrop(amount=100000 * mock_token_agent._M)
_origin, ursula, *everybody_else = chain.provider.w3.eth.accounts
miner = Miner(miner_agent=mock_miner_agent, address=ursula)
return miner
chain._token_airdrop(token_agent=token_agent, amount=10000)
miner = Miner(miner_agent=mock_miner_agent, address=chain.provider.w3.eth.accounts[1])
def test_miner_locking_tokens(chain, miner, mock_miner_agent):
an_amount_of_tokens = 1000 * mock_token_deployer._M
miner.stake(amount=an_amount_of_tokens, locktime=mock_miner_agent._deployer._min_locked_periods)
assert mock_miner_agent.min_allowed_locked < miner.token_balance(), "Insufficient miner balance"
# Verify that the escrow is allowed to receive tokens
miner.stake(amount=mock_miner_agent.min_allowed_locked, # Lock the minimum amount of tokens
periods=mock_miner_agent.min_locked_periods) # ... for the fewest number of periods
# Verify that the escrow is "approved" to receive tokens
assert mock_miner_agent.token_agent.contract.functions.allowance(miner.address, mock_miner_agent.contract_address).call() == 0
# Stake starts after one period
assert miner.token_balance() == 0
# Staking starts after one period
assert mock_miner_agent.contract.functions.getLockedTokens(miner.address).call() == 0
# Wait for it...
chain.time_travel(mock_miner_agent._deployer._hours_per_period)
assert mock_miner_agent.contract.functions.getLockedTokens(miner.address).call() == an_amount_of_tokens
chain.time_travel(periods=1)
assert mock_miner_agent.contract.functions.getLockedTokens(miner.address).call() == mock_miner_agent.min_allowed_locked
@pytest.mark.skip("Last 5 stubborn blockchain tests.")
def test_mine_then_withdraw_tokens(chain, mock_token_deployer, token_agent, mock_miner_agent, mock_miner_escrow_deployer):
"""
- Airdrop tokens to everyone
- Create a Miner (Ursula)
- Spawn additional miners
- All miners lock tokens
- Wait (with time)
- Miner (Ursula) mints new tokens
"""
def test_miner_collects_staking_reward_tokens(chain, miner, mock_token_agent, mock_miner_agent):
_origin, *everybody = chain.provider.w3.eth.accounts
ursula_address, *everyone_else = everybody
miner = Miner(miner_agent=mock_miner_agent, address=ursula_address)
# Miner has no locked tokens
assert miner.locked_tokens == 0
# Capture the initial token balance of the miner
# Capture the current token balance of the miner
initial_balance = miner.token_balance()
assert token_agent.get_balance(miner.address) == miner.token_balance()
# Stake a random amount of tokens
# stake_amount = (10 + random.randrange(9000)) * mock_token_deployer._M
half_of_stake = initial_balance // 2
miner.stake(amount=half_of_stake, locktime=1)
# Ensure the miner has the right amount of staked tokens
assert miner.locked_tokens == half_of_stake
# Ensure the MinerEscrow contract is allowed to receive tokens form Alice
# assert miner.token_agent.contract.functions.allowance(miner.address, miner.miner_agent.contract_address).call() == half_of_stake
# Blockchain staking starts after one period
# assert mock_miner_agent.contract.functions.getAllLockedTokens().call() == 0
# Wait for it...
# chain.wait_time(2)
assert mock_token_agent.get_balance(miner.address) == miner.token_balance()
# Have other address lock tokens
chain.spawn_miners(miner_agent=mock_miner_agent,
addresses=everyone_else,
locktime=1,
m=mock_token_deployer._M)
# The miner starts unlocking periods...
_origin, ursula, *everybody_else = chain.provider.w3.eth.accounts
mock_miner_agent.spawn_random_miners(addresses=everybody_else)
# ...wait out the lock period...
for _ in range(28):
chain.time_travel(periods=1)
miner.confirm_activity()
# ...wait more...
chain.time_travel(mock_miner_agent._deployer._hours_per_period)
# miner.confirm_activity()
# ...wait more...
chain.time_travel(mock_miner_agent._deployer._hours_per_period)
chain.time_travel(periods=2)
miner.mint()
miner.collect_staking_reward()
final_balance = token_agent.get_balance(miner.address)
final_balance = mock_token_agent.get_balance(miner.address)
assert final_balance > initial_balance