Draft of the slashing method

pull/507/head
szotov 2018-11-13 20:18:55 +03:00
parent 2ef2a8f9b6
commit e24263dbd5
3 changed files with 91 additions and 14 deletions

View File

@ -84,15 +84,17 @@ contract ChallengeOverseer {
// Extract miner's address and check that is real miner
address miner = SignatureVerifier.recover(
SignatureVerifier.hash(_minerPublicKey, hashAlgorithm), _minerPublicKeySignature);
require(escrow.getLockedTokens(miner) > 0); // TODO check that miner can be slashed
// Check that miner can be slashed
uint256 minerValue;
(minerValue,,,) = escrow.minerInfo(miner);
require(minerValue > 0);
// Verify correctness of re-encryption
UmbralDeserializer.Capsule memory capsule = _capsuleBytes.toCapsule();
UmbralDeserializer.CapsuleFrag memory cFrag = _cFragBytes.toCapsuleFrag();
UmbralDeserializer.PreComputedData memory data = _preComputedData.toPreComputedData();
if (!isCapsuleFragCorrect(capsule, cFrag, data)) {
//TODO calculate penalty - depends on how many time was slashed
// escrow.slashMiner(miner, PENALTY);
if (!isCapsuleFragCorrect(
_capsuleBytes.toCapsule(), _cFragBytes.toCapsuleFrag(), _preComputedData.toPreComputedData())) {
// TODO calculate penalty - depends on how many time was slashed
// TODO set reward
escrow.slashMiner(miner, PENALTY, msg.sender, PENALTY);
}
challengedCFrags[challengeHash] = true;
}

View File

@ -114,12 +114,12 @@ contract Issuer is Upgradeable {
)
internal returns (uint256 amount)
{
if (currentSupply1 == totalSupply || currentSupply2 == totalSupply) {
return;
}
uint256 currentSupply = _currentPeriod <= currentMintingPeriod ?
Math.min(currentSupply1, currentSupply2) :
Math.max(currentSupply1, currentSupply2);
if (currentSupply == totalSupply) {
return 0;
}
//totalSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2) -
//currentSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2)
@ -157,6 +157,15 @@ contract Issuer is Upgradeable {
}
}
/**
* @notice Return tokens for future minting
* @param _amount Amount of tokens
**/
function unMint(uint256 _amount) internal {
currentSupply1 = currentSupply1.sub(_amount);
currentSupply2 = currentSupply2.sub(_amount);
}
function verifyState(address _testTarget) public onlyOwner {
require(address(uint160(delegateGet(_testTarget, "token()"))) == address(token));
require(delegateGet(_testTarget, "miningCoefficient()") == miningCoefficient);

View File

@ -710,6 +710,8 @@ contract MinersEscrow is Issuer {
}
}
uint16 constant MAX_PERIOD = 65535;
// TODO complete
function slashMiner(
address _miner,
@ -720,10 +722,13 @@ contract MinersEscrow is Issuer {
public
{
require(msg.sender == address(challengeOverseer));
require(_penalty > 0);
MinerInfo storage info = minerInfo[_miner];
//TODO maybe raise error
if (info.value < _penalty) {
_penalty = info.value;
//clear or remove all sub stakes
info.subStakes.length = 0;
}
info.value -= _penalty;
//TODO maybe raise error
@ -731,10 +736,71 @@ contract MinersEscrow is Issuer {
_reward = _penalty;
}
//choose short stake
//decrease stake(s)
//refresh values in Issuer
token.safeTransfer(_investigator, _reward);
// decrease sub stakes
if (info.subStakes.length > 0) {
uint16 currentPeriod = getCurrentPeriod();
uint16 startPeriod = getStartPeriod(info, startPeriod);
uint256 lockedTokens = getLockedTokens(_miner);
if (info.value < lockedTokens) {
slashMiner(info, lockedTokens - info.value, currentPeriod, startPeriod, false);
}
lockedTokens = getLockedTokens(_miner, 1);
if (info.value < lockedTokens) {
slashMiner(info, lockedTokens - info.value, currentPeriod.add16(1), startPeriod, false);
}
}
unMint(_penalty - _reward);
if (_reward > 0) {
token.safeTransfer(_investigator, _reward);
}
}
// TODO complete
function slashMiner(
MinerInfo storage _info,
uint256 _penalty,
uint16 _period,
uint16 _startPeriod,
bool _strict
)
internal
{
while(_penalty > 0) {
uint16 minSubStakeLastPeriod = MAX_PERIOD; //TODO
for (uint256 i = 0; i < _info.subStakes.length; i++) {
SubStakeInfo storage subStake = _info.subStakes[i];
uint16 lastPeriod = getLastPeriodOfSubStake(subStake, _startPeriod);
if ((_strict && subStake.firstPeriod == _period ||
!_strict && subStake.firstPeriod <= _period) &&
lastPeriod >= _period &&
lastPeriod < minSubStakeLastPeriod)
{
SubStakeInfo storage shortestSubStake = subStake;
minSubStakeLastPeriod = lastPeriod;
}
}
if (minSubStakeLastPeriod == MAX_PERIOD) {
break;
}
uint256 appliedPenalty = _penalty;
if (_penalty < shortestSubStake.lockedValue) {
shortestSubStake.lockedValue -= _penalty;
_penalty = 0;
} else {
shortestSubStake.lastPeriod = 1;
_penalty -= shortestSubStake.lockedValue;
appliedPenalty = shortestSubStake.lockedValue;
}
if (_info.confirmedPeriod1 >= _period &&
_info.confirmedPeriod1 <= lastPeriod) {
lockedPerPeriod[_info.confirmedPeriod1] -= appliedPenalty;
}
if (_info.confirmedPeriod2 >= _period &&
_info.confirmedPeriod2 <= lastPeriod) {
lockedPerPeriod[_info.confirmedPeriod2] -= appliedPenalty;
}
}
}
//-------------Additional getters for miners info-------------