diff --git a/Dockerfile b/Dockerfile index 9aff88a..7e83bd8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,6 @@ RUN make lint RUN make test-poa # Integration tests RUN make test-integration -RUN make test-upgrade # Simulation tests RUN make test-sim-benchmark-simulation RUN make test-sim-full-app-fast diff --git a/Makefile b/Makefile index c370d0b..3855b3c 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ COMMIT := $(shell git log -1 --format='%H') BINDIR ?= $(GOPATH)/bin APP = ./app +# Upgrade testsuite values +LATEST_UPGRADE ?= $(shell ls -d ./app/upgrades/* | sort -r | head -n 1) +SNAPSHOT_DIR ?= .exrpd # don't override user values ifeq (,$(VERSION)) VERSION := $(shell git describe --tags) @@ -126,11 +129,13 @@ mocks: @echo "--> Generating mocks" @./scripts/mockgen.sh -test: test-poa test-integration test-upgrade test-sim-benchmark-simulation test-sim-full-app-fast +test: test-poa test-integration test-sim-benchmark-simulation test-sim-full-app-fast test-upgrade: - @echo "--> Running upgrade testsuite" - @go test -mod=readonly -v ./tests/upgrade + @echo "--> Running upgrade testsuite from snapshot: $(SNAPSHOT_DIR), into $(LATEST_UPGRADE)" + @rm -rf $(LATEST_UPGRADE)/integration/.exrpd + @cp -r $(SNAPSHOT_DIR) $(LATEST_UPGRADE)/integration/.exrpd + @go test -mod=readonly -v $(LATEST_UPGRADE)/integration test-integration: @echo "--> Running integration testsuite" diff --git a/app/upgrades.go b/app/upgrades.go index efeb33c..5a9db19 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -12,6 +12,7 @@ import ( v4 "github.com/xrplevm/node/v6/app/upgrades/v4" v5 "github.com/xrplevm/node/v6/app/upgrades/v5" v6 "github.com/xrplevm/node/v6/app/upgrades/v6" + v7 "github.com/xrplevm/node/v6/app/upgrades/v7" ) func (app *App) setupUpgradeHandlers() { @@ -44,6 +45,14 @@ func (app *App) setupUpgradeHandlers() { app.configurator, ), ) + app.UpgradeKeeper.SetUpgradeHandler( + v7.UpgradeName, + v7.CreateUpgradeHandler( + app.mm, + app.configurator, + app.StakingKeeper, + ), + ) // When a planned update height is reached, the old binary will panic // writing on disk the height and name of the update that triggered it @@ -68,7 +77,7 @@ func (app *App) setupUpgradeHandlers() { }, Deleted: []string{}, } - case v5.UpgradeName, v6.UpgradeName: + case v5.UpgradeName, v6.UpgradeName, v7.UpgradeName: // No store upgrades for v5 storeUpgrades = &storetypes.StoreUpgrades{} } diff --git a/app/upgrades/v7/constants.go b/app/upgrades/v7/constants.go new file mode 100644 index 0000000..ab8f7f4 --- /dev/null +++ b/app/upgrades/v7/constants.go @@ -0,0 +1,5 @@ +package v7 + +const ( + UpgradeName = "v7.0.0" +) diff --git a/app/upgrades/v7/integration/auth_test.go b/app/upgrades/v7/integration/auth_test.go new file mode 100644 index 0000000..64f965d --- /dev/null +++ b/app/upgrades/v7/integration/auth_test.go @@ -0,0 +1,44 @@ +//nolint:dupl +package integration + +import ( + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_Auth_Params() { + prevParams, err := s.network.GetAuthClient().Params( + s.network.GetContext(), + &authtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetAuthClient().Params( + s.network.GetContext(), + &authtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} + +func (s *UpgradeTestSuite) TestUpgrade_Auth_Accounts() { + res, err := s.network.GetAuthClient().Accounts( + s.network.GetContext(), + &authtypes.QueryAccountsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postRes, err := s.network.GetAuthClient().Accounts( + s.network.GetContext(), + &authtypes.QueryAccountsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified accounts are the same + s.Require().Equal(res.Accounts, postRes.Accounts) +} diff --git a/app/upgrades/v7/integration/bank_test.go b/app/upgrades/v7/integration/bank_test.go new file mode 100644 index 0000000..17f6b04 --- /dev/null +++ b/app/upgrades/v7/integration/bank_test.go @@ -0,0 +1,102 @@ +package integration + +import ( + sdktypes "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_Bank_Params() { + prevParams, err := s.network.GetBankClient().Params( + s.network.GetContext(), + &banktypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetBankClient().Params( + s.network.GetContext(), + &banktypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} + +func (s *UpgradeTestSuite) TestUpgrade_Bank_TotalSupply() { + res, err := s.network.GetBankClient().TotalSupply( + s.network.GetContext(), + &banktypes.QueryTotalSupplyRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postRes, err := s.network.GetBankClient().TotalSupply( + s.network.GetContext(), + &banktypes.QueryTotalSupplyRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified balances are the same + s.Require().Equal(res.Supply, postRes.Supply) +} + +func (s *UpgradeTestSuite) TestUpgrade_Bank_Send() { + // Replace with the desired addresses + sender, err := sdktypes.AccAddressFromBech32("ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg") + s.Require().NoError(err) + receiver, err := sdktypes.AccAddressFromBech32("ethm1nqvn2hmte72e3z0xyqmh06hdwd9qu6hgdcavhh") + s.Require().NoError(err) + amount := sdktypes.NewInt64Coin(s.network.GetDenom(), 100) + + prevBalancesSender, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: sender.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + prevBalancesReceiver, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: receiver.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + err = s.network.BankKeeper().SendCoins( + s.network.GetContext(), + sender, + receiver, + sdktypes.NewCoins(amount), + ) + s.Require().NoError(err) + + postBalancesSender, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: sender.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + postBalancesReceiver, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: receiver.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + s.Require().Equal(prevBalancesSender.Balance.Amount.Sub(amount.Amount).String(), postBalancesSender.Balance.Amount.String()) + s.Require().Equal(prevBalancesReceiver.Balance.Amount.Add(amount.Amount).String(), postBalancesReceiver.Balance.Amount.String()) +} diff --git a/app/upgrades/v7/integration/distribution_test.go b/app/upgrades/v7/integration/distribution_test.go new file mode 100644 index 0000000..ab3240a --- /dev/null +++ b/app/upgrades/v7/integration/distribution_test.go @@ -0,0 +1,24 @@ +package integration + +import ( + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_DistributionParams() { + prevParams, err := s.network.GetDistrClient().Params( + s.network.GetContext(), + &distributiontypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetDistrClient().Params( + s.network.GetContext(), + &distributiontypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} diff --git a/app/upgrades/v7/integration/erc20_test.go b/app/upgrades/v7/integration/erc20_test.go new file mode 100644 index 0000000..5435ec2 --- /dev/null +++ b/app/upgrades/v7/integration/erc20_test.go @@ -0,0 +1,166 @@ +package integration + +import ( + sdktypes "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + erc20types "github.com/evmos/evmos/v20/x/erc20/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_ERC20Params() { + prevParams, err := s.network.GetERC20Client().Params( + s.network.GetContext(), + &erc20types.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetERC20Client().Params( + s.network.GetContext(), + &erc20types.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} + +func (s *UpgradeTestSuite) TestUpgrade_ERC20_TokenPairs() { + prevTokenPairs, err := s.network.GetERC20Client().TokenPairs( + s.network.GetContext(), + &erc20types.QueryTokenPairsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postTokenPairs, err := s.network.GetERC20Client().TokenPairs( + s.network.GetContext(), + &erc20types.QueryTokenPairsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified token pairs are the same + s.Require().Equal(prevTokenPairs.TokenPairs, postTokenPairs.TokenPairs) +} + +func (s *UpgradeTestSuite) TestUpgrade_ERC20_MintCoins() { + tokenPairs, err := s.network.GetERC20Client().TokenPairs( + s.network.GetContext(), + &erc20types.QueryTokenPairsRequest{}, + ) + s.Require().NoError(err) + s.Require().Equal(len(tokenPairs.TokenPairs), 1) + + tokenPair := tokenPairs.TokenPairs[0] + + sender, err := sdktypes.AccAddressFromBech32(tokenPair.OwnerAddress) + s.Require().NoError(err) + + receiver, err := sdktypes.AccAddressFromBech32("ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg") + s.Require().NoError(err) + + amount := sdktypes.NewInt64Coin(s.network.GetDenom(), 100) + + prevBalancesReceiver, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: receiver.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + s.RunUpgrade(upgradeName) + + err = s.network.ERC20Keeper().MintCoins( + s.network.GetContext(), + sender, + receiver, + amount.Amount, + s.network.GetDenom(), + ) + s.Require().NoError(err) + + postBalancesReceiver, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: receiver.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + s.Require().Equal(prevBalancesReceiver.Balance.Amount.Add(amount.Amount).String(), postBalancesReceiver.Balance.Amount.String()) +} + +func (s *UpgradeTestSuite) TestUpgrade_ERC20_BurnCoins() { + sender, err := sdktypes.AccAddressFromBech32("ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg") + s.Require().NoError(err) + + amount := sdktypes.NewInt64Coin(s.network.GetDenom(), 100) + + prevBalancesSender, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: sender.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + err = s.network.ERC20Keeper().BurnCoins( + s.network.GetContext(), + sender, + amount.Amount, + s.network.GetDenom(), + ) + s.Require().NoError(err) + + postBalancesSender, err := s.network.GetBankClient().Balance( + s.network.GetContext(), + &banktypes.QueryBalanceRequest{ + Address: sender.String(), + Denom: s.network.GetDenom(), + }, + ) + s.Require().NoError(err) + + s.Require().Equal(prevBalancesSender.Balance.Amount.Sub(amount.Amount).String(), postBalancesSender.Balance.Amount.String()) +} + +func (s *UpgradeTestSuite) TestUpgrade_ERC20_TransferOwnership() { + tokenPairs, err := s.network.GetERC20Client().TokenPairs( + s.network.GetContext(), + &erc20types.QueryTokenPairsRequest{}, + ) + s.Require().NoError(err) + s.Require().Equal(len(tokenPairs.TokenPairs), 1) + + tokenPair := tokenPairs.TokenPairs[0] + + sender, err := sdktypes.AccAddressFromBech32(tokenPair.OwnerAddress) + s.Require().NoError(err) + + newOwner, err := sdktypes.AccAddressFromBech32("ethm1nqvn2hmte72e3z0xyqmh06hdwd9qu6hgdcavhh") + s.Require().NoError(err) + + err = s.network.ERC20Keeper().TransferOwnership( + s.network.GetContext(), + sender, + newOwner, + tokenPair.Denom, + ) + s.Require().NoError(err) + + postTokenPair, err := s.network.GetERC20Client().TokenPair( + s.network.GetContext(), + &erc20types.QueryTokenPairRequest{ + Token: tokenPair.Denom, + }, + ) + s.Require().NoError(err) + + s.Require().Equal(newOwner.String(), postTokenPair.TokenPair.OwnerAddress) +} diff --git a/app/upgrades/v7/integration/evm_test.go b/app/upgrades/v7/integration/evm_test.go new file mode 100644 index 0000000..a56fb3c --- /dev/null +++ b/app/upgrades/v7/integration/evm_test.go @@ -0,0 +1,24 @@ +package integration + +import ( + evmtypes "github.com/evmos/evmos/v20/x/evm/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_EvmParams() { + prevParams, err := s.network.GetEvmClient().Params( + s.network.GetContext(), + &evmtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetEvmClient().Params( + s.network.GetContext(), + &evmtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} diff --git a/app/upgrades/v7/integration/feemarket_test.go b/app/upgrades/v7/integration/feemarket_test.go new file mode 100644 index 0000000..8af75d5 --- /dev/null +++ b/app/upgrades/v7/integration/feemarket_test.go @@ -0,0 +1,24 @@ +package integration + +import ( + feemarkettypes "github.com/evmos/evmos/v20/x/feemarket/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_FeeMarketParams() { + prevParams, err := s.network.GetFeeMarketClient().Params( + s.network.GetContext(), + &feemarkettypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetFeeMarketClient().Params( + s.network.GetContext(), + &feemarkettypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} diff --git a/app/upgrades/v7/integration/gov_test.go b/app/upgrades/v7/integration/gov_test.go new file mode 100644 index 0000000..3790d9c --- /dev/null +++ b/app/upgrades/v7/integration/gov_test.go @@ -0,0 +1,24 @@ +package integration + +import ( + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" +) + +func (s *UpgradeTestSuite) TestUpgrade_GovParams() { + prevParams, err := s.network.GetGovClient().Params( + s.network.GetContext(), + &govtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetGovClient().Params( + s.network.GetContext(), + &govtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} diff --git a/tests/upgrade/network.go b/app/upgrades/v7/integration/network.go similarity index 86% rename from tests/upgrade/network.go rename to app/upgrades/v7/integration/network.go index 960cbab..f82507b 100644 --- a/tests/upgrade/network.go +++ b/app/upgrades/v7/integration/network.go @@ -1,11 +1,13 @@ -package testupgrade +package integration import ( + upgradetypes "cosmossdk.io/x/upgrade/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" erc20types "github.com/evmos/evmos/v20/x/erc20/types" evmtypes "github.com/evmos/evmos/v20/x/evm/types" @@ -65,6 +67,10 @@ func (n *UpgradeTestNetwork) GetStakingClient() stakingtypes.QueryClient { return exrpcommon.GetStakingClient(n) } +func (n *UpgradeTestNetwork) GetSlashingClient() slashingtypes.QueryClient { + return exrpcommon.GetSlashingClient(n) +} + func (n *UpgradeTestNetwork) GetDistrClient() distrtypes.QueryClient { return exrpcommon.GetDistrClient(n) } @@ -72,3 +78,7 @@ func (n *UpgradeTestNetwork) GetDistrClient() distrtypes.QueryClient { func (n *UpgradeTestNetwork) GetPoaClient() poatypes.QueryClient { return exrpcommon.GetPoaClient(n) } + +func (n *UpgradeTestNetwork) GetUpgradeClient() upgradetypes.QueryClient { + return exrpcommon.GetUpgradeClient(n) +} diff --git a/app/upgrades/v7/integration/poa_test.go b/app/upgrades/v7/integration/poa_test.go new file mode 100644 index 0000000..e95e182 --- /dev/null +++ b/app/upgrades/v7/integration/poa_test.go @@ -0,0 +1,97 @@ +package integration + +import ( + "math/rand" + "time" + + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + poatypes "github.com/xrplevm/node/v6/x/poa/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_Poa_ExecuteRemoveValidator() { + validators, err := s.network.GetStakingClient().Validators( + s.network.GetContext(), + &stakingtypes.QueryValidatorsRequest{}, + ) + s.Require().NoError(err) + s.Require().Greater(len(validators.Validators), 0) + + validator := validators.Validators[0] + valAddr, err := sdktypes.ValAddressFromBech32(validator.OperatorAddress) + s.Require().NoError(err) + valAccAddr := sdktypes.AccAddress(valAddr) + + _, err = s.network.GetStakingClient().Validator( + s.network.GetContext(), + &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: validator.OperatorAddress, + }, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + err = s.network.PoaKeeper().ExecuteRemoveValidator( + s.network.GetContext(), + valAccAddr.String(), + ) + s.Require().NoError(err) + + postValidator, err := s.network.GetStakingClient().Validator( + s.network.GetContext(), + &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: validator.OperatorAddress, + }, + ) + + s.Require().NoError(err) + s.Require().True(postValidator.Validator.Tokens.IsZero(), "validator tokens should be zero") + s.Require().True(postValidator.Validator.DelegatorShares.RoundInt().IsZero(), "validator delegator shares should be zero") +} + +func (s *UpgradeTestSuite) TestUpgrade_Poa_ExecuteAddValidator() { + randomAccs := simtypes.RandomAccounts(rand.New(rand.NewSource(time.Now().UnixNano())), 1) //nolint:gosec + randomAcc := randomAccs[0] + randomValAddr := sdktypes.ValAddress(randomAcc.Address.Bytes()) + + authority := sdktypes.AccAddress(address.Module("gov")) + msg, err := poatypes.NewMsgAddValidator( + authority.String(), + randomAcc.Address.String(), + randomAcc.ConsKey.PubKey(), + stakingtypes.Description{ + Moniker: "test", + }, + ) + s.Require().NoError(err) + + _, err = s.network.GetStakingClient().Validator( + s.network.GetContext(), + &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: randomValAddr.String(), + }, + ) + s.Require().Error(err) + + s.RunUpgrade(upgradeName) + + err = s.network.PoaKeeper().ExecuteAddValidator( + s.network.GetContext(), + msg, + ) + s.Require().NoError(err) + + val, err := s.network.GetStakingClient().Validator( + s.network.GetContext(), + &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: randomValAddr.String(), + }, + ) + s.Require().NoError(err) + s.Require().Equal(val.Validator.Status, stakingtypes.Unbonded) + s.Require().Equal(val.Validator.Tokens, sdktypes.DefaultPowerReduction) + s.Require().Equal(val.Validator.DelegatorShares, sdktypes.DefaultPowerReduction.ToLegacyDec()) +} diff --git a/app/upgrades/v7/integration/slashing_test.go b/app/upgrades/v7/integration/slashing_test.go new file mode 100644 index 0000000..ee0d4cd --- /dev/null +++ b/app/upgrades/v7/integration/slashing_test.go @@ -0,0 +1,44 @@ +//nolint:dupl +package integration + +import ( + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_SlashingParams() { + prevParams, err := s.network.GetSlashingClient().Params( + s.network.GetContext(), + &slashingtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetSlashingClient().Params( + s.network.GetContext(), + &slashingtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params, postParams.Params) +} + +func (s *UpgradeTestSuite) TestUpgrade_Slashing_SigningInfos() { + prevSigningInfos, err := s.network.GetSlashingClient().SigningInfos( + s.network.GetContext(), + &slashingtypes.QuerySigningInfosRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postSigningInfos, err := s.network.GetSlashingClient().SigningInfos( + s.network.GetContext(), + &slashingtypes.QuerySigningInfosRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified signing infos are the same + s.Require().Equal(prevSigningInfos.Info, postSigningInfos.Info) +} diff --git a/app/upgrades/v7/integration/staking_test.go b/app/upgrades/v7/integration/staking_test.go new file mode 100644 index 0000000..0ac3760 --- /dev/null +++ b/app/upgrades/v7/integration/staking_test.go @@ -0,0 +1,105 @@ +package integration + +import ( + "time" + + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func (s *UpgradeTestSuite) TestUpgrade_Staking_Params() { + prevParams, err := s.network.GetStakingClient().Params( + s.network.GetContext(), + &stakingtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postParams, err := s.network.GetStakingClient().Params( + s.network.GetContext(), + &stakingtypes.QueryParamsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified params are the same + s.Require().Equal(prevParams.Params.BondDenom, postParams.Params.BondDenom) + s.Require().Equal(prevParams.Params.MaxValidators, postParams.Params.MaxValidators) + s.Require().Equal(prevParams.Params.MinCommissionRate, postParams.Params.MinCommissionRate) + s.Require().Equal(prevParams.Params.MaxEntries, postParams.Params.MaxEntries) + s.Require().Equal(prevParams.Params.HistoricalEntries, postParams.Params.HistoricalEntries) + + // Check that unbonding time was modified + s.Require().Equal(postParams.Params.UnbondingTime, 100*time.Second) +} + +func (s *UpgradeTestSuite) TestUpgrade_Staking_Validators() { + res, err := s.network.GetStakingClient().Validators( + s.network.GetContext(), + &stakingtypes.QueryValidatorsRequest{}, + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postRes, err := s.network.GetStakingClient().Validators( + s.network.GetContext(), + &stakingtypes.QueryValidatorsRequest{}, + ) + s.Require().NoError(err) + + // Check that not modified validators are the same + s.Require().Equal(res.Validators, postRes.Validators) +} + +func (s *UpgradeTestSuite) TestUpgrade_Staking_Delegations() { + prevDelegations, err := s.network.StakingKeeper().GetAllDelegations( + s.network.GetContext(), + ) + s.Require().NoError(err) + + s.RunUpgrade(upgradeName) + + postDelegations, err := s.network.StakingKeeper().GetAllDelegations( + s.network.GetContext(), + ) + s.Require().NoError(err) + + // Check that not modified delegations are the same + s.Require().Equal(prevDelegations, postDelegations) +} + +func (s *UpgradeTestSuite) TestUpgrade_Staking_UnbondingDelegations() { + prevValidators, err := s.network.StakingKeeper().GetAllValidators( + s.network.GetContext(), + ) + s.Require().NoError(err) + + unbondingDelegations := make(map[string][]stakingtypes.UnbondingDelegation, len(prevValidators)) + for _, validator := range prevValidators { + res, err := s.network.GetStakingClient().ValidatorUnbondingDelegations( + s.network.GetContext(), + &stakingtypes.QueryValidatorUnbondingDelegationsRequest{ + ValidatorAddr: validator.OperatorAddress, + }, + ) + s.Require().NoError(err) + unbondingDelegations[validator.OperatorAddress] = res.UnbondingResponses + } + + s.RunUpgrade(upgradeName) + + postUnbondingDelegations := make(map[string][]stakingtypes.UnbondingDelegation, len(prevValidators)) + for _, validator := range prevValidators { + res, err := s.network.GetStakingClient().ValidatorUnbondingDelegations( + s.network.GetContext(), + &stakingtypes.QueryValidatorUnbondingDelegationsRequest{ + ValidatorAddr: validator.OperatorAddress, + }, + ) + s.Require().NoError(err) + postUnbondingDelegations[validator.OperatorAddress] = res.UnbondingResponses + } + + // Check that not modified unbonding delegations are the same + s.Require().Equal(unbondingDelegations, postUnbondingDelegations) +} diff --git a/app/upgrades/v7/integration/suite.go b/app/upgrades/v7/integration/suite.go new file mode 100644 index 0000000..718a5e3 --- /dev/null +++ b/app/upgrades/v7/integration/suite.go @@ -0,0 +1,80 @@ +package integration + +import ( + "os/exec" + + upgradetypes "cosmossdk.io/x/upgrade/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + "github.com/xrplevm/node/v6/testutil/integration/common/grpc" + "github.com/xrplevm/node/v6/testutil/integration/common/keyring" + exrpcommon "github.com/xrplevm/node/v6/testutil/integration/exrp/common" + exrpupgrade "github.com/xrplevm/node/v6/testutil/integration/exrp/upgrade" +) + +const ( + upgradeName = "v7.0.0" + testSnapshotDir = ".exrpd" +) + +type UpgradeTestSuite struct { + suite.Suite + + network *UpgradeTestNetwork + keyring keyring.Keyring + grpcHandler grpc.Handler +} + +func (s *UpgradeTestSuite) Network() *UpgradeTestNetwork { + return s.network +} + +func (s *UpgradeTestSuite) SetupSuite() { + // Setup the SDK config + s.network.SetupSdkConfig() + + s.Require().Equal(sdk.GetConfig().GetBech32AccountAddrPrefix(), "ethm") +} + +func (s *UpgradeTestSuite) SetupTest() { + // Check that the network was created successfully + kr := keyring.New(5) + + s.Require().NoError(exec.Command("cp", "-r", testSnapshotDir, testSnapshotDir+"-"+upgradeName).Run()) + + // Create the network + s.network = NewUpgradeTestNetwork( + exrpupgrade.WithUpgradePlanName(upgradeName), + exrpupgrade.WithDataDir(testSnapshotDir+"-"+upgradeName+"/data"), + exrpupgrade.WithNodeDBName("application"), + exrpcommon.WithBondDenom("apoa"), + exrpcommon.WithDenom("token"), + ) + + rpcHandler := grpc.NewIntegrationHandler(s.network) + + s.grpcHandler = rpcHandler + s.keyring = kr +} + +func (s *UpgradeTestSuite) TearDownTest() { + s.Require().NoError(exec.Command("rm", "-rf", testSnapshotDir+"-"+upgradeName).Run()) +} + +func (s *UpgradeTestSuite) RunUpgrade(name string) { + res, err := s.network.GetUpgradeClient().CurrentPlan( + s.network.GetContext(), + &upgradetypes.QueryCurrentPlanRequest{}, + ) + s.Require().NoError(err) + s.Require().Equal(name, res.Plan.Name) + + s.Require().True(s.Network().UpgradeKeeper().HasHandler(name)) + + err = s.network.UpgradeKeeper().ApplyUpgrade( + s.Network().GetContext(), + *res.Plan, + ) + + s.Require().NoError(err) +} diff --git a/app/upgrades/v7/integration/suite_test.go b/app/upgrades/v7/integration/suite_test.go new file mode 100644 index 0000000..dd3fe6f --- /dev/null +++ b/app/upgrades/v7/integration/suite_test.go @@ -0,0 +1,11 @@ +package integration + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeTestSuite)) +} diff --git a/app/upgrades/v7/upgrades.go b/app/upgrades/v7/upgrades.go new file mode 100644 index 0000000..484c63d --- /dev/null +++ b/app/upgrades/v7/upgrades.go @@ -0,0 +1,35 @@ +package v7 + +import ( + "context" + "time" + + upgradetypes "cosmossdk.io/x/upgrade/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + stakingkeeper "github.com/evmos/evmos/v20/x/staking/keeper" +) + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + sk *stakingkeeper.Keeper, +) upgradetypes.UpgradeHandler { + return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + ctx := sdk.UnwrapSDKContext(c) + logger := ctx.Logger().With("upgrade", UpgradeName) + logger.Info("Running v7 upgrade handler...") + + params, err := sk.GetParams(ctx) + if err != nil { + return vm, err + } + params.UnbondingTime = 100 * time.Second + err = sk.SetParams(ctx, params) + if err != nil { + return vm, err + } + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/local-node.sh b/local-node.sh index 3144a7b..4fdec5c 100755 --- a/local-node.sh +++ b/local-node.sh @@ -42,7 +42,7 @@ jq '.app_state["evm"]["params"]["evm_denom"]="token"' "$GENESIS" >"$TMP_GENESIS" jq '.app_state["evm"]["params"]["allow_unprotected_txs"]=true' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="token"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" jq '.app_state["gov"]["params"]["min_deposit"][0]["amount"]="1"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" -jq '.app_state["gov"]["params"]["voting_period"]="10s"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" +jq '.app_state["gov"]["params"]["voting_period"]="60s"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" jq '.app_state["gov"]["params"]["expedited_voting_period"]="5s"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" jq '.app_state["staking"]["params"]["bond_denom"]="apoa"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" jq '.app_state["staking"]["params"]["unbonding_time"]="60s"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" diff --git a/tests/upgrade/README.md b/tests/upgrade/README.md deleted file mode 100644 index 0a05141..0000000 --- a/tests/upgrade/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Upgrade testsuite - -## Download exported state - -```bash - -``` - -## Setup - -Set the `UPGRADE_STATE_FILE` environment variable to the path to the exported state file. -```bash -UPGRADE_STATE_FILE="path/to/exported-state.json" -``` \ No newline at end of file diff --git a/tests/upgrade/suite.go b/tests/upgrade/suite.go deleted file mode 100644 index ec76fc4..0000000 --- a/tests/upgrade/suite.go +++ /dev/null @@ -1,43 +0,0 @@ -package testupgrade - -import ( - "os" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" - exrpupgrade "github.com/xrplevm/node/v6/testutil/integration/exrp/upgrade" -) - -const defaultStateFile = "upgrade-state.json" - -type UpgradeTestSuite struct { - suite.Suite - - network *UpgradeTestNetwork -} - -func (s *UpgradeTestSuite) Network() *UpgradeTestNetwork { - return s.network -} - -func (s *UpgradeTestSuite) SetupTest() { - // Get the state file from the environment variable, or use the default one - stateFile := os.Getenv("UPGRADE_STATE_FILE") - if stateFile == "" { - stateFile = defaultStateFile - } - s.Require().NotEmpty(stateFile) - - // Setup the SDK config - s.network.SetupSdkConfig() - - s.Require().Equal(sdk.GetConfig().GetBech32AccountAddrPrefix(), "ethm") - - // Create the network - s.network = NewUpgradeTestNetwork( - exrpupgrade.WithGenesisFile(stateFile), - ) - - // Check that the network was created successfully - s.Require().NotNil(s.network) -} diff --git a/tests/upgrade/suite_test.go b/tests/upgrade/suite_test.go deleted file mode 100644 index a5513a2..0000000 --- a/tests/upgrade/suite_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package testupgrade - -import ( - "testing" - - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/suite" - "github.com/xrplevm/node/v6/app" -) - -func TestUpgradeTestSuite(t *testing.T) { - suite.Run(t, new(UpgradeTestSuite)) -} - -func (s *UpgradeTestSuite) TestUpgrade() { - denom := s.network.GetDenom() - s.Require().NotEmpty(denom) - s.Require().Equal(denom, app.BaseDenom) - - balances, err := s.Network().GetBankClient().AllBalances(s.network.GetContext(), &banktypes.QueryAllBalancesRequest{ - Address: "ethm1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3w48d64", - }) - - s.T().Log("balances", balances) - s.Require().NoError(err) - - err = s.network.NextBlock() - s.Require().NoError(err) - - res, err := s.Network().GetStakingClient().Validators(s.network.GetContext(), &stakingtypes.QueryValidatorsRequest{}) - s.Require().NoError(err) - - s.T().Log("validators", len(res.Validators)) - s.Require().Equal(len(res.Validators), 1) -} diff --git a/tests/upgrade/upgrade-state.json b/tests/upgrade/upgrade-state.json deleted file mode 100644 index af21608..0000000 --- a/tests/upgrade/upgrade-state.json +++ /dev/null @@ -1,656 +0,0 @@ -{ - "app_name": "exrpd", - "app_version": "v4.0.0-7-g40ab899", - "genesis_time": "2024-11-27T17:14:04.871328Z", - "chain_id": "exrp_1440002-1", - "initial_height": 8, - "app_hash": null, - "app_state": { - "auth": { - "params": { - "max_memo_characters": "256", - "tx_sig_limit": "7", - "tx_size_cost_per_byte": "10", - "sig_verify_cost_ed25519": "590", - "sig_verify_cost_secp256k1": "1000" - }, - "accounts": [ - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm1glht96kr2rseywuvhhay894qw7ekuc4q32ac2y", - "pub_key": null, - "account_number": "7", - "sequence": "0" - }, - "name": "erc20", - "permissions": [ - "minter", - "burner" - ] - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3w48d64", - "pub_key": null, - "account_number": "3", - "sequence": "0" - }, - "name": "bonded_tokens_pool", - "permissions": [ - "burner", - "staking" - ] - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm1tygms3xhhs3yv487phx3dw4a95jn7t7l64muvp", - "pub_key": null, - "account_number": "4", - "sequence": "0" - }, - "name": "not_bonded_tokens_pool", - "permissions": [ - "burner", - "staking" - ] - }, - { - "@type": "/cosmos.auth.v1beta1.BaseAccount", - "address": "ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg", - "pub_key": { - "@type": "/ethermint.crypto.v1.ethsecp256k1.PubKey", - "key": "AyzS/NPje8oX+4+4uWP9f3060duAFXh3MpNWELtTxPz1" - }, - "account_number": "0", - "sequence": "1" - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm1wztruvatpslu6ngetc65272cshcnzsxgphqyau", - "pub_key": null, - "account_number": "8", - "sequence": "0" - }, - "name": "poa", - "permissions": [ - "minter", - "burner" - ] - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm10d07y265gmmuvt4z0w9aw880jnsr700jpva843", - "pub_key": null, - "account_number": "5", - "sequence": "0" - }, - "name": "gov", - "permissions": [ - "burner" - ] - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8u3272a", - "pub_key": null, - "account_number": "2", - "sequence": "0" - }, - "name": "distribution", - "permissions": [] - }, - { - "@type": "/ethermint.types.v1.EthAccount", - "base_account": { - "address": "ethm16j2fvexdsfnq4t5ehmwqxjsda29qh4gh75fmg2", - "pub_key": null, - "account_number": "6", - "sequence": "0" - }, - "code_hash": "0x7b477c761b4d0469f03f27ba58d0a7eacbfdd62b69b82c6c683ae5f81c67fe80" - }, - { - "@type": "/cosmos.auth.v1beta1.ModuleAccount", - "base_account": { - "address": "ethm17xpfvakm2amg962yls6f84z3kell8c5lthdzgl", - "pub_key": null, - "account_number": "1", - "sequence": "0" - }, - "name": "fee_collector", - "permissions": [] - } - ] - }, - "authz": { - "authorization": [] - }, - "bank": { - "params": { - "send_enabled": [], - "default_send_enabled": true - }, - "balances": [ - { - "address": "ethm1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3w48d64", - "coins": [ - { - "denom": "apoa", - "amount": "1000000" - } - ] - }, - { - "address": "ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg", - "coins": [ - { - "denom": "token", - "amount": "1000000000000000000000000000" - } - ] - } - ], - "supply": [ - { - "denom": "apoa", - "amount": "1000000" - }, - { - "denom": "token", - "amount": "1000000000000000000000000000" - } - ], - "denom_metadata": [], - "send_enabled": [] - }, - "capability": { - "index": "3", - "owners": [ - { - "index": "1", - "index_owners": { - "owners": [ - { - "module": "ibc", - "name": "ports/transfer" - }, - { - "module": "transfer", - "name": "ports/transfer" - } - ] - } - }, - { - "index": "2", - "index_owners": { - "owners": [ - { - "module": "ibc", - "name": "ports/icahost" - }, - { - "module": "icahost", - "name": "ports/icahost" - } - ] - } - } - ] - }, - "crisis": { - "constant_fee": { - "denom": "token", - "amount": "1000" - } - }, - "distribution": { - "params": { - "community_tax": "0.020000000000000000", - "base_proposer_reward": "0.000000000000000000", - "bonus_proposer_reward": "0.000000000000000000", - "withdraw_addr_enabled": true - }, - "fee_pool": { - "community_pool": [] - }, - "delegator_withdraw_infos": [], - "previous_proposer": "ethmvalcons123s7tvluhrla7tpj5mwysxqlcgwwzwavxenru7", - "outstanding_rewards": [ - { - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "outstanding_rewards": [] - } - ], - "validator_accumulated_commissions": [ - { - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "accumulated": { - "commission": [] - } - } - ], - "validator_historical_rewards": [ - { - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "period": "1", - "rewards": { - "cumulative_reward_ratio": [], - "reference_count": 2 - } - } - ], - "validator_current_rewards": [ - { - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "rewards": { - "rewards": [], - "period": "2" - } - } - ], - "delegator_starting_infos": [ - { - "delegator_address": "ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg", - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "starting_info": { - "previous_period": "1", - "stake": "1000000.000000000000000000", - "height": "0" - } - } - ], - "validator_slash_events": [] - }, - "erc20": { - "params": { - "enable_erc20": true, - "native_precompiles": [ - "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517" - ], - "dynamic_precompiles": [] - }, - "token_pairs": [ - { - "erc20_address": "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517", - "denom": "token", - "enabled": true, - "contract_owner": "OWNER_MODULE", - "owner_address": "ethm1zrxl239wa6ad5xge3gs68rt98227xgnjq0xyw2" - } - ] - }, - "evidence": { - "evidence": [] - }, - "evm": { - "accounts": [ - { - "address": "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517", - "code": "608060405234801561001057600080fd5b50600436106101da5760003560e01c80635c975abb11610104578063a217fddf116100a2578063d539139311610071578063d53913931461057d578063d547741f1461059b578063dd62ed3e146105b7578063e63ab1e9146105e7576101da565b8063a217fddf146104cf578063a457c2d7146104ed578063a9059cbb1461051d578063ca15c8731461054d576101da565b80638456cb59116100de5780638456cb59146104475780639010d07c1461045157806391d148541461048157806395d89b41146104b1576101da565b80635c975abb146103dd57806370a08231146103fb57806379cc67901461042b576101da565b8063282c51f31161017c578063395093511161014b578063395093511461036b5780633f4ba83a1461039b57806340c10f19146103a557806342966c68146103c1576101da565b8063282c51f3146102f75780632f2ff15d14610315578063313ce5671461033157806336568abe1461034f576101da565b806318160ddd116101b857806318160ddd1461025d5780631cf2c7e21461027b57806323b872dd14610297578063248a9ca3146102c7576101da565b806301ffc9a7146101df57806306fdde031461020f578063095ea7b31461022d575b600080fd5b6101f960048036038101906101f49190612216565b610605565b604051610206919061225e565b60405180910390f35b61021761067f565b6040516102249190612312565b60405180910390f35b610247600480360381019061024291906123c8565b610711565b604051610254919061225e565b60405180910390f35b61026561072f565b6040516102729190612417565b60405180910390f35b610295600480360381019061029091906123c8565b610739565b005b6102b160048036038101906102ac9190612432565b6107b7565b6040516102be919061225e565b60405180910390f35b6102e160048036038101906102dc91906124bb565b6108af565b6040516102ee91906124f7565b60405180910390f35b6102ff6108ce565b60405161030c91906124f7565b60405180910390f35b61032f600480360381019061032a9190612512565b6108f2565b005b61033961091b565b604051610346919061256e565b60405180910390f35b61036960048036038101906103649190612512565b610932565b005b610385600480360381019061038091906123c8565b6109b5565b604051610392919061225e565b60405180910390f35b6103a3610a61565b005b6103bf60048036038101906103ba91906123c8565b610adb565b005b6103db60048036038101906103d69190612589565b610b59565b005b6103e5610b6d565b6040516103f2919061225e565b60405180910390f35b610415600480360381019061041091906125b6565b610b84565b6040516104229190612417565b60405180910390f35b610445600480360381019061044091906123c8565b610bcd565b005b61044f610c48565b005b61046b600480360381019061046691906125e3565b610cc2565b6040516104789190612632565b60405180910390f35b61049b60048036038101906104969190612512565b610cf1565b6040516104a8919061225e565b60405180910390f35b6104b9610d5b565b6040516104c69190612312565b60405180910390f35b6104d7610ded565b6040516104e491906124f7565b60405180910390f35b610507600480360381019061050291906123c8565b610df4565b604051610514919061225e565b60405180910390f35b610537600480360381019061053291906123c8565b610edf565b604051610544919061225e565b60405180910390f35b610567600480360381019061056291906124bb565b610efd565b6040516105749190612417565b60405180910390f35b610585610f21565b60405161059291906124f7565b60405180910390f35b6105b560048036038101906105b09190612512565b610f45565b005b6105d160048036038101906105cc919061264d565b610f6e565b6040516105de9190612417565b60405180910390f35b6105ef610ff5565b6040516105fc91906124f7565b60405180910390f35b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610678575061067782611129565b5b9050919050565b60606005805461068e906126bc565b80601f01602080910402602001604051908101604052809291908181526020018280546106ba906126bc565b80156107075780601f106106dc57610100808354040283529160200191610707565b820191906000526020600020905b8154815290600101906020018083116106ea57829003601f168201915b5050505050905090565b600061072561071e6111a3565b84846111ab565b6001905092915050565b6000600454905090565b61076a7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486107656111a3565b610cf1565b6107a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a090612760565b60405180910390fd5b6107b38282611376565b5050565b60006107c484848461154f565b6000600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061080f6111a3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508281101561088f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610886906127f2565b60405180910390fd5b6108a38561089b6111a3565b8584036111ab565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6108fb826108af565b61090c816109076111a3565b6117d3565b6109168383611870565b505050565b6000600760019054906101000a900460ff16905090565b61093a6111a3565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099e90612884565b60405180910390fd5b6109b182826118a4565b5050565b6000610a576109c26111a3565b8484600360006109d06111a3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a5291906128d3565b6111ab565b6001905092915050565b610a927f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610a8d6111a3565b610cf1565b610ad1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac89061299b565b60405180910390fd5b610ad96118d8565b565b610b0c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b076111a3565b610cf1565b610b4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4290612a2d565b60405180910390fd5b610b55828261197a565b5050565b610b6a610b646111a3565b82611376565b50565b6000600760009054906101000a900460ff16905090565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610be083610bdb6111a3565b610f6e565b905081811015610c25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1c90612abf565b60405180910390fd5b610c3983610c316111a3565b8484036111ab565b610c438383611376565b505050565b610c797f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c746111a3565b610cf1565b610cb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610caf90612b51565b60405180910390fd5b610cc0611adb565b565b6000610ce98260016000868152602001908152602001600020611b7e90919063ffffffff16565b905092915050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060068054610d6a906126bc565b80601f0160208091040260200160405190810160405280929190818152602001828054610d96906126bc565b8015610de35780601f10610db857610100808354040283529160200191610de3565b820191906000526020600020905b815481529060010190602001808311610dc657829003601f168201915b5050505050905090565b6000801b81565b60008060036000610e036111a3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb790612be3565b60405180910390fd5b610ed4610ecb6111a3565b858584036111ab565b600191505092915050565b6000610ef3610eec6111a3565b848461154f565b6001905092915050565b6000610f1a60016000848152602001908152602001600020611b98565b9050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b610f4e826108af565b610f5f81610f5a6111a3565b6117d3565b610f6983836118a4565b505050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6110238282610cf1565b6110f557600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061109a6111a3565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000611121836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611bad565b905092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061119c575061119b82611c1d565b5b9050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561121b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121290612c75565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128290612d07565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516113699190612417565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156113e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113dd90612d99565b60405180910390fd5b6113f282600083611c87565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147090612e2b565b60405180910390fd5b818103600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600460008282546114d19190612e4b565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115369190612417565b60405180910390a361154a83600084611c97565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b690612ef1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561162f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162690612f83565b60405180910390fd5b61163a838383611c87565b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156116c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b890613015565b60405180910390fd5b818103600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461175691906128d3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516117ba9190612417565b60405180910390a36117cd848484611c97565b50505050565b6117dd8282610cf1565b61186c576118028173ffffffffffffffffffffffffffffffffffffffff166014611c9c565b6118108360001c6020611c9c565b604051602001611821929190613109565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118639190612312565b60405180910390fd5b5050565b61187a8282611019565b61189f81600160008581526020019081526020016000206110f990919063ffffffff16565b505050565b6118ae8282611ed8565b6118d38160016000858152602001908152602001600020611fb990919063ffffffff16565b505050565b6118e0610b6d565b61191f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119169061318f565b60405180910390fd5b6000600760006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6119636111a3565b6040516119709190612632565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156119ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e1906131fb565b60405180910390fd5b6119f660008383611c87565b8060046000828254611a0891906128d3565b9250508190555080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a5e91906128d3565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611ac39190612417565b60405180910390a3611ad760008383611c97565b5050565b611ae3610b6d565b15611b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1a90613267565b60405180910390fd5b6001600760006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b676111a3565b604051611b749190612632565b60405180910390a1565b6000611b8d8360000183611fe9565b60001c905092915050565b6000611ba682600001612014565b9050919050565b6000611bb98383612025565b611c12578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611c17565b600090505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611c92838383612048565b505050565b505050565b606060006002836002611caf9190613287565b611cb991906128d3565b67ffffffffffffffff811115611cd257611cd16132e1565b5b6040519080825280601f01601f191660200182016040528015611d045781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611d3c57611d3b613310565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611da057611d9f613310565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611de09190613287565b611dea91906128d3565b90505b6001811115611e8a577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611e2c57611e2b613310565b5b1a60f81b828281518110611e4357611e42613310565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080611e839061333f565b9050611ded565b5060008414611ece576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec5906133b5565b60405180910390fd5b8091505092915050565b611ee28282610cf1565b15611fb557600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f5a6111a3565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000611fe1836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6120a0565b905092915050565b600082600001828154811061200157612000613310565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b6120538383836121b4565b61205b610b6d565b1561209b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209290613447565b60405180910390fd5b505050565b600080836001016000848152602001908152602001600020549050600081146121a85760006001826120d29190612e4b565b90506000600186600001805490506120ea9190612e4b565b905081811461215957600086600001828154811061210b5761210a613310565b5b906000526020600020015490508087600001848154811061212f5761212e613310565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061216d5761216c613467565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506121ae565b60009150505b92915050565b505050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6121f3816121be565b81146121fe57600080fd5b50565b600081359050612210816121ea565b92915050565b60006020828403121561222c5761222b6121b9565b5b600061223a84828501612201565b91505092915050565b60008115159050919050565b61225881612243565b82525050565b6000602082019050612273600083018461224f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156122b3578082015181840152602081019050612298565b838111156122c2576000848401525b50505050565b6000601f19601f8301169050919050565b60006122e482612279565b6122ee8185612284565b93506122fe818560208601612295565b612307816122c8565b840191505092915050565b6000602082019050818103600083015261232c81846122d9565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061235f82612334565b9050919050565b61236f81612354565b811461237a57600080fd5b50565b60008135905061238c81612366565b92915050565b6000819050919050565b6123a581612392565b81146123b057600080fd5b50565b6000813590506123c28161239c565b92915050565b600080604083850312156123df576123de6121b9565b5b60006123ed8582860161237d565b92505060206123fe858286016123b3565b9150509250929050565b61241181612392565b82525050565b600060208201905061242c6000830184612408565b92915050565b60008060006060848603121561244b5761244a6121b9565b5b60006124598682870161237d565b935050602061246a8682870161237d565b925050604061247b868287016123b3565b9150509250925092565b6000819050919050565b61249881612485565b81146124a357600080fd5b50565b6000813590506124b58161248f565b92915050565b6000602082840312156124d1576124d06121b9565b5b60006124df848285016124a6565b91505092915050565b6124f181612485565b82525050565b600060208201905061250c60008301846124e8565b92915050565b60008060408385031215612529576125286121b9565b5b6000612537858286016124a6565b92505060206125488582860161237d565b9150509250929050565b600060ff82169050919050565b61256881612552565b82525050565b6000602082019050612583600083018461255f565b92915050565b60006020828403121561259f5761259e6121b9565b5b60006125ad848285016123b3565b91505092915050565b6000602082840312156125cc576125cb6121b9565b5b60006125da8482850161237d565b91505092915050565b600080604083850312156125fa576125f96121b9565b5b6000612608858286016124a6565b9250506020612619858286016123b3565b9150509250929050565b61262c81612354565b82525050565b60006020820190506126476000830184612623565b92915050565b60008060408385031215612664576126636121b9565b5b60006126728582860161237d565b92505060206126838582860161237d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806126d457607f821691505b602082108114156126e8576126e761268d565b5b50919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d7573742060008201527f68617665206275726e657220726f6c6520746f206275726e0000000000000000602082015250565b600061274a603883612284565b9150612755826126ee565b604082019050919050565b600060208201905081810360008301526127798161273d565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b60006127dc602883612284565b91506127e782612780565b604082019050919050565b6000602082019050818103600083015261280b816127cf565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b600061286e602f83612284565b915061287982612812565b604082019050919050565b6000602082019050818103600083015261289d81612861565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006128de82612392565b91506128e983612392565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561291e5761291d6128a4565b5b828201905092915050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d7573742060008201527f686176652070617573657220726f6c6520746f20756e70617573650000000000602082015250565b6000612985603b83612284565b915061299082612929565b604082019050919050565b600060208201905081810360008301526129b481612978565b9050919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d7573742060008201527f68617665206d696e74657220726f6c6520746f206d696e740000000000000000602082015250565b6000612a17603883612284565b9150612a22826129bb565b604082019050919050565b60006020820190508181036000830152612a4681612a0a565b9050919050565b7f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b6000612aa9602483612284565b9150612ab482612a4d565b604082019050919050565b60006020820190508181036000830152612ad881612a9c565b9050919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d7573742060008201527f686176652070617573657220726f6c6520746f20706175736500000000000000602082015250565b6000612b3b603983612284565b9150612b4682612adf565b604082019050919050565b60006020820190508181036000830152612b6a81612b2e565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000612bcd602583612284565b9150612bd882612b71565b604082019050919050565b60006020820190508181036000830152612bfc81612bc0565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612c5f602483612284565b9150612c6a82612c03565b604082019050919050565b60006020820190508181036000830152612c8e81612c52565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000612cf1602283612284565b9150612cfc82612c95565b604082019050919050565b60006020820190508181036000830152612d2081612ce4565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000612d83602183612284565b9150612d8e82612d27565b604082019050919050565b60006020820190508181036000830152612db281612d76565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000612e15602283612284565b9150612e2082612db9565b604082019050919050565b60006020820190508181036000830152612e4481612e08565b9050919050565b6000612e5682612392565b9150612e6183612392565b925082821015612e7457612e736128a4565b5b828203905092915050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000612edb602583612284565b9150612ee682612e7f565b604082019050919050565b60006020820190508181036000830152612f0a81612ece565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000612f6d602383612284565b9150612f7882612f11565b604082019050919050565b60006020820190508181036000830152612f9c81612f60565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b6000612fff602683612284565b915061300a82612fa3565b604082019050919050565b6000602082019050818103600083015261302e81612ff2565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000613076601783613035565b915061308182613040565b601782019050919050565b600061309782612279565b6130a18185613035565b93506130b1818560208601612295565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b60006130f3601183613035565b91506130fe826130bd565b601182019050919050565b600061311482613069565b9150613120828561308c565b915061312b826130e6565b9150613137828461308c565b91508190509392505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b6000613179601483612284565b915061318482613143565b602082019050919050565b600060208201905081810360008301526131a88161316c565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b60006131e5601f83612284565b91506131f0826131af565b602082019050919050565b60006020820190508181036000830152613214816131d8565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000613251601083612284565b915061325c8261321b565b602082019050919050565b6000602082019050818103600083015261328081613244565b9050919050565b600061329282612392565b915061329d83612392565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156132d6576132d56128a4565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061334a82612392565b9150600082141561335e5761335d6128a4565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600061339f602083612284565b91506133aa82613369565b602082019050919050565b600060208201905081810360008301526133ce81613392565b9050919050565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6000613431602a83612284565b915061343c826133d5565b604082019050919050565b6000602082019050818103600083015261346081613424565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220c3d4a4231a6c94cfb03623ea4b77df2c9ccfa487132bebf43620219e3dc2f4cf64736f6c63430008090033", - "storage": [] - } - ], - "params": { - "evm_denom": "token", - "extra_eips": [ - "ethereum_3855" - ], - "chain_config": { - "homestead_block": "0", - "dao_fork_block": "0", - "dao_fork_support": true, - "eip150_block": "0", - "eip150_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155_block": "0", - "eip158_block": "0", - "byzantium_block": "0", - "constantinople_block": "0", - "petersburg_block": "0", - "istanbul_block": "0", - "muir_glacier_block": "0", - "berlin_block": "0", - "london_block": "0", - "arrow_glacier_block": "0", - "gray_glacier_block": "0", - "merge_netsplit_block": "0", - "shanghai_block": "0", - "cancun_block": "0" - }, - "allow_unprotected_txs": true, - "evm_channels": [ - "channel-10", - "channel-31", - "channel-83" - ], - "access_control": { - "create": { - "access_type": "ACCESS_TYPE_PERMISSIONLESS", - "access_control_list": [] - }, - "call": { - "access_type": "ACCESS_TYPE_PERMISSIONLESS", - "access_control_list": [] - } - }, - "active_static_precompiles": [ - "0x0000000000000000000000000000000000000100", - "0x0000000000000000000000000000000000000400", - "0x0000000000000000000000000000000000000800", - "0x0000000000000000000000000000000000000801", - "0x0000000000000000000000000000000000000802", - "0x0000000000000000000000000000000000000803", - "0x0000000000000000000000000000000000000804", - "0x0000000000000000000000000000000000000805" - ] - } - }, - "feegrant": { - "allowances": [] - }, - "feemarket": { - "params": { - "no_base_fee": false, - "base_fee_change_denominator": 8, - "elasticity_multiplier": 2, - "enable_height": "0", - "base_fee": "0", - "min_gas_price": "0.000000000000000000", - "min_gas_multiplier": "0.500000000000000000" - }, - "block_gas": "0" - }, - "genutil": { - "gen_txs": [] - }, - "gov": { - "starting_proposal_id": "1", - "deposits": [], - "votes": [], - "proposals": [], - "deposit_params": null, - "voting_params": null, - "tally_params": null, - "params": { - "min_deposit": [ - { - "denom": "token", - "amount": "1" - } - ], - "max_deposit_period": "172800s", - "voting_period": "10s", - "quorum": "0.334000000000000000", - "threshold": "0.500000000000000000", - "veto_threshold": "0.334000000000000000", - "min_initial_deposit_ratio": "0.000000000000000000", - "proposal_cancel_ratio": "0.500000000000000000", - "proposal_cancel_dest": "", - "expedited_voting_period": "5s", - "expedited_threshold": "0.667000000000000000", - "expedited_min_deposit": [ - { - "denom": "stake", - "amount": "50000000" - } - ], - "burn_vote_quorum": false, - "burn_proposal_deposit_prevote": false, - "burn_vote_veto": true, - "min_deposit_ratio": "0.010000000000000000" - }, - "constitution": "" - }, - "ibc": { - "client_genesis": { - "clients": [ - { - "client_id": "09-localhost", - "client_state": { - "@type": "/ibc.lightclients.localhost.v2.ClientState", - "latest_height": { - "revision_number": "1", - "revision_height": "7" - } - } - } - ], - "clients_consensus": [], - "clients_metadata": [], - "params": { - "allowed_clients": [ - "*" - ] - }, - "create_localhost": false, - "next_client_sequence": "0" - }, - "connection_genesis": { - "connections": [ - { - "id": "connection-localhost", - "client_id": "09-localhost", - "versions": [ - { - "identifier": "1", - "features": [ - "ORDER_ORDERED", - "ORDER_UNORDERED" - ] - } - ], - "state": "STATE_OPEN", - "counterparty": { - "client_id": "09-localhost", - "connection_id": "connection-localhost", - "prefix": { - "key_prefix": "aWJj" - } - }, - "delay_period": "0" - } - ], - "client_connection_paths": [], - "next_connection_sequence": "0", - "params": { - "max_expected_time_per_block": "30000000000" - } - }, - "channel_genesis": { - "channels": [], - "acknowledgements": [], - "commitments": [], - "receipts": [], - "send_sequences": [], - "recv_sequences": [], - "ack_sequences": [], - "next_channel_sequence": "0", - "params": { - "upgrade_timeout": { - "height": { - "revision_number": "0", - "revision_height": "0" - }, - "timestamp": "600000000000" - } - } - } - }, - "interchainaccounts": { - "controller_genesis_state": { - "active_channels": [], - "interchain_accounts": [], - "ports": [], - "params": { - "controller_enabled": true - } - }, - "host_genesis_state": { - "active_channels": [], - "interchain_accounts": [], - "port": "icahost", - "params": { - "host_enabled": true, - "allow_messages": [ - "*" - ] - } - } - }, - "poa": { - "params": {} - }, - "ratelimit": { - "params": {}, - "rate_limits": [], - "whitelisted_address_pairs": [], - "blacklisted_denoms": [], - "pending_send_packet_sequence_numbers": [], - "hour_epoch": { - "epoch_number": "17", - "duration": "3600s", - "epoch_start_time": "2024-11-27T17:00:00Z", - "epoch_start_height": "0" - } - }, - "slashing": { - "params": { - "signed_blocks_window": "100", - "min_signed_per_window": "0.500000000000000000", - "downtime_jail_duration": "600s", - "slash_fraction_double_sign": "0.000000000000000000", - "slash_fraction_downtime": "0.000000000000000000" - }, - "signing_infos": [ - { - "address": "ethmvalcons123s7tvluhrla7tpj5mwysxqlcgwwzwavxenru7", - "validator_signing_info": { - "address": "ethmvalcons123s7tvluhrla7tpj5mwysxqlcgwwzwavxenru7", - "start_height": "0", - "index_offset": "6", - "jailed_until": "1970-01-01T00:00:00Z", - "tombstoned": false, - "missed_blocks_counter": "0" - } - } - ], - "missed_blocks": [ - { - "address": "ethmvalcons123s7tvluhrla7tpj5mwysxqlcgwwzwavxenru7", - "missed_blocks": [] - } - ] - }, - "staking": { - "params": { - "unbonding_time": "60s", - "max_validators": 100, - "max_entries": 7, - "historical_entries": 10000, - "bond_denom": "apoa", - "min_commission_rate": "0.000000000000000000" - }, - "last_total_power": "1", - "last_validator_powers": [ - { - "address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "power": "1" - } - ], - "validators": [ - { - "operator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "consensus_pubkey": { - "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "x39TSSHGypcFLoD91nkVBQTiRT/KcVnnvyJrnXn0Bps=" - }, - "jailed": false, - "status": "BOND_STATUS_BONDED", - "tokens": "1000000", - "delegator_shares": "1000000.000000000000000000", - "description": { - "moniker": "localnet", - "identity": "", - "website": "", - "security_contact": "", - "details": "" - }, - "unbonding_height": "0", - "unbonding_time": "1970-01-01T00:00:00Z", - "commission": { - "commission_rates": { - "rate": "0.100000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.010000000000000000" - }, - "update_time": "2024-11-27T17:14:04.871328Z" - }, - "min_self_delegation": "1", - "unbonding_on_hold_ref_count": "0", - "unbonding_ids": [] - } - ], - "delegations": [ - { - "delegator_address": "ethm1dakgyqjulg29m5fmv992g2y66m9g2mjn6hahwg", - "validator_address": "ethmvaloper1dakgyqjulg29m5fmv992g2y66m9g2mjn48hmk4", - "shares": "1000000.000000000000000000" - } - ], - "unbonding_delegations": [], - "redelegations": [], - "exported": true - }, - "transfer": { - "port_id": "transfer", - "denom_traces": [], - "params": { - "send_enabled": true, - "receive_enabled": true - }, - "total_escrowed": [] - }, - "upgrade": {} - }, - "consensus": { - "validators": [ - { - "address": "5461E5B3FCB8FFDF2C32A6DC48181FC21CE13BAC", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "x39TSSHGypcFLoD91nkVBQTiRT/KcVnnvyJrnXn0Bps=" - }, - "power": "1", - "name": "localnet" - } - ], - "params": { - "block": { - "max_bytes": 22020096, - "max_gas": 10500000 - }, - "evidence": { - "max_age_num_blocks": 100000, - "max_age_duration": 172800000000000, - "max_bytes": 1048576 - }, - "validator": { - "pub_key_types": [ - "ed25519" - ] - }, - "version": { - "app": 0 - }, - "abci": { - "vote_extensions_enable_height": 0 - } - } - } -} \ No newline at end of file diff --git a/testutil/integration/common/network/network.go b/testutil/integration/common/network/network.go index bb98e18..993f4f6 100644 --- a/testutil/integration/common/network/network.go +++ b/testutil/integration/common/network/network.go @@ -45,7 +45,6 @@ type Network interface { GetDistrClient() distrtypes.QueryClient GetFeeMarketClient() feemarkettypes.QueryClient GetGovClient() govtypes.QueryClient - BroadcastTxSync(txBytes []byte) (abcitypes.ExecTxResult, error) Simulate(txBytes []byte) (*txtypes.SimulateResponse, error) CheckTx(txBytes []byte) (*abcitypes.ResponseCheckTx, error) diff --git a/testutil/integration/exrp/common/clients.go b/testutil/integration/exrp/common/clients.go index f10d2db..07b60ef 100644 --- a/testutil/integration/exrp/common/clients.go +++ b/testutil/integration/exrp/common/clients.go @@ -21,6 +21,8 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper" erc20types "github.com/evmos/evmos/v20/x/erc20/types" evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper" @@ -46,14 +48,14 @@ type NetworkKeepers interface { AuthzKeeper() authzkeeper.Keeper FeeMarketKeeper() feemarketkeeper.Keeper PoaKeeper() poakeeper.Keeper + UpgradeKeeper() upgradekeeper.Keeper } func getQueryHelper(ctx sdktypes.Context, encCfg testutil.TestEncodingConfig) *baseapp.QueryServiceTestHelper { interfaceRegistry := encCfg.InterfaceRegistry // This is needed so that state changes are not committed in precompiles // simulations. - cacheCtx, _ := ctx.CacheContext() - return baseapp.NewQueryServerTestHelper(cacheCtx, interfaceRegistry) + return baseapp.NewQueryServerTestHelper(ctx, interfaceRegistry) } func GetERC20Client(n NetworkKeepers) erc20types.QueryClient { @@ -121,3 +123,9 @@ func GetPoaClient(n NetworkKeepers) poatypes.QueryClient { poatypes.RegisterQueryServer(queryHelper, poakeeper.Querier{Keeper: n.PoaKeeper()}) return poatypes.NewQueryClient(queryHelper) } + +func GetUpgradeClient(n NetworkKeepers) upgradetypes.QueryClient { + queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig()) + upgradetypes.RegisterQueryServer(queryHelper, n.UpgradeKeeper()) + return upgradetypes.NewQueryClient(queryHelper) +} diff --git a/testutil/integration/exrp/common/config.go b/testutil/integration/exrp/common/config.go index 952d149..5ff04bd 100644 --- a/testutil/integration/exrp/common/config.go +++ b/testutil/integration/exrp/common/config.go @@ -34,6 +34,9 @@ type Config struct { CustomBaseAppOpts []func(*baseapp.BaseApp) MinDepositAmt sdkmath.Int Quorum string + UpgradePlanName string + DataDir string + NodeDBName string } type CustomGenesisState map[string]interface{} diff --git a/testutil/integration/exrp/integration/keepers.go b/testutil/integration/exrp/integration/keepers.go index 067b6ff..187c3ce 100644 --- a/testutil/integration/exrp/integration/keepers.go +++ b/testutil/integration/exrp/integration/keepers.go @@ -9,6 +9,7 @@ import ( slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper" evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper" feemarketkeeper "github.com/evmos/evmos/v20/x/feemarket/keeper" @@ -58,3 +59,7 @@ func (n *IntegrationNetwork) FeeMarketKeeper() feemarketkeeper.Keeper { func (n *IntegrationNetwork) PoaKeeper() poakeeper.Keeper { return n.app.PoaKeeper } + +func (n *IntegrationNetwork) UpgradeKeeper() upgradekeeper.Keeper { + return *n.app.UpgradeKeeper +} diff --git a/testutil/integration/exrp/upgrade/config.go b/testutil/integration/exrp/upgrade/config.go index 524423f..9faa342 100644 --- a/testutil/integration/exrp/upgrade/config.go +++ b/testutil/integration/exrp/upgrade/config.go @@ -23,3 +23,22 @@ func WithGenesisFile(genesisFile string) exrpcommon.ConfigOption { cfg.GenesisBytes = genesisBytes } } + +// WithUpgradePlanName sets the upgrade plan name for the network. +func WithUpgradePlanName(name string) exrpcommon.ConfigOption { + return func(cfg *exrpcommon.Config) { + cfg.UpgradePlanName = name + } +} + +func WithDataDir(dataDir string) exrpcommon.ConfigOption { + return func(cfg *exrpcommon.Config) { + cfg.DataDir = dataDir + } +} + +func WithNodeDBName(nodeDBName string) exrpcommon.ConfigOption { + return func(cfg *exrpcommon.Config) { + cfg.NodeDBName = nodeDBName + } +} diff --git a/testutil/integration/exrp/upgrade/keepers.go b/testutil/integration/exrp/upgrade/keepers.go index bf0d139..cd34b9a 100644 --- a/testutil/integration/exrp/upgrade/keepers.go +++ b/testutil/integration/exrp/upgrade/keepers.go @@ -9,6 +9,8 @@ import ( slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" erc20keeper "github.com/evmos/evmos/v20/x/erc20/keeper" evmkeeper "github.com/evmos/evmos/v20/x/evm/keeper" feemarketkeeper "github.com/evmos/evmos/v20/x/feemarket/keeper" @@ -58,3 +60,11 @@ func (n *UpgradeIntegrationNetwork) FeeMarketKeeper() feemarketkeeper.Keeper { func (n *UpgradeIntegrationNetwork) PoaKeeper() poakeeper.Keeper { return n.app.PoaKeeper } + +func (n *UpgradeIntegrationNetwork) UpgradeKeeper() upgradekeeper.Keeper { + return *n.app.UpgradeKeeper +} + +func (n *UpgradeIntegrationNetwork) ParamsKeeper() paramskeeper.Keeper { + return n.app.ParamsKeeper +} diff --git a/testutil/integration/exrp/upgrade/network.go b/testutil/integration/exrp/upgrade/network.go index 329f2c4..e92076b 100644 --- a/testutil/integration/exrp/upgrade/network.go +++ b/testutil/integration/exrp/upgrade/network.go @@ -4,9 +4,7 @@ package exrpupgrade import ( - "encoding/json" "fmt" - "math" "math/big" "time" @@ -14,18 +12,18 @@ import ( "github.com/xrplevm/node/v6/app" exrpcommon "github.com/xrplevm/node/v6/testutil/integration/exrp/common" + upgradetypes "cosmossdk.io/x/upgrade/types" abcitypes "github.com/cometbft/cometbft/abci/types" ed25519 "github.com/cometbft/cometbft/crypto/ed25519" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" tmversion "github.com/cometbft/cometbft/proto/tendermint/version" cmttypes "github.com/cometbft/cometbft/types" "github.com/cometbft/cometbft/version" + "github.com/cosmos/cosmos-sdk/runtime" sdktypes "github.com/cosmos/cosmos-sdk/types" sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" txtypes "github.com/cosmos/cosmos-sdk/types/tx" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - "github.com/evmos/evmos/v20/types" ) // Network is the interface that wraps the methods to interact with integration test network. @@ -71,9 +69,6 @@ func New(opts ...exrpcommon.ConfigOption) *UpgradeIntegrationNetwork { validators: []stakingtypes.Validator{}, } - if cfg.GenesisBytes == nil { - panic("GenesisBytes is nil") - } err := network.configureAndInitChain() if err != nil { panic(err) @@ -81,111 +76,27 @@ func New(opts ...exrpcommon.ConfigOption) *UpgradeIntegrationNetwork { return network } -func getValidatorsAndSignersFromCustomGenesisState( - stakingState stakingtypes.GenesisState, -) ( - *cmttypes.ValidatorSet, - map[string]cmttypes.PrivValidator, - []abcitypes.ValidatorUpdate, error, -) { - genesisValidators := stakingState.Validators - - tmValidators := make([]*cmttypes.Validator, 0, len(genesisValidators)) - validatorsUpdates := make([]abcitypes.ValidatorUpdate, 0, len(genesisValidators)) - valSigners := make(map[string]cmttypes.PrivValidator, len(genesisValidators)) - - // For each validator, we need to get the pubkey and create a new validator - for _, val := range genesisValidators { - pb, err := val.CmtConsPublicKey() - if err != nil { - return nil, nil, nil, err - } - pubKey := ed25519.PubKey(pb.GetEd25519()) - - validator := cmttypes.NewValidator(pubKey, 10000000) - tmValidators = append(tmValidators, validator) - validatorsUpdates = append(validatorsUpdates, abcitypes.ValidatorUpdate{ - PubKey: pb, - Power: val.GetConsensusPower(val.Tokens), - }) - } - - return cmttypes.NewValidatorSet(tmValidators), valSigners, validatorsUpdates, nil -} - // configureAndInitChain initializes the network with the given configuration. // It creates the genesis state and starts the network. func (n *UpgradeIntegrationNetwork) configureAndInitChain() error { // Create a new EvmosApp with the following params - exrpApp := exrpcommon.CreateExrpApp(n.cfg.ChainID, n.cfg.CustomBaseAppOpts...) - - var genesisState app.GenesisState - err := json.Unmarshal(n.cfg.GenesisBytes, &genesisState) - if err != nil { - return fmt.Errorf("error unmarshalling genesis state: %w", err) - } - - stateBytes, ok := genesisState["app_state"] - if !ok { - return fmt.Errorf("app_state not found in genesis state") - } - - var appState map[string]json.RawMessage - err = json.Unmarshal(genesisState["app_state"], &appState) - if err != nil { - return fmt.Errorf("error unmarshalling app state: %w", err) - } - - var stakingState stakingtypes.GenesisState - err = exrpApp.AppCodec().UnmarshalJSON(appState["staking"], &stakingState) - if err != nil { - return fmt.Errorf("error unmarshalling staking state: %w", err) - } - - valSet, valSigners, _, err := getValidatorsAndSignersFromCustomGenesisState(stakingState) - if err != nil { - return fmt.Errorf("error getting validators and signers from custom genesis state: %w", err) - } - - // Consensus module does not have a genesis state on the app, - // but can customize the consensus parameters of the chain on initialization + exrpApp := CreateExrpApp(n.cfg.ChainID, n.cfg.DataDir, n.cfg.NodeDBName, n.cfg.CustomBaseAppOpts...) - var consensusState map[string]json.RawMessage - err = json.Unmarshal(genesisState["consensus"], &consensusState) + validators, err := exrpApp.StakingKeeper.GetBondedValidatorsByPower(exrpApp.NewContext(true)) if err != nil { - return fmt.Errorf("error unmarshalling consensus state: %w", err) + return err } - var consensusParams *cmtproto.ConsensusParams - err = json.Unmarshal(consensusState["params"], &consensusParams) + valSet, err := createStakingValidators(validators) if err != nil { - return fmt.Errorf("error unmarshalling consensus params: %w", err) - } - - var initialHeight int64 - if err := json.Unmarshal(genesisState["initial_height"], &initialHeight); err != nil { - return fmt.Errorf("initial_height is not an int64") - } - - now := time.Now().UTC() - if _, err := exrpApp.InitChain( - &abcitypes.RequestInitChain{ - Time: now, - ChainId: n.cfg.ChainID, - Validators: []abcitypes.ValidatorUpdate{}, - ConsensusParams: consensusParams, - AppStateBytes: stateBytes, - InitialHeight: initialHeight, - }, - ); err != nil { return err } header := cmtproto.Header{ ChainID: n.cfg.ChainID, - Height: initialHeight, + Height: exrpApp.LastBlockHeight() + 1, AppHash: exrpApp.LastCommitID().Hash, - Time: now, + Time: time.Now().UTC(), ValidatorsHash: valSet.Hash(), NextValidatorsHash: valSet.Hash(), ProposerAddress: valSet.Proposer.Address, @@ -199,27 +110,36 @@ func (n *UpgradeIntegrationNetwork) configureAndInitChain() error { return err } + // Store upgrade plan on finalizeblock state. + upgradePlan := upgradetypes.Plan{ + Name: n.cfg.UpgradePlanName, + Height: exrpApp.LastBlockHeight() + 1, + } + + bz, err := exrpApp.AppCodec().Marshal(&upgradePlan) + if err != nil { + return err + } + // TODO - this might not be the best way to initilize the context n.ctx = exrpApp.BaseApp.NewContextLegacy(false, header) - // Commit genesis changes - if _, err := exrpApp.Commit(); err != nil { + upgradeKey := exrpApp.GetKey(upgradetypes.StoreKey) + upgradeStoreService := runtime.NewKVStoreService(upgradeKey) + upgradeStore := upgradeStoreService.OpenKVStore(n.ctx) + err = upgradeStore.Set(upgradetypes.PlanKey(), bz) + if err != nil { return err } - // Set networks global parameters - var blockMaxGas uint64 = math.MaxUint64 - if consensusParams.Block != nil && consensusParams.Block.MaxGas > 0 { - blockMaxGas = uint64(consensusParams.Block.MaxGas) //nolint:gosec // G115 + // Commit genesis changes + if _, err := exrpApp.Commit(); err != nil { + return err } n.app = exrpApp - n.ctx = n.ctx.WithConsensusParams(*consensusParams) - n.ctx = n.ctx.WithBlockGasMeter(types.NewInfiniteGasMeterWithLimit(blockMaxGas)) - n.validators = stakingState.Validators n.valSet = valSet - n.valSigners = valSigners return nil } @@ -330,3 +250,17 @@ func (n *UpgradeIntegrationNetwork) CheckTx(txBytes []byte) (*abcitypes.Response } return res, nil } + +func createStakingValidators(validators []stakingtypes.Validator) (*cmttypes.ValidatorSet, error) { + tmValidators := make([]*cmttypes.Validator, 0, len(validators)) + for _, val := range validators { + pb, err := val.CmtConsPublicKey() + if err != nil { + return nil, err + } + pubKey := ed25519.PubKey(pb.GetEd25519()) + validator := cmttypes.NewValidator(pubKey, val.GetConsensusPower(val.Tokens)) + tmValidators = append(tmValidators, validator) + } + return cmttypes.NewValidatorSet(tmValidators), nil +} diff --git a/testutil/integration/exrp/upgrade/setup.go b/testutil/integration/exrp/upgrade/setup.go new file mode 100644 index 0000000..d60bf74 --- /dev/null +++ b/testutil/integration/exrp/upgrade/setup.go @@ -0,0 +1,39 @@ +package exrpupgrade + +import ( + "cosmossdk.io/log" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" + simutils "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/xrplevm/node/v6/app" + exrpcommon "github.com/xrplevm/node/v6/testutil/integration/exrp/common" +) + +// createExrpApp creates an exrp app +func CreateExrpApp(chainID string, dataDir string, nodeDBName string, customBaseAppOptions ...func(*baseapp.BaseApp)) *app.App { + testNodeHome := exrpcommon.MustGetIntegrationTestNodeHome() + // Create exrp app + db, err := dbm.NewGoLevelDB(nodeDBName, dataDir, nil) + if err != nil { + panic(err) + } + logger := log.NewNopLogger() + loadLatest := true + skipUpgradeHeights := map[int64]bool{} + homePath := testNodeHome + invCheckPeriod := uint(5) + appOptions := simutils.NewAppOptionsWithFlagHome(homePath) + baseAppOptions := append(customBaseAppOptions, baseapp.SetChainID(chainID)) //nolint:gocritic + + return app.New( + logger, + db, + nil, + loadLatest, + skipUpgradeHeights, + homePath, + invCheckPeriod, + appOptions, + baseAppOptions..., + ) +}