Skip to content

Commit 0a653dd

Browse files
committed
test: added integration test for supply-burn upgrade
1 parent c1b418c commit 0a653dd

1 file changed

Lines changed: 227 additions & 0 deletions

File tree

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package integrationtest
2+
3+
import (
4+
"testing"
5+
6+
sdkmath "cosmossdk.io/math"
7+
sdk "github.com/cosmos/cosmos-sdk/types"
8+
"github.com/stretchr/testify/require"
9+
10+
supplyburn "github.com/pushchain/push-chain-node/app/upgrades/supply-burn"
11+
pchaintypes "github.com/pushchain/push-chain-node/types"
12+
utils "github.com/pushchain/push-chain-node/test/utils"
13+
)
14+
15+
func TestExecuteBurnEntries_BurnAll(t *testing.T) {
16+
chainApp := utils.SetupApp(t)
17+
ctx := chainApp.BaseApp.NewContext(true)
18+
19+
// Fund account with 1000 PC, keep_pc=0 → burn entire spendable balance
20+
addr := sdk.AccAddress([]byte("test-burn-account-1 "))
21+
acc := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr)
22+
chainApp.AccountKeeper.SetAccount(ctx, acc)
23+
24+
fundAmt := sdkmath.NewInt(1000).Mul(onePCInUPC)
25+
fundCoins := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, fundAmt))
26+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, fundCoins))
27+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr, fundCoins))
28+
29+
entries := []supplyburn.BurnEntry{
30+
{Address: addr.String(), KeepPC: 0},
31+
}
32+
33+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
34+
35+
require.Equal(t, fundAmt, totalBurned, "should burn the entire 1000 PC")
36+
require.Equal(t, 1, success)
37+
require.Equal(t, 0, skipped)
38+
require.Equal(t, 0, errCount)
39+
40+
// Account must be empty
41+
bal := chainApp.BankKeeper.GetAllBalances(ctx, addr).AmountOf(pchaintypes.BaseDenom)
42+
require.True(t, bal.IsZero(), "account should be empty after burn-all")
43+
}
44+
45+
func TestExecuteBurnEntries_KeepPartial(t *testing.T) {
46+
chainApp := utils.SetupApp(t)
47+
ctx := chainApp.BaseApp.NewContext(true)
48+
49+
// Fund account with 1000 PC, keep_pc=100 → burn 900 PC
50+
addr := sdk.AccAddress([]byte("test-burn-account-2 "))
51+
acc := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr)
52+
chainApp.AccountKeeper.SetAccount(ctx, acc)
53+
54+
fundAmt := sdkmath.NewInt(1000).Mul(onePCInUPC)
55+
fundCoins := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, fundAmt))
56+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, fundCoins))
57+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr, fundCoins))
58+
59+
entries := []supplyburn.BurnEntry{
60+
{Address: addr.String(), KeepPC: 100},
61+
}
62+
63+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
64+
65+
expectedBurn := sdkmath.NewInt(900).Mul(onePCInUPC)
66+
require.Equal(t, expectedBurn, totalBurned, "should burn exactly 900 PC")
67+
require.Equal(t, 1, success)
68+
require.Equal(t, 0, skipped)
69+
require.Equal(t, 0, errCount)
70+
71+
// Account must have exactly 100 PC
72+
bal := chainApp.BankKeeper.GetAllBalances(ctx, addr).AmountOf(pchaintypes.BaseDenom)
73+
require.Equal(t, sdkmath.NewInt(100).Mul(onePCInUPC), bal,
74+
"account should have exactly 100 PC remaining")
75+
}
76+
77+
func TestExecuteBurnEntries_SkipWhenSpendableLEKeep(t *testing.T) {
78+
chainApp := utils.SetupApp(t)
79+
ctx := chainApp.BaseApp.NewContext(true)
80+
81+
// Fund account with 50 PC, keep_pc=100 → spendable <= keep → skip
82+
addr := sdk.AccAddress([]byte("test-burn-account-3 "))
83+
acc := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr)
84+
chainApp.AccountKeeper.SetAccount(ctx, acc)
85+
86+
fundAmt := sdkmath.NewInt(50).Mul(onePCInUPC)
87+
fundCoins := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, fundAmt))
88+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, fundCoins))
89+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr, fundCoins))
90+
91+
entries := []supplyburn.BurnEntry{
92+
{Address: addr.String(), KeepPC: 100},
93+
}
94+
95+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
96+
97+
require.Equal(t, sdkmath.ZeroInt(), totalBurned, "nothing should be burned")
98+
require.Equal(t, 0, success)
99+
require.Equal(t, 1, skipped, "entry should be skipped, not errored")
100+
require.Equal(t, 0, errCount)
101+
102+
// Balance must be unchanged
103+
bal := chainApp.BankKeeper.GetAllBalances(ctx, addr).AmountOf(pchaintypes.BaseDenom)
104+
require.Equal(t, fundAmt, bal, "balance should be unchanged when skipped")
105+
}
106+
107+
func TestExecuteBurnEntries_SkipZeroBalance(t *testing.T) {
108+
chainApp := utils.SetupApp(t)
109+
ctx := chainApp.BaseApp.NewContext(true)
110+
111+
// Account exists but has no funds, keep_pc=0 → skip (nothing to burn)
112+
addr := sdk.AccAddress([]byte("test-burn-account-4 "))
113+
acc := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr)
114+
chainApp.AccountKeeper.SetAccount(ctx, acc)
115+
116+
entries := []supplyburn.BurnEntry{
117+
{Address: addr.String(), KeepPC: 0},
118+
}
119+
120+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
121+
122+
require.Equal(t, sdkmath.ZeroInt(), totalBurned)
123+
require.Equal(t, 0, success)
124+
require.Equal(t, 1, skipped)
125+
require.Equal(t, 0, errCount)
126+
}
127+
128+
func TestExecuteBurnEntries_InvalidAddress(t *testing.T) {
129+
chainApp := utils.SetupApp(t)
130+
ctx := chainApp.BaseApp.NewContext(true)
131+
132+
entries := []supplyburn.BurnEntry{
133+
{Address: "not-a-valid-bech32-address", KeepPC: 0},
134+
}
135+
136+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
137+
138+
require.Equal(t, sdkmath.ZeroInt(), totalBurned)
139+
require.Equal(t, 0, success)
140+
require.Equal(t, 0, skipped)
141+
require.Equal(t, 1, errCount, "invalid bech32 address should be counted as an error")
142+
}
143+
144+
func TestExecuteBurnEntries_MultipleEntries(t *testing.T) {
145+
chainApp := utils.SetupApp(t)
146+
ctx := chainApp.BaseApp.NewContext(true)
147+
148+
// addr1: 1000 PC, keep=0 → burn 1000 PC
149+
addr1 := sdk.AccAddress([]byte("test-burn-account-5 "))
150+
acc1 := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr1)
151+
chainApp.AccountKeeper.SetAccount(ctx, acc1)
152+
coins1 := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, sdkmath.NewInt(1000).Mul(onePCInUPC)))
153+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, coins1))
154+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr1, coins1))
155+
156+
// addr2: 500 PC, keep=200 → burn 300 PC
157+
addr2 := sdk.AccAddress([]byte("test-burn-account-6 "))
158+
acc2 := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr2)
159+
chainApp.AccountKeeper.SetAccount(ctx, acc2)
160+
coins2 := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, sdkmath.NewInt(500).Mul(onePCInUPC)))
161+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, coins2))
162+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr2, coins2))
163+
164+
// addr3: 50 PC, keep=100 → spendable <= keep → skip
165+
addr3 := sdk.AccAddress([]byte("test-burn-account-7 "))
166+
acc3 := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr3)
167+
chainApp.AccountKeeper.SetAccount(ctx, acc3)
168+
coins3 := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, sdkmath.NewInt(50).Mul(onePCInUPC)))
169+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, coins3))
170+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr3, coins3))
171+
172+
entries := []supplyburn.BurnEntry{
173+
{Address: addr1.String(), KeepPC: 0}, // burn 1000 PC
174+
{Address: addr2.String(), KeepPC: 200}, // burn 300 PC
175+
{Address: addr3.String(), KeepPC: 100}, // skip (50 < 100)
176+
{Address: "bad-addr", KeepPC: 0}, // invalid → error
177+
}
178+
179+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
180+
181+
// 1000 + 300 = 1300 PC burned
182+
require.Equal(t, sdkmath.NewInt(1300).Mul(onePCInUPC), totalBurned)
183+
require.Equal(t, 2, success)
184+
require.Equal(t, 1, skipped)
185+
require.Equal(t, 1, errCount)
186+
187+
// addr1 must be empty
188+
bal1 := chainApp.BankKeeper.GetAllBalances(ctx, addr1).AmountOf(pchaintypes.BaseDenom)
189+
require.True(t, bal1.IsZero(), "addr1 should be fully burned")
190+
191+
// addr2 must have exactly 200 PC
192+
bal2 := chainApp.BankKeeper.GetAllBalances(ctx, addr2).AmountOf(pchaintypes.BaseDenom)
193+
require.Equal(t, sdkmath.NewInt(200).Mul(onePCInUPC), bal2, "addr2 should keep 200 PC")
194+
195+
// addr3 must be unchanged (50 PC)
196+
bal3 := chainApp.BankKeeper.GetAllBalances(ctx, addr3).AmountOf(pchaintypes.BaseDenom)
197+
require.Equal(t, sdkmath.NewInt(50).Mul(onePCInUPC), bal3, "addr3 should be unchanged")
198+
}
199+
200+
func TestExecuteBurnEntries_ExactKeepEqualsSpendable(t *testing.T) {
201+
chainApp := utils.SetupApp(t)
202+
ctx := chainApp.BaseApp.NewContext(true)
203+
204+
// Fund 100 PC, keep=100 → spendable == keep → skip (nothing to burn)
205+
addr := sdk.AccAddress([]byte("test-burn-account-8 "))
206+
acc := chainApp.AccountKeeper.NewAccountWithAddress(ctx, addr)
207+
chainApp.AccountKeeper.SetAccount(ctx, acc)
208+
209+
fundAmt := sdkmath.NewInt(100).Mul(onePCInUPC)
210+
fundCoins := sdk.NewCoins(sdk.NewCoin(pchaintypes.BaseDenom, fundAmt))
211+
require.NoError(t, chainApp.BankKeeper.MintCoins(ctx, utils.MintModule, fundCoins))
212+
require.NoError(t, chainApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, utils.MintModule, addr, fundCoins))
213+
214+
entries := []supplyburn.BurnEntry{
215+
{Address: addr.String(), KeepPC: 100},
216+
}
217+
218+
totalBurned, success, skipped, errCount := supplyburn.ExecuteBurnEntries(ctx, chainApp.BankKeeper, entries)
219+
220+
require.Equal(t, sdkmath.ZeroInt(), totalBurned)
221+
require.Equal(t, 0, success)
222+
require.Equal(t, 1, skipped, "equal spendable and keep should be skipped")
223+
require.Equal(t, 0, errCount)
224+
225+
bal := chainApp.BankKeeper.GetAllBalances(ctx, addr).AmountOf(pchaintypes.BaseDenom)
226+
require.Equal(t, fundAmt, bal, "balance should be unchanged")
227+
}

0 commit comments

Comments
 (0)