Skip to content

Commit f3b81fd

Browse files
committed
test: add unit tests
1 parent fb33b4a commit f3b81fd

21 files changed

+1645
-0
lines changed

.Lib9c.Tests/Action/ActionContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public class ActionContext : IActionContext
2828

2929
public int BlockProtocolVersion { get; set; }
3030

31+
public BlockCommit LastCommit { get; set; }
32+
3133
public IWorld PreviousState { get; set; }
3234

3335
public int RandomSeed { get; set; }
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System.Collections.Immutable;
2+
using Lib9c.DPoS.Exception;
3+
using Lib9c.DPoS.Misc;
4+
using Lib9c.DPoS.Model;
5+
using Libplanet.Action.State;
6+
using Libplanet.Crypto;
7+
using Libplanet.Tests.PoS;
8+
using Libplanet.Types.Assets;
9+
using Nekoyume.Module;
10+
11+
namespace Lib9c.DPoS.Tests
12+
{
13+
public class DelegateCtrlTest : PoSTest
14+
{
15+
private readonly PublicKey _operatorPublicKey;
16+
private readonly Address _operatorAddress;
17+
private readonly Address _delegatorAddress;
18+
private readonly Address _validatorAddress;
19+
private ImmutableHashSet<Currency> _nativeTokens;
20+
private IWorld _states;
21+
22+
public DelegateCtrlTest()
23+
{
24+
_operatorPublicKey = new PrivateKey().PublicKey;
25+
_operatorAddress = _operatorPublicKey.Address;
26+
_delegatorAddress = CreateAddress();
27+
_validatorAddress = Validator.DeriveAddress(_operatorAddress);
28+
_nativeTokens = ImmutableHashSet.Create(
29+
Asset.GovernanceToken, Asset.ConsensusToken, Asset.Share);
30+
_states = InitializeStates();
31+
}
32+
33+
[Fact]
34+
public void InvalidCurrencyTest()
35+
{
36+
Initialize(500, 500, 100);
37+
_states = _states.MintAsset(_delegatorAddress, Asset.ConsensusToken * 50);
38+
Assert.Throws<InvalidCurrencyException>(
39+
() => _states = DelegateCtrl.Execute(
40+
_states,
41+
_delegatorAddress,
42+
_validatorAddress,
43+
Asset.ConsensusToken * 30,
44+
_nativeTokens,
45+
1));
46+
}
47+
48+
[Fact]
49+
public void InvalidValidatorTest()
50+
{
51+
Initialize(500, 500, 100);
52+
Assert.Throws<NullValidatorException>(
53+
() => _states = DelegateCtrl.Execute(
54+
_states,
55+
_delegatorAddress,
56+
CreateAddress(),
57+
Asset.GovernanceToken * 10,
58+
_nativeTokens,
59+
1));
60+
}
61+
62+
[Fact]
63+
public void InvalidShareTest()
64+
{
65+
Initialize(500, 500, 100);
66+
_states = _states.BurnAsset(_validatorAddress, Asset.ConsensusToken * 100);
67+
Assert.Throws<InvalidExchangeRateException>(
68+
() => _states = DelegateCtrl.Execute(
69+
_states,
70+
_delegatorAddress,
71+
_validatorAddress,
72+
Asset.GovernanceToken * 10,
73+
_nativeTokens,
74+
1));
75+
}
76+
77+
[Theory]
78+
[InlineData(500, 500, 100, 10)]
79+
[InlineData(500, 500, 100, 20)]
80+
public void BalanceTest(
81+
int operatorMintAmount,
82+
int delegatorMintAmount,
83+
int selfDelegateAmount,
84+
int delegateAmount)
85+
{
86+
Initialize(operatorMintAmount, delegatorMintAmount, selfDelegateAmount);
87+
_states = DelegateCtrl.Execute(
88+
_states,
89+
_delegatorAddress,
90+
_validatorAddress,
91+
Asset.GovernanceToken * delegateAmount,
92+
_nativeTokens,
93+
1);
94+
Assert.Equal(
95+
Asset.GovernanceToken * 0,
96+
_states.GetBalance(_validatorAddress, Asset.GovernanceToken));
97+
Assert.Equal(
98+
Asset.ConsensusToken * 0,
99+
_states.GetBalance(_operatorAddress, Asset.ConsensusToken));
100+
Assert.Equal(
101+
Asset.ConsensusToken * 0,
102+
_states.GetBalance(_delegatorAddress, Asset.ConsensusToken));
103+
Assert.Equal(
104+
Asset.Share * 0,
105+
_states.GetBalance(_operatorAddress, Asset.Share));
106+
Assert.Equal(
107+
Asset.Share * 0,
108+
_states.GetBalance(_delegatorAddress, Asset.Share));
109+
Assert.Equal(
110+
Asset.ConsensusToken * (selfDelegateAmount + delegateAmount),
111+
_states.GetBalance(_validatorAddress, Asset.ConsensusToken));
112+
Assert.Equal(
113+
Asset.GovernanceToken * (operatorMintAmount - selfDelegateAmount),
114+
_states.GetBalance(_operatorAddress, Asset.GovernanceToken));
115+
Assert.Equal(
116+
Asset.GovernanceToken * (delegatorMintAmount - delegateAmount),
117+
_states.GetBalance(_delegatorAddress, Asset.GovernanceToken));
118+
Assert.Equal(
119+
Asset.GovernanceToken * (selfDelegateAmount + delegateAmount),
120+
_states.GetBalance(ReservedAddress.UnbondedPool, Asset.GovernanceToken));
121+
Assert.Equal(
122+
ValidatorCtrl.GetValidator(_states, _validatorAddress).DelegatorShares,
123+
_states.GetBalance(
124+
Delegation.DeriveAddress(_operatorAddress, _validatorAddress), Asset.Share)
125+
+ _states.GetBalance(
126+
Delegation.DeriveAddress(_delegatorAddress, _validatorAddress), Asset.Share));
127+
}
128+
129+
private void Initialize(
130+
int operatorMintAmount, int delegatorMintAmount, int selfDelegateAmount)
131+
{
132+
_states = InitializeStates();
133+
_states = _states.MintAsset(
134+
_operatorAddress, Asset.GovernanceToken * operatorMintAmount);
135+
_states = _states.MintAsset(
136+
_delegatorAddress, Asset.GovernanceToken * delegatorMintAmount);
137+
_states = ValidatorCtrl.Create(
138+
_states,
139+
_operatorAddress,
140+
_operatorPublicKey,
141+
Asset.GovernanceToken * selfDelegateAmount,
142+
_nativeTokens,
143+
1);
144+
}
145+
}
146+
}

