Skip to content

Commit 5e77a05

Browse files
authored
Merge pull request #2147 from boscohyun/feat/scenario-test-for-staking
more unit tests for "stake3" and "claim_stake_reward9"
2 parents 08e296d + b7f1a03 commit 5e77a05

File tree

5 files changed

+435
-159
lines changed

5 files changed

+435
-159
lines changed

.Lib9c.Tests/Action/ClaimStakeRewardTest.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ public ClaimStakeRewardTest(ITestOutputHelper outputHelper)
8080
_stakePolicySheet = initialStatesWithAvatarStateV2.GetSheet<StakePolicySheet>();
8181
}
8282

83+
// NOTE: object[] {
84+
// long startedBlockIndex,
85+
// long? receivedBlockIndex,
86+
// long stakedBalance,
87+
// long blockIndex,
88+
// (Address balanceAddr, FungibleAssetValue fav)[] expectedBalances,
89+
// (int itemSheetId, int count)[] expectedItems)
90+
// }
8391
public static IEnumerable<object[]>
8492
GetMemberData_Execute_Success_With_StakePolicySheetFixtureV1()
8593
{
@@ -200,6 +208,13 @@ public static IEnumerable<object[]>
200208
};
201209
}
202210

211+
// NOTE: object[] {
212+
// long startedBlockIndex,
213+
// long? receivedBlockIndex,
214+
// long stakedBalance,
215+
// long blockIndex,
216+
// (Address balanceAddr, FungibleAssetValue fav)[] expectedBalances,
217+
// (int itemSheetId, int count)[] expectedItems)
203218
public static IEnumerable<object[]>
204219
GetMemberData_Execute_Success_With_StakePolicySheetFixtureV2()
205220
{
@@ -651,11 +666,7 @@ private static StakeStateV2 PrepareStakeStateV2(
651666
long startedBlockIndex,
652667
long? receivedBlockIndex)
653668
{
654-
var contract = new Contract(
655-
stakePolicySheet.StakeRegularFixedRewardSheetValue,
656-
stakePolicySheet.StakeRegularRewardSheetValue,
657-
stakePolicySheet.RewardIntervalValue,
658-
stakePolicySheet.LockupIntervalValue);
669+
var contract = new Contract(stakePolicySheet);
659670
return receivedBlockIndex is null
660671
? new StakeStateV2(contract, startedBlockIndex)
661672
: new StakeStateV2(contract, startedBlockIndex, receivedBlockIndex.Value);
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
namespace Lib9c.Tests.Action.Scenario
2+
{
3+
using System.Collections.Generic;
4+
using Bencodex.Types;
5+
using Lib9c.Tests.Fixtures.TableCSV;
6+
using Lib9c.Tests.Fixtures.TableCSV.Stake;
7+
using Lib9c.Tests.Util;
8+
using Libplanet.Action.State;
9+
using Libplanet.Crypto;
10+
using Libplanet.Types.Assets;
11+
using Nekoyume;
12+
using Nekoyume.Action;
13+
using Nekoyume.Model.Stake;
14+
using Nekoyume.Model.State;
15+
using Nekoyume.TableData;
16+
using Nekoyume.TableData.Stake;
17+
using Serilog;
18+
using Xunit;
19+
using Xunit.Abstractions;
20+
21+
/// <summary>
22+
/// This class is used for testing the stake and claim scenario with patching table sheets.
23+
/// This class considers only AvatarStateV2 not AvatarState.
24+
/// </summary>
25+
public class StakeAndClaimScenarioTest
26+
{
27+
private readonly Address _agentAddr;
28+
private readonly Address _avatarAddr;
29+
private readonly IAccount _initialStateWithoutStakePolicySheet;
30+
private readonly Currency _ncg;
31+
32+
public StakeAndClaimScenarioTest(ITestOutputHelper output)
33+
{
34+
Log.Logger = new LoggerConfiguration()
35+
.MinimumLevel.Verbose()
36+
.WriteTo.TestOutput(output)
37+
.CreateLogger();
38+
39+
var tuple = InitializeUtil.InitializeStates(
40+
sheetsOverride: new Dictionary<string, string>
41+
{
42+
{
43+
nameof(GameConfigSheet),
44+
GameConfigSheetFixtures.Default
45+
},
46+
{
47+
"StakeRegularFixedRewardSheet_V1",
48+
StakeRegularFixedRewardSheetFixtures.V1
49+
},
50+
{
51+
"StakeRegularFixedRewardSheet_V2",
52+
StakeRegularFixedRewardSheetFixtures.V2
53+
},
54+
{
55+
"StakeRegularRewardSheet_V1",
56+
StakeRegularRewardSheetFixtures.V1
57+
},
58+
{
59+
"StakeRegularRewardSheet_V2",
60+
StakeRegularRewardSheetFixtures.V2
61+
},
62+
{
63+
nameof(StakePolicySheet),
64+
StakePolicySheetFixtures.V2
65+
},
66+
});
67+
_agentAddr = tuple.agentAddr;
68+
_avatarAddr = tuple.avatarAddr;
69+
_initialStateWithoutStakePolicySheet = tuple.initialStatesWithAvatarStateV2;
70+
_ncg = _initialStateWithoutStakePolicySheet.GetGoldCurrency();
71+
}
72+
73+
[Fact]
74+
public void Test()
75+
{
76+
// Mint NCG to agent.
77+
var state = MintAsset(
78+
_initialStateWithoutStakePolicySheet,
79+
_agentAddr,
80+
10_000_000 * _ncg,
81+
0);
82+
83+
// Stake 50 NCG via stake2.
84+
const long stakedAmount = 50;
85+
const int stake2BlockIndex = 1;
86+
state = Stake2(state, _agentAddr, stakedAmount, stake2BlockIndex);
87+
88+
// Validate staked.
89+
var stakedNCG = stakedAmount * _ncg;
90+
ValidateStakedState(state, _agentAddr, stakedNCG, stake2BlockIndex);
91+
92+
// Claim stake reward via claim_stake_reward9.
93+
state = ClaimStakeReward9(
94+
state,
95+
_agentAddr,
96+
_avatarAddr,
97+
stake2BlockIndex + StakeState.LockupInterval);
98+
99+
// Validate staked.
100+
ValidateStakedStateV2(
101+
state,
102+
_agentAddr,
103+
stakedNCG,
104+
stake2BlockIndex,
105+
"StakeRegularFixedRewardSheet_V1",
106+
"StakeRegularRewardSheet_V1",
107+
StakeState.RewardInterval,
108+
StakeState.LockupInterval);
109+
110+
// Withdraw stake via stake3.
111+
state = Stake3(state, _agentAddr, 0, stake2BlockIndex + StakeState.LockupInterval + 1);
112+
113+
// Stake 50 NCG via stake3 before patching.
114+
const long firstStake3BlockIndex = stake2BlockIndex + StakeState.LockupInterval + 1;
115+
state = Stake3(
116+
state,
117+
_agentAddr,
118+
stakedAmount,
119+
firstStake3BlockIndex);
120+
121+
// Validate staked.
122+
ValidateStakedStateV2(
123+
state,
124+
_agentAddr,
125+
stakedNCG,
126+
firstStake3BlockIndex,
127+
"StakeRegularFixedRewardSheet_V2",
128+
"StakeRegularRewardSheet_V2",
129+
50_400,
130+
201_600);
131+
132+
// Patch StakePolicySheet and so on.
133+
state = state.SetState(
134+
Addresses.GetSheetAddress(nameof(StakePolicySheet)),
135+
StakePolicySheetFixtures.V3.Serialize());
136+
137+
// Stake 50 NCG via stake3 after patching.
138+
state = Stake3(
139+
state,
140+
_agentAddr,
141+
stakedAmount,
142+
firstStake3BlockIndex + 1);
143+
144+
// Validate staked.
145+
ValidateStakedStateV2(
146+
state,
147+
_agentAddr,
148+
stakedNCG,
149+
firstStake3BlockIndex + 1,
150+
"StakeRegularFixedRewardSheet_V1",
151+
"StakeRegularRewardSheet_V1",
152+
40,
153+
150);
154+
}
155+
156+
private static IAccount MintAsset(
157+
IAccount state,
158+
Address recipient,
159+
FungibleAssetValue amount,
160+
long blockIndex)
161+
{
162+
return state.MintAsset(
163+
new ActionContext
164+
{
165+
PreviousState = state,
166+
Signer = Addresses.Admin,
167+
BlockIndex = blockIndex,
168+
Rehearsal = false,
169+
},
170+
recipient,
171+
amount);
172+
}
173+
174+
private static IAccount Stake2(
175+
IAccount state,
176+
Address agentAddr,
177+
long stakingAmount,
178+
long blockIndex)
179+
{
180+
var stake2 = new Stake2(stakingAmount);
181+
return stake2.Execute(new ActionContext
182+
{
183+
PreviousState = state,
184+
Signer = agentAddr,
185+
BlockIndex = blockIndex,
186+
Rehearsal = false,
187+
});
188+
}
189+
190+
private static IAccount Stake3(
191+
IAccount state,
192+
Address agentAddr,
193+
long stakingAmount,
194+
long blockIndex)
195+
{
196+
var stake3 = new Stake(stakingAmount);
197+
return stake3.Execute(new ActionContext
198+
{
199+
PreviousState = state,
200+
Signer = agentAddr,
201+
BlockIndex = blockIndex,
202+
Rehearsal = false,
203+
});
204+
}
205+
206+
private static IAccount ClaimStakeReward9(
207+
IAccount state,
208+
Address agentAddr,
209+
Address avatarAddr,
210+
long blockIndex)
211+
{
212+
var claimStakingReward9 = new ClaimStakeReward(avatarAddr);
213+
return claimStakingReward9.Execute(new ActionContext
214+
{
215+
PreviousState = state,
216+
Signer = agentAddr,
217+
BlockIndex = blockIndex,
218+
Rehearsal = false,
219+
});
220+
}
221+
222+
private static void ValidateStakedState(
223+
IAccountState state,
224+
Address agentAddr,
225+
FungibleAssetValue expectStakedAmount,
226+
long expectStartedBlockIndex)
227+
{
228+
var stakeAddr = StakeState.DeriveAddress(agentAddr);
229+
var actualStakedAmount = state.GetBalance(stakeAddr, expectStakedAmount.Currency);
230+
Assert.Equal(expectStakedAmount, actualStakedAmount);
231+
var stakeState = new StakeState((Dictionary)state.GetState(stakeAddr));
232+
Assert.Equal(expectStartedBlockIndex, stakeState.StartedBlockIndex);
233+
}
234+
235+
private static void ValidateStakedStateV2(
236+
IAccountState state,
237+
Address agentAddr,
238+
FungibleAssetValue expectStakedAmount,
239+
long expectStartedBlockIndex,
240+
string expectStakeRegularFixedRewardSheetName,
241+
string expectStakeRegularRewardSheetName,
242+
long expectRewardInterval,
243+
long expectLockupInterval)
244+
{
245+
var stakeAddr = StakeState.DeriveAddress(agentAddr);
246+
var actualStakedAmount = state.GetBalance(stakeAddr, expectStakedAmount.Currency);
247+
Assert.Equal(expectStakedAmount, actualStakedAmount);
248+
var stakeState = new StakeStateV2(state.GetState(stakeAddr));
249+
Assert.Equal(expectStartedBlockIndex, stakeState.StartedBlockIndex);
250+
Assert.Equal(
251+
expectStakeRegularFixedRewardSheetName,
252+
stakeState.Contract.StakeRegularFixedRewardSheetTableName);
253+
Assert.Equal(
254+
expectStakeRegularRewardSheetName,
255+
stakeState.Contract.StakeRegularRewardSheetTableName);
256+
Assert.Equal(expectRewardInterval, stakeState.Contract.RewardInterval);
257+
Assert.Equal(expectLockupInterval, stakeState.Contract.LockupInterval);
258+
}
259+
}
260+
}

0 commit comments

Comments
 (0)