Skip to content

Commit

Permalink
Merge pull request #3013 from OnedgeLee/fix/stake
Browse files Browse the repository at this point in the history
Fix stake without guild not to send guild gold
  • Loading branch information
OnedgeLee authored Nov 18, 2024
2 parents cd378f2 + 0ac599d commit 25b1307
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 126 deletions.
5 changes: 3 additions & 2 deletions .Lib9c.Tests/Action/ApprovePledgeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public void Execute(int mead)
public void Execute_JoinGuild(int mead)
{
var address = new PrivateKey().Address;
var validatorKey = new PrivateKey();
var patron = MeadConfig.PatronAddress;
var contractAddress = address.Derive(nameof(RequestPledge));
var guildAddress = AddressUtil.CreateGuildAddress();
Expand All @@ -71,15 +72,15 @@ public void Execute_JoinGuild(int mead)
);

states = DelegationUtil.EnsureValidatorPromotionReady(
states, ValidatorConfig.PlanetariumValidatorPublicKey, 0L);
states, validatorKey.PublicKey, 0L);

states = new GuildRepository(
states,
new ActionContext
{
Signer = GuildConfig.PlanetariumGuildOwner,
})
.MakeGuild(guildAddress, ValidatorConfig.PlanetariumValidatorAddress).World;
.MakeGuild(guildAddress, validatorKey.Address).World;

