diff --git a/Lib9c/Action/Guild/BanGuildMember.cs b/Lib9c/Action/Guild/BanGuildMember.cs index 79574ad0ac..5a39e98097 100644 --- a/Lib9c/Action/Guild/BanGuildMember.cs +++ b/Lib9c/Action/Guild/BanGuildMember.cs @@ -52,12 +52,7 @@ public override IWorld Execute(IActionContext context) var repository = new GuildRepository(world, context); var signer = context.GetAgentAddress(); - if (repository.GetJoinedGuild(signer) is not { } guildAddress) - { - throw new InvalidOperationException("The signer does not have a guild."); - } - - repository.Ban(guildAddress, signer, Target); + repository.Ban(signer, Target); return repository.World; } diff --git a/Lib9c/Action/Guild/RemoveGuild.cs b/Lib9c/Action/Guild/RemoveGuild.cs index 68553df99c..7ebc29bed0 100644 --- a/Lib9c/Action/Guild/RemoveGuild.cs +++ b/Lib9c/Action/Guild/RemoveGuild.cs @@ -38,7 +38,6 @@ public override IWorld Execute(IActionContext context) var world = context.PreviousState; var repository = new GuildRepository(world, context); - // TODO: Do something to return 'Power' token; repository.RemoveGuild(); return repository.World; } diff --git a/Lib9c/Action/Guild/UnbanGuildMember.cs b/Lib9c/Action/Guild/UnbanGuildMember.cs index a91c59f00a..13d8168634 100644 --- a/Lib9c/Action/Guild/UnbanGuildMember.cs +++ b/Lib9c/Action/Guild/UnbanGuildMember.cs @@ -53,12 +53,7 @@ public override IWorld Execute(IActionContext context) var repository = new GuildRepository(world, context); var signer = context.GetAgentAddress(); - if (repository.GetJoinedGuild(signer) is not { } guildAddress) - { - throw new InvalidOperationException("The signer does not join any guild."); - } - - repository.Unban(guildAddress, signer, Target); + repository.Unban(signer, Target); return repository.World; } } diff --git a/Lib9c/Model/Guild/GuildRejoinCooldown.cs b/Lib9c/Model/Guild/GuildRejoinCooldown.cs index 18c512453f..93b203c193 100644 --- a/Lib9c/Model/Guild/GuildRejoinCooldown.cs +++ b/Lib9c/Model/Guild/GuildRejoinCooldown.cs @@ -9,10 +9,12 @@ namespace Nekoyume.Model.Guild { public class GuildRejoinCooldown : IBencodable, IEquatable { + public static readonly long CooldownPeriod = ValidatorDelegatee.ValidatorUnbondingPeriod; + public GuildRejoinCooldown(AgentAddress agentAddress, long quitHeight) { AgentAddress = agentAddress; - ReleaseHeight = quitHeight + ValidatorDelegatee.ValidatorUnbondingPeriod; + ReleaseHeight = quitHeight + CooldownPeriod; } public GuildRejoinCooldown(AgentAddress agentAddress, IValue bencoded) diff --git a/Lib9c/Module/Guild/GuildBanModule.cs b/Lib9c/Module/Guild/GuildBanModule.cs index 810fb02fd8..c2dd1795d1 100644 --- a/Lib9c/Module/Guild/GuildBanModule.cs +++ b/Lib9c/Module/Guild/GuildBanModule.cs @@ -30,10 +30,14 @@ public static bool IsBanned(this GuildRepository repository, GuildAddress guildA public static void Ban( this GuildRepository repository, - GuildAddress guildAddress, AgentAddress signer, AgentAddress target) { + if (repository.GetJoinedGuild(signer) is not { } guildAddress) + { + throw new InvalidOperationException("The signer does not have a guild."); + } + if (!repository.TryGetGuild(guildAddress, out var guild)) { throw new InvalidOperationException("There is no such guild."); @@ -60,8 +64,13 @@ public static void Ban( account => account.SetState(target, (Boolean)true))); } - public static void Unban(this GuildRepository repository, GuildAddress guildAddress, AgentAddress signer, Address target) + public static void Unban(this GuildRepository repository, AgentAddress signer, Address target) { + if (repository.GetJoinedGuild(signer) is not { } guildAddress) + { + throw new InvalidOperationException("The signer does not join any guild."); + } + if (!repository.TryGetGuild(guildAddress, out var guild)) { throw new InvalidOperationException("There is no such guild."); diff --git a/Lib9c/Module/Guild/GuildModule.cs b/Lib9c/Module/Guild/GuildModule.cs index 3b57b1d238..34f1a85c32 100644 --- a/Lib9c/Module/Guild/GuildModule.cs +++ b/Lib9c/Module/Guild/GuildModule.cs @@ -39,8 +39,8 @@ public static GuildRepository MakeGuild( GuildAddress guildAddress, Address validatorAddress) { - var signer = new AgentAddress(repository.ActionContext.Signer); - if (repository.GetJoinedGuild(signer) is not null) + var signer = repository.ActionContext.Signer; + if (repository.GetJoinedGuild(new AgentAddress(signer)) is not null) { throw new InvalidOperationException("The signer already has a guild."); } @@ -56,9 +56,16 @@ public static GuildRepository MakeGuild( throw new InvalidOperationException("The validator does not exist."); } - var guild = new Model.Guild.Guild(guildAddress, signer, validatorAddress, repository); + if (validatorRepository.TryGetValidatorDelegatee(signer, out var _)) + { + throw new InvalidOperationException("Validator cannot make a guild."); + } + + var guildMasterAddress = new AgentAddress(signer); + var guild = new Model.Guild.Guild( + guildAddress, guildMasterAddress, validatorAddress, repository); repository.SetGuild(guild); - repository.JoinGuild(guildAddress, signer); + repository.JoinGuild(guildAddress, guildMasterAddress); return repository; } @@ -89,7 +96,7 @@ public static GuildRepository RemoveGuild( var validatorRepository = new ValidatorRepository(repository.World, repository.ActionContext); var validatorDelegatee = validatorRepository.GetValidatorDelegatee(guild.ValidatorAddress); - var bond = validatorRepository.GetBond(validatorDelegatee, signer); + var bond = validatorRepository.GetBond(validatorDelegatee, guild.Address); if (bond.Share > 0) { throw new InvalidOperationException("The signer has a bond with the validator."); diff --git a/Lib9c/Module/Guild/GuildParticipantModule.cs b/Lib9c/Module/Guild/GuildParticipantModule.cs index 95211584d4..179fc9d02d 100644 --- a/Lib9c/Module/Guild/GuildParticipantModule.cs +++ b/Lib9c/Module/Guild/GuildParticipantModule.cs @@ -6,6 +6,7 @@ using Lib9c; using Libplanet.Types.Assets; using Nekoyume.Model.Guild; +using Nekoyume.Module.ValidatorDelegation; using Nekoyume.TypedAddress; using Nekoyume.ValidatorDelegation; @@ -27,9 +28,11 @@ public static GuildRepository JoinGuild( GuildAddress guildAddress, AgentAddress target) { + var height = repository.ActionContext.BlockIndex; + var signer = repository.ActionContext.Signer; if (repository.TryGetGuildParticipant(target, out _)) { - throw new ArgumentException("The signer already joined a guild."); + throw new InvalidOperationException("The signer already joined a guild."); } if (repository.GetGuildRejoinCooldown(target) is { } cooldown @@ -39,13 +42,20 @@ public static GuildRepository JoinGuild( $"The signer is in the rejoin cooldown period until block {cooldown.ReleaseHeight}"); } + var validatorRepository = new ValidatorRepository(repository.World, repository.ActionContext); + if (validatorRepository.TryGetValidatorDelegatee(signer, out var _)) + { + throw new InvalidOperationException("Validator cannot join a guild."); + } + var guildParticipant = new GuildParticipant(target, guildAddress, repository); var guildGold = repository.GetBalance(guildParticipant.DelegationPoolAddress, Currencies.GuildGold); + var guild = repository.GetGuild(guildAddress); repository.SetGuildParticipant(guildParticipant); repository.IncreaseGuildMemberCount(guildAddress); if (guildGold.RawValue > 0) { - repository.Delegate(target, guildGold); + guildParticipant.Delegate(guild, guildGold, height); } return repository; @@ -56,6 +66,7 @@ public static GuildRepository MoveGuild( AgentAddress guildParticipantAddress, GuildAddress dstGuildAddress) { + var height = repository.ActionContext.BlockIndex; var guildParticipant1 = repository.GetGuildParticipant(guildParticipantAddress); var srcGuild = repository.GetGuild(guildParticipant1.GuildAddress); var dstGuild = repository.GetGuild(dstGuildAddress); @@ -68,14 +79,15 @@ public static GuildRepository MoveGuild( } var guildParticipant2 = new GuildParticipant(guildParticipantAddress, dstGuildAddress, repository); - var bond = validatorRepository.GetBond(srcValidatorDelegatee, guildParticipantAddress); + var bond = validatorRepository.GetBond(srcValidatorDelegatee, srcGuild.Address); + var share = bond.Share; repository.RemoveGuildParticipant(guildParticipantAddress); repository.DecreaseGuildMemberCount(guildParticipant1.GuildAddress); repository.SetGuildParticipant(guildParticipant2); repository.IncreaseGuildMemberCount(dstGuildAddress); - if (bond.Share > 0) + if (share > 0) { - repository.Redelegate(guildParticipantAddress, dstGuildAddress); + guildParticipant1.Redelegate(srcGuild, dstGuild, share, height); } return repository; @@ -102,17 +114,21 @@ public static GuildRepository LeaveGuild( "The signer is a guild master. Guild master cannot quit the guild."); } + var height = repository.ActionContext.BlockIndex; + var guildParticipant = repository.GetGuildParticipant(agentAddress); var validatorRepository = new ValidatorRepository(repository.World, repository.ActionContext); var validatorDelegatee = validatorRepository.GetValidatorDelegatee(guild.ValidatorAddress); - var bond = validatorRepository.GetBond(validatorDelegatee, agentAddress); + var bond = validatorRepository.GetBond(validatorDelegatee, guild.Address); + var share = bond.Share; - repository.RemoveGuildParticipant(agentAddress); - repository.DecreaseGuildMemberCount(guild.Address); if (bond.Share > 0) { - repository.Undelegate(agentAddress); + guildParticipant.Undelegate(guild, share, height); } + repository.RemoveGuildParticipant(agentAddress); + repository.DecreaseGuildMemberCount(guild.Address); + repository.SetGuildRejoinCooldown(agentAddress, repository.ActionContext.BlockIndex); return repository; @@ -135,67 +151,6 @@ public static bool TryGetGuildParticipant( } } - // TODO: Hide this method as private after migration. - public static GuildRepository Delegate( - this GuildRepository repository, - AgentAddress guildParticipantAddress, - FungibleAssetValue fav) - { - var height = repository.ActionContext.BlockIndex; - var guildParticipant = repository.GetGuildParticipant(guildParticipantAddress); - var guild = repository.GetGuild(guildParticipant.GuildAddress); - guildParticipant.Delegate(guild, fav, height); - - return repository; - } - - private static GuildRepository Undelegate( - this GuildRepository repository, - AgentAddress guildParticipantAddress) - { - var height = repository.ActionContext.BlockIndex; - var guildParticipant = repository.GetGuildParticipant(guildParticipantAddress); - var guild = repository.GetGuild(guildParticipant.GuildAddress); - var share = repository.GetBond( - new ValidatorRepository(repository.World, repository.ActionContext) - .GetValidatorDelegatee(guild.ValidatorAddress), - guildParticipantAddress).Share; - guildParticipant.Undelegate(guild, share, height); - - return repository; - } - - private static GuildRepository Undelegate( - this GuildRepository repository, - AgentAddress guildParticipantAddress, - BigInteger share) - { - var height = repository.ActionContext.BlockIndex; - var guildParticipant = repository.GetGuildParticipant(guildParticipantAddress); - var guild = repository.GetGuild(guildParticipant.GuildAddress); - guildParticipant.Undelegate(guild, share, height); - - return repository; - } - - public static GuildRepository Redelegate( - this GuildRepository repository, - AgentAddress guildParticipantAddress, - GuildAddress dstGuildAddress) - { - var height = repository.ActionContext.BlockIndex; - var guildParticipant = repository.GetGuildParticipant(guildParticipantAddress); - var guild = repository.GetGuild(guildParticipant.GuildAddress); - var share = repository.GetBond( - new ValidatorRepository(repository.World, repository.ActionContext) - .GetValidatorDelegatee(guild.ValidatorAddress), - guildParticipantAddress).Share; - var dstGuild = repository.GetGuild(dstGuildAddress); - guildParticipant.Redelegate(guild, dstGuild, share, height); - - return repository; - } - private static GuildRepository SetGuildRejoinCooldown( this GuildRepository repository, AgentAddress guildParticipantAddress,