Fixed small issues, added setWorker to UserEscrow

pull/1029/head
szotov 2019-04-26 16:28:37 +03:00 committed by David Núñez
parent 8bc89805ff
commit b545e3ec9b
8 changed files with 89 additions and 33 deletions

View File

@ -5,7 +5,7 @@ import "contracts/NuCypherToken.sol";
import "zeppelin/math/SafeMath.sol";
import "zeppelin/math/Math.sol";
import "contracts/proxy/Upgradeable.sol";
import "./lib/AdditionalMath.sol";
import "contracts/lib/AdditionalMath.sol";
/**

View File

@ -375,7 +375,8 @@ contract MinersEscrow is Issuer {
"Not enough time has passed since the previous setting worker");
require(_worker == address(0) || workerToMiner[_worker] == address(0),
"Specified worker is already in use");
require(minerInfo[_worker].value == 0, "Specified worker is a miner");
require(minerInfo[_worker].value == 0 || _worker == msg.sender,
"Specified worker is an another miner");
// remove relation between the old worker and the miner
if (info.worker != address(0)) {
@ -543,7 +544,7 @@ contract MinersEscrow is Issuer {
if (info.confirmedPeriod1 != nextPeriod && info.confirmedPeriod2 != nextPeriod) {
saveSubStake(info, nextPeriod, 0, _periods, _value);
} else {
// TODO check and add docs. maybe extract or rename event
// next period is confirmed
saveSubStake(info, nextPeriod, 0, _periods - 1, _value);
lockedPerPeriod[nextPeriod] = lockedPerPeriod[nextPeriod].add(_value);
emit ActivityConfirmed(_miner, nextPeriod, _value);
@ -619,7 +620,6 @@ contract MinersEscrow is Issuer {
// if the next period is confirmed and
// old sub stake is finishing in the current period then update confirmation
if (lastPeriod == currentPeriod && startPeriod > currentPeriod) {
// TODO maybe extract or rename event
lockedPerPeriod[startPeriod] = lockedPerPeriod[startPeriod].add(_newValue);
emit ActivityConfirmed(msg.sender, startPeriod, _newValue);
}
@ -650,6 +650,8 @@ contract MinersEscrow is Issuer {
* @notice Confirm activity for the next period and mine for the previous period
**/
function confirmActivity() external onlyMiner {
require(getWorkerByMiner(msg.sender) == tx.origin, "Only worker can confirm activity");
uint16 lastActivePeriod = getLastActivePeriod(msg.sender);
mint(msg.sender);
MinerInfo storage info = minerInfo[msg.sender];
@ -693,13 +695,16 @@ contract MinersEscrow is Issuer {
* @notice Mint tokens for previous periods if miner locked their tokens and confirmed activity
**/
function mint() external onlyMiner {
// save last active period to the storage if only one period is confirmed
// because after this minting confirmed periods can be empty and can't calculate period from them
// save last active period to the storage if both periods will be empty after minting
// because we won't be able to calculate last active period
// see getLastActivePeriod(address)
MinerInfo storage info = minerInfo[msg.sender];
// TODO recheck condition
if (info.confirmedPeriod1 != EMPTY_CONFIRMED_PERIOD ||
info.confirmedPeriod2 != EMPTY_CONFIRMED_PERIOD) {
uint16 previousPeriod = getCurrentPeriod().sub16(1);
if (info.confirmedPeriod1 <= previousPeriod &&
info.confirmedPeriod2 <= previousPeriod &&
(info.confirmedPeriod1 != EMPTY_CONFIRMED_PERIOD ||
info.confirmedPeriod2 != EMPTY_CONFIRMED_PERIOD))
{
info.lastActivePeriod = AdditionalMath.max16(info.confirmedPeriod1, info.confirmedPeriod2);
}
mint(msg.sender);
@ -1237,7 +1242,9 @@ contract MinersEscrow is Issuer {
infoToCheck.confirmedPeriod2 == info.confirmedPeriod2 &&
infoToCheck.reStake == info.reStake &&
infoToCheck.lockReStakeUntilPeriod == info.lockReStakeUntilPeriod &&
infoToCheck.lastActivePeriod == info.lastActivePeriod);
infoToCheck.lastActivePeriod == info.lastActivePeriod &&
infoToCheck.worker == info.worker &&
infoToCheck.workerStartPeriod == info.workerStartPeriod);
require(delegateGet(_testTarget, "getPastDowntimeLength(address)", miner) ==
info.pastDowntime.length);
@ -1257,6 +1264,11 @@ contract MinersEscrow is Issuer {
subStakeInfoToCheck.periods == subStakeInfo.periods &&
subStakeInfoToCheck.lockedValue == subStakeInfo.lockedValue);
}
if (info.worker != address(0)) {
require(address(delegateGet(_testTarget, "workerToMiner(address)", bytes32(uint256(info.worker)))) ==
workerToMiner[info.worker]);
}
}
/// @dev the `onlyWhileUpgrading` modifier works through a call to the parent `finishUpgrade`

View File

@ -4,7 +4,7 @@ pragma solidity ^0.5.3;
import "zeppelin/token/ERC20/SafeERC20.sol";
import "zeppelin/math/SafeMath.sol";
import "zeppelin/math/Math.sol";
import "./lib/AdditionalMath.sol";
import "contracts/lib/AdditionalMath.sol";
import "contracts/MinersEscrow.sol";
import "contracts/NuCypherToken.sol";
import "contracts/proxy/Upgradeable.sol";

View File

@ -1,7 +1,7 @@
pragma solidity ^0.5.3;
import "./UserEscrow.sol";
import "contracts/UserEscrow.sol";
import "contracts/NuCypherToken.sol";
import "contracts/MinersEscrow.sol";
import "contracts/PolicyManager.sol";
@ -14,16 +14,17 @@ import "contracts/PolicyManager.sol";
**/
contract UserEscrowProxy {
event DepositedAsMiner(address indexed owner, uint256 value, uint16 periods);
event WithdrawnAsMiner(address indexed owner, uint256 value);
event Locked(address indexed owner, uint256 value, uint16 periods);
event Divided(address indexed owner, uint256 index, uint256 newValue, uint16 periods);
event ActivityConfirmed(address indexed owner);
event Mined(address indexed owner);
event PolicyRewardWithdrawn(address indexed owner, uint256 value);
event MinRewardRateSet(address indexed owner, uint256 value);
event ReStakeSet(address indexed owner, bool reStake);
event ReStakeLocked(address indexed owner, uint16 lockUntilPeriod);
event DepositedAsMiner(address indexed sender, uint256 value, uint16 periods);
event WithdrawnAsMiner(address indexed sender, uint256 value);
event Locked(address indexed sender, uint256 value, uint16 periods);
event Divided(address indexed sender, uint256 index, uint256 newValue, uint16 periods);
event ActivityConfirmed(address indexed sender);
event Mined(address indexed sender);
event PolicyRewardWithdrawn(address indexed sender, uint256 value);
event MinRewardRateSet(address indexed sender, uint256 value);
event ReStakeSet(address indexed sender, bool reStake);
event ReStakeLocked(address indexed sender, uint16 lockUntilPeriod);
event WorkerSet(address indexed sender, address worker);
NuCypherToken public token;
MinersEscrow public escrow;
@ -60,6 +61,15 @@ contract UserEscrowProxy {
return UserEscrowProxy(linker.target());
}
/**
* @notice Set `worker` parameter in the miners escrow
* @param _worker Worker address. Use zero address to set miner as worker
**/
function setWorker(address _worker) public {
getStateContract().escrow().setWorker(_worker);
emit WorkerSet(msg.sender, _worker);
}
/**
* @notice Set `reStake` parameter in the miners escrow
* @param _reStake Value for parameter

View File

@ -19,6 +19,7 @@ contract MinersEscrowForUserEscrowMock {
uint256 public index;
bool public reStake;
uint16 public lockReStakeUntilPeriod;
address public worker;
constructor(NuCypherToken _token) public {
token = _token;
@ -67,6 +68,10 @@ contract MinersEscrowForUserEscrowMock {
function lockReStake(uint16 _lockReStakeUntilPeriod) public {
lockReStakeUntilPeriod = _lockReStakeUntilPeriod;
}
function setWorker(address _worker) public {
worker = _worker;
}
}

View File

@ -99,6 +99,8 @@ def test_upgrading(testerchain, token):
testerchain.wait_for_receipt(tx)
tx = contract.functions.lockReStake(contract.functions.getCurrentPeriod().call() + 1).transact({'from': miner})
testerchain.wait_for_receipt(tx)
tx = contract.functions.setWorker(miner).transact({'from': miner})
testerchain.wait_for_receipt(tx)
# Upgrade to the second version
tx = dispatcher.functions.upgrade(contract_library_v2.address, secret, secret2_hash).transact({'from': creator})
@ -434,3 +436,8 @@ def test_re_stake(testerchain, token, escrow_contract):
assert sub_stake == escrow.functions.getLockedTokensInPast(ursula, 1).call()
assert sub_stake == escrow.functions.getLockedTokens(ursula).call()
assert sub_stake == escrow.functions.lockedPerPeriod(period - 1).call()
@pytest.mark.slow
def test_worker(testerchain, token, escrow_contract):
pass

View File

@ -149,7 +149,7 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
events = miner_deposits.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 1500 == event_args['value']
assert 5 == event_args['periods']
@ -180,6 +180,9 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
with pytest.raises((TransactionFailed, ValueError)):
tx = proxy.functions.lockReStake(0).transact({'from': user})
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = proxy.functions.setWorker(user).transact({'from': user})
testerchain.wait_for_receipt(tx)
locks = user_escrow_proxy.events.Locked.createFilter(fromBlock='latest')
divides = user_escrow_proxy.events.Divided.createFilter(fromBlock='latest')
@ -189,6 +192,7 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
withdraws = user_escrow.events.TokensWithdrawn.createFilter(fromBlock='latest')
re_stakes = user_escrow_proxy.events.ReStakeSet.createFilter(fromBlock='latest')
re_stake_locks = user_escrow_proxy.events.ReStakeLocked.createFilter(fromBlock='latest')
worker_logs = user_escrow_proxy.events.WorkerSet.createFilter(fromBlock='latest')
# Use miners methods through the user escrow
tx = user_escrow_proxy.functions.lock(100, 1).transact({'from': user})
@ -226,17 +230,22 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
testerchain.wait_for_receipt(tx)
assert 123 == escrow.functions.lockReStakeUntilPeriod().call()
# Test setting worker
tx = user_escrow_proxy.functions.setWorker(user).transact({'from': user})
testerchain.wait_for_receipt(tx)
assert user == escrow.functions.worker().call()
events = locks.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 100 == event_args['value']
assert 1 == event_args['periods']
events = divides.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 1 == event_args['index']
assert 100 == event_args['newValue']
assert 1 == event_args['periods']
@ -244,34 +253,40 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
events = confirms.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
events = mints.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
events = miner_withdraws.get_all_entries()
assert 2 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 1500 == event_args['value']
event_args = events[1]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 1000 == event_args['value']
events = re_stakes.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert event_args['reStake']
events = re_stake_locks.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 123 == event_args['lockUntilPeriod']
events = worker_logs.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['sender']
assert user == event_args['worker']
# User can withdraw reward for mining but no more than locked
with pytest.raises((TransactionFailed, ValueError)):
tx = user_escrow.functions.withdrawTokens(2500).transact({'from': user})
@ -333,7 +348,7 @@ def test_policy(testerchain, policy_manager, user_escrow, user_escrow_proxy):
events = miner_reward.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 10000 == event_args['value']
events = rewards.get_all_entries()
@ -351,5 +366,5 @@ def test_policy(testerchain, policy_manager, user_escrow, user_escrow_proxy):
events = min_reward_sets.get_all_entries()
assert 1 == len(events)
event_args = events[0]['args']
assert user == event_args['owner']
assert user == event_args['sender']
assert 222 == event_args['value']

View File

@ -243,6 +243,13 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
tx = miner_functions.deposit(MIN_ALLOWED_LOCKED * 3, MIN_LOCKED_PERIODS).transact({'from': ursula3})
testerchain.wait_for_receipt(tx)
tx = miner_functions.confirmActivity().transact({'from': ursula1})
testerchain.wait_for_receipt(tx)
tx = miner_functions.confirmActivity().transact({'from': ursula2})
testerchain.wait_for_receipt(tx)
tx = miner_functions.confirmActivity().transact({'from': ursula3})
testerchain.wait_for_receipt(tx)
#
# Wait 1 period and confirm activity
#