var action = new ApprovePledge
{
Expand Down
7 changes: 5 additions & 2 deletions .Lib9c.Tests/Action/StakeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,6 @@ public void Execute_Success_When_Exist_StakeStateV3_Without_Guild(
world = world.MintAsset(new ActionContext(), _agentAddr, ncgToStake);
world = world.TransferAsset(
new ActionContext(), _agentAddr, stakeStateAddr, ncgToStake);
world = world.TransferAsset(
new ActionContext(), stakeStateAddr, Addresses.NonValidatorDelegatee, gg);
}

world = world.SetLegacyState(stakeStateAddr, stakeState.Serialize());
Expand Down Expand Up @@ -459,7 +457,12 @@ public void Execute_Success_When_Exist_StakeStateV3_Without_Guild(

var expectedBalance = _ncg * Math.Max(0, previousAmount - amount);
var actualBalance = world.GetBalance(_agentAddr, _ncg);
var nonValidatorDelegateeBalance = world.GetBalance(
Addresses.NonValidatorDelegatee, Currencies.GuildGold);
var stakeBalance = world.GetBalance(stakeStateAddr, Currencies.GuildGold);
Assert.Equal(expectedBalance, actualBalance);
Assert.Equal(Currencies.GuildGold * 0, nonValidatorDelegateeBalance);
Assert.Equal(Currencies.GuildGold * amount, stakeBalance);
}

private IWorld Execute(
Expand Down
12 changes: 6 additions & 6 deletions .Lib9c.Tests/Delegation/DelegatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void Undelegate()
Assert.Equal(unbondLockIn.Address, Assert.Single(unbondingSet.FlattenedUnbondingRefs).Address);
Assert.Equal(2, unbondLockIn.Entries.Count);

unbondLockIn = unbondLockIn.Release(10L + delegatee.UnbondingPeriod - 1);
unbondLockIn = unbondLockIn.Release(10L + delegatee.UnbondingPeriod - 1, out _);
delegatorBalance = repo.World.GetBalance(delegator.Address, delegatee.DelegationCurrency);
delegateeBalance = repo.World.GetBalance(delegatee.DelegationPoolAddress, delegatee.DelegationCurrency);
Assert.Equal(2, unbondLockIn.Entries.Count);
Expand All @@ -162,7 +162,7 @@ public void Undelegate()
Assert.Equal(delegatorInitialBalance - delegatingFAV, delegatorBalance);
Assert.Equal(delegatingFAV, delegateeBalance);

unbondLockIn = unbondLockIn.Release(10L + delegatee.UnbondingPeriod);
unbondLockIn = unbondLockIn.Release(10L + delegatee.UnbondingPeriod, out _);
delegatorBalance = repo.World.GetBalance(delegator.Address, delegatee.DelegationCurrency);
delegateeBalance = repo.World.GetBalance(delegatee.DelegationPoolAddress, delegatee.DelegationCurrency);
entriesByExpireHeight = Assert.Single(unbondLockIn.Entries);
Expand All @@ -175,7 +175,7 @@ public void Undelegate()
Assert.Equal(delegatorInitialBalance - delegatingFAV + undelegatingFAV, delegatorBalance);
Assert.Equal(delegatingFAV - undelegatingFAV, delegateeBalance);

unbondLockIn = unbondLockIn.Release(12L + delegatee.UnbondingPeriod);
unbondLockIn = unbondLockIn.Release(12L + delegatee.UnbondingPeriod, out _);
delegatorBalance = repo.World.GetBalance(delegator.Address, delegatee.DelegationCurrency);
delegateeBalance = repo.World.GetBalance(delegatee.DelegationPoolAddress, delegatee.DelegationCurrency);
Assert.Empty(unbondLockIn.Entries);
Expand Down Expand Up @@ -253,7 +253,7 @@ public void Redelegate()
Assert.Equal(rebondGrace.Address, Assert.Single(unbondingSet.FlattenedUnbondingRefs).Address);
Assert.Equal(2, rebondGrace.Entries.Count);

rebondGrace = rebondGrace.Release(10L + delegatee1.UnbondingPeriod - 1);
rebondGrace = rebondGrace.Release(10L + delegatee1.UnbondingPeriod - 1, out _);
Assert.Equal(2, rebondGrace.Entries.Count);
entriesByExpireHeight = rebondGrace.Entries.ElementAt(0);
Assert.Equal(10L + delegatee1.UnbondingPeriod, entriesByExpireHeight.Key);
Expand All @@ -272,7 +272,7 @@ public void Redelegate()
Assert.Equal(12L, entry.CreationHeight);
Assert.Equal(12L + delegatee1.UnbondingPeriod, entry.ExpireHeight);

rebondGrace = rebondGrace.Release(10L + delegatee1.UnbondingPeriod);
rebondGrace = rebondGrace.Release(10L + delegatee1.UnbondingPeriod, out _);
entriesByExpireHeight = Assert.Single(rebondGrace.Entries);
Assert.Equal(12L + delegatee1.UnbondingPeriod, entriesByExpireHeight.Key);
entry = Assert.Single(entriesByExpireHeight.Value);
Expand All @@ -282,7 +282,7 @@ public void Redelegate()
Assert.Equal(12L, entry.CreationHeight);
Assert.Equal(12L + delegatee1.UnbondingPeriod, entry.ExpireHeight);

rebondGrace = rebondGrace.Release(12L + delegatee1.UnbondingPeriod);
rebondGrace = rebondGrace.Release(12L + delegatee1.UnbondingPeriod, out _);
Assert.Empty(rebondGrace.Entries);
}

Expand Down
3 changes: 1 addition & 2 deletions Lib9c/Action/Guild/Migration/MigratePlanetariumGuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Bencodex.Types;
using Libplanet.Action.State;
using Libplanet.Action;
using Nekoyume.Action.ValidatorDelegation;
using Nekoyume.Model.Guild;
using Nekoyume.Action.Guild.Migration.LegacyModels;
using Lib9c;
Expand Down Expand Up @@ -59,7 +58,7 @@ public override IWorld Execute(IActionContext context)
var guild = new Model.Guild.Guild(
guildAddress,
legacyGuild.GuildMasterAddress,
ValidatorConfig.PlanetariumValidatorAddress,
context.Miner,
repository);
repository.SetGuild(guild);

Expand Down
14 changes: 3 additions & 11 deletions Lib9c/Action/Stake.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Libplanet.Action.State;
using Libplanet.Crypto;
using Libplanet.Types.Assets;
using Nekoyume.Delegation;
using Nekoyume.Exceptions;
using Nekoyume.Extensions;
using Nekoyume.Model.Guild;
Expand All @@ -23,7 +22,6 @@
using Nekoyume.ValidatorDelegation;
using Serilog;
using static Lib9c.SerializeKeys;
using static Nekoyume.Model.WorldInformation;

namespace Nekoyume.Action
{
Expand Down Expand Up @@ -210,12 +208,6 @@ private static IWorld ContractNewStake(
guildParticipant.Delegate(guild, gg, height);
state = guildRepository.World;
}
else
{
state = state
.TransferAsset(context, stakeStateAddr, Addresses.NonValidatorDelegatee, gg);
}

}
else if (additionalBalance.Sign < 0)
{
Expand All @@ -239,15 +231,15 @@ private static IWorld ContractNewStake(
validatorDelegatee.Unbond(validatorDelegator, share, height);

state = validatorRepository.World;

state = state.BurnAsset(context, guildDelegatee.DelegationPoolAddress, gg);
}
else
{
state = state.BurnAsset(context, Addresses.NonValidatorDelegatee, gg);
state = state.BurnAsset(context, stakeStateAddr, gg);
}

state = state.TransferAsset(context, stakeStateAddr, context.Signer, -additionalBalance);
state = state
.TransferAsset(context, stakeStateAddr, context.Signer, -additionalBalance);

// TODO : [GuildMigration] Revive below code when the migration is done.
// if (guildRepository.TryGetGuildParticipant(agentAddress, out var guildParticipant))
Expand Down
36 changes: 18 additions & 18 deletions Lib9c/Action/ValidatorDelegation/ReleaseValidatorUnbondings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,18 @@ public override IWorld Execute(IActionContext context)
var unbondingSet = repository.GetUnbondingSet();
var unbondings = unbondingSet.UnbondingsToRelease(context.BlockIndex);

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

foreach (var unbonding in unbondings)
{
switch (unbonding)
{
case UnbondLockIn unbondLockIn:
{
repository.SetUnbondLockIn(unbondLockIn);
repository.UpdateWorld(
Unstake(repository.World, context, unbondLockIn.DelegatorAddress));
}
unbondLockIn.Release(context.BlockIndex, out var releasedFAV);
repository.SetUnbondLockIn(unbondLockIn);
repository.UpdateWorld(
Unstake(repository.World, context, unbondLockIn, releasedFAV));
break;
case RebondGrace rebondGrace:
rebondGrace.Release(context.BlockIndex, out _);
repository.SetRebondGrace(rebondGrace);
break;
default:
Expand All @@ -72,9 +70,10 @@ public override IWorld Execute(IActionContext context)
return repository.World;
}

private IWorld Unstake(IWorld world, IActionContext context, Address address)
private IWorld Unstake(
IWorld world, IActionContext context, UnbondLockIn unbondLockIn, FungibleAssetValue? releasedFAV)
{
var agentAddress = new AgentAddress(address);
var agentAddress = new AgentAddress(unbondLockIn.DelegatorAddress);
var guildRepository = new GuildRepository(world, context);
var goldCurrency = world.GetGoldCurrency();
if (guildRepository.TryGetGuildParticipant(agentAddress, out var guildParticipant))
Expand All @@ -87,20 +86,21 @@ private IWorld Unstake(IWorld world, IActionContext context, Address address)
var (ncg, _) = ConvertToGoldCurrency(gg, goldCurrency);
world = world.BurnAsset(context, stakeStateAddress, gg);
world = world.TransferAsset(
context, stakeStateAddress, address, ncg);
context, stakeStateAddress, agentAddress, ncg);
}
}
else if (!IsValidator(world, context, address))
else if (!IsValidator(world, context, unbondLockIn.DelegateeAddress))
{
var stakeStateAddress = StakeState.DeriveAddress(address);
var gg = world.GetBalance(stakeStateAddress, Currencies.GuildGold);
if (gg.Sign > 0)
if (releasedFAV is not FungibleAssetValue gg || gg.Sign < 1)
{
var (ncg, _) = ConvertToGoldCurrency(gg, goldCurrency);
world = world.BurnAsset(context, stakeStateAddress, gg);
world = world.TransferAsset(
context, stakeStateAddress, address, ncg);
return world;
}

var stakeStateAddress = StakeState.DeriveAddress(agentAddress);
var (ncg, _) = ConvertToGoldCurrency(gg, goldCurrency);
world = world
.TransferAsset(context, stakeStateAddress, agentAddress, ncg)
.BurnAsset(context, stakeStateAddress, gg);
}

return world;
Expand Down
8 changes: 4 additions & 4 deletions Lib9c/Action/ValidatorDelegation/SlashValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public override IWorld Execute(IActionContext context)
validatorDelegatee.Jail(context.BlockIndex + AbstainJailTime);

var guildRepository = new GuildRepository(repository.World, repository.ActionContext);
var validatorDelegateeForGuildParticipant = guildRepository.GetGuildDelegatee(abstain.Address);
validatorDelegateeForGuildParticipant.Slash(LivenessSlashFactor, context.BlockIndex, context.BlockIndex);
var guildDelegatee = guildRepository.GetGuildDelegatee(abstain.Address);
guildDelegatee.Slash(LivenessSlashFactor, context.BlockIndex, context.BlockIndex);
repository.UpdateWorld(guildRepository.World);
}

