mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-27 00:35:18 +00:00
9de9de671e
Module reserve represents fractional balances, so it should be hidden to consumers to not have a misleading total balance that doubles the fractional balances. This modifies GetBalance() and SpendableCoin() to always return zero coins when fetching the reserve address balance for fractional amounts.
203 lines
5.6 KiB
Go
203 lines
5.6 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
sdkmath "cosmossdk.io/math"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
|
|
|
"github.com/kava-labs/kava/x/precisebank/testutil"
|
|
"github.com/kava-labs/kava/x/precisebank/types"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type viewIntegrationTestSuite struct {
|
|
testutil.Suite
|
|
}
|
|
|
|
func (suite *viewIntegrationTestSuite) SetupTest() {
|
|
suite.Suite.SetupTest()
|
|
}
|
|
|
|
func TestViewIntegrationTestSuite(t *testing.T) {
|
|
suite.Run(t, new(viewIntegrationTestSuite))
|
|
}
|
|
|
|
func (suite *viewIntegrationTestSuite) TestKeeper_SpendableCoin() {
|
|
tests := []struct {
|
|
name string
|
|
giveDenom string // queried denom for balance
|
|
|
|
giveBankBal sdk.Coins // full balance
|
|
giveFractionalBal sdkmath.Int // stored fractional balance for giveAddr
|
|
giveLockedCoins sdk.Coins // locked coins
|
|
|
|
wantSpendableBal sdk.Coin
|
|
}{
|
|
{
|
|
"extended denom, no fractional - locked coins",
|
|
types.ExtendedCoinDenom,
|
|
// queried bank balance in ukava when querying for akava
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(1000))),
|
|
sdkmath.ZeroInt(),
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(10))),
|
|
// (integer + fractional) - locked
|
|
sdk.NewCoin(
|
|
types.ExtendedCoinDenom,
|
|
types.ConversionFactor().MulRaw(1000-10),
|
|
),
|
|
},
|
|
{
|
|
"extended denom, with fractional - locked coins",
|
|
types.ExtendedCoinDenom,
|
|
// queried bank balance in ukava when querying for akava
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(1000))),
|
|
sdkmath.NewInt(5000),
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(10))),
|
|
sdk.NewCoin(
|
|
types.ExtendedCoinDenom,
|
|
// (integer - locked) + fractional
|
|
types.ConversionFactor().MulRaw(1000-10).AddRaw(5000),
|
|
),
|
|
},
|
|
{
|
|
"non-extended denom - ukava returns ukava",
|
|
types.IntegerCoinDenom,
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(1000))),
|
|
sdkmath.ZeroInt(),
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(10))),
|
|
sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(990)),
|
|
},
|
|
{
|
|
"non-extended denom, with fractional - ukava returns ukava",
|
|
types.IntegerCoinDenom,
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(1000))),
|
|
// does not affect balance
|
|
sdkmath.NewInt(100),
|
|
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(10))),
|
|
sdk.NewCoin(types.IntegerCoinDenom, sdk.NewInt(990)),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
addr := sdk.AccAddress([]byte("test-address"))
|
|
|
|
suite.MintToAccount(addr, tt.giveBankBal)
|
|
|
|
// Set fractional balance in store before query
|
|
suite.Keeper.SetFractionalBalance(suite.Ctx, addr, tt.giveFractionalBal)
|
|
|
|
// Add some locked coins
|
|
acc := suite.AccountKeeper.GetAccount(suite.Ctx, addr)
|
|
if acc == nil {
|
|
acc = authtypes.NewBaseAccount(addr, nil, 0, 0)
|
|
}
|
|
|
|
vestingAcc := vestingtypes.NewPeriodicVestingAccount(
|
|
acc.(*authtypes.BaseAccount),
|
|
tt.giveLockedCoins,
|
|
suite.Ctx.BlockTime().Unix(),
|
|
vestingtypes.Periods{
|
|
vestingtypes.Period{
|
|
Length: 100,
|
|
Amount: tt.giveLockedCoins,
|
|
},
|
|
},
|
|
)
|
|
suite.AccountKeeper.SetAccount(suite.Ctx, vestingAcc)
|
|
|
|
fetchedLockedCoins := vestingAcc.LockedCoins(suite.Ctx.BlockTime())
|
|
suite.Require().Equal(
|
|
tt.giveLockedCoins,
|
|
fetchedLockedCoins,
|
|
"locked coins should be matching at current block time",
|
|
)
|
|
|
|
spendableCoinsWithLocked := suite.Keeper.SpendableCoin(suite.Ctx, addr, tt.giveDenom)
|
|
|
|
suite.Require().Equalf(
|
|
tt.wantSpendableBal,
|
|
spendableCoinsWithLocked,
|
|
"expected spendable coins of denom %s",
|
|
tt.giveDenom,
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *viewIntegrationTestSuite) TestKeeper_HiddenReserve() {
|
|
// Reserve balances should not be shown to consumers of x/precisebank, as it
|
|
// represents the fractional balances of accounts.
|
|
|
|
moduleAddr := authtypes.NewModuleAddress(types.ModuleName)
|
|
addr1 := sdk.AccAddress{1}
|
|
|
|
// Make the reserve hold a non-zero balance
|
|
// Mint fractional coins to an account, which should cause a mint of 1
|
|
// integer coin to the reserve to back it.
|
|
extCoin := sdk.NewCoin(types.ExtendedCoinDenom, types.ConversionFactor().AddRaw(1000))
|
|
unrelatedCoin := sdk.NewCoin("unrelated", sdk.NewInt(1000))
|
|
suite.MintToAccount(
|
|
addr1,
|
|
sdk.NewCoins(
|
|
extCoin,
|
|
unrelatedCoin,
|
|
),
|
|
)
|
|
|
|
// Check underlying x/bank balance for reserve
|
|
reserveIntCoin := suite.BankKeeper.GetBalance(suite.Ctx, moduleAddr, types.IntegerCoinDenom)
|
|
suite.Require().Equal(
|
|
sdkmath.NewInt(1),
|
|
reserveIntCoin.Amount,
|
|
"reserve should hold 1 integer coin",
|
|
)
|
|
|
|
tests := []struct {
|
|
name string
|
|
giveAddr sdk.AccAddress
|
|
giveDenom string
|
|
wantAmount sdkmath.Int
|
|
}{
|
|
{
|
|
"reserve account - hidden extended denom",
|
|
moduleAddr,
|
|
types.ExtendedCoinDenom,
|
|
sdkmath.ZeroInt(),
|
|
},
|
|
{
|
|
"reserve account - visible integer denom",
|
|
moduleAddr,
|
|
types.IntegerCoinDenom,
|
|
sdkmath.OneInt(),
|
|
},
|
|
{
|
|
"user account - visible extended denom",
|
|
addr1,
|
|
types.ExtendedCoinDenom,
|
|
extCoin.Amount,
|
|
},
|
|
{
|
|
"user account - visible integer denom",
|
|
addr1,
|
|
types.IntegerCoinDenom,
|
|
extCoin.Amount.Quo(types.ConversionFactor()),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
coin := suite.Keeper.GetBalance(suite.Ctx, tt.giveAddr, tt.giveDenom)
|
|
suite.Require().Equal(tt.wantAmount.Int64(), coin.Amount.Int64())
|
|
|
|
spendableCoin := suite.Keeper.SpendableCoin(suite.Ctx, tt.giveAddr, tt.giveDenom)
|
|
suite.Require().Equal(tt.wantAmount.Int64(), spendableCoin.Amount.Int64())
|
|
})
|
|
}
|
|
}
|