Skip to content

Commit

Permalink
feat: Add slashing-related code.
Browse files Browse the repository at this point in the history
  • Loading branch information
s2quake committed Apr 9, 2024
1 parent 06b38a2 commit 9e8f7d5
Show file tree
Hide file tree
Showing 20 changed files with 1,108 additions and 23 deletions.
7 changes: 7 additions & 0 deletions Lib9c/Action/DPoS/Control/DelegateCtrl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ internal static class DelegateCtrl
return null;
}

internal static Delegation? GetDelegation(IWorldState states, Address delegatorAddress, Address validatorAddress)
{
Address delegationAddress = Delegation.DeriveAddress(
delegatorAddress, validatorAddress);
return GetDelegation(states, delegationAddress);
}

internal static (IWorld, Delegation) FetchDelegation(
IWorld states,
Address delegatorAddress,
Expand Down
30 changes: 30 additions & 0 deletions Lib9c/Action/DPoS/Control/Environment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Numerics;

namespace Nekoyume.Action.DPoS.Control
{
public static class Environment
{
public const long SignedBlocksWindow = 10000;

public const double MinSignedPerWindow = 0.5;

public static readonly TimeSpan DowntimeJailDuration = TimeSpan.FromSeconds(60);

public static readonly BigInteger SlashFractionDoubleSign = new BigInteger(20); // 0.05

public static readonly BigInteger SlashFractionDowntime = new BigInteger(10000); // 0.0001

public const long ValidatorUpdateDelay = 1;

public const long MaxAgeNumBlocks = 100000;

public static readonly TimeSpan MaxAgeDuration = TimeSpan.FromSeconds(172800); // s (즉, 48시간)

public const long MaxBytes = 1048576; // (즉, 1MB)

public static readonly DateTimeOffset DoubleSignJailEndTime = DateTimeOffset.FromUnixTimeSeconds(253402300799);

public const int MissedBlockBitmapChunkSize = 1024;
}
}
97 changes: 97 additions & 0 deletions Lib9c/Action/DPoS/Control/EvidenceCtrl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#nullable enable
using Nekoyume.Action.DPoS.Exception;
using Nekoyume.Action.DPoS.Model;
using Libplanet.Action;
using Libplanet.Action.State;
using Libplanet.Crypto;
using System.Collections.Immutable;
using Libplanet.Types.Assets;

namespace Nekoyume.Action.DPoS.Control
{
internal static class EvidenceCtrl
{
internal static Evidence? GetEvidence(IWorldState states, Address validatorAddress)
{
var address = Evidence.DeriveAddress(validatorAddress);
if (states.GetDPoSState(address) is { } value)
{
return new Evidence(value);
}

return null;
}

internal static IWorld SetEvidence(IWorld world, Evidence evidence)
{
var address = Evidence.DeriveAddress(evidence.Address);
var value = evidence.Serialize();
return world.SetDPoSState(address, value);
}

internal static IWorld Remove(IWorld world, Evidence evidence)
{
var address = Evidence.DeriveAddress(evidence.Address);
return world.RemoveDPoSState(address);
}

internal static IWorld Execute(
IWorld world,
IActionContext actionContext,
Address validatorAddress,
Evidence evidence,
IImmutableSet<Currency> nativeTokens)
{
if (!(ValidatorCtrl.GetValidator(world, validatorAddress) is { } validator))
{
throw new NullValidatorException(validatorAddress);
}

if (validator.Status == BondingStatus.Unbonded)
{
return world;
}

var blockHeight = actionContext.BlockIndex;
var infractionHeight = evidence.Height;
var ageBlocks = blockHeight - infractionHeight;

if (ageBlocks > Environment.MaxAgeNumBlocks)
{
return world;
}

if (ValidatorCtrl.IsTombstoned(world, validatorAddress))
{
return world;
}

var distributionHeight = infractionHeight - Environment.ValidatorUpdateDelay;
var slashFractionDoubleSign = Environment.SlashFractionDoubleSign;

world = SlashCtrl.SlashWithInfractionReason(
world,
actionContext,
validatorAddress,
distributionHeight,
evidence.Power,
slashFractionDoubleSign,
Infraction.DoubleSign,
nativeTokens
);

if (!validator.Jailed)
{
world = ValidatorCtrl.Jail(world, validatorAddress);
}

world = ValidatorCtrl.JailUntil(
world: world,
validatorAddress: validatorAddress,
blockHeight: long.MaxValue);
world = ValidatorCtrl.Tombstone(world, validatorAddress);
world = Remove(world, evidence);
return world;
}
}
}
41 changes: 40 additions & 1 deletion Lib9c/Action/DPoS/Control/RedelegateCtrl.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Bencodex.Types;
Expand All @@ -9,7 +10,6 @@
using Nekoyume.Action.DPoS.Exception;
using Nekoyume.Action.DPoS.Misc;
using Nekoyume.Action.DPoS.Model;
using Nekoyume.Action.DPoS.Util;
using Nekoyume.Module;

namespace Nekoyume.Action.DPoS.Control
Expand All @@ -28,6 +28,45 @@ internal static class RedelegateCtrl
return null;
}

internal static Redelegation? GetRedelegation(
IWorldState states,
Address delegatorAddress, Address srcValidatorAddress, Address dstValidatorAddress)
{
Address redelegationAddress = Redelegation.DeriveAddress(
delegatorAddress, srcValidatorAddress, dstValidatorAddress);
return GetRedelegation(states, redelegationAddress);
}

internal static Redelegation[] GetRedelegationsByDelegator(IWorldState worldState, Address delegatorAddress)
{
var redelegationList = new List<Redelegation>();
var unbondingSet = UnbondingSetCtrl.GetUnbondingSet(worldState)!;
foreach (var item in unbondingSet.RedelegationAddressSet)
{
if (GetRedelegation(worldState, item) is not { } redelegation)
{
throw new InvalidOperationException("undelegation is null.");
}

if (redelegation.DelegatorAddress.Equals(delegatorAddress))
{
redelegationList.Add(redelegation);
}
}

return redelegationList.ToArray();
}

internal static RedelegationEntry? GetRedelegationEntry(IWorldState worldState, Address redelegationEntryAddress)
{
if (worldState.GetDPoSState(redelegationEntryAddress) is { } value)
{
return new RedelegationEntry(value);
}

return null;
}

internal static (IWorld, Redelegation) FetchRedelegation(
IWorld states,
Address delegatorAddress,
Expand Down
Loading

0 comments on commit 9e8f7d5

Please sign in to comment.