Expand All @@ -76,8 +76,8 @@ public override IWorld Execute(IActionContext context)
validatorDelegatee.Tombstone();

var guildRepository = new GuildRepository(repository.World, repository.ActionContext);
var validatorDelegateeForGuildParticipant = guildRepository.GetGuildDelegatee(e.TargetAddress);
validatorDelegateeForGuildParticipant.Slash(DuplicateVoteSlashFactor, e.Height, context.BlockIndex);
var guildDelegatee = guildRepository.GetGuildDelegatee(e.TargetAddress);
guildDelegatee.Slash(DuplicateVoteSlashFactor, e.Height, context.BlockIndex);
repository.UpdateWorld(guildRepository.World);
break;
default:
Expand Down
12 changes: 6 additions & 6 deletions Lib9c/Action/ValidatorDelegation/UpdateValidators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public override IWorld Execute(IActionContext context)
validatorDelegatee.Deactivate();
repository.SetValidatorDelegatee(validatorDelegatee);
var guildRepository = new GuildRepository(repository.World, repository.ActionContext);
var validatorDelegateeForGuildParticipant = guildRepository.GetGuildDelegatee(deactivated);
validatorDelegateeForGuildParticipant.Deactivate();
guildRepository.SetGuildDelgatee(validatorDelegateeForGuildParticipant);
var guildDelegatee = guildRepository.GetGuildDelegatee(deactivated);
guildDelegatee.Deactivate();
guildRepository.SetGuildDelgatee(guildDelegatee);
repository.UpdateWorld(guildRepository.World);
}

