Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSM e2e tests #1

Open
wants to merge 39 commits into
base: masa/tests-gaia-lsm-ics
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a25f396
lsm e2e test work - wip
jstr1121 Jul 14, 2023
7307227
Add validator bond functionality on lsm happy path
jstr1121 Jul 14, 2023
66e29ad
add tokenize share check on lsm test & redeemShare utility function
jstr1121 Jul 14, 2023
e0deb2f
add bank send lsm tokens test
jstr1121 Jul 14, 2023
ef4ed7d
Add test for transfer reward ownership, and redeem shares
jstr1121 Jul 14, 2023
d0cc711
bring v10.0.2 changelog to main (#2648)
mpoke Jul 17, 2023
3dfe577
add missing changelog for PFM bump
mpoke Jul 18, 2023
6e01021
fix typo in PFM changelog
mpoke Jul 18, 2023
87fade8
Add staking param query utility & LSM params update process on LSM e2…
jstr1121 Jul 18, 2023
a759409
Merge pull request from GHSA-354m-4qv6-x846
dongsam Jul 18, 2023
69d1dd0
refactor: use gci linter to sort imports (#2608)
faddat Jul 18, 2023
700da38
chore: remove depguard and bump golangci-lint (#2596)
faddat Jul 18, 2023
934be9b
fix: use the latest release of hermes for e2e (#2644)
faddat Jul 18, 2023
de8358f
Add IBC transfer test on LSM share tokens & Resolve e2e tests by upda…
jstr1121 Jul 18, 2023
cd8c670
resolve github action bot comments
jstr1121 Jul 18, 2023
31e3d61
bring all e2e test items back to enabled
jstr1121 Jul 18, 2023
bc98c30
deps!: bump liquidity to v1.6.0-forced-withdrawal (#2652)
mpoke Jul 18, 2023
cdc5089
add changelog entry for gov bug fix (#2653)
mpoke Jul 18, 2023
9330b46
Update tests/e2e/e2e_lsm_test.go
jstr1121 Jul 25, 2023
7729919
resolve comments
jstr1121 Jul 25, 2023
d77b032
Merge branch 'main' into masa/tests-gaia-lsm-ics
MSalopek Jul 25, 2023
0952f5e
chore: bump iqlusion:cosmos-sdk to latest
MSalopek Jul 25, 2023
0a4fb3c
upgrade release testnet to v11 (#2665)
dasanchez Jul 25, 2023
85cb852
docs: refactor gaia ADRs (#2628)
mpoke Jul 25, 2023
1ff7c9c
mergify and dependabot for v11 (#2654)
mpoke Jul 25, 2023
1869b86
reenable tokenize share record module account balance check
jstr1121 Jul 26, 2023
0611123
fix: fix tag sorting in goreleaser (#2666)
MSalopek Jul 26, 2023
0dcfcae
chore: update Cosmos Hub Upgrade Epic (#2661)
mpoke Jul 27, 2023
04e869e
fix: add "v" prefix to release binary version (#2671)
MSalopek Jul 27, 2023
581ef19
feat: update module name to v12 (#2672)
yaruwangway Jul 27, 2023
8769bb3
feat: add upgrade test for v12 (#2678)
yaruwangway Jul 31, 2023
f6bb443
test: fix upgrade test (#2680)
yaruwangway Aug 1, 2023
1bab491
fix: update upgrade handler to v12 (#2681)
yaruwangway Aug 1, 2023
7fb9cf8
Merge branch 'main' into masa/tests-gaia-lsm-ics
MSalopek Aug 4, 2023
4343315
Jstr/lsm e2e tests (#2679)
riley-stride Aug 7, 2023
243afe6
fix staking test affected by other test
jstr1121 Aug 7, 2023
003c089
Add lsm params to upgrade handler (#2686)
sampocs Aug 7, 2023
7b1e69b
chore: bump cosmos-sdk and ics to latest
MSalopek Aug 7, 2023
136bd56
Merge remote-tracking branch 'upstream/masa/tests-gaia-lsm-ics' into …
sampocs Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions tests/e2e/e2e_exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,3 +692,108 @@
return false
}
}

func (s *IntegrationTestSuite) executeValidatorBond(c *chain, valIdx int, valOperAddress, delegatorAddr, home, delegateFees string) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

s.T().Logf("Executing gaiad tx staking validator-bond %s", c.id)

gaiaCommand := []string{
gaiadBinary,
txCommand,
stakingtypes.ModuleName,
"validator-bond",
valOperAddress,
fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr),
fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id),
fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees),
"--keyring-backend=test",
fmt.Sprintf("--%s=%s", flags.FlagHome, home),
"--output=json",
"-y",
}

s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Logf("%s successfully executed validator bond tx to %s", delegatorAddr, valOperAddress)
}

func (s *IntegrationTestSuite) executeTokenizeShares(c *chain, valIdx int, amount, valOperAddress, delegatorAddr, home, delegateFees string) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

s.T().Logf("Executing gaiad tx staking tokenize-share %s", c.id)

gaiaCommand := []string{
gaiadBinary,
txCommand,
stakingtypes.ModuleName,
"tokenize-share",
valOperAddress,
amount,
delegatorAddr,
fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr),
fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id),
fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees),
fmt.Sprintf("--%s=%d", flags.FlagGas, 1000000),
"--keyring-backend=test",
fmt.Sprintf("--%s=%s", flags.FlagHome, home),
"--output=json",
"-y",
}

s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Logf("%s successfully executed tokenize share tx from %s", delegatorAddr, valOperAddress)
}

func (s *IntegrationTestSuite) executeRedeemShares(c *chain, valIdx int, amount, delegatorAddr, home, delegateFees string) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

s.T().Logf("Executing gaiad tx staking redeem-tokens %s", c.id)

gaiaCommand := []string{
gaiadBinary,
txCommand,
stakingtypes.ModuleName,
"redeem-tokens",
amount,
fmt.Sprintf("--%s=%s", flags.FlagFrom, delegatorAddr),
fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id),
fmt.Sprintf("--%s=%s", flags.FlagGasPrices, delegateFees),
fmt.Sprintf("--%s=%d", flags.FlagGas, 1000000),
"--keyring-backend=test",
fmt.Sprintf("--%s=%s", flags.FlagHome, home),
"--output=json",
"-y",
}

s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Logf("%s successfully executed redeem share tx for %s", delegatorAddr, amount)
}

func (s *IntegrationTestSuite) executeTransferTokenizeShareRecord(c *chain, valIdx int, recordId, owner, newOwner, home, txFees string) {

Check failure on line 775 in tests/e2e/e2e_exec_test.go

View workflow job for this annotation

GitHub Actions / Analyze

var-naming: method parameter recordId should be recordID (revive)

Check failure on line 775 in tests/e2e/e2e_exec_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

var-naming: method parameter recordId should be recordID (revive)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

s.T().Logf("Executing gaiad tx staking transfer-tokenize-share-record %s", c.id)

gaiaCommand := []string{
gaiadBinary,
txCommand,
stakingtypes.ModuleName,
"transfer-tokenize-share-record",
recordId,
newOwner,
fmt.Sprintf("--%s=%s", flags.FlagFrom, owner),
fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id),
fmt.Sprintf("--%s=%s", flags.FlagGasPrices, txFees),
"--keyring-backend=test",
fmt.Sprintf("--%s=%s", flags.FlagHome, home),
"--output=json",
"-y",
}

s.executeGaiaTxCommand(ctx, c, gaiaCommand, valIdx, s.defaultExecValidation(c, valIdx))
s.T().Logf("%s successfully executed transfer tokenize share record for %s", owner, recordId)
}
221 changes: 221 additions & 0 deletions tests/e2e/e2e_lsm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package e2e

import (
"fmt"
"strconv"
"strings"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

func (s *IntegrationTestSuite) testLSM() {
chainEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp"))

validatorA := s.chainA.validators[0]
validatorAAddr := validatorA.keyInfo.GetAddress()

validatorAddressA := sdk.ValAddress(validatorAAddr).String()

// Set parameters (global liquid staking cap, validator liquid staking cap, validator bond factor)
s.writeLiquidStakingParamsUpdateProposal(s.chainA)
proposalCounter++
submitGovFlags := []string{"param-change", configFile(proposalLSMParamUpdateFilename)}
depositGovFlags := []string{strconv.Itoa(proposalCounter), depositAmount.String()}
voteGovFlags := []string{strconv.Itoa(proposalCounter), "yes"}

// gov proposing LSM parameters (global liquid staking cap, validator liquid staking cap, validator bond factor)
s.T().Logf("Proposal number: %d", proposalCounter)
s.T().Logf("Submitting, deposit and vote legacy Gov Proposal: Set parameters (global liquid staking cap, validator liquid staking cap, validator bond factor)")
s.runGovProcess(chainEndpoint, validatorAAddr.String(), proposalCounter, paramtypes.ProposalTypeChange, submitGovFlags, depositGovFlags, voteGovFlags, "vote", false)

// query the proposal status and new fee
s.Require().Eventually(
func() bool {
proposal, err := queryGovProposal(chainEndpoint, proposalCounter)
s.Require().NoError(err)
return proposal.GetProposal().Status == gov.StatusPassed
},
15*time.Second,
5*time.Second,
)

s.Require().Eventually(
func() bool {
stakingParams, err := queryStakingParams(chainEndpoint)
s.T().Logf("After LSM parameters update proposal")
s.Require().NoError(err)

s.Require().Equal(stakingParams.Params.GlobalLiquidStakingCap, sdk.NewDecWithPrec(25, 2))
s.Require().Equal(stakingParams.Params.ValidatorLiquidStakingCap, sdk.NewDecWithPrec(50, 2))
s.Require().Equal(stakingParams.Params.ValidatorBondFactor, sdk.NewDec(250))

return true
},
15*time.Second,
5*time.Second,
)
delegatorAddress := s.chainA.genesisAccounts[2].keyInfo.GetAddress().String()

fees := sdk.NewCoin(uatomDenom, sdk.NewInt(1))

// Validator bond
s.executeValidatorBond(s.chainA, 0, validatorAddressA, validatorAAddr.String(), gaiaHomePath, fees.String())

// Validate validator bond successful
selfBondedShares := sdk.ZeroDec()
s.Require().Eventually(
func() bool {
res, err := queryDelegation(chainEndpoint, validatorAddressA, validatorAAddr.String())
delegation := res.GetDelegationResponse().GetDelegation()
selfBondedShares = delegation.Shares
isValidatorBond := delegation.ValidatorBond
s.Require().NoError(err)

return isValidatorBond == true
},
20*time.Second,
5*time.Second,
)

delegationAmount := sdk.NewInt(500000000)
delegation := sdk.NewCoin(uatomDenom, delegationAmount) // 500 atom

// Alice delegate uatom to Validator A
s.executeDelegate(s.chainA, 0, delegation.String(), validatorAddressA, delegatorAddress, gaiaHomePath, fees.String())

// Validate delegation successful
s.Require().Eventually(
func() bool {
res, err := queryDelegation(chainEndpoint, validatorAddressA, delegatorAddress)
amt := res.GetDelegationResponse().GetDelegation().GetShares()
s.Require().NoError(err)

return amt.Equal(sdk.NewDecFromInt(delegationAmount))
},
20*time.Second,
5*time.Second,
)

// Tokenize shares
tokenizeAmount := sdk.NewInt(200000000)
tokenize := sdk.NewCoin(uatomDenom, tokenizeAmount) // 200 atom
s.executeTokenizeShares(s.chainA, 0, tokenize.String(), validatorAddressA, delegatorAddress, gaiaHomePath, fees.String())

// Validate delegation reduced
s.Require().Eventually(
func() bool {
res, err := queryDelegation(chainEndpoint, validatorAddressA, delegatorAddress)
amt := res.GetDelegationResponse().GetDelegation().GetShares()
s.Require().NoError(err)

return amt.Equal(sdk.NewDecFromInt(delegationAmount.Sub(tokenizeAmount)))
},
20*time.Second,
5*time.Second,
)

// Validate balance increased
recordID := int(1)
shareDenom := fmt.Sprintf("%s/%s", strings.ToLower(validatorAddressA), strconv.Itoa(recordID))
s.Require().Eventually(
func() bool {
res, err := getSpecificBalance(chainEndpoint, delegatorAddress, shareDenom)
s.Require().NoError(err)
return res.Amount.Equal(tokenizeAmount)
},
20*time.Second,
5*time.Second,
)

// Bank send LSM token
sendAmount := sdk.NewCoin(shareDenom, tokenizeAmount)
s.execBankSend(s.chainA, 0, delegatorAddress, validatorAAddr.String(), sendAmount.String(), standardFees.String(), false)

// Validate tokens are sent properly
s.Require().Eventually(
func() bool {
afterSenderShareDenomBalance, err := getSpecificBalance(chainEndpoint, delegatorAddress, shareDenom)
s.Require().NoError(err)

afterRecipientShareDenomBalance, err := getSpecificBalance(chainEndpoint, validatorAAddr.String(), shareDenom)
s.Require().NoError(err)

decremented := afterSenderShareDenomBalance.IsNil() || afterSenderShareDenomBalance.IsZero()
incremented := afterRecipientShareDenomBalance.IsEqual(sendAmount)

return decremented && incremented
},
time.Minute,
5*time.Second,
)

// transfer reward ownership
s.executeTransferTokenizeShareRecord(s.chainA, 0, strconv.Itoa(recordID), delegatorAddress, validatorAAddr.String(), gaiaHomePath, standardFees.String())
tokenizeShareRecord := stakingtypes.TokenizeShareRecord{}
// Validate ownership transferred correctly
s.Require().Eventually(
func() bool {
record, err := queryTokenizeShareRecordByID(chainEndpoint, recordID)
s.Require().NoError(err)
tokenizeShareRecord = record
return record.Owner == validatorAAddr.String()
},
time.Minute,
5*time.Second,
)
_ = tokenizeShareRecord

// IBC transfer LSM token
ibcTransferAmount := sdk.NewCoin(shareDenom, sdk.NewInt(100000000))
sendRecipientAddr := s.chainB.validators[0].keyInfo.GetAddress()
s.sendIBC(s.chainA, 0, validatorAAddr.String(), sendRecipientAddr.String(), ibcTransferAmount.String(), standardFees.String(), "memo")

s.Require().Eventually(
func() bool {
afterSenderShareBalance, err := getSpecificBalance(chainEndpoint, validatorAAddr.String(), shareDenom)
s.Require().NoError(err)

decremented := afterSenderShareBalance.Add(ibcTransferAmount).IsEqual(sendAmount)
return decremented
sampocs marked this conversation as resolved.
Show resolved Hide resolved
},
1*time.Minute,
5*time.Second,
)

// Redeem tokens for shares
redeemAmount := sendAmount.Sub(ibcTransferAmount)
s.executeRedeemShares(s.chainA, 0, redeemAmount.String(), validatorAAddr.String(), gaiaHomePath, fees.String())

// check redeem success
s.Require().Eventually(
func() bool {
balanceRes, err := getSpecificBalance(chainEndpoint, validatorAAddr.String(), shareDenom)
s.Require().NoError(err)
if !balanceRes.Amount.IsNil() && balanceRes.Amount.IsZero() {
return false
}

delegationRes, err := queryDelegation(chainEndpoint, validatorAddressA, validatorAAddr.String())
delegation := delegationRes.GetDelegationResponse().GetDelegation()
s.Require().NoError(err)

if !delegation.Shares.Equal(selfBondedShares.Add(sdk.NewDecFromInt(redeemAmount.Amount))) {

Check failure on line 206 in tests/e2e/e2e_lsm_test.go

View workflow job for this annotation

GitHub Actions / Analyze

S1008: should use 'return delegation.Shares.Equal(selfBondedShares.Add(sdk.NewDecFromInt(redeemAmount.Amount)))' instead of 'if !delegation.Shares.Equal(selfBondedShares.Add(sdk.NewDecFromInt(redeemAmount.Amount))) { return false }; return true' (gosimple)

Check failure on line 206 in tests/e2e/e2e_lsm_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

S1008: should use 'return delegation.Shares.Equal(selfBondedShares.Add(sdk.NewDecFromInt(redeemAmount.Amount)))' instead of 'if !delegation.Shares.Equal(selfBondedShares.Add(sdk.NewDecFromInt(redeemAmount.Amount))) { return false }; return true' (gosimple)
return false
}

// // check tokenize share record module account balance
jstr1121 marked this conversation as resolved.
Show resolved Hide resolved
// balanceRes, err = getSpecificBalance(chainEndpoint, tokenizeShareRecord.ModuleAccount, uatomDenom)
// s.Require().NoError(err)
// if balanceRes.Amount.IsNil() || balanceRes.Amount.IsZero() {
// return false
// }
return true
},
20*time.Second,
5*time.Second,
)
jstr1121 marked this conversation as resolved.
Show resolved Hide resolved
}
43 changes: 43 additions & 0 deletions tests/e2e/e2e_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const (
proposalCommunitySpendFilename = "proposal_community_spend.json"
proposalAddConsumerChainFilename = "proposal_add_consumer.json"
proposalRemoveConsumerChainFilename = "proposal_remove_consumer.json"
proposalLSMParamUpdateFilename = "proposal_lsm_param_update.json"

hermesBinary = "hermes"
hermesConfigWithGasPrices = "/root/.hermes/config.toml"
Expand Down Expand Up @@ -929,6 +930,48 @@ func (s *IntegrationTestSuite) writeAddRemoveConsumerProposals(c *chain, consume
s.Require().NoError(err)
}

func (s *IntegrationTestSuite) writeLiquidStakingParamsUpdateProposal(c *chain) {
type ParamInfo struct {
Subspace string `json:"subspace"`
Key string `json:"key"`
Value sdk.Dec `json:"value"`
}

type ParamChangeMessage struct {
Title string `json:"title"`
Description string `json:"description"`
Changes []ParamInfo `json:"changes"`
Deposit string `json:"deposit"`
}

paramChangeProposalBody, err := json.MarshalIndent(ParamChangeMessage{
Title: "liquid staking params update",
Description: "liquid staking params update",
Changes: []ParamInfo{
{
Subspace: "staking",
Key: "GlobalLiquidStakingCap",
Value: sdk.NewDecWithPrec(25, 2), // 25%
},
{
Subspace: "staking",
Key: "ValidatorLiquidStakingCap",
Value: sdk.NewDecWithPrec(50, 2), // 50%
},
{
Subspace: "staking",
Key: "ValidatorBondFactor",
Value: sdk.NewDec(250), // -1
},
},
Deposit: "1000uatom",
}, "", " ")
s.Require().NoError(err)

err = writeFile(filepath.Join(c.validators[0].configDir(), "config", proposalLSMParamUpdateFilename), paramChangeProposalBody)
s.Require().NoError(err)
}

func configFile(filename string) string {
filepath := filepath.Join(gaiaConfigPath, filename)
return filepath
Expand Down
Loading
Loading