0g-chain/x/incentive/testutil/integration.go

665 lines
23 KiB
Go
Raw Normal View History

package testutil
import (
"errors"
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
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"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
proposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/suite"
abcitypes "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/kava-labs/kava/app"
cdpkeeper "github.com/kava-labs/kava/x/cdp/keeper"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
committeetypes "github.com/kava-labs/kava/x/committee/types"
earnkeeper "github.com/kava-labs/kava/x/earn/keeper"
earntypes "github.com/kava-labs/kava/x/earn/types"
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
hardtypes "github.com/kava-labs/kava/x/hard/types"
incentivekeeper "github.com/kava-labs/kava/x/incentive/keeper"
"github.com/kava-labs/kava/x/incentive/types"
liquidkeeper "github.com/kava-labs/kava/x/liquid/keeper"
liquidtypes "github.com/kava-labs/kava/x/liquid/types"
routerkeeper "github.com/kava-labs/kava/x/router/keeper"
routertypes "github.com/kava-labs/kava/x/router/types"
swapkeeper "github.com/kava-labs/kava/x/swap/keeper"
swaptypes "github.com/kava-labs/kava/x/swap/types"
)
Add EVM Support (#1215) * ibc v3 upgrade * ibc no longer uses confio * add proofs proto for ibc/v3 * wip add ethermint module * update cosmos to 0.45.0 * add ethermint proto & bug fixes * remove todo * update docs * fix a number of bugs * minor comments update * fix breaking tests * Wrap bank keeper for EVM to convert decimals (#1154) * Add bankkeeper wrapper for evm * Remove agas from init-new-chain.sh, use ukava for evm_denom * Fix sdk.Coins conversion, require min 1 coin amount * Remove gas from init script idk how this happened lol * Remove debug logging stmt * Restore original init ukava amounts * Fix inplace coins conversion * Use evmtypes.BankKeeper interface insteadof banktypes * Add TestGetBalance * Add doc comments, remove temp actualAmt vars actualAmt vars replaced with inline calls to make it more clear that the converted value is being used, as opposed to accidentally reusing the raw EVM amt. * Add TestSetBalance * Add TestIdempotentConversion * Panic if converted coin from EVM is 0 This happens if a value is less than 1ukava * Deep copy coins instead of in place modification * Update test coins amount * Add panic tests for small EVM amounts * Use evmtypes.BankKeeper as NewEVMBankKeeper param * Tidy test setup * ensure sdk config is set when creating new apps * Respond EVM bank keeper GetBalance with SpendableCoins Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> * further speed up docker builds * feat: restore previous keys add defaults, add eth flag (#1172) * feat: restore previous keys add defaults, add eth flag * remove outdated comment * fix: remove redundant flag default * evm bank keeper with akava handling * fix issues * add remaining tests * add emv module to app * add missing imports * clean up comments * wip akava keeper * evm keeper * fix genesis import * reduce module permissions * add bank keeper tests * cleanup tests * genesis tests * change defaults * add eth faucet key & fix issues * switch to kava ethermint * add a lot of tests * add balances invariant * add evm tests * Remove panic if Swagger disabled in config (#1155) (#1183) Co-authored-by: Derrick Lee <derrick@dlee.dev> * add invariant to catch any akava balance > 1 ukava * clarify name of balances invariant * connect invariants to app * fix evmbankkeeper akava issues * add spec for evmutil * remove zero balance accounts from state * minor adustments * update to ethermint 0.10.0 * fix eth ante * add missing godoc comment * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update ethermint to v0.12 (#1203) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * evm migrations for tesnet alpha 2 (#1206) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * add upgrade handler for evm-alpha testnet 2 * v17 migration setup + evm modules * refactor migrate states * x/feemarket migration * v17 migrations setup + evm modules migration (#1210) * v17 migration setup + evm modules * refactor migrate states * update gen time * fix: update genesis time in test output Co-authored-by: karzak <kjydavis3@gmail.com> * add savings module to app blockers Co-authored-by: Derrick Lee <derrick@dlee.dev> Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: karzak <kjydavis3@gmail.com>
2022-04-21 20:16:28 +00:00
var testChainID = "kavatest_1-1"
type IntegrationTester struct {
suite.Suite
App app.TestApp
Ctx sdk.Context
GenesisTime time.Time
}
func (suite *IntegrationTester) SetupSuite() {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
// Default genesis time, can be overridden with WithGenesisTime
suite.GenesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC)
}
func (suite *IntegrationTester) SetApp() {
suite.App = app.NewTestApp()
}
func (suite *IntegrationTester) SetupTest() {
suite.SetApp()
}
func (suite *IntegrationTester) WithGenesisTime(genesisTime time.Time) {
suite.GenesisTime = genesisTime
}
func (suite *IntegrationTester) StartChainWithBuilders(builders ...GenesisBuilder) {
var builtGenStates []app.GenesisState
for _, builder := range builders {
builtGenStates = append(builtGenStates, builder.BuildMarshalled(suite.App.AppCodec()))
}
suite.StartChain(builtGenStates...)
}
func (suite *IntegrationTester) StartChain(genesisStates ...app.GenesisState) {
Add EVM Support (#1215) * ibc v3 upgrade * ibc no longer uses confio * add proofs proto for ibc/v3 * wip add ethermint module * update cosmos to 0.45.0 * add ethermint proto & bug fixes * remove todo * update docs * fix a number of bugs * minor comments update * fix breaking tests * Wrap bank keeper for EVM to convert decimals (#1154) * Add bankkeeper wrapper for evm * Remove agas from init-new-chain.sh, use ukava for evm_denom * Fix sdk.Coins conversion, require min 1 coin amount * Remove gas from init script idk how this happened lol * Remove debug logging stmt * Restore original init ukava amounts * Fix inplace coins conversion * Use evmtypes.BankKeeper interface insteadof banktypes * Add TestGetBalance * Add doc comments, remove temp actualAmt vars actualAmt vars replaced with inline calls to make it more clear that the converted value is being used, as opposed to accidentally reusing the raw EVM amt. * Add TestSetBalance * Add TestIdempotentConversion * Panic if converted coin from EVM is 0 This happens if a value is less than 1ukava * Deep copy coins instead of in place modification * Update test coins amount * Add panic tests for small EVM amounts * Use evmtypes.BankKeeper as NewEVMBankKeeper param * Tidy test setup * ensure sdk config is set when creating new apps * Respond EVM bank keeper GetBalance with SpendableCoins Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> * further speed up docker builds * feat: restore previous keys add defaults, add eth flag (#1172) * feat: restore previous keys add defaults, add eth flag * remove outdated comment * fix: remove redundant flag default * evm bank keeper with akava handling * fix issues * add remaining tests * add emv module to app * add missing imports * clean up comments * wip akava keeper * evm keeper * fix genesis import * reduce module permissions * add bank keeper tests * cleanup tests * genesis tests * change defaults * add eth faucet key & fix issues * switch to kava ethermint * add a lot of tests * add balances invariant * add evm tests * Remove panic if Swagger disabled in config (#1155) (#1183) Co-authored-by: Derrick Lee <derrick@dlee.dev> * add invariant to catch any akava balance > 1 ukava * clarify name of balances invariant * connect invariants to app * fix evmbankkeeper akava issues * add spec for evmutil * remove zero balance accounts from state * minor adustments * update to ethermint 0.10.0 * fix eth ante * add missing godoc comment * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update ethermint to v0.12 (#1203) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * evm migrations for tesnet alpha 2 (#1206) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * add upgrade handler for evm-alpha testnet 2 * v17 migration setup + evm modules * refactor migrate states * x/feemarket migration * v17 migrations setup + evm modules migration (#1210) * v17 migration setup + evm modules * refactor migrate states * update gen time * fix: update genesis time in test output Co-authored-by: karzak <kjydavis3@gmail.com> * add savings module to app blockers Co-authored-by: Derrick Lee <derrick@dlee.dev> Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: karzak <kjydavis3@gmail.com>
2022-04-21 20:16:28 +00:00
suite.App.InitializeFromGenesisStatesWithTimeAndChainID(
suite.GenesisTime,
Add EVM Support (#1215) * ibc v3 upgrade * ibc no longer uses confio * add proofs proto for ibc/v3 * wip add ethermint module * update cosmos to 0.45.0 * add ethermint proto & bug fixes * remove todo * update docs * fix a number of bugs * minor comments update * fix breaking tests * Wrap bank keeper for EVM to convert decimals (#1154) * Add bankkeeper wrapper for evm * Remove agas from init-new-chain.sh, use ukava for evm_denom * Fix sdk.Coins conversion, require min 1 coin amount * Remove gas from init script idk how this happened lol * Remove debug logging stmt * Restore original init ukava amounts * Fix inplace coins conversion * Use evmtypes.BankKeeper interface insteadof banktypes * Add TestGetBalance * Add doc comments, remove temp actualAmt vars actualAmt vars replaced with inline calls to make it more clear that the converted value is being used, as opposed to accidentally reusing the raw EVM amt. * Add TestSetBalance * Add TestIdempotentConversion * Panic if converted coin from EVM is 0 This happens if a value is less than 1ukava * Deep copy coins instead of in place modification * Update test coins amount * Add panic tests for small EVM amounts * Use evmtypes.BankKeeper as NewEVMBankKeeper param * Tidy test setup * ensure sdk config is set when creating new apps * Respond EVM bank keeper GetBalance with SpendableCoins Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> * further speed up docker builds * feat: restore previous keys add defaults, add eth flag (#1172) * feat: restore previous keys add defaults, add eth flag * remove outdated comment * fix: remove redundant flag default * evm bank keeper with akava handling * fix issues * add remaining tests * add emv module to app * add missing imports * clean up comments * wip akava keeper * evm keeper * fix genesis import * reduce module permissions * add bank keeper tests * cleanup tests * genesis tests * change defaults * add eth faucet key & fix issues * switch to kava ethermint * add a lot of tests * add balances invariant * add evm tests * Remove panic if Swagger disabled in config (#1155) (#1183) Co-authored-by: Derrick Lee <derrick@dlee.dev> * add invariant to catch any akava balance > 1 ukava * clarify name of balances invariant * connect invariants to app * fix evmbankkeeper akava issues * add spec for evmutil * remove zero balance accounts from state * minor adustments * update to ethermint 0.10.0 * fix eth ante * add missing godoc comment * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update ethermint to v0.12 (#1203) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * evm migrations for tesnet alpha 2 (#1206) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * add upgrade handler for evm-alpha testnet 2 * v17 migration setup + evm modules * refactor migrate states * x/feemarket migration * v17 migrations setup + evm modules migration (#1210) * v17 migration setup + evm modules * refactor migrate states * update gen time * fix: update genesis time in test output Co-authored-by: karzak <kjydavis3@gmail.com> * add savings module to app blockers Co-authored-by: Derrick Lee <derrick@dlee.dev> Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: karzak <kjydavis3@gmail.com>
2022-04-21 20:16:28 +00:00
testChainID,
genesisStates...,
)
suite.Ctx = suite.App.NewContext(false, tmproto.Header{
Height: 1,
Time: suite.GenesisTime,
ChainID: testChainID,
})
}
func (suite *IntegrationTester) NextBlockAfter(blockDuration time.Duration) {
suite.NextBlockAfterWithReq(
blockDuration,
abcitypes.RequestEndBlock{},
abcitypes.RequestBeginBlock{},
)
}
func (suite *IntegrationTester) NextBlockAfterWithReq(
blockDuration time.Duration,
reqEnd abcitypes.RequestEndBlock,
reqBegin abcitypes.RequestBeginBlock,
) (abcitypes.ResponseEndBlock, abcitypes.ResponseBeginBlock) {
return suite.NextBlockAtWithRequest(
suite.Ctx.BlockTime().Add(blockDuration),
reqEnd,
reqBegin,
)
}
func (suite *IntegrationTester) NextBlockAt(
blockTime time.Time,
) (abcitypes.ResponseEndBlock, abcitypes.ResponseBeginBlock) {
return suite.NextBlockAtWithRequest(
blockTime,
abcitypes.RequestEndBlock{},
abcitypes.RequestBeginBlock{},
)
}
func (suite *IntegrationTester) NextBlockAtWithRequest(
blockTime time.Time,
reqEnd abcitypes.RequestEndBlock,
reqBegin abcitypes.RequestBeginBlock,
) (abcitypes.ResponseEndBlock, abcitypes.ResponseBeginBlock) {
if !suite.Ctx.BlockTime().Before(blockTime) {
panic(fmt.Sprintf("new block time %s must be after current %s", blockTime, suite.Ctx.BlockTime()))
}
blockHeight := suite.Ctx.BlockHeight() + 1
responseEndBlock := suite.App.EndBlocker(suite.Ctx, reqEnd)
Add EVM Support (#1215) * ibc v3 upgrade * ibc no longer uses confio * add proofs proto for ibc/v3 * wip add ethermint module * update cosmos to 0.45.0 * add ethermint proto & bug fixes * remove todo * update docs * fix a number of bugs * minor comments update * fix breaking tests * Wrap bank keeper for EVM to convert decimals (#1154) * Add bankkeeper wrapper for evm * Remove agas from init-new-chain.sh, use ukava for evm_denom * Fix sdk.Coins conversion, require min 1 coin amount * Remove gas from init script idk how this happened lol * Remove debug logging stmt * Restore original init ukava amounts * Fix inplace coins conversion * Use evmtypes.BankKeeper interface insteadof banktypes * Add TestGetBalance * Add doc comments, remove temp actualAmt vars actualAmt vars replaced with inline calls to make it more clear that the converted value is being used, as opposed to accidentally reusing the raw EVM amt. * Add TestSetBalance * Add TestIdempotentConversion * Panic if converted coin from EVM is 0 This happens if a value is less than 1ukava * Deep copy coins instead of in place modification * Update test coins amount * Add panic tests for small EVM amounts * Use evmtypes.BankKeeper as NewEVMBankKeeper param * Tidy test setup * ensure sdk config is set when creating new apps * Respond EVM bank keeper GetBalance with SpendableCoins Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> * further speed up docker builds * feat: restore previous keys add defaults, add eth flag (#1172) * feat: restore previous keys add defaults, add eth flag * remove outdated comment * fix: remove redundant flag default * evm bank keeper with akava handling * fix issues * add remaining tests * add emv module to app * add missing imports * clean up comments * wip akava keeper * evm keeper * fix genesis import * reduce module permissions * add bank keeper tests * cleanup tests * genesis tests * change defaults * add eth faucet key & fix issues * switch to kava ethermint * add a lot of tests * add balances invariant * add evm tests * Remove panic if Swagger disabled in config (#1155) (#1183) Co-authored-by: Derrick Lee <derrick@dlee.dev> * add invariant to catch any akava balance > 1 ukava * clarify name of balances invariant * connect invariants to app * fix evmbankkeeper akava issues * add spec for evmutil * remove zero balance accounts from state * minor adustments * update to ethermint 0.10.0 * fix eth ante * add missing godoc comment * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update x/evmutil/spec/01_concepts.md Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> * Update ethermint to v0.12 (#1203) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * evm migrations for tesnet alpha 2 (#1206) * update to ethermint v0.12.2 * use app.Options for new evm options * fix missed references to app.Options * use ethermint branch while waiting on upstream fix * add upgrade handler for evm-alpha testnet 2 * v17 migration setup + evm modules * refactor migrate states * x/feemarket migration * v17 migrations setup + evm modules migration (#1210) * v17 migration setup + evm modules * refactor migrate states * update gen time * fix: update genesis time in test output Co-authored-by: karzak <kjydavis3@gmail.com> * add savings module to app blockers Co-authored-by: Derrick Lee <derrick@dlee.dev> Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: karzak <kjydavis3@gmail.com>
2022-04-21 20:16:28 +00:00
suite.Ctx = suite.Ctx.WithBlockTime(blockTime).WithBlockHeight(blockHeight).WithChainID(testChainID)
responseBeginBlock := suite.App.BeginBlocker(suite.Ctx, reqBegin) // height and time in RequestBeginBlock are ignored by module begin blockers
return responseEndBlock, responseBeginBlock
}
func (suite *IntegrationTester) DeliverIncentiveMsg(msg sdk.Msg) error {
msgServer := incentivekeeper.NewMsgServerImpl(suite.App.GetIncentiveKeeper())
var err error
switch msg := msg.(type) {
case *types.MsgClaimHardReward:
_, err = msgServer.ClaimHardReward(sdk.WrapSDKContext(suite.Ctx), msg)
case *types.MsgClaimSwapReward:
_, err = msgServer.ClaimSwapReward(sdk.WrapSDKContext(suite.Ctx), msg)
case *types.MsgClaimUSDXMintingReward:
_, err = msgServer.ClaimUSDXMintingReward(sdk.WrapSDKContext(suite.Ctx), msg)
case *types.MsgClaimDelegatorReward:
_, err = msgServer.ClaimDelegatorReward(sdk.WrapSDKContext(suite.Ctx), msg)
case *types.MsgClaimEarnReward:
_, err = msgServer.ClaimEarnReward(sdk.WrapSDKContext(suite.Ctx), msg)
default:
panic("unhandled incentive msg")
}
return err
}
// MintLiquidAnyValAddr mints liquid tokens with the given validator address,
// creating the validator if it does not already exist.
// **Note:** This will increment the block height/time and run the End and Begin
// blockers!
func (suite *IntegrationTester) MintLiquidAnyValAddr(
owner sdk.AccAddress,
validator sdk.ValAddress,
amount sdk.Coin,
) (sdk.Coin, error) {
// Check if validator already created
_, found := suite.App.GetStakingKeeper().GetValidator(suite.Ctx, validator)
if !found {
// Create validator
if err := suite.DeliverMsgCreateValidator(validator, sdk.NewCoin("ukava", sdk.NewInt(1e9))); err != nil {
return sdk.Coin{}, err
}
// new block required to bond validator
suite.NextBlockAfter(7 * time.Second)
}
// Delegate and mint liquid tokens
return suite.DeliverMsgDelegateMint(owner, validator, amount)
}
func (suite *IntegrationTester) GetAbciValidator(valAddr sdk.ValAddress) abcitypes.Validator {
sk := suite.App.GetStakingKeeper()
val, found := sk.GetValidator(suite.Ctx, valAddr)
suite.Require().True(found)
pk, err := val.ConsPubKey()
suite.Require().NoError(err)
return abcitypes.Validator{
Address: pk.Address(),
Power: val.GetConsensusPower(sk.PowerReduction(suite.Ctx)),
}
}
func (suite *IntegrationTester) DeliverMsgCreateValidator(address sdk.ValAddress, selfDelegation sdk.Coin) error {
msg, err := stakingtypes.NewMsgCreateValidator(
address,
ed25519.GenPrivKey().PubKey(),
selfDelegation,
stakingtypes.Description{},
stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
sdk.NewInt(1_000_000),
)
if err != nil {
return err
}
msgServer := stakingkeeper.NewMsgServerImpl(suite.App.GetStakingKeeper())
_, err = msgServer.CreateValidator(sdk.WrapSDKContext(suite.Ctx), msg)
return err
}
func (suite *IntegrationTester) DeliverMsgDelegate(delegator sdk.AccAddress, validator sdk.ValAddress, amount sdk.Coin) error {
msg := stakingtypes.NewMsgDelegate(
delegator,
validator,
amount,
)
msgServer := stakingkeeper.NewMsgServerImpl(suite.App.GetStakingKeeper())
_, err := msgServer.Delegate(sdk.WrapSDKContext(suite.Ctx), msg)
return err
}
func (suite *IntegrationTester) DeliverSwapMsgDeposit(depositor sdk.AccAddress, tokenA, tokenB sdk.Coin, slippage sdk.Dec) error {
msg := swaptypes.NewMsgDeposit(
depositor.String(),
tokenA,
tokenB,
slippage,
suite.Ctx.BlockTime().Add(time.Hour).Unix(), // ensure msg will not fail due to short deadline
)
msgServer := swapkeeper.NewMsgServerImpl(suite.App.GetSwapKeeper())
_, err := msgServer.Deposit(sdk.WrapSDKContext(suite.Ctx), msg)
return err
}
func (suite *IntegrationTester) DeliverHardMsgDeposit(owner sdk.AccAddress, deposit sdk.Coins) error {
msg := hardtypes.NewMsgDeposit(owner, deposit)
msgServer := hardkeeper.NewMsgServerImpl(suite.App.GetHardKeeper())
_, err := msgServer.Deposit(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverHardMsgBorrow(owner sdk.AccAddress, borrow sdk.Coins) error {
msg := hardtypes.NewMsgBorrow(owner, borrow)
msgServer := hardkeeper.NewMsgServerImpl(suite.App.GetHardKeeper())
_, err := msgServer.Borrow(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverHardMsgRepay(owner sdk.AccAddress, repay sdk.Coins) error {
msg := hardtypes.NewMsgRepay(owner, owner, repay)
msgServer := hardkeeper.NewMsgServerImpl(suite.App.GetHardKeeper())
_, err := msgServer.Repay(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverHardMsgWithdraw(owner sdk.AccAddress, withdraw sdk.Coins) error {
msg := hardtypes.NewMsgWithdraw(owner, withdraw)
msgServer := hardkeeper.NewMsgServerImpl(suite.App.GetHardKeeper())
_, err := msgServer.Withdraw(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverMsgCreateCDP(owner sdk.AccAddress, collateral, principal sdk.Coin, collateralType string) error {
msg := cdptypes.NewMsgCreateCDP(owner, collateral, principal, collateralType)
msgServer := cdpkeeper.NewMsgServerImpl(suite.App.GetCDPKeeper())
_, err := msgServer.CreateCDP(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverCDPMsgRepay(owner sdk.AccAddress, collateralType string, payment sdk.Coin) error {
msg := cdptypes.NewMsgRepayDebt(owner, collateralType, payment)
msgServer := cdpkeeper.NewMsgServerImpl(suite.App.GetCDPKeeper())
_, err := msgServer.RepayDebt(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverCDPMsgBorrow(owner sdk.AccAddress, collateralType string, draw sdk.Coin) error {
msg := cdptypes.NewMsgDrawDebt(owner, collateralType, draw)
msgServer := cdpkeeper.NewMsgServerImpl(suite.App.GetCDPKeeper())
_, err := msgServer.DrawDebt(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverMsgMintDerivative(
sender sdk.AccAddress,
validator sdk.ValAddress,
amount sdk.Coin,
) (sdk.Coin, error) {
msg := liquidtypes.NewMsgMintDerivative(sender, validator, amount)
msgServer := liquidkeeper.NewMsgServerImpl(suite.App.GetLiquidKeeper())
res, err := msgServer.MintDerivative(sdk.WrapSDKContext(suite.Ctx), &msg)
if err != nil {
// Instead of returning res.Received, as res will be nil if there is an error
return sdk.Coin{}, err
}
return res.Received, err
}
func (suite *IntegrationTester) DeliverEarnMsgDeposit(
depositor sdk.AccAddress,
amount sdk.Coin,
strategy earntypes.StrategyType,
) error {
msg := earntypes.NewMsgDeposit(depositor.String(), amount, strategy)
msgServer := earnkeeper.NewMsgServerImpl(suite.App.GetEarnKeeper())
_, err := msgServer.Deposit(sdk.WrapSDKContext(suite.Ctx), msg)
return err
}
func (suite *IntegrationTester) ProposeAndVoteOnNewParams(voter sdk.AccAddress, committeeID uint64, changes []proposaltypes.ParamChange) {
propose, err := committeetypes.NewMsgSubmitProposal(
proposaltypes.NewParameterChangeProposal(
"test title",
"test description",
changes,
),
voter,
committeeID,
)
suite.NoError(err)
msgServer := committeekeeper.NewMsgServerImpl(suite.App.GetCommitteeKeeper())
res, err := msgServer.SubmitProposal(sdk.WrapSDKContext(suite.Ctx), propose)
suite.NoError(err)
proposalID := res.ProposalID
vote := committeetypes.NewMsgVote(voter, proposalID, committeetypes.VOTE_TYPE_YES)
_, err = msgServer.Vote(sdk.WrapSDKContext(suite.Ctx), vote)
suite.NoError(err)
}
func (suite *IntegrationTester) GetAccount(addr sdk.AccAddress) authtypes.AccountI {
ak := suite.App.GetAccountKeeper()
return ak.GetAccount(suite.Ctx, addr)
}
func (suite *IntegrationTester) GetModuleAccount(name string) authtypes.ModuleAccountI {
ak := suite.App.GetAccountKeeper()
return ak.GetModuleAccount(suite.Ctx, name)
}
func (suite *IntegrationTester) GetBalance(address sdk.AccAddress) sdk.Coins {
bk := suite.App.GetBankKeeper()
return bk.GetAllBalances(suite.Ctx, address)
}
func (suite *IntegrationTester) ErrorIs(err, target error) bool {
return suite.Truef(errors.Is(err, target), "err didn't match: %s, it was: %s", target, err)
}
func (suite *IntegrationTester) BalanceEquals(address sdk.AccAddress, expected sdk.Coins) {
bk := suite.App.GetBankKeeper()
suite.Equalf(
expected,
bk.GetAllBalances(suite.Ctx, address),
"expected account balance to equal coins %s, but got %s",
expected,
bk.GetAllBalances(suite.Ctx, address),
)
}
func (suite *IntegrationTester) BalanceInEpsilon(address sdk.AccAddress, expected sdk.Coins, epsilon float64) {
actual := suite.GetBalance(address)
allDenoms := expected.Add(actual...)
for _, coin := range allDenoms {
suite.InEpsilonf(
expected.AmountOf(coin.Denom).Int64(),
actual.AmountOf(coin.Denom).Int64(),
epsilon,
"expected balance to be within %f%% of coins %s, but got %s", epsilon*100, expected, actual,
)
}
}
func (suite *IntegrationTester) VestingPeriodsEqual(address sdk.AccAddress, expectedPeriods []vestingtypes.Period) {
acc := suite.App.GetAccountKeeper().GetAccount(suite.Ctx, address)
suite.Require().NotNil(acc, "expected vesting account not to be nil")
vacc, ok := acc.(*vestingtypes.PeriodicVestingAccount)
suite.Require().True(ok, "expected vesting account to be type PeriodicVestingAccount")
suite.Equal(expectedPeriods, vacc.VestingPeriods)
}
// -----------------------------------------------------------------------------
// x/incentive
func (suite *IntegrationTester) SwapRewardEquals(owner sdk.AccAddress, expected sdk.Coins) {
claim, found := suite.App.GetIncentiveKeeper().GetSwapClaim(suite.Ctx, owner)
suite.Require().Truef(found, "expected swap claim to be found for %s", owner)
suite.Equalf(expected, claim.Reward, "expected swap claim reward to be %s, but got %s", expected, claim.Reward)
}
func (suite *IntegrationTester) DelegatorRewardEquals(owner sdk.AccAddress, expected sdk.Coins) {
claim, found := suite.App.GetIncentiveKeeper().GetDelegatorClaim(suite.Ctx, owner)
suite.Require().Truef(found, "expected delegator claim to be found for %s", owner)
suite.Equalf(expected, claim.Reward, "expected delegator claim reward to be %s, but got %s", expected, claim.Reward)
}
func (suite *IntegrationTester) HardRewardEquals(owner sdk.AccAddress, expected sdk.Coins) {
claim, found := suite.App.GetIncentiveKeeper().GetHardLiquidityProviderClaim(suite.Ctx, owner)
suite.Require().Truef(found, "expected delegator claim to be found for %s", owner)
suite.Equalf(expected, claim.Reward, "expected delegator claim reward to be %s, but got %s", expected, claim.Reward)
}
func (suite *IntegrationTester) USDXRewardEquals(owner sdk.AccAddress, expected sdk.Coin) {
claim, found := suite.App.GetIncentiveKeeper().GetUSDXMintingClaim(suite.Ctx, owner)
suite.Require().Truef(found, "expected delegator claim to be found for %s", owner)
suite.Equalf(expected, claim.Reward, "expected delegator claim reward to be %s, but got %s", expected, claim.Reward)
}
func (suite *IntegrationTester) EarnRewardEquals(owner sdk.AccAddress, expected sdk.Coins) {
claim, found := suite.App.GetIncentiveKeeper().GetEarnClaim(suite.Ctx, owner)
suite.Require().Truef(found, "expected earn claim to be found for %s", owner)
suite.Truef(expected.IsEqual(claim.Reward), "expected earn claim reward to be %s, but got %s", expected, claim.Reward)
}
// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys.
func (suite *IntegrationTester) AddTestAddrsFromPubKeys(ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt sdk.Int) {
initCoins := sdk.NewCoins(sdk.NewCoin(suite.App.GetStakingKeeper().BondDenom(ctx), accAmt))
for _, pk := range pubKeys {
err := suite.App.FundAccount(ctx, sdk.AccAddress(pk.Address()), initCoins)
suite.Require().NoError(err)
}
}
func (suite *IntegrationTester) StoredEarnTimeEquals(denom string, expected time.Time) {
storedTime, found := suite.App.GetIncentiveKeeper().GetEarnRewardAccrualTime(suite.Ctx, denom)
suite.Equal(found, expected != time.Time{}, "expected time is %v but time found = %v", expected, found)
if found {
suite.Equal(expected, storedTime)
} else {
suite.Empty(storedTime)
}
}
func (suite *IntegrationTester) StoredEarnIndexesEqual(denom string, expected types.RewardIndexes) {
storedIndexes, found := suite.App.GetIncentiveKeeper().GetEarnRewardIndexes(suite.Ctx, denom)
suite.Equal(found, expected != nil)
if found {
suite.Equal(expected, storedIndexes)
} else {
// Can't compare Equal for types.RewardIndexes(nil) vs types.RewardIndexes{}
suite.Empty(storedIndexes)
}
}
func (suite *IntegrationTester) StoredTimeEquals(claimType types.ClaimType, denom string, expected time.Time) {
storedTime, found := suite.App.GetIncentiveKeeper().Store.GetRewardAccrualTime(suite.Ctx, claimType, denom)
suite.Equal(found, expected != time.Time{}, "expected time is %v but time found = %v", expected, found)
if found {
suite.Equal(expected, storedTime)
} else {
suite.Empty(storedTime)
}
}
func (suite *IntegrationTester) StoredIndexesEqual(claimType types.ClaimType, denom string, expected types.RewardIndexes) {
storedIndexes, found := suite.App.GetIncentiveKeeper().Store.GetRewardIndexesOfClaimType(suite.Ctx, claimType, denom)
suite.Equal(found, expected != nil)
if found {
suite.Equal(expected, storedIndexes)
} else {
// Can't compare Equal for types.RewardIndexes(nil) vs types.RewardIndexes{}
suite.Empty(storedIndexes)
}
}
func (suite *IntegrationTester) AddIncentiveEarnMultiRewardPeriod(period types.MultiRewardPeriod) {
ik := suite.App.GetIncentiveKeeper()
params := ik.GetParams(suite.Ctx)
for i, reward := range params.EarnRewardPeriods {
if reward.CollateralType == period.CollateralType {
// Replace existing reward period if the collateralType exists.
// Params are invalid if there are multiple reward periods for the
// same collateral type.
params.EarnRewardPeriods[i] = period
ik.SetParams(suite.Ctx, params)
return
}
}
params.EarnRewardPeriods = append(params.EarnRewardPeriods, period)
suite.NoError(params.Validate())
ik.SetParams(suite.Ctx, params)
}
func (suite *IntegrationTester) AddIncentiveMultiRewardPeriod(
claimType types.ClaimType,
period types.MultiRewardPeriod,
) {
ik := suite.App.GetIncentiveKeeper()
params := ik.GetParams(suite.Ctx)
for i, rewardPeriod := range params.RewardPeriods {
if claimType == rewardPeriod.ClaimType {
for j, reward := range rewardPeriod.RewardPeriods {
if reward.CollateralType == period.CollateralType {
// Replace existing reward period if the collateralType exists.
// Params are invalid if there are multiple reward periods for the
// same collateral type.
params.RewardPeriods[i].RewardPeriods[j] = period
ik.SetParams(suite.Ctx, params)
return
}
}
// Claim type period exists but not the specific collateral type
params.RewardPeriods[i].RewardPeriods = append(params.RewardPeriods[i].RewardPeriods, period)
return
}
}
// Claim type does not exist in params
params.RewardPeriods = append(params.RewardPeriods, types.NewTypedMultiRewardPeriod(
claimType,
types.MultiRewardPeriods{
period,
},
))
suite.NoError(params.Validate())
ik.SetParams(suite.Ctx, params)
}
// -----------------------------------------------------------------------------
// x/router
func (suite *IntegrationTester) DeliverRouterMsgDelegateMintDeposit(
depositor sdk.AccAddress,
validator sdk.ValAddress,
amount sdk.Coin,
) error {
msg := routertypes.MsgDelegateMintDeposit{
Depositor: depositor.String(),
Validator: validator.String(),
Amount: amount,
}
msgServer := routerkeeper.NewMsgServerImpl(suite.App.GetRouterKeeper())
_, err := msgServer.DelegateMintDeposit(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverRouterMsgMintDeposit(
depositor sdk.AccAddress,
validator sdk.ValAddress,
amount sdk.Coin,
) error {
msg := routertypes.MsgMintDeposit{
Depositor: depositor.String(),
Validator: validator.String(),
Amount: amount,
}
msgServer := routerkeeper.NewMsgServerImpl(suite.App.GetRouterKeeper())
_, err := msgServer.MintDeposit(sdk.WrapSDKContext(suite.Ctx), &msg)
return err
}
func (suite *IntegrationTester) DeliverMsgDelegateMint(
delegator sdk.AccAddress,
validator sdk.ValAddress,
amount sdk.Coin,
) (sdk.Coin, error) {
if err := suite.DeliverMsgDelegate(delegator, validator, amount); err != nil {
return sdk.Coin{}, err
}
return suite.DeliverMsgMintDerivative(delegator, validator, amount)
}
// -----------------------------------------------------------------------------
// x/distribution
func (suite *IntegrationTester) GetBeginBlockClaimedStakingRewards(
resBeginBlock abcitypes.ResponseBeginBlock,
) (validatorRewards map[string]sdk.Coins, totalRewards sdk.Coins) {
// Events emitted in BeginBlocker are in the ResponseBeginBlock, not in
// ctx.EventManager().Events() as BeginBlock is called with a NewEventManager()
// cosmos-sdk/types/module/module.go: func(m *Manager) BeginBlock(...)
// We also need to parse the events to get the rewards as querying state will
// always contain 0 rewards -- rewards are always claimed right after
// mint+distribution in BeginBlocker which resets distribution state back to
// 0 for reward amounts
blockRewardsClaimed := make(map[string]sdk.Coins)
for _, event := range resBeginBlock.Events {
if event.Type != distributiontypes.EventTypeWithdrawRewards {
continue
}
// Example event attributes, amount can be empty for no rewards
//
// Event: withdraw_rewards
// - amount:
// - validator: kavavaloper1em2mlkrkx0qsa6327tgvl3g0fh8a95hjnqvrwh
// Event: withdraw_rewards
// - amount: 523909ukava
// - validator: kavavaloper1nmgpgr8l4t8pw9zqx9cltuymvz85wmw9sy8kjy
attrsMap := attrsToMap(event.Attributes)
validator, found := attrsMap[distributiontypes.AttributeKeyValidator]
suite.Require().Truef(found, "expected validator attribute to be found in event %s", event)
amountStr, found := attrsMap[sdk.AttributeKeyAmount]
suite.Require().Truef(found, "expected amount attribute to be found in event %s", event)
amount := sdk.NewCoins()
// Only parse amount if it is not empty
if len(amountStr) > 0 {
parsedAmt, err := sdk.ParseCoinNormalized(amountStr)
suite.Require().NoError(err)
amount = amount.Add(parsedAmt)
}
blockRewardsClaimed[validator] = amount
}
totalClaimedRewards := sdk.NewCoins()
for _, amount := range blockRewardsClaimed {
totalClaimedRewards = totalClaimedRewards.Add(amount...)
}
return blockRewardsClaimed, totalClaimedRewards
}
func attrsToMap(attrs []abcitypes.EventAttribute) map[string]string {
out := make(map[string]string)
for _, attr := range attrs {
out[string(attr.Key)] = string(attr.Value)
}
return out
}