Expand All @@ -52,9 +52,9 @@ public override IWorld Execute(IActionContext context)
validatorDelegatee.Activate();
repository.SetValidatorDelegatee(validatorDelegatee);
var guildRepository = new GuildRepository(repository.World, repository.ActionContext);
var validatorDelegateeForGuildParticipant = guildRepository.GetGuildDelegatee(activated);
validatorDelegateeForGuildParticipant.Activate();
guildRepository.SetGuildDelgatee(validatorDelegateeForGuildParticipant);
var guildDelegatee = guildRepository.GetGuildDelegatee(activated);
guildDelegatee.Activate();
guildRepository.SetGuildDelgatee(guildDelegatee);
repository.UpdateWorld(guildRepository.World);
}

Expand Down
13 changes: 0 additions & 13 deletions Lib9c/Action/ValidatorDelegation/ValidatorConfig.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Lib9c/Delegation/IUnbonding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface IUnbonding

bool IsEmpty { get; }

IUnbonding Release(long height);
IUnbonding Release(long height, out FungibleAssetValue? releasedFAV);

IUnbonding Slash(
BigInteger slashFactor,
Expand Down
6 changes: 4 additions & 2 deletions Lib9c/Delegation/RebondGrace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ public List Bencoded

IValue IBencodable.Bencoded => Bencoded;

public RebondGrace Release(long height)
public RebondGrace Release(long height, out FungibleAssetValue? releasedFAV)
{
releasedFAV = null;

if (height <= 0)
{
throw new ArgumentOutOfRangeException(
Expand All @@ -137,7 +139,7 @@ public RebondGrace Release(long height)
return UpdateEntries(updatedEntries);
}

IUnbonding IUnbonding.Release(long height) => Release(height);
IUnbonding IUnbonding.Release(long height, out FungibleAssetValue? releasedFAV) => Release(height, out releasedFAV);

public RebondGrace Slash(
BigInteger slashFactor,
Expand Down
22 changes: 7 additions & 15 deletions Lib9c/Delegation/UnbondLockIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public List Bencoded

IValue IBencodable.Bencoded => Bencoded;

public UnbondLockIn Release(long height)
public UnbondLockIn Release(long height, out FungibleAssetValue? releasedFAV)
{
CannotMutateRelationsWithoutRepository();
if (height <= 0)
Expand All @@ -149,16 +149,16 @@ public UnbondLockIn Release(long height)
}

var updatedEntries = Entries;
FungibleAssetValue? releasingFAV = null;
releasedFAV = null;
foreach (var (expireHeight, entries) in updatedEntries)
{
if (expireHeight <= height)
{
FungibleAssetValue entriesFAV = entries
.Select(e => e.UnbondingFAV)
.Aggregate((accum, next) => accum + next);
releasingFAV = releasingFAV.HasValue
? releasingFAV.Value + entriesFAV
releasedFAV = releasedFAV.HasValue
? releasedFAV.Value + entriesFAV
: entriesFAV;
updatedEntries = updatedEntries.Remove(expireHeight);
}
Expand All @@ -168,7 +168,7 @@ public UnbondLockIn Release(long height)
}
}

if (releasingFAV.HasValue)
if (releasedFAV.HasValue)
{
if (DelegateeAddress != Addresses.NonValidatorDelegatee)
{
Expand All @@ -177,22 +177,14 @@ public UnbondLockIn Release(long height)
_repository!.TransferAsset(
delegateeMetadata.DelegationPoolAddress,
delegatorMetadata.DelegationPoolAddress,
releasingFAV.Value);
}
else
{
var stakeStateAddress = StakeState.DeriveAddress(DelegatorAddress);
_repository!.TransferAsset(
Addresses.NonValidatorDelegatee,
stakeStateAddress,
releasingFAV.Value);
releasedFAV.Value);
}
}

return UpdateEntries(updatedEntries);
}

IUnbonding IUnbonding.Release(long height) => Release(height);
IUnbonding IUnbonding.Release(long height, out FungibleAssetValue? releasedFAV) => Release(height, out releasedFAV);

public UnbondLockIn Slash(
BigInteger slashFactor,
Expand Down
Loading

0 comments on commit 25b1307

Please sign in to comment.