mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-29 09:45:18 +00:00
528be6350e
* add IterateAllDeployedCosmosCoinContracts method * refactor unpacking big int from erc20 query * add QueryERC20TotalSupply method * feat(evmutil): add CosmosCoinsFullyBackedInvariant * update changelog
440 lines
10 KiB
Go
440 lines
10 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
sdkmath "cosmossdk.io/math"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/kava-labs/kava/x/evmutil/testutil"
|
|
"github.com/kava-labs/kava/x/evmutil/types"
|
|
)
|
|
|
|
type keeperTestSuite struct {
|
|
testutil.Suite
|
|
}
|
|
|
|
func (suite *keeperTestSuite) SetupTest() {
|
|
suite.Suite.SetupTest()
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestGetAllAccounts() {
|
|
tests := []struct {
|
|
name string
|
|
expAccounts []types.Account
|
|
}{
|
|
{
|
|
"no accounts",
|
|
[]types.Account{},
|
|
},
|
|
{
|
|
"with accounts",
|
|
[]types.Account{
|
|
{Address: suite.Addrs[0], Balance: sdkmath.NewInt(100)},
|
|
{Address: suite.Addrs[1], Balance: sdkmath.NewInt(200)},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
for _, account := range tt.expAccounts {
|
|
suite.Keeper.SetBalance(suite.Ctx, account.Address, account.Balance)
|
|
}
|
|
|
|
accounts := suite.Suite.Keeper.GetAllAccounts(suite.Ctx)
|
|
if len(tt.expAccounts) == 0 {
|
|
suite.Require().Len(tt.expAccounts, 0)
|
|
} else {
|
|
suite.Require().Equal(tt.expAccounts, accounts)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestSetAccount_ZeroBalance() {
|
|
existingAccount := types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdkmath.NewInt(100),
|
|
}
|
|
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
|
|
suite.Require().NoError(err)
|
|
err = suite.Keeper.SetAccount(suite.Ctx, types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdk.ZeroInt(),
|
|
})
|
|
suite.Require().NoError(err)
|
|
bal := suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0])
|
|
suite.Require().Equal(sdk.ZeroInt(), bal)
|
|
expAcct := suite.Keeper.GetAccount(suite.Ctx, suite.Addrs[0])
|
|
suite.Require().Nil(expAcct)
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestSetAccount() {
|
|
existingAccount := types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdkmath.NewInt(100),
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
account types.Account
|
|
success bool
|
|
}{
|
|
{
|
|
"invalid address",
|
|
types.Account{Address: nil, Balance: sdkmath.NewInt(100)},
|
|
false,
|
|
},
|
|
{
|
|
"invalid balance",
|
|
types.Account{Address: suite.Addrs[0], Balance: sdkmath.NewInt(-100)},
|
|
false,
|
|
},
|
|
{
|
|
"empty account",
|
|
types.Account{},
|
|
false,
|
|
},
|
|
{
|
|
"valid account",
|
|
types.Account{Address: suite.Addrs[1], Balance: sdkmath.NewInt(100)},
|
|
true,
|
|
},
|
|
{
|
|
"replaces account",
|
|
types.Account{Address: suite.Addrs[0], Balance: sdkmath.NewInt(50)},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
|
|
suite.Require().NoError(err)
|
|
err = suite.Keeper.SetAccount(suite.Ctx, tt.account)
|
|
if tt.success {
|
|
suite.Require().NoError(err)
|
|
expAcct := suite.Keeper.GetAccount(suite.Ctx, tt.account.Address)
|
|
suite.Require().Equal(tt.account, *expAcct)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
suite.Require().Nil(suite.Keeper.GetAccount(suite.Ctx, suite.Addrs[1]))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestSendBalance() {
|
|
startingSenderBal := sdkmath.NewInt(100)
|
|
startingRecipientBal := sdkmath.NewInt(50)
|
|
tests := []struct {
|
|
name string
|
|
amt sdkmath.Int
|
|
expSenderBal sdkmath.Int
|
|
expRecipientBal sdkmath.Int
|
|
success bool
|
|
}{
|
|
{
|
|
"fails when sending negative amount",
|
|
sdkmath.NewInt(-5),
|
|
sdk.ZeroInt(),
|
|
sdk.ZeroInt(),
|
|
false,
|
|
},
|
|
{
|
|
"send zero amount",
|
|
sdk.ZeroInt(),
|
|
startingSenderBal,
|
|
startingRecipientBal,
|
|
true,
|
|
},
|
|
{
|
|
"fails when sender does not have enough balance",
|
|
sdkmath.NewInt(101),
|
|
sdk.ZeroInt(),
|
|
sdk.ZeroInt(),
|
|
false,
|
|
},
|
|
{
|
|
"send valid amount",
|
|
sdkmath.NewInt(80),
|
|
sdkmath.NewInt(20),
|
|
sdkmath.NewInt(130),
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
err := suite.Keeper.SetBalance(suite.Ctx, suite.Addrs[0], startingSenderBal)
|
|
suite.Require().NoError(err)
|
|
err = suite.Keeper.SetBalance(suite.Ctx, suite.Addrs[1], startingRecipientBal)
|
|
suite.Require().NoError(err)
|
|
|
|
err = suite.Keeper.SendBalance(suite.Ctx, suite.Addrs[0], suite.Addrs[1], tt.amt)
|
|
if tt.success {
|
|
suite.Require().NoError(err)
|
|
suite.Require().Equal(tt.expSenderBal, suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[0]))
|
|
suite.Require().Equal(tt.expRecipientBal, suite.Keeper.GetBalance(suite.Ctx, suite.Addrs[1]))
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestSetBalance() {
|
|
existingAccount := types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdkmath.NewInt(100),
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
address sdk.AccAddress
|
|
balance sdkmath.Int
|
|
success bool
|
|
}{
|
|
{
|
|
"invalid balance",
|
|
suite.Addrs[0],
|
|
sdkmath.NewInt(-100),
|
|
false,
|
|
},
|
|
{
|
|
"set new account balance",
|
|
suite.Addrs[1],
|
|
sdkmath.NewInt(100),
|
|
true,
|
|
},
|
|
{
|
|
"replace account balance",
|
|
suite.Addrs[0],
|
|
sdkmath.NewInt(50),
|
|
true,
|
|
},
|
|
{
|
|
"invalid address",
|
|
nil,
|
|
sdkmath.NewInt(100),
|
|
false,
|
|
},
|
|
{
|
|
"zero balance",
|
|
suite.Addrs[0],
|
|
sdk.ZeroInt(),
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
|
|
suite.Require().NoError(err)
|
|
err = suite.Keeper.SetBalance(suite.Ctx, tt.address, tt.balance)
|
|
if tt.success {
|
|
suite.Require().NoError(err)
|
|
expBal := suite.Keeper.GetBalance(suite.Ctx, tt.address)
|
|
suite.Require().Equal(expBal, tt.balance)
|
|
|
|
if tt.balance.IsZero() {
|
|
account := suite.Keeper.GetAccount(suite.Ctx, tt.address)
|
|
suite.Require().Nil(account)
|
|
}
|
|
} else {
|
|
suite.Require().Error(err)
|
|
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
|
|
suite.Require().Equal(expBal, existingAccount.Balance)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestRemoveBalance() {
|
|
existingAccount := types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdkmath.NewInt(100),
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
amt sdkmath.Int
|
|
expBal sdkmath.Int
|
|
success bool
|
|
}{
|
|
{
|
|
"fails if amount is negative",
|
|
sdkmath.NewInt(-10),
|
|
sdk.ZeroInt(),
|
|
false,
|
|
},
|
|
{
|
|
"remove zero amount",
|
|
sdk.ZeroInt(),
|
|
existingAccount.Balance,
|
|
true,
|
|
},
|
|
{
|
|
"not enough balance",
|
|
sdkmath.NewInt(101),
|
|
sdk.ZeroInt(),
|
|
false,
|
|
},
|
|
{
|
|
"remove full balance",
|
|
sdkmath.NewInt(100),
|
|
sdk.ZeroInt(),
|
|
true,
|
|
},
|
|
{
|
|
"remove some balance",
|
|
sdkmath.NewInt(10),
|
|
sdkmath.NewInt(90),
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
|
|
suite.Require().NoError(err)
|
|
err = suite.Keeper.RemoveBalance(suite.Ctx, existingAccount.Address, tt.amt)
|
|
if tt.success {
|
|
suite.Require().NoError(err)
|
|
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
|
|
suite.Require().Equal(expBal, tt.expBal)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
expBal := suite.Keeper.GetBalance(suite.Ctx, existingAccount.Address)
|
|
suite.Require().Equal(expBal, existingAccount.Balance)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestGetBalance() {
|
|
existingAccount := types.Account{
|
|
Address: suite.Addrs[0],
|
|
Balance: sdkmath.NewInt(100),
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
addr sdk.AccAddress
|
|
expBal sdkmath.Int
|
|
}{
|
|
{
|
|
"returns 0 balance if account does not exist",
|
|
suite.Addrs[1],
|
|
sdk.ZeroInt(),
|
|
},
|
|
{
|
|
"returns account balance",
|
|
suite.Addrs[0],
|
|
sdkmath.NewInt(100),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
suite.Run(tt.name, func() {
|
|
suite.SetupTest()
|
|
|
|
err := suite.Keeper.SetAccount(suite.Ctx, existingAccount)
|
|
suite.Require().NoError(err)
|
|
balance := suite.Keeper.GetBalance(suite.Ctx, tt.addr)
|
|
suite.Require().Equal(tt.expBal, balance)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestDeployedCosmosCoinContractStoreState() {
|
|
suite.Run("returns nil for nonexistent denom", func() {
|
|
suite.SetupTest()
|
|
addr, found := suite.Keeper.GetDeployedCosmosCoinContract(suite.Ctx, "undeployed-denom")
|
|
suite.False(found)
|
|
suite.Equal(addr, types.InternalEVMAddress{})
|
|
})
|
|
|
|
suite.Run("handles setting & getting a contract address", func() {
|
|
suite.SetupTest()
|
|
denom := "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2"
|
|
address := testutil.RandomInternalEVMAddress()
|
|
|
|
err := suite.Keeper.SetDeployedCosmosCoinContract(suite.Ctx, denom, address)
|
|
suite.NoError(err)
|
|
|
|
stored, found := suite.Keeper.GetDeployedCosmosCoinContract(suite.Ctx, denom)
|
|
suite.True(found)
|
|
suite.Equal(address, stored)
|
|
})
|
|
|
|
suite.Run("fails when setting an invalid denom", func() {
|
|
suite.SetupTest()
|
|
invalidDenom := ""
|
|
err := suite.Keeper.SetDeployedCosmosCoinContract(suite.Ctx, invalidDenom, testutil.RandomInternalEVMAddress())
|
|
suite.ErrorContains(err, "invalid cosmos denom")
|
|
})
|
|
|
|
suite.Run("fails when setting 0 address", func() {
|
|
suite.SetupTest()
|
|
invalidAddr := types.InternalEVMAddress{}
|
|
err := suite.Keeper.SetDeployedCosmosCoinContract(suite.Ctx, "denom", invalidAddr)
|
|
suite.ErrorContains(err, "attempting to register empty contract address")
|
|
})
|
|
}
|
|
|
|
func (suite *keeperTestSuite) TestIterateAllDeployedCosmosCoinContracts() {
|
|
suite.SetupTest()
|
|
address := testutil.RandomInternalEVMAddress()
|
|
denoms := []string{}
|
|
register := func(denom string) {
|
|
addr := testutil.RandomInternalEVMAddress()
|
|
if denom == "waldo" {
|
|
addr = address
|
|
}
|
|
err := suite.Keeper.SetDeployedCosmosCoinContract(suite.Ctx, denom, addr)
|
|
suite.NoError(err)
|
|
denoms = append(denoms, denom)
|
|
}
|
|
|
|
// register some contracts
|
|
register("magic")
|
|
register("popcorn")
|
|
register("waldo")
|
|
register("zzz")
|
|
register("ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2")
|
|
|
|
suite.Run("stops when told", func() {
|
|
// test out stopping the iteration
|
|
// NOTE: don't actually look for a single contract this way. the keys are deterministic by denom.
|
|
var contract types.DeployedCosmosCoinContract
|
|
suite.Keeper.IterateAllDeployedCosmosCoinContracts(suite.Ctx, func(c types.DeployedCosmosCoinContract) bool {
|
|
contract = c
|
|
return c.CosmosDenom == "waldo"
|
|
})
|
|
suite.Equal(types.NewDeployedCosmosCoinContract("waldo", address), contract)
|
|
})
|
|
|
|
suite.Run("iterates all contracts", func() {
|
|
foundDenoms := make([]string, 0, len(denoms))
|
|
suite.Keeper.IterateAllDeployedCosmosCoinContracts(suite.Ctx, func(c types.DeployedCosmosCoinContract) bool {
|
|
foundDenoms = append(foundDenoms, c.CosmosDenom)
|
|
return false
|
|
})
|
|
suite.Len(foundDenoms, len(denoms))
|
|
suite.ElementsMatch(denoms, foundDenoms)
|
|
})
|
|
}
|
|
|
|
func TestKeeperTestSuite(t *testing.T) {
|
|
suite.Run(t, new(keeperTestSuite))
|
|
}
|