-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2853 from s2quake/test/improve-readability-pos
Improve code readability for PoS test
- Loading branch information
Showing
12 changed files
with
1,686 additions
and
1,829 deletions.
There are no files selected for viewing
237 changes: 115 additions & 122 deletions
237
.Lib9c.Tests/Action/ValidatorDelegation/AllocateRewardTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,143 +1,136 @@ | ||
#nullable enable | ||
namespace Lib9c.Tests.Action.ValidatorDelegation | ||
namespace Lib9c.Tests.Action.ValidatorDelegation; | ||
|
||
using System; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Numerics; | ||
using Libplanet.Action.State; | ||
using Libplanet.Crypto; | ||
using Libplanet.Types.Assets; | ||
using Libplanet.Types.Blocks; | ||
using Libplanet.Types.Consensus; | ||
using Nekoyume; | ||
using Nekoyume.Action.ValidatorDelegation; | ||
using Nekoyume.Model.State; | ||
using Nekoyume.Module.ValidatorDelegation; | ||
using Nekoyume.ValidatorDelegation; | ||
using Xunit; | ||
|
||
public class AllocateRewardTest : ValidatorDelegationTestBase | ||
{ | ||
using System; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Numerics; | ||
using Libplanet.Action.State; | ||
using Libplanet.Crypto; | ||
using Libplanet.Mocks; | ||
using Libplanet.Types.Assets; | ||
using Libplanet.Types.Blocks; | ||
using Libplanet.Types.Consensus; | ||
using Nekoyume; | ||
using Nekoyume.Action.ValidatorDelegation; | ||
using Nekoyume.Model.State; | ||
using Nekoyume.Module; | ||
using Nekoyume.Module.ValidatorDelegation; | ||
using Nekoyume.ValidatorDelegation; | ||
using Xunit; | ||
|
||
public class AllocateRewardTest | ||
[Fact] | ||
public void Serialization() | ||
{ | ||
[Fact] | ||
public void Serialization() | ||
{ | ||
var action = new AllocateReward(); | ||
var plainValue = action.PlainValue; | ||
var action = new AllocateReward(); | ||
var plainValue = action.PlainValue; | ||
|
||
var deserialized = new AllocateReward(); | ||
deserialized.LoadPlainValue(plainValue); | ||
} | ||
var deserialized = new AllocateReward(); | ||
deserialized.LoadPlainValue(plainValue); | ||
} | ||
|
||
[Fact] | ||
public void Execute() | ||
[Fact] | ||
public void Execute() | ||
{ | ||
IWorld world = World; | ||
var context = new ActionContext { }; | ||
var privateKeys = Enumerable.Range(0, 200).Select(_ => new PrivateKey()).ToArray(); | ||
var favs = Enumerable.Range(0, 200).Select(i => NCG * (i + 1)).ToArray(); | ||
|
||
for (int i = 0; i < 200; i++) | ||
{ | ||
IWorld world = new World(MockUtil.MockModernWorldState); | ||
var context = new ActionContext { }; | ||
var ncg = Currency.Uncapped("NCG", 2, null); | ||
// TODO: Use Currencies.GuildGold when it's available. | ||
// var gg = Currencies.GuildGold; | ||
var gg = ncg; | ||
var goldCurrencyState = new GoldCurrencyState(ncg); | ||
world = world | ||
.SetLegacyState(Addresses.GoldCurrency, goldCurrencyState.Serialize()); | ||
var privateKeys = Enumerable.Range(0, 200).Select(_ => new PrivateKey()).ToArray(); | ||
var favs = Enumerable.Range(0, 200).Select(i => gg * (i + 1)).ToArray(); | ||
|
||
for (int i = 0; i < 200; i++) | ||
var signer = privateKeys[i]; | ||
world = world.MintAsset(context, signer.Address, NCG * 1000); | ||
world = new PromoteValidator(signer.PublicKey, favs[i]).Execute(new ActionContext | ||
{ | ||
var signer = privateKeys[i]; | ||
world = world.MintAsset(context, signer.Address, gg * 1000); | ||
world = new PromoteValidator(signer.PublicKey, favs[i]).Execute(new ActionContext | ||
{ | ||
PreviousState = world, | ||
Signer = signer.Address, | ||
BlockIndex = 10L, | ||
}); | ||
} | ||
|
||
var blockHash = new BlockHash(Enumerable.Repeat((byte)0x01, BlockHash.Size).ToArray()); | ||
var timestamp = DateTimeOffset.UtcNow; | ||
var voteFlags = Enumerable.Range(0, 100).Select(i => i % 2 == 0 ? VoteFlag.PreCommit : VoteFlag.Null).ToArray(); | ||
var repository = new ValidatorRepository(world, context); | ||
var bondedSet = repository.GetValidatorList().GetBonded(); | ||
|
||
var proposer = bondedSet.First(); | ||
repository.SetProposerInfo(new ProposerInfo(9L, proposer.OperatorAddress)); | ||
var votes = bondedSet.Select( | ||
(v, i) => new VoteMetadata( | ||
9L, 0, blockHash, timestamp, v.PublicKey, v.Power, i % 2 == 0 ? VoteFlag.PreCommit : VoteFlag.Null) | ||
.Sign(i % 2 == 0 ? privateKeys.First(k => k.PublicKey.Equals(v.PublicKey)) : null)).ToImmutableArray(); | ||
|
||
var totalReward = ncg * 1000; | ||
world = repository.World.MintAsset(context, Addresses.RewardPool, totalReward); | ||
PreviousState = world, | ||
Signer = signer.Address, | ||
BlockIndex = 10L, | ||
}); | ||
} | ||
|
||
// TODO: Remove this after delegation currency has been changed into GuildGold. | ||
var initialFAVs = votes.Select(vote => world.GetBalance(vote.ValidatorPublicKey.Address, ncg)).ToArray(); | ||
var blockHash = new BlockHash(Enumerable.Repeat((byte)0x01, BlockHash.Size).ToArray()); | ||
var timestamp = DateTimeOffset.UtcNow; | ||
var voteFlags = Enumerable.Range(0, 100).Select(i => i % 2 == 0 ? VoteFlag.PreCommit : VoteFlag.Null).ToArray(); | ||
var repository = new ValidatorRepository(world, context); | ||
var bondedSet = repository.GetValidatorList().GetBonded(); | ||
|
||
context = new ActionContext | ||
{ | ||
BlockIndex = 10L, | ||
PreviousState = world, | ||
Signer = privateKeys[199].Address, | ||
LastCommit = new BlockCommit(9L, 0, blockHash, votes), | ||
}; | ||
var proposer = bondedSet.First(); | ||
repository.SetProposerInfo(new ProposerInfo(9L, proposer.OperatorAddress)); | ||
var votes = bondedSet.Select( | ||
(v, i) => new VoteMetadata( | ||
9L, 0, blockHash, timestamp, v.PublicKey, v.Power, i % 2 == 0 ? VoteFlag.PreCommit : VoteFlag.Null) | ||
.Sign(i % 2 == 0 ? privateKeys.First(k => k.PublicKey.Equals(v.PublicKey)) : null)).ToImmutableArray(); | ||
|
||
var action = new AllocateReward(); | ||
world = action.Execute(context); | ||
var totalReward = NCG * 1000; | ||
world = repository.World.MintAsset(context, Addresses.RewardPool, totalReward); | ||
|
||
BigInteger totalPower = votes.Aggregate( | ||
BigInteger.Zero, | ||
(accum, next) => accum + (BigInteger)next.ValidatorPower!); | ||
// TODO: Remove this after delegation currency has been changed into GuildGold. | ||
var initialFAVs = votes.Select(vote => world.GetBalance(vote.ValidatorPublicKey.Address, NCG)).ToArray(); | ||
|
||
BigInteger preCommitPower = votes.Aggregate( | ||
BigInteger.Zero, | ||
(accum, next) => accum + (BigInteger)next.ValidatorPower! * (next.Flag == VoteFlag.PreCommit ? 1 : 0)); | ||
context = new ActionContext | ||
{ | ||
BlockIndex = 10L, | ||
PreviousState = world, | ||
Signer = privateKeys[199].Address, | ||
LastCommit = new BlockCommit(9L, 0, blockHash, votes), | ||
}; | ||
|
||
var action = new AllocateReward(); | ||
world = action.Execute(context); | ||
|
||
BigInteger totalPower = votes.Aggregate( | ||
BigInteger.Zero, | ||
(accum, next) => accum + (BigInteger)next.ValidatorPower!); | ||
|
||
BigInteger preCommitPower = votes.Aggregate( | ||
BigInteger.Zero, | ||
(accum, next) => accum + (BigInteger)next.ValidatorPower! * (next.Flag == VoteFlag.PreCommit ? 1 : 0)); | ||
|
||
var baseProposerReward | ||
= (totalReward * ValidatorDelegatee.BaseProposerRewardPercentage) | ||
.DivRem(100).Quotient; | ||
var bonusProposerReward | ||
= (totalReward * preCommitPower * ValidatorDelegatee.BonusProposerRewardPercentage) | ||
.DivRem(totalPower * 100).Quotient; | ||
|
||
var proposerReward = baseProposerReward + bonusProposerReward; | ||
var remains = totalReward - proposerReward; | ||
repository.UpdateWorld(world); | ||
|
||
foreach (var (vote, index) in votes.Select((v, i) => (v, i))) | ||
{ | ||
var initialFAV = initialFAVs[index]; | ||
var validator = repository.GetValidatorDelegatee(vote.ValidatorPublicKey.Address); | ||
|
||
var baseProposerReward | ||
= (totalReward * ValidatorDelegatee.BaseProposerRewardPercentage) | ||
FungibleAssetValue rewardAllocated | ||
= (remains * vote.ValidatorPower!.Value).DivRem(totalPower).Quotient; | ||
FungibleAssetValue commission | ||
= (rewardAllocated * validator.CommissionPercentage) | ||
.DivRem(100).Quotient; | ||
var bonusProposerReward | ||
= (totalReward * preCommitPower * ValidatorDelegatee.BonusProposerRewardPercentage) | ||
.DivRem(totalPower * 100).Quotient; | ||
|
||
var proposerReward = baseProposerReward + bonusProposerReward; | ||
var remains = totalReward - proposerReward; | ||
repository.UpdateWorld(world); | ||
if (vote.Flag == VoteFlag.Null) | ||
{ | ||
Assert.Equal(initialFAV, world.GetBalance(vote.ValidatorPublicKey.Address, NCG)); | ||
Assert.Equal( | ||
NCG * 0, world.GetBalance(validator.CurrentLumpSumRewardsRecordAddress(), NCG)); | ||
continue; | ||
} | ||
|
||
foreach (var (vote, index) in votes.Select((v, i) => (v, i))) | ||
if (vote.ValidatorPublicKey.Equals(proposer.PublicKey)) | ||
{ | ||
var initialFAV = initialFAVs[index]; | ||
var validator = repository.GetValidatorDelegatee(vote.ValidatorPublicKey.Address); | ||
|
||
FungibleAssetValue rewardAllocated | ||
= (remains * vote.ValidatorPower!.Value).DivRem(totalPower).Quotient; | ||
FungibleAssetValue commission | ||
= (rewardAllocated * validator.CommissionPercentage) | ||
.DivRem(100).Quotient; | ||
|
||
if (vote.Flag == VoteFlag.Null) | ||
{ | ||
Assert.Equal(initialFAV, world.GetBalance(vote.ValidatorPublicKey.Address, ncg)); | ||
Assert.Equal(ncg * 0, world.GetBalance(validator.CurrentLumpSumRewardsRecordAddress(), ncg)); | ||
continue; | ||
} | ||
|
||
if (vote.ValidatorPublicKey.Equals(proposer.PublicKey)) | ||
{ | ||
Assert.Equal( | ||
proposerReward + commission + initialFAV, | ||
world.GetBalance(vote.ValidatorPublicKey.Address, ncg)); | ||
} | ||
else | ||
{ | ||
Assert.Equal(commission + initialFAV, world.GetBalance(vote.ValidatorPublicKey.Address, ncg)); | ||
} | ||
|
||
Assert.Equal(rewardAllocated - commission, world.GetBalance(validator.CurrentLumpSumRewardsRecordAddress(), ncg)); | ||
Assert.Equal( | ||
proposerReward + commission + initialFAV, | ||
world.GetBalance(vote.ValidatorPublicKey.Address, NCG)); | ||
} | ||
else | ||
{ | ||
Assert.Equal(commission + initialFAV, world.GetBalance(vote.ValidatorPublicKey.Address, NCG)); | ||
} | ||
|
||
Assert.Equal( | ||
rewardAllocated - commission, | ||
world.GetBalance(validator.CurrentLumpSumRewardsRecordAddress(), NCG)); | ||
} | ||
} | ||
} |
Oops, something went wrong.