Lib9c.DPoS.Tests/DelegationTest.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Libplanet.PoS.Model;
2+
using Xunit;
3+
4+
namespace Libplanet.Tests.PoS
5+
{
6+
public class DelegationTest : PoSTest
7+
{
8+
private readonly Delegation _delegation;
9+
10+
public DelegationTest()
11+
{
12+
_delegation = new Delegation(CreateAddress(), CreateAddress());
13+
}
14+
15+
[Fact]
16+
public void MarshallingTest()
17+
{
18+
Delegation newDelegation
19+
= new Delegation(_delegation.Serialize());
20+
Assert.Equal(_delegation, newDelegation);
21+
}
22+
}
23+
}

Lib9c.DPoS.Tests/DistributeTest.cs

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
using System.Collections.Generic;
2+
using System.Collections.Immutable;
3+
using Libplanet.Action;
4+
using Libplanet.Assets;
5+
using Libplanet.Consensus;
6+
using Libplanet.Crypto;
7+
using Libplanet.PoS;
8+
using Libplanet.PoS.Control;
9+
using Libplanet.PoS.Model;
10+
using Xunit;
11+
12+
namespace Libplanet.Tests.PoS
13+
{
14+
public class DistributeTest : PoSTest
15+
{
16+
private readonly ImmutableHashSet<Currency> _nativeTokens;
17+
private IAccountStateDelta _states;
18+
19+
public DistributeTest()
20+
: base()
21+
{
22+
_nativeTokens = ImmutableHashSet.Create(
23+
Asset.GovernanceToken, Asset.ConsensusToken, Asset.Share);
24+
_states = InitializeStates();
25+
OperatorPrivateKeys = new List<PrivateKey>();
26+
OperatorPublicKeys = new List<PublicKey>();
27+
OperatorAddresses = new List<Address>();
28+
ValidatorAddresses = new List<Address>();
29+
DelegatorAddress = CreateAddress();
30+
_states = _states.MintAsset(DelegatorAddress, Asset.GovernanceToken * 100000);
31+
for (int i = 0; i < 200; i++)
32+
{
33+
PrivateKey operatorPrivateKey = new PrivateKey();
34+
PublicKey operatorPublicKey = operatorPrivateKey.PublicKey;
35+
Address operatorAddress = operatorPublicKey.ToAddress();
36+
_states = _states.MintAsset(operatorAddress, Asset.GovernanceToken * 1000);
37+
38+
OperatorPrivateKeys.Add(operatorPrivateKey);
39+
OperatorPublicKeys.Add(operatorPublicKey);
40+
OperatorAddresses.Add(operatorAddress);
41+
_states = ValidatorCtrl.Create(
42+
_states,
43+
operatorAddress,
44+
operatorPublicKey,
45+
Asset.GovernanceToken * 1,
46+
_nativeTokens,
47+
1);
48+
ValidatorAddresses.Add(Validator.DeriveAddress(operatorAddress));
49+
}
50+
}
51+
52+
private List<PrivateKey> OperatorPrivateKeys { get; set; }
53+
54+
private List<PublicKey> OperatorPublicKeys { get; set; }
55+
56+
private List<Address> OperatorAddresses { get; set; }
57+
58+
private List<Address> ValidatorAddresses { get; set; }
59+
60+
private Address DelegatorAddress { get; set; }
61+
62+
[Fact]
63+
public void ValidatorSetTest()
64+
{
65+
for (int i = 0; i < 200; i++)
66+
{
67+
_states = DelegateCtrl.Execute(
68+
_states,
69+
DelegatorAddress,
70+
ValidatorAddresses[i],
71+
Asset.GovernanceToken * (i + 1),
72+
_nativeTokens,
73+
1);
74+
}
75+
76+
Address validatorAddressA = ValidatorAddresses[3];
77+
Address validatorAddressB = ValidatorAddresses[5];
78+
79+
_states = DelegateCtrl.Execute(
80+
_states,
81+
DelegatorAddress,
82+
validatorAddressA,
83+
Asset.GovernanceToken * 200,
84+
_nativeTokens,
85+
1);
86+
87+
_states = DelegateCtrl.Execute(
88+
_states,
89+
DelegatorAddress,
90+
validatorAddressB,
91+
Asset.GovernanceToken * 300,
92+
_nativeTokens,
93+
1);
94+
95+
_states = ValidatorSetCtrl.Update(_states, 1);
96+
97+
(_states, _) = ValidatorSetCtrl.FetchBondedValidatorSet(_states);
98+
99+
List<Vote> votes = new List<Vote>()
100+
{
101+
new Vote(
102+
default,
103+
default,
104+
default,
105+
default,
106+
OperatorPrivateKeys[3].PublicKey,
107+
VoteFlag.Commit,
108+
null).Sign(OperatorPrivateKeys[3]),
109+
new Vote(
110+
default,
111+
default,
112+
default,
113+
default,
114+
OperatorPrivateKeys[5].PublicKey,
115+
VoteFlag.Commit,
116+
null).Sign(OperatorPrivateKeys[5]),
117+
};
118+
FungibleAssetValue blockReward = Asset.ConsensusToken * 50;
119+
_states = _states.MintAsset(ReservedAddress.RewardPool, blockReward);
120+
_states = AllocateReward.Execute(
121+
_states, _nativeTokens, votes, OperatorAddresses[3], 1);
122+
123+
var (baseProposerReward, _)
124+
= (blockReward * AllocateReward.BaseProposerRewardNumer)
125+
.DivRem(AllocateReward.BaseProposerRewardDenom);
126+
var (bonusProposerReward, _)
127+
= (blockReward * (205 + 307)
128+
* AllocateReward.BonusProposerRewardNumer)
129+
.DivRem((100 + (101 + 200) * 50 - 101 - 102 + 204 + 306)
130+
* AllocateReward.BonusProposerRewardDenom);
131+
FungibleAssetValue proposerReward = baseProposerReward + bonusProposerReward;
132+
FungibleAssetValue validatorRewardSum = blockReward - proposerReward;
133+
134+
var (validatorRewardA, _)
135+
= (validatorRewardSum * 205)
136+
.DivRem(100 + (101 + 200) * 50 - 101 - 102 + 204 + 306);
137+
var (commissionA, _)
138+
= (validatorRewardA * Validator.CommissionNumer)
139+
.DivRem(Validator.CommissionDenom);
140+
var (validatorRewardB, _)
141+
= (validatorRewardSum * 307)
142+
.DivRem(100 + (101 + 200) * 50 - 101 - 102 + 204 + 306);
143+
var (commissionB, _)
144+
= (validatorRewardB * Validator.CommissionNumer)
145+
.DivRem(Validator.CommissionDenom);
146+
147+
Assert.Equal(
148+
Asset.ConsensusToken * 0,
149+
_states.GetBalance(ReservedAddress.RewardPool, Asset.ConsensusToken));
150+
151+
Assert.Equal(
152+
Asset.GovernanceToken * (100 + (101 + 200) * 50 - 101 - 102 + 204 + 306),
153+
_states.GetBalance(ReservedAddress.BondedPool, Asset.GovernanceToken));
154+
155+
Assert.Equal(
156+
Asset.ConsensusToken * 205,
157+
_states.GetBalance(validatorAddressA, Asset.ConsensusToken));
158+
159+
Assert.Equal(
160+
Asset.ConsensusToken * 307,
161+
_states.GetBalance(validatorAddressB, Asset.ConsensusToken));
162+
163+
Assert.Equal(
164+
proposerReward + commissionA,
165+
_states.GetBalance(
166+
AllocateReward.RewardAddress(OperatorAddresses[3]), Asset.ConsensusToken));
167+
168+
Assert.Equal(
169+
commissionB,
170+
_states.GetBalance(
171+
AllocateReward.RewardAddress(OperatorAddresses[5]), Asset.ConsensusToken));
172+
173+
Address delegationAddressA
174+
= Delegation.DeriveAddress(DelegatorAddress, validatorAddressA);
175+
176+
Assert.Equal(
177+
Asset.ConsensusToken * 0,
178+
_states.GetBalance(
179+
AllocateReward.RewardAddress(DelegatorAddress), Asset.ConsensusToken));
180+
181+
var (delegatorToken, _)
182+
= (_states.GetBalance(
183+
ValidatorRewards.DeriveAddress(validatorAddressA, Asset.ConsensusToken),
184+
Asset.ConsensusToken)
185+
* _states.GetBalance(
186+
Delegation.DeriveAddress(DelegatorAddress, validatorAddressA),
187+
Asset.Share)
188+
.RawValue)
189+
.DivRem(ValidatorCtrl.GetValidator(_states, validatorAddressA)
190+
.DelegatorShares.RawValue);
191+
192+
_states = DelegateCtrl.Distribute(_states, _nativeTokens, delegationAddressA, 5);
193+
194+
Assert.Equal(
195+
delegatorToken,
196+
_states.GetBalance(
197+
AllocateReward.RewardAddress(DelegatorAddress), Asset.ConsensusToken));
198+
}
199+
}
200+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\Lib9c.DPoS\Lib9c.DPoS.csproj" />
11+
<ProjectReference Include="..\.Libplanet\Libplanet.Action\Libplanet.Action.csproj" />
12+
<ProjectReference Include="..\.Libplanet\Libplanet.Crypto\Libplanet.Crypto.csproj" />
13+
<ProjectReference Include="..\.Libplanet\Libplanet.Types\Libplanet.Types.csproj" />
14+
</ItemGroup>
15+
16+
</Project>

0 commit comments

Comments
 (0)