From 78e23eb5590c6d97c1d3ecc4b317f4cc8b0dba75 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Fri, 5 Apr 2024 16:04:34 +0900 Subject: [PATCH] bugfix: fix logic error in dpos methods --- Lib9c/Action/DPoS/Control/Bond.cs | 2 -- Lib9c/Action/DPoS/Control/DelegateCtrl.cs | 7 +++++++ Lib9c/Action/DPoS/Control/ValidatorCtrl.cs | 17 +++++++++++------ Lib9c/Action/DPoS/Sys/UpdateValidators.cs | 15 ++++++++------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Lib9c/Action/DPoS/Control/Bond.cs b/Lib9c/Action/DPoS/Control/Bond.cs index e1e535ad52..a834fc46c8 100644 --- a/Lib9c/Action/DPoS/Control/Bond.cs +++ b/Lib9c/Action/DPoS/Control/Bond.cs @@ -81,8 +81,6 @@ internal static (IWorld, FungibleAssetValue) Cancel( Address delegationAddress, IImmutableSet nativeTokens) { - long blockHeight = ctx.BlockIndex; - // Currency check if (!share.Currency.Equals(Asset.Share)) { diff --git a/Lib9c/Action/DPoS/Control/DelegateCtrl.cs b/Lib9c/Action/DPoS/Control/DelegateCtrl.cs index b6b3f718d7..2f3da3c31d 100644 --- a/Lib9c/Action/DPoS/Control/DelegateCtrl.cs +++ b/Lib9c/Action/DPoS/Control/DelegateCtrl.cs @@ -9,6 +9,7 @@ using Nekoyume.Action.DPoS.Model; using Nekoyume.Action.DPoS.Util; using Nekoyume.Module; +using Serilog; namespace Nekoyume.Action.DPoS.Control { @@ -122,6 +123,12 @@ internal static IWorld Distribute( delegation.LatestDistributeHeight, blockHeight); + // Skip if there is no reward to distribute. + if (delegationRewardSum.RawValue == 0) + { + continue; + } + if (!(ValidatorCtrl.TokenPortionByShare( states, delegation.ValidatorAddress, diff --git a/Lib9c/Action/DPoS/Control/ValidatorCtrl.cs b/Lib9c/Action/DPoS/Control/ValidatorCtrl.cs index be6dd22733..78bd5735ac 100644 --- a/Lib9c/Action/DPoS/Control/ValidatorCtrl.cs +++ b/Lib9c/Action/DPoS/Control/ValidatorCtrl.cs @@ -214,12 +214,17 @@ internal static IWorld Unbond( validator.UnbondingCompletionBlockHeight = blockHeight + UnbondingSet.Period; if (validator.Status == BondingStatus.Bonded) { - states = states.TransferAsset( - ctx, - ReservedAddress.BondedPool, - ReservedAddress.UnbondedPool, - Asset.GovernanceFromConsensus( - states.GetBalance(validator.Address, Asset.ConsensusToken))); + var consensusToken = states.GetBalance(validator.Address, Asset.ConsensusToken); + if (consensusToken.RawValue > 0) + { + // Transfer consensus token to unbonded pool if remaining. + states = states.TransferAsset( + ctx, + ReservedAddress.BondedPool, + ReservedAddress.UnbondedPool, + Asset.GovernanceFromConsensus( + states.GetBalance(validator.Address, Asset.ConsensusToken))); + } } validator.Status = BondingStatus.Unbonding; diff --git a/Lib9c/Action/DPoS/Sys/UpdateValidators.cs b/Lib9c/Action/DPoS/Sys/UpdateValidators.cs index 353088c360..5f98e01bad 100644 --- a/Lib9c/Action/DPoS/Sys/UpdateValidators.cs +++ b/Lib9c/Action/DPoS/Sys/UpdateValidators.cs @@ -1,3 +1,4 @@ +using System.Linq; using Bencodex.Types; using Libplanet.Action; using Libplanet.Action.State; @@ -36,13 +37,13 @@ public override IWorld Execute(IActionContext context) states = ValidatorSetCtrl.Update(states, context); ValidatorSet bondedSet; (states, bondedSet) = ValidatorSetCtrl.FetchBondedValidatorSet(states); - foreach (var validator in bondedSet.Set) - { - states = states.SetValidator( - new Libplanet.Types.Consensus.Validator( - validator.OperatorPublicKey, - validator.ConsensusToken.RawValue)); - } + var validatorSet = new Libplanet.Types.Consensus.ValidatorSet( + bondedSet.Set.Select( + v => new Libplanet.Types.Consensus.Validator( + v.OperatorPublicKey, + v.ConsensusToken.RawValue)) + .ToList()); + states = states.UpdateValidatorSet(validatorSet); return states; }