Skip to content

Commit

Permalink
fix: Fix bugs on delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
OnedgeLee committed Oct 4, 2024
1 parent b300492 commit e87f69a
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 71 deletions.
1 change: 1 addition & 0 deletions .Lib9c.Tests/Delegation/DummyDelegatee.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public DummyDelegatee(Address address, Address accountAddress, DummyRepository r
DelegationFixture.TestCurrency,
address,
DelegationFixture.FixedPoolAddress,
DelegationFixture.FixedPoolAddress,
3,
5,
5,
Expand Down
1 change: 1 addition & 0 deletions .Lib9c.Tests/Delegation/TestDelegatee.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public TestDelegatee(Address address, Address accountAddress, TestRepository rep
DelegationFixture.TestCurrency,
address,
DelegationFixture.FixedPoolAddress,
DelegationFixture.FixedPoolAddress,
3,
5,
5,
Expand Down
23 changes: 21 additions & 2 deletions Lib9c/Action/ValidatorDelegation/ReleaseValidatorUnbondings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
using Libplanet.Action;
using Libplanet.Crypto;
using Nekoyume.ValidatorDelegation;
using Nekoyume.Delegation;
using System;
using System.Linq;
using System.Collections.Immutable;

namespace Nekoyume.Action.ValidatorDelegation
{
Expand All @@ -26,13 +30,28 @@ public override IWorld Execute(IActionContext context)

var world = context.PreviousState;
var repository = new ValidatorRepository(world, context);
var unbondings = repository.GetUnbondingSet().UnbondingsToRelease(context.BlockIndex);
var unbondingSet = repository.GetUnbondingSet();
var unbondings = unbondingSet.UnbondingsToRelease(context.BlockIndex);

unbondings = unbondings.Select(unbonding => unbonding.Release(context.BlockIndex)).ToImmutableArray();

foreach (var unbonding in unbondings)
{
unbonding.Release(context.BlockIndex);
switch (unbonding)
{
case UnbondLockIn unbondLockIn:
repository.SetUnbondLockIn(unbondLockIn);
break;
case RebondGrace rebondGrace:
repository.SetRebondGrace(rebondGrace);
break;
default:
throw new InvalidOperationException("Invalid unbonding type.");
}
}

repository.SetUnbondingSet(unbondingSet.SetUnbondings(unbondings));

return repository.World;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Lib9c/Action/ValidatorDelegation/SlashValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override IWorld Execute(IActionContext context)
{
var validatorDelegatee = repository.GetValidatorDelegatee(abstain.Address);
validatorDelegatee.Slash(LivenessSlashFactor, context.BlockIndex, context.BlockIndex);
validatorDelegatee.Jail(context.BlockIndex + AbstainJailTime, context.BlockIndex);
validatorDelegatee.Jail(context.BlockIndex + AbstainJailTime);
}

foreach (var evidence in context.Evidence)
Expand Down
69 changes: 51 additions & 18 deletions Lib9c/Delegation/Delegatee.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public Delegatee(
Currency rewardCurrency,
Address delegationPoolAddress,
Address rewardRemainderPoolAddress,
Address slashedPoolAddress,
long unbondingPeriod,
int maxUnbondLockInEntries,
int maxRebondGraceEntries,
Expand All @@ -32,6 +33,7 @@ public Delegatee(
rewardCurrency,
delegationPoolAddress,
rewardRemainderPoolAddress,
slashedPoolAddress,
unbondingPeriod,
maxUnbondLockInEntries,
maxRebondGraceEntries),
Expand All @@ -54,9 +56,9 @@ private Delegatee(DelegateeMetadata metadata, IDelegationRepository repository)

public event EventHandler<long>? DelegationChanged;

public event EventHandler<long>? Enjailed;
public event EventHandler? Enjailed;

public event EventHandler<long>? Unjailed;
public event EventHandler? Unjailed;

public DelegateeMetadata Metadata { get; }

Expand All @@ -76,6 +78,8 @@ private Delegatee(DelegateeMetadata metadata, IDelegationRepository repository)

public Address RewardRemainderPoolAddress => Metadata.RewardRemainderPoolAddress;

public Address SlashedPoolAddress => Metadata.SlashedPoolAddress;

public long UnbondingPeriod => Metadata.UnbondingPeriod;

public int MaxUnbondLockInEntries => Metadata.MaxUnbondLockInEntries;
Expand Down Expand Up @@ -113,23 +117,41 @@ public FungibleAssetValue Unbond(IDelegator delegator, BigInteger share, long he
public void DistributeReward(IDelegator delegator, long height)
=> DistributeReward((T)delegator, height);

public void Jail(long releaseHeight, long height)
public void Jail(long releaseHeight)
{
Metadata.JailUntil(releaseHeight);
Metadata.JailedUntil = releaseHeight;
Metadata.Jailed = true;
Repository.SetDelegateeMetadata(Metadata);
Enjailed?.Invoke(this, height);
Enjailed?.Invoke(this, EventArgs.Empty);
}

public void Unjail(long height)
{
Metadata.Unjail(height);
if (!Jailed)
{
throw new InvalidOperationException("Cannot unjail non-jailed delegatee.");
}

if (Tombstoned)
{
throw new InvalidOperationException("Cannot unjail tombstoned delegatee.");
}

if (JailedUntil >= height)
{
throw new InvalidOperationException("Cannot unjail before jailed until.");
}

Metadata.JailedUntil = -1L;
Metadata.Jailed = false;
Repository.SetDelegateeMetadata(Metadata);
Unjailed?.Invoke(this, height);
Unjailed?.Invoke(this, EventArgs.Empty);
}

public void Tombstone()
{
Metadata.Tombstone();
Jail(long.MaxValue);
Metadata.Tombstoned = true;
Repository.SetDelegateeMetadata(Metadata);
}

Expand Down Expand Up @@ -277,13 +299,30 @@ public void CollectRewards(long height)
Delegators,
RewardCurrency);
record = record.AddLumpSumRewards(rewards);
Repository.TransferAsset(RewardPoolAddress, record.Address, rewards);

if (rewards.Sign > 0)
{
Repository.TransferAsset(RewardPoolAddress, record.Address, rewards);
}

Repository.SetLumpSumRewardsRecord(record);
}

public void Slash(BigInteger slashFactor, long infractionHeight, long height)
{
FungibleAssetValue? fav = null;
FungibleAssetValue slashed = TotalDelegated.DivRem(slashFactor, out var rem);
if (rem.Sign > 0)
{
slashed += FungibleAssetValue.FromRawValue(rem.Currency, 1);
}

if (slashed > Metadata.TotalDelegatedFAV)
{
slashed = Metadata.TotalDelegatedFAV;
}

Metadata.RemoveDelegatedFAV(slashed);

foreach (var item in Metadata.UnbondingRefs)
{
var unbonding = UnbondingFactory.GetUnbondingFromRef(item, Repository);
Expand All @@ -292,9 +331,7 @@ public void Slash(BigInteger slashFactor, long infractionHeight, long height)

if (slashedFAV.HasValue)
{
fav = fav.HasValue
? fav.Value + slashedFAV.Value
: slashedFAV.Value;
slashed += slashedFAV.Value;
}

if (unbonding.IsEmpty)
Expand All @@ -315,11 +352,7 @@ public void Slash(BigInteger slashFactor, long infractionHeight, long height)
}
}

if (fav.HasValue)
{
Metadata.RemoveDelegatedFAV(fav.Value);
}

Repository.TransferAsset(DelegationPoolAddress, SlashedPoolAddress, slashed);
Repository.SetDelegateeMetadata(Metadata);
DelegationChanged?.Invoke(this, height);
}
Expand Down
63 changes: 19 additions & 44 deletions Lib9c/Delegation/DelegateeMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public DelegateeMetadata(
Currency rewardCurrency,
Address delegationPoolAddress,
Address rewardRemainderPoolAddress,
Address slashedPoolAddress,
long unbondingPeriod,
int maxUnbondLockInEntries,
int maxRebondGraceEntries)
Expand All @@ -32,6 +33,7 @@ public DelegateeMetadata(
rewardCurrency,
delegationPoolAddress,
rewardRemainderPoolAddress,
slashedPoolAddress,
unbondingPeriod,
maxUnbondLockInEntries,
maxRebondGraceEntries,
Expand Down Expand Up @@ -64,16 +66,17 @@ public DelegateeMetadata(
new Currency(bencoded[1]),
new Address(bencoded[2]),
new Address(bencoded[3]),
(Integer)bencoded[4],
new Address(bencoded[4]),
(Integer)bencoded[5],
(Integer)bencoded[6],
((List)bencoded[7]).Select(item => new Address(item)),
new FungibleAssetValue(bencoded[8]),
(Integer)bencoded[9],
(Bencodex.Types.Boolean)bencoded[10],
(Integer)bencoded[11],
(Bencodex.Types.Boolean)bencoded[12],
((List)bencoded[13]).Select(item => new UnbondingRef(item)))
(Integer)bencoded[7],
((List)bencoded[8]).Select(item => new Address(item)),
new FungibleAssetValue(bencoded[9]),
(Integer)bencoded[10],
(Bencodex.Types.Boolean)bencoded[11],
(Integer)bencoded[12],
(Bencodex.Types.Boolean)bencoded[13],
((List)bencoded[14]).Select(item => new UnbondingRef(item)))
{
}

Expand All @@ -84,6 +87,7 @@ private DelegateeMetadata(
Currency rewardCurrency,
Address delegationPoolAddress,
Address rewardRemainderPoolAddress,
Address slashedPoolAddress,
long unbondingPeriod,
int maxUnbondLockInEntries,
int maxRebondGraceEntries,
Expand Down Expand Up @@ -122,6 +126,7 @@ private DelegateeMetadata(
RewardCurrency = rewardCurrency;
DelegationPoolAddress = delegationPoolAddress;
RewardRemainderPoolAddress = rewardRemainderPoolAddress;
SlashedPoolAddress = slashedPoolAddress;
UnbondingPeriod = unbondingPeriod;
MaxUnbondLockInEntries = maxUnbondLockInEntries;
MaxRebondGraceEntries = maxRebondGraceEntries;
Expand Down Expand Up @@ -151,6 +156,8 @@ public Address Address

public Address RewardRemainderPoolAddress { get; }

public Address SlashedPoolAddress { get; }

public long UnbondingPeriod { get; }

public int MaxUnbondLockInEntries { get; }
Expand All @@ -166,11 +173,11 @@ public Address RewardPoolAddress

public BigInteger TotalShares { get; private set; }

public bool Jailed { get; private set; }
public bool Jailed { get; internal set; }

public long JailedUntil { get; private set; }
public long JailedUntil { get; internal set; }

public bool Tombstoned { get; private set; }
public bool Tombstoned { get; internal set; }

public ImmutableSortedSet<UnbondingRef> UnbondingRefs { get; private set; }

Expand Down Expand Up @@ -232,39 +239,6 @@ public void RemoveShare(BigInteger share)
TotalShares -= share;
}

public void JailUntil(long height)
{
JailedUntil = height;
Jailed = true;
}

public void Unjail(long height)
{
if (!Jailed)
{
throw new InvalidOperationException("Cannot unjail non-jailed delegatee.");
}

if (Tombstoned)
{
throw new InvalidOperationException("Cannot unjail tombstoned delegatee.");
}

if (JailedUntil >= height)
{
throw new InvalidOperationException("Cannot unjail before jailed until.");
}

JailedUntil = -1L;
Jailed = false;
}

public void Tombstone()
{
JailUntil(long.MaxValue);
Tombstoned = true;
}

public void AddUnbondingRef(UnbondingRef unbondingRef)
{
UnbondingRefs = UnbondingRefs.Add(unbondingRef);
Expand Down Expand Up @@ -303,6 +277,7 @@ public virtual bool Equals(IDelegateeMetadata? other)
&& RewardCurrency.Equals(delegatee.RewardCurrency)
&& DelegationPoolAddress.Equals(delegatee.DelegationPoolAddress)
&& RewardRemainderPoolAddress.Equals(delegatee.RewardRemainderPoolAddress)
&& SlashedPoolAddress.Equals(delegatee.SlashedPoolAddress)
&& UnbondingPeriod == delegatee.UnbondingPeriod
&& RewardPoolAddress.Equals(delegatee.RewardPoolAddress)
&& Delegators.SequenceEqual(delegatee.Delegators)
Expand Down
2 changes: 1 addition & 1 deletion Lib9c/Delegation/IDelegatee.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public interface IDelegatee

void Slash(BigInteger slashFactor, long infractionHeight, long height);

void Jail(long releaseHeight, long height);
void Jail(long releaseHeight);

void Unjail(long height);

Expand Down
7 changes: 6 additions & 1 deletion Lib9c/Delegation/UnbondingEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,12 @@ public UnbondingEntry Slash(
"The infraction height must be between in creation height and expire height of entry.");
}

var favToSlash = InitialUnbondingFAV.DivRem(slashFactor).Quotient;
var favToSlash = InitialUnbondingFAV.DivRem(slashFactor, out var rem);
if (rem.Sign > 0)
{
favToSlash += FungibleAssetValue.FromRawValue(rem.Currency, 1);
}

slashedFAV = favToSlash < UnbondingFAV
? favToSlash
: UnbondingFAV;
Expand Down
1 change: 1 addition & 0 deletions Lib9c/Model/Guild/Guild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public Guild(
rewardCurrency: rewardCurrency,
delegationPoolAddress: address,
rewardRemainderPoolAddress: Addresses.CommunityPool,
slashedPoolAddress: Addresses.CommunityPool,
unbondingPeriod: 75600L,
maxUnbondLockInEntries: 10,
maxRebondGraceEntries: 10,
Expand Down
Loading

0 comments on commit e87f69a

Please sign in to comment.