From e6a4af605ed49c494ac8b3743732ce19509f7381 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Fri, 5 Apr 2024 15:58:25 +0900 Subject: [PATCH 1/5] refactor: rename AllocateRewardCtrl --- .Lib9c.Tests/Action/DPoS/DistributeTest.cs | 18 +++++++++--------- ...AllocateReward.cs => AllocateRewardCtrl.cs} | 2 +- Lib9c/Action/DPoS/Control/DelegateCtrl.cs | 2 +- Lib9c/Action/DPoS/Sys/AllocateReward.cs | 2 +- Lib9c/Action/DPoS/WithdrawDelegator.cs | 4 ++-- Lib9c/Action/DPoS/WithdrawValidator.cs | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) rename Lib9c/Action/DPoS/Control/{AllocateReward.cs => AllocateRewardCtrl.cs} (99%) diff --git a/.Lib9c.Tests/Action/DPoS/DistributeTest.cs b/.Lib9c.Tests/Action/DPoS/DistributeTest.cs index ff3db76a7b..2d297aa95b 100644 --- a/.Lib9c.Tests/Action/DPoS/DistributeTest.cs +++ b/.Lib9c.Tests/Action/DPoS/DistributeTest.cs @@ -160,7 +160,7 @@ public void ValidatorSetTest() }, ReservedAddress.RewardPool, blockReward); - _states = AllocateReward.Execute( + _states = AllocateRewardCtrl.Execute( _states, new ActionContext { @@ -172,13 +172,13 @@ public void ValidatorSetTest() OperatorAddresses[3]); var (baseProposerReward, _) - = (blockReward * AllocateReward.BaseProposerRewardNumerator) - .DivRem(AllocateReward.BaseProposerRewardDenominator); + = (blockReward * AllocateRewardCtrl.BaseProposerRewardNumerator) + .DivRem(AllocateRewardCtrl.BaseProposerRewardDenominator); var (bonusProposerReward, _) = (blockReward * (205 + 307) - * AllocateReward.BonusProposerRewardNumerator) + * AllocateRewardCtrl.BonusProposerRewardNumerator) .DivRem((100 + (101 + 200) * 50 - 101 - 102 + 204 + 306) - * AllocateReward.BonusProposerRewardDenominator); + * AllocateRewardCtrl.BonusProposerRewardDenominator); FungibleAssetValue proposerReward = baseProposerReward + bonusProposerReward; FungibleAssetValue validatorRewardSum = blockReward - proposerReward; @@ -214,12 +214,12 @@ public void ValidatorSetTest() Assert.Equal( proposerReward + commissionA, _states.GetBalance( - AllocateReward.RewardAddress(OperatorAddresses[3]), Asset.ConsensusToken)); + AllocateRewardCtrl.RewardAddress(OperatorAddresses[3]), Asset.ConsensusToken)); Assert.Equal( commissionB, _states.GetBalance( - AllocateReward.RewardAddress(OperatorAddresses[5]), Asset.ConsensusToken)); + AllocateRewardCtrl.RewardAddress(OperatorAddresses[5]), Asset.ConsensusToken)); Address delegationAddressA = Delegation.DeriveAddress(DelegatorAddress, validatorAddressA); @@ -227,7 +227,7 @@ Address delegationAddressA Assert.Equal( Asset.ConsensusFromGovernance(0), _states.GetBalance( - AllocateReward.RewardAddress(DelegatorAddress), Asset.ConsensusToken)); + AllocateRewardCtrl.RewardAddress(DelegatorAddress), Asset.ConsensusToken)); var (delegatorToken, _) = (_states.GetBalance( @@ -253,7 +253,7 @@ Address delegationAddressA Assert.Equal( delegatorToken, _states.GetBalance( - AllocateReward.RewardAddress(DelegatorAddress), Asset.ConsensusToken)); + AllocateRewardCtrl.RewardAddress(DelegatorAddress), Asset.ConsensusToken)); } } } diff --git a/Lib9c/Action/DPoS/Control/AllocateReward.cs b/Lib9c/Action/DPoS/Control/AllocateRewardCtrl.cs similarity index 99% rename from Lib9c/Action/DPoS/Control/AllocateReward.cs rename to Lib9c/Action/DPoS/Control/AllocateRewardCtrl.cs index 702303c1ca..ea830068e3 100644 --- a/Lib9c/Action/DPoS/Control/AllocateReward.cs +++ b/Lib9c/Action/DPoS/Control/AllocateRewardCtrl.cs @@ -18,7 +18,7 @@ namespace Nekoyume.Action.DPoS.Control { - public static class AllocateReward + public static class AllocateRewardCtrl { public static BigInteger BaseProposerRewardNumerator => 1; diff --git a/Lib9c/Action/DPoS/Control/DelegateCtrl.cs b/Lib9c/Action/DPoS/Control/DelegateCtrl.cs index 10ece08084..b6b3f718d7 100644 --- a/Lib9c/Action/DPoS/Control/DelegateCtrl.cs +++ b/Lib9c/Action/DPoS/Control/DelegateCtrl.cs @@ -139,7 +139,7 @@ Address validatorRewardAddress states = states.TransferAsset( ctx, validatorRewardAddress, - AllocateReward.RewardAddress(delegation.DelegatorAddress), + AllocateRewardCtrl.RewardAddress(delegation.DelegatorAddress), reward); } } diff --git a/Lib9c/Action/DPoS/Sys/AllocateReward.cs b/Lib9c/Action/DPoS/Sys/AllocateReward.cs index ea9cd189f9..93c3f70852 100644 --- a/Lib9c/Action/DPoS/Sys/AllocateReward.cs +++ b/Lib9c/Action/DPoS/Sys/AllocateReward.cs @@ -34,7 +34,7 @@ public override IWorld Execute(IActionContext context) var states = context.PreviousState; var nativeTokens = ImmutableHashSet.Create( Asset.GovernanceToken, Asset.ConsensusToken, Asset.Share); - states = Control.AllocateReward.Execute( + states = Control.AllocateRewardCtrl.Execute( states, context, nativeTokens, diff --git a/Lib9c/Action/DPoS/WithdrawDelegator.cs b/Lib9c/Action/DPoS/WithdrawDelegator.cs index b72c6d4c1d..2215cf7f0f 100644 --- a/Lib9c/Action/DPoS/WithdrawDelegator.cs +++ b/Lib9c/Action/DPoS/WithdrawDelegator.cs @@ -72,12 +72,12 @@ public override IWorld Execute(IActionContext context) foreach (Currency nativeToken in nativeTokens) { FungibleAssetValue reward = states.GetBalance( - AllocateReward.RewardAddress(ctx.Signer), nativeToken); + AllocateRewardCtrl.RewardAddress(ctx.Signer), nativeToken); if (reward.Sign > 0) { states = states.TransferAsset( ctx, - AllocateReward.RewardAddress(ctx.Signer), + AllocateRewardCtrl.RewardAddress(ctx.Signer), ctx.Signer, reward); } diff --git a/Lib9c/Action/DPoS/WithdrawValidator.cs b/Lib9c/Action/DPoS/WithdrawValidator.cs index 9d20873203..70563bfa9b 100644 --- a/Lib9c/Action/DPoS/WithdrawValidator.cs +++ b/Lib9c/Action/DPoS/WithdrawValidator.cs @@ -50,12 +50,12 @@ public override IWorld Execute(IActionContext context) foreach (Currency nativeToken in nativeTokens) { FungibleAssetValue reward = states.GetBalance( - AllocateReward.RewardAddress(ctx.Signer), nativeToken); + AllocateRewardCtrl.RewardAddress(ctx.Signer), nativeToken); if (reward.Sign > 0) { states = states.TransferAsset( ctx, - AllocateReward.RewardAddress(ctx.Signer), + AllocateRewardCtrl.RewardAddress(ctx.Signer), ctx.Signer, reward); } From 98ffc27e38e3e1a7cdc268c32c7c1bf710d05cb6 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Fri, 5 Apr 2024 15:42:22 +0900 Subject: [PATCH 2/5] bump: libplanet --- .Libplanet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.Libplanet b/.Libplanet index 96970ec83a..1398e6bb17 160000 --- a/.Libplanet +++ b/.Libplanet @@ -1 +1 @@ -Subproject commit 96970ec83a91f1590560b82834f8cb64518754a8 +Subproject commit 1398e6bb177dda739d30043165ac072ef33dbaf5 From 181d40f5d641a4728387fc4f523de9eb42447464 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Tue, 9 Apr 2024 16:47:26 +0900 Subject: [PATCH 3/5] feat: adjust changes from the libplanet API changes --- .Lib9c.Benchmarks/Program.cs | 3 ++- .Lib9c.Plugin/PluginActionEvaluator.cs | 5 ++++- .Lib9c.Tests/Action/RewardGoldTest.cs | 6 ++++-- .Lib9c.Tests/Policy/BlockPolicyTest.cs | 18 ++++++++++++------ .Lib9c.Tests/TestHelper/BlockChainHelper.cs | 3 ++- .Lib9c.Tools/SubCommand/State.cs | 3 ++- .../RemoteAccount.cs | 5 +++++ Lib9c.DevExtensions/Utils.cs | 3 ++- Lib9c.Policy/Policy/BlockPolicySource.cs | 4 +++- Lib9c.Policy/Policy/DebugPolicy.cs | 8 +++++++- Lib9c.Policy/Policy/NCBlockPolicy.cs | 7 +++++-- Lib9c.Utils/BlockHelper.cs | 6 ++++-- Lib9c/Action/DPoS/Sys/UpdateValidators.cs | 15 ++++++++------- Lib9c/Module/LegacyModule.cs | 8 ++++++++ 14 files changed, 68 insertions(+), 26 deletions(-) diff --git a/.Lib9c.Benchmarks/Program.cs b/.Lib9c.Benchmarks/Program.cs index 6b4126dd01..3d91bff182 100644 --- a/.Lib9c.Benchmarks/Program.cs +++ b/.Lib9c.Benchmarks/Program.cs @@ -81,7 +81,8 @@ static void Main(string[] args) IKeyValueStore stateKeyValueStore = new RocksDBKeyValueStore(Path.Combine(storePath, "states")); var stateStore = new TrieStateStore(stateKeyValueStore); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _ => policy.BeginBlockActions, + _ => policy.EndBlockActions, stateStore, new NCActionLoader()); var chain = new BlockChain( diff --git a/.Lib9c.Plugin/PluginActionEvaluator.cs b/.Lib9c.Plugin/PluginActionEvaluator.cs index 7c76b9602e..92d8404b62 100644 --- a/.Lib9c.Plugin/PluginActionEvaluator.cs +++ b/.Lib9c.Plugin/PluginActionEvaluator.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using System.Security.Cryptography; using Lib9c.Plugin.Shared; using Libplanet.Action; @@ -5,6 +6,7 @@ using Libplanet.Extensions.ActionEvaluatorCommonComponents; using Libplanet.Store; using Nekoyume.Action; +using Nekoyume.Action.DPoS.Sys; using Nekoyume.Action.Loader; @@ -18,7 +20,8 @@ public PluginActionEvaluator(IPluginKeyValueStore keyValueStore) { var stateStore = new TrieStateStore(new WrappedKeyValueStore(keyValueStore)); _actionEvaluator = new ActionEvaluator( - _ => new RewardGold(), + _ => new IAction[] { }.ToImmutableArray(), + _ => new IAction[] { new RewardGold() }.ToImmutableArray(), stateStore, new NCActionLoader()); } diff --git a/.Lib9c.Tests/Action/RewardGoldTest.cs b/.Lib9c.Tests/Action/RewardGoldTest.cs index 08096bcc43..6a0bc68775 100644 --- a/.Lib9c.Tests/Action/RewardGoldTest.cs +++ b/.Lib9c.Tests/Action/RewardGoldTest.cs @@ -542,7 +542,8 @@ public async Task Genesis_StateRootHash(bool mainnet) pendingActivationStates: pendingActivationStates.ToArray() ); var tempActionEvaluator = new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: new TrieStateStore(new MemoryKeyValueStore()), actionTypeLoader: new NCActionLoader()); genesis = BlockChain.ProposeGenesisBlock( @@ -565,7 +566,8 @@ public async Task Genesis_StateRootHash(bool mainnet) stateStore: stateStore, genesisBlock: genesis, actionEvaluator: new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ), diff --git a/.Lib9c.Tests/Policy/BlockPolicyTest.cs b/.Lib9c.Tests/Policy/BlockPolicyTest.cs index f5591b66cb..cc0205e12e 100644 --- a/.Lib9c.Tests/Policy/BlockPolicyTest.cs +++ b/.Lib9c.Tests/Policy/BlockPolicyTest.cs @@ -65,7 +65,8 @@ public void ValidateNextBlockTx() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ), @@ -273,7 +274,8 @@ public void BlockCommitFromNonValidator() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ), @@ -327,7 +329,8 @@ public void MustNotIncludeBlockActionAtTransaction() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: actionLoader ), @@ -380,7 +383,8 @@ public void EarnMiningGoldWhenSuccessMining() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ), @@ -432,7 +436,8 @@ public void ValidateNextBlockWithManyTransactions() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ) @@ -533,7 +538,8 @@ public void ValidateNextBlockWithManyTransactionsPerSigner() stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ) diff --git a/.Lib9c.Tests/TestHelper/BlockChainHelper.cs b/.Lib9c.Tests/TestHelper/BlockChainHelper.cs index 42a9b17e2f..a073ba1053 100644 --- a/.Lib9c.Tests/TestHelper/BlockChainHelper.cs +++ b/.Lib9c.Tests/TestHelper/BlockChainHelper.cs @@ -47,7 +47,8 @@ public static BlockChain MakeBlockChain( stateStore, genesis, new ActionEvaluator( - policyBlockActionGetter: _ => policy.BlockAction, + policyBeginBlockActionsGetter: _ => policy.BeginBlockActions, + policyEndBlockActionsGetter: _ => policy.EndBlockActions, stateStore: stateStore, actionTypeLoader: new NCActionLoader() ), diff --git a/.Lib9c.Tools/SubCommand/State.cs b/.Lib9c.Tools/SubCommand/State.cs index d418ebe4f4..b57c5e8e6e 100644 --- a/.Lib9c.Tools/SubCommand/State.cs +++ b/.Lib9c.Tools/SubCommand/State.cs @@ -115,7 +115,8 @@ IStateStore stateStore var actionLoader = TypedActionLoader.Create( typeof(ActionBase).Assembly, typeof(ActionBase)); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _ => policy.BeginBlockActions, + _ => policy.EndBlockActions, stateStore, actionLoader); HashDigest stateRootHash = block.Index < 1 diff --git a/.Libplanet.Extensions.RemoteBlockChainStates/RemoteAccount.cs b/.Libplanet.Extensions.RemoteBlockChainStates/RemoteAccount.cs index 69e7860b71..d2a70fe495 100644 --- a/.Libplanet.Extensions.RemoteBlockChainStates/RemoteAccount.cs +++ b/.Libplanet.Extensions.RemoteBlockChainStates/RemoteAccount.cs @@ -62,6 +62,11 @@ public IAccount SetValidator(Validator validator) throw new NotSupportedException(); } + public IAccount SetValidatorSet(ValidatorSet validatorSet) + { + throw new NotSupportedException(); + } + public IAccount TransferAsset(IActionContext context, Address sender, Address recipient, FungibleAssetValue value, bool allowNegativeBalance = false) { throw new NotSupportedException(); diff --git a/Lib9c.DevExtensions/Utils.cs b/Lib9c.DevExtensions/Utils.cs index 5e2dcc1a7c..77fd8063df 100644 --- a/Lib9c.DevExtensions/Utils.cs +++ b/Lib9c.DevExtensions/Utils.cs @@ -85,7 +85,8 @@ Guid chainIdValue var blockChainStates = new BlockChainStates(store, stateStore); var actionLoader = new NCDevActionLoader(); ActionEvaluator actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _ => policy.BeginBlockActions, + _ => policy.EndBlockActions, stateStore, actionLoader); diff --git a/Lib9c.Policy/Policy/BlockPolicySource.cs b/Lib9c.Policy/Policy/BlockPolicySource.cs index edd16ab940..7722883aff 100644 --- a/Lib9c.Policy/Policy/BlockPolicySource.cs +++ b/Lib9c.Policy/Policy/BlockPolicySource.cs @@ -16,6 +16,7 @@ using Libplanet.Crypto; using Libplanet.Types.Blocks; using Libplanet.Types.Tx; +using Nekoyume.Action.DPoS.Sys; #if UNITY_EDITOR || UNITY_STANDALONE using UniRx; @@ -130,7 +131,8 @@ internal IBlockPolicy GetPolicy( // FIXME: Slight inconsistency due to pre-existing delegate. return new BlockPolicy( - new RewardGold(), + new IAction[] { }.ToImmutableArray(), + new IAction[] { new RewardGold() }.ToImmutableArray(), blockInterval: BlockInterval, validateNextBlockTx: validateNextBlockTx, validateNextBlock: validateNextBlock, diff --git a/Lib9c.Policy/Policy/DebugPolicy.cs b/Lib9c.Policy/Policy/DebugPolicy.cs index 54985c7aec..ab9a6f16b2 100644 --- a/Lib9c.Policy/Policy/DebugPolicy.cs +++ b/Lib9c.Policy/Policy/DebugPolicy.cs @@ -1,9 +1,11 @@ +using System.Collections.Immutable; using Libplanet.Action; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; using Libplanet.Types.Blocks; using Libplanet.Types.Tx; using Nekoyume.Action; +using Nekoyume.Action.DPoS.Sys; namespace Nekoyume.Blockchain.Policy { @@ -13,7 +15,11 @@ public DebugPolicy() { } - public IAction BlockAction { get; } = new RewardGold(); + public ImmutableArray BeginBlockActions { get; } = + new IAction[] { }.ToImmutableArray(); + + public ImmutableArray EndBlockActions { get; } = + new IAction[] { new RewardGold() }.ToImmutableArray(); public TxPolicyViolationException ValidateNextBlockTx( BlockChain blockChain, Transaction transaction) diff --git a/Lib9c.Policy/Policy/NCBlockPolicy.cs b/Lib9c.Policy/Policy/NCBlockPolicy.cs index aa47725cd3..9c763b275e 100644 --- a/Lib9c.Policy/Policy/NCBlockPolicy.cs +++ b/Lib9c.Policy/Policy/NCBlockPolicy.cs @@ -4,13 +4,15 @@ using Libplanet.Types.Blocks; using Libplanet.Types.Tx; using System; +using System.Collections.Immutable; namespace Nekoyume.Blockchain.Policy { public class NCBlockPolicy : BlockPolicy { public NCBlockPolicy( - IAction blockAction, + ImmutableArray beginBlockActions, + ImmutableArray endBlockActions, TimeSpan blockInterval, Func? validateNextBlockTx = null, @@ -21,7 +23,8 @@ public NCBlockPolicy( Func? getMaxTransactionsPerBlock = null, Func? getMaxTransactionsPerSignerPerBlock = null) : base( - blockAction: blockAction, + beginBlockActions: beginBlockActions, + endBlockActions: endBlockActions, blockInterval: blockInterval, validateNextBlockTx: validateNextBlockTx, validateNextBlock: validateNextBlock, diff --git a/Lib9c.Utils/BlockHelper.cs b/Lib9c.Utils/BlockHelper.cs index a28fa9c51b..a4dab1aa7d 100644 --- a/Lib9c.Utils/BlockHelper.cs +++ b/Lib9c.Utils/BlockHelper.cs @@ -94,10 +94,12 @@ public static Block ProposeGenesisBlock( { actions.AddRange(actionBases); } - var blockAction = new BlockPolicySource().GetPolicy().BlockAction; + var beginBlockActions = new BlockPolicySource().GetPolicy().BeginBlockActions; + var endBlockActions = new BlockPolicySource().GetPolicy().EndBlockActions; var actionLoader = new NCActionLoader(); var actionEvaluator = new ActionEvaluator( - _ => blockAction, + _ => beginBlockActions, + _ => endBlockActions, new TrieStateStore(new MemoryKeyValueStore()), actionLoader); return diff --git a/Lib9c/Action/DPoS/Sys/UpdateValidators.cs b/Lib9c/Action/DPoS/Sys/UpdateValidators.cs index 353088c360..410866ceb4 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.SetValidatorSet(validatorSet); return states; } diff --git a/Lib9c/Module/LegacyModule.cs b/Lib9c/Module/LegacyModule.cs index d4313b3577..a38ea53fbd 100644 --- a/Lib9c/Module/LegacyModule.cs +++ b/Lib9c/Module/LegacyModule.cs @@ -103,6 +103,14 @@ public static IWorld SetValidator( world.GetAccount(ReservedAddresses.LegacyAccount) .SetValidator(validator)); + public static IWorld SetValidatorSet( + this IWorld world, + ValidatorSet validatorSet) => + world.SetAccount( + ReservedAddresses.LegacyAccount, + world.GetAccount(ReservedAddresses.LegacyAccount) + .SetValidatorSet(validatorSet)); + // Methods from AccountExtensions public static IWorld MarkBalanceChanged( this IWorld world, From 24bca50bbebb4ef9323ff6cb264d2238ee70aeed Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Fri, 5 Apr 2024 15:59:47 +0900 Subject: [PATCH 4/5] test: add regression test --- .../Action/DPoS/Sys/UpdateValidatorsTest.cs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .Lib9c.Tests/Action/DPoS/Sys/UpdateValidatorsTest.cs diff --git a/.Lib9c.Tests/Action/DPoS/Sys/UpdateValidatorsTest.cs b/.Lib9c.Tests/Action/DPoS/Sys/UpdateValidatorsTest.cs new file mode 100644 index 0000000000..68e427dbd6 --- /dev/null +++ b/.Lib9c.Tests/Action/DPoS/Sys/UpdateValidatorsTest.cs @@ -0,0 +1,92 @@ +namespace Lib9c.Tests.Action.DPoS.Sys +{ + using System.Linq; + using Libplanet.Action.State; + using Libplanet.Crypto; + using Libplanet.Types.Assets; + using Nekoyume.Action.DPoS; + using Nekoyume.Action.DPoS.Control; + using Nekoyume.Action.DPoS.Misc; + using Nekoyume.Action.DPoS.Model; + using Nekoyume.Action.DPoS.Sys; + using Nekoyume.Module; + using Xunit; + + public class UpdateValidatorsTest : PoSTest + { + [Fact] + public void Execute() + { + // Prepare initial state. + IWorld initialState = new World(new MockWorldState()); + const int count = 4; + var validatorKeys = Enumerable.Range(0, count).Select(_ => new PrivateKey().PublicKey).ToArray(); + initialState = validatorKeys.Aggregate( + initialState, + (current, key) => current.MintAsset( + new ActionContext(), + key.Address, + new FungibleAssetValue(Asset.GovernanceToken, 1, 0))); + foreach (var key in validatorKeys) + { + Assert.Equal(1, initialState.GetBalance(key.Address, Asset.GovernanceToken).MajorUnit); + Assert.Equal(0, initialState.GetBalance(key.Address, Asset.GovernanceToken).MinorUnit); + } + + // Stake 1 for each validator. + foreach (var key in validatorKeys) + { + initialState = new PromoteValidator( + key, + new FungibleAssetValue(Asset.GovernanceToken, 1, 0)).Execute( + new ActionContext + { + PreviousState = initialState, + Signer = key.Address, + }); + } + + Assert.Equal(0, ValidatorSetCtrl.FetchBondedValidatorSet(initialState).Item2.Count); + Assert.Equal(0, initialState.GetValidatorSet().TotalCount); + + // Execute the action. + initialState = new UpdateValidators().Execute( + new ActionContext + { + PreviousState = initialState, + LastCommit = null, + }); + + Assert.Equal(count, ValidatorSetCtrl.FetchBondedValidatorSet(initialState).Item2.Count); + Assert.Equal(count, initialState.GetValidatorSet().TotalCount); + Assert.Equal( + validatorKeys.ToHashSet(), + initialState.GetValidatorSet() + .Validators.Select(validator => validator.PublicKey) + .ToHashSet()); + + initialState = new Undelegate( + Validator.DeriveAddress(validatorKeys[0].Address), + new FungibleAssetValue(Asset.Share, 100, 0)).Execute( + new ActionContext + { + PreviousState = initialState, + Signer = validatorKeys[0].Address, + }); + + Assert.Equal(count, ValidatorSetCtrl.FetchBondedValidatorSet(initialState).Item2.Count); + Assert.Equal(count, initialState.GetValidatorSet().TotalCount); + + // Execute the action. + initialState = new UpdateValidators().Execute( + new ActionContext + { + PreviousState = initialState, + LastCommit = null, + }); + + Assert.Equal(count - 1, ValidatorSetCtrl.FetchBondedValidatorSet(initialState).Item2.Count); + Assert.Equal(count - 1, initialState.GetValidatorSet().TotalCount); + } + } +} From 939328c0b20cbb83219255367af4c9dbc1485d1c Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Fri, 5 Apr 2024 16:04:34 +0900 Subject: [PATCH 5/5] 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 +++++++++++------ 3 files changed, 18 insertions(+), 8 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 8bf071f46e..36536cea6f 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;