From d9663310e200ee5167786dd51571385170c8c508 Mon Sep 17 00:00:00 2001 From: ilgyu Date: Wed, 22 Jan 2025 15:44:58 +0900 Subject: [PATCH 1/2] fix: Block leaving guild while unbonding --- .Lib9c.Tests/Action/Guild/QuitGuildTest.cs | 18 ++++++++++++++++-- .Lib9c.Tests/Action/Guild/RemoveGuildTest.cs | 13 ++++++++++++- Lib9c/Module/Guild/GuildModule.cs | 6 ++++++ Lib9c/Module/Guild/GuildParticipantModule.cs | 6 ++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs b/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs index 79f4231bae..5f5c4a90fe 100644 --- a/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs +++ b/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs @@ -222,12 +222,25 @@ private void ExecuteWithFixture(IQuitGuildFixture fixture) var expectedTotalGG = slashedGG - expectedAgengGG; var expectedTotalShares = totalShare - agentShare; var quitGuild = new QuitGuild(); + + world = EnsureToStake(world, agentAddress, agentNCG.Currency * 50, height++); var actionContext = new ActionContext { PreviousState = world, Signer = agentAddress, BlockIndex = height++, }; + + Assert.Throws(() => world = quitGuild.Execute(actionContext)); + height += ValidatorDelegatee.DefaultUnbondingPeriod; + world = EnsureToReleaseUnbonding(world, agentAddress, height++); + actionContext = new ActionContext + { + PreviousState = world, + Signer = agentAddress, + BlockIndex = height++, + }; + world = quitGuild.Execute(actionContext); var delegatee = new GuildRepository(world, new ActionContext { }).GetDelegatee(validatorKey.Address); world = EnsureToReleaseUnbonding( @@ -241,9 +254,10 @@ private void ExecuteWithFixture(IQuitGuildFixture fixture) Assert.Throws( () => guildRepository.GetGuildParticipant(agentAddress)); - Assert.Equal(expectedTotalGG, guildDelegatee.TotalDelegated); + var comparerGG = new FungibleAssetValueEqualityComparer(GGEpsilon); + Assert.Equal(expectedTotalGG, guildDelegatee.TotalDelegated, comparerGG); Assert.Equal(expectedTotalShares, guildDelegatee.TotalShares); - Assert.Equal(expectedTotalGG, validatorDelegatee.TotalDelegated); + Assert.Equal(expectedTotalGG, validatorDelegatee.TotalDelegated, comparerGG); Assert.Equal(expectedTotalShares, validatorDelegatee.TotalShares); } diff --git a/.Lib9c.Tests/Action/Guild/RemoveGuildTest.cs b/.Lib9c.Tests/Action/Guild/RemoveGuildTest.cs index 9c66c4242c..d349a1301e 100644 --- a/.Lib9c.Tests/Action/Guild/RemoveGuildTest.cs +++ b/.Lib9c.Tests/Action/Guild/RemoveGuildTest.cs @@ -301,7 +301,18 @@ private void ExecuteWithFixture(IRemoveGuildFixture fixture) { PreviousState = world, Signer = masterAddress, - BlockIndex = height, + BlockIndex = height++, + }; + Assert.Throws(() => removeGuild.Execute(actionContext)); + + height += ValidatorDelegatee.DefaultUnbondingPeriod; + world = EnsureToReleaseUnbonding(world, masterAddress, height++); + + actionContext = new ActionContext + { + PreviousState = world, + Signer = masterAddress, + BlockIndex = height++, }; world = removeGuild.Execute(actionContext); diff --git a/Lib9c/Module/Guild/GuildModule.cs b/Lib9c/Module/Guild/GuildModule.cs index 10f8c5b926..851307291e 100644 --- a/Lib9c/Module/Guild/GuildModule.cs +++ b/Lib9c/Module/Guild/GuildModule.cs @@ -103,6 +103,12 @@ public static GuildRepository RemoveGuild( throw new InvalidOperationException("There are remained participants in the guild."); } + if (repository.GetDelegator(signer).UnbondingRefs.Count > 0) + { + throw new InvalidOperationException( + $"The signer cannot remove guild while unbonding"); + } + var delegatee = repository.GetDelegatee(guild.ValidatorAddress); var bond = repository.GetBond(delegatee, signer); if (bond.Share > 0) diff --git a/Lib9c/Module/Guild/GuildParticipantModule.cs b/Lib9c/Module/Guild/GuildParticipantModule.cs index 8d2e6d6fb4..2271353feb 100644 --- a/Lib9c/Module/Guild/GuildParticipantModule.cs +++ b/Lib9c/Module/Guild/GuildParticipantModule.cs @@ -117,6 +117,12 @@ public static GuildRepository LeaveGuild( "The signer is a guild master. Guild master cannot quit the guild."); } + if (repository.GetDelegator(agentAddress).UnbondingRefs.Count > 0) + { + throw new InvalidOperationException( + $"The signer cannot leave guild while unbonding"); + } + var height = repository.ActionContext.BlockIndex; var guildParticipant = repository.GetGuildParticipant(agentAddress); var delegatee = repository.GetDelegatee(guild.ValidatorAddress); From ca04e03997d34b5140d5e6ab8b7f0ffb77574d8f Mon Sep 17 00:00:00 2001 From: ilgyu Date: Wed, 22 Jan 2025 16:01:04 +0900 Subject: [PATCH 2/2] test: Fix QuitGuildTest to cover initial NCG below 50 --- .Lib9c.Tests/Action/Guild/QuitGuildTest.cs | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs b/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs index 5f5c4a90fe..269dc32546 100644 --- a/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs +++ b/.Lib9c.Tests/Action/Guild/QuitGuildTest.cs @@ -223,18 +223,22 @@ private void ExecuteWithFixture(IQuitGuildFixture fixture) var expectedTotalShares = totalShare - agentShare; var quitGuild = new QuitGuild(); - world = EnsureToStake(world, agentAddress, agentNCG.Currency * 50, height++); - var actionContext = new ActionContext + if (agentNCG.MajorUnit > 50) { - PreviousState = world, - Signer = agentAddress, - BlockIndex = height++, - }; + world = EnsureToStake(world, agentAddress, agentNCG.Currency * 50, height++); + var actionContextToThrow = new ActionContext + { + PreviousState = world, + Signer = agentAddress, + BlockIndex = height++, + }; + + Assert.Throws(() => world = quitGuild.Execute(actionContextToThrow)); + height += ValidatorDelegatee.DefaultUnbondingPeriod; + world = EnsureToReleaseUnbonding(world, agentAddress, height++); + } - Assert.Throws(() => world = quitGuild.Execute(actionContext)); - height += ValidatorDelegatee.DefaultUnbondingPeriod; - world = EnsureToReleaseUnbonding(world, agentAddress, height++); - actionContext = new ActionContext + var actionContext = new ActionContext { PreviousState = world, Signer = agentAddress,