From 456e0b29ad5533e3c380eeb340ed699f43278a82 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Wed, 7 Oct 2020 00:39:05 +0300 Subject: [PATCH 01/20] Release: [DFI-873] simulator update, Cosmos SDK bump, genesis update (#212) * [DFI-873] simulator: rewards lock added, LP staking added, major refactoring; ccstorage: LPT default currency added * [DFI-873] simulator: refactoring, undelegateOp fix * [DFI-873] simulator: Linter fixes * [DFI-873] unified app default GenesisState override func added and used for Simulator * All genesis params are gathered in one place; major defaults refactoring (circular dep fix); Cosmos SDK version bump --- app/common_test.go | 14 +- app/integ_app_test.go | 4 +- app/integ_gov_test.go | 26 +- app/unit_distribution_test.go | 4 +- cmd/config/bech_config.go | 20 + cmd/config/cli_config.go | 3 +- cmd/config/config.go | 125 ------ cmd/config/gen_init.go | 211 --------- cmd/config/genesis/cmd_init.go | 140 ++++++ .../genesis/defaults/common_defaults.go | 53 +++ cmd/config/genesis/genesis.go | 279 ++++++++++++ cmd/config/restrictions/restrictions.go | 9 +- cmd/config/vm_config.go | 85 ++++ cmd/dncli/main.go | 11 +- cmd/dnode/main.go | 4 +- cmd/dnode/testnet.go | 410 ------------------ go.mod | 3 +- go.sum | 2 + helpers/tests/clitester/cli_tester_configs.go | 38 +- helpers/tests/clitester/cli_tester_init.go | 12 +- helpers/tests/clitester/cli_tester_rest.go | 10 +- helpers/tests/clitester/types_tx.go | 4 +- helpers/tests/simulator/inflation_test.go | 204 +++++++-- helpers/tests/simulator/sim.go | 128 +++--- helpers/tests/simulator/sim_account.go | 107 ++++- helpers/tests/simulator/sim_helpers.go | 153 ++----- helpers/tests/simulator/sim_invariant.go | 45 +- helpers/tests/simulator/sim_operation.go | 52 ++- helpers/tests/simulator/sim_ops.go | 362 ---------------- .../simulator/sim_ops_create_validator.go | 83 ++++ helpers/tests/simulator/sim_ops_delegate.go | 156 +++++++ helpers/tests/simulator/sim_ops_redelegate.go | 172 ++++++++ .../simulator/sim_ops_rewards_delegator.go | 78 ++++ .../tests/simulator/sim_ops_rewards_lock.go | 76 ++++ .../simulator/sim_ops_rewards_validator.go | 73 ++++ helpers/tests/simulator/sim_ops_undelegate.go | 134 ++++++ helpers/tests/simulator/sim_options.go | 17 +- helpers/tests/simulator/sim_queries.go | 18 +- helpers/tests/simulator/sim_report.go | 66 +-- helpers/tests/simulator/sim_report_csv.go | 36 +- helpers/tests/simulator/sim_report_debug.go | 2 +- helpers/tests/simulator/sim_txs.go | 96 +++- helpers/tests/simulator/sim_validator.go | 133 +++++- x/ccstorage/internal/types/genesis.go | 4 + x/core/ante_decor_common.go | 4 +- x/core/ante_decor_denom.go | 4 +- 46 files changed, 2161 insertions(+), 1509 deletions(-) create mode 100644 cmd/config/bech_config.go delete mode 100644 cmd/config/config.go delete mode 100644 cmd/config/gen_init.go create mode 100644 cmd/config/genesis/cmd_init.go create mode 100644 cmd/config/genesis/defaults/common_defaults.go create mode 100644 cmd/config/genesis/genesis.go create mode 100644 cmd/config/vm_config.go delete mode 100644 cmd/dnode/testnet.go delete mode 100644 helpers/tests/simulator/sim_ops.go create mode 100644 helpers/tests/simulator/sim_ops_create_validator.go create mode 100644 helpers/tests/simulator/sim_ops_delegate.go create mode 100644 helpers/tests/simulator/sim_ops_redelegate.go create mode 100644 helpers/tests/simulator/sim_ops_rewards_delegator.go create mode 100644 helpers/tests/simulator/sim_ops_rewards_lock.go create mode 100644 helpers/tests/simulator/sim_ops_rewards_validator.go create mode 100644 helpers/tests/simulator/sim_ops_undelegate.go diff --git a/app/common_test.go b/app/common_test.go index 28de268d..7e98a9f5 100644 --- a/app/common_test.go +++ b/app/common_test.go @@ -31,8 +31,8 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/test/bufconn" - dnConfig "github.com/dfinance/dnode/cmd/config" vmConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/cmd/config/restrictions" "github.com/dfinance/dnode/helpers/tests" "github.com/dfinance/dnode/x/currencies" @@ -369,13 +369,13 @@ func GetGenesis(app *DnServiceApp, chainID, monikerID string, nodeAccPrivKey sec stakingGenesis := staking.GenesisState{} app.cdc.MustUnmarshalJSON(genesisState[staking.ModuleName], &stakingGenesis) - stakingGenesis.Params.BondDenom = dnConfig.MainDenom + stakingGenesis.Params.BondDenom = defaults.MainDenom genesisState[staking.ModuleName] = codec.MustMarshalJSONIndent(app.cdc, stakingGenesis) // update mint denom mintGenesis := mint.GenesisState{} app.cdc.MustUnmarshalJSON(genesisState[mint.ModuleName], &mintGenesis) - mintGenesis.Params.MintDenom = dnConfig.MainDenom + mintGenesis.Params.MintDenom = defaults.MainDenom genesisState[mint.ModuleName] = codec.MustMarshalJSONIndent(app.cdc, mintGenesis) oracleGenesis := oracle.GenesisState{ @@ -408,14 +408,14 @@ func GetGenesis(app *DnServiceApp, chainID, monikerID string, nodeAccPrivKey sec msg := staking.NewMsgCreateValidator( nodeAcc.Address.Bytes(), nodeAcc.PubKey, - sdk.NewCoin(dnConfig.MainDenom, tokenAmount), + sdk.NewCoin(defaults.MainDenom, tokenAmount), staking.NewDescription(monikerID, "", "", "", ""), staking.NewCommissionRates(commissionRate, commissionMaxRate, commissionChangeRate), minSelfDelegation, ) txFee := auth.StdFee{ - Amount: sdk.Coins{{Denom: dnConfig.MainDenom, Amount: sdk.NewInt(1)}}, + Amount: sdk.Coins{{Denom: defaults.MainDenom, Amount: sdk.NewInt(1)}}, Gas: defGasAmount, } txMemo := "testmemo" @@ -503,7 +503,7 @@ func GenTx(msgs []sdk.Msg, accnums []uint64, seq []uint64, priv ...crypto.PrivKe memo := "testmemotestmemo" fee := auth.StdFee{ - Amount: sdk.Coins{{Denom: dnConfig.MainDenom, Amount: sdk.NewInt(1)}}, + Amount: sdk.Coins{{Denom: defaults.MainDenom, Amount: sdk.NewInt(1)}}, Gas: defGasAmount, } @@ -524,7 +524,7 @@ func GenTx(msgs []sdk.Msg, accnums []uint64, seq []uint64, priv ...crypto.PrivKe // GenDefCoins returns Coins with xfi amount. func GenDefCoins(t *testing.T) sdk.Coins { - coins, err := sdk.ParseCoins("1000000000000000000000" + dnConfig.MainDenom) + coins, err := sdk.ParseCoins("1000000000000000000000" + defaults.MainDenom) if t != nil { require.NoError(t, err) } diff --git a/app/integ_app_test.go b/app/integ_app_test.go index 9e0bca57..f817f94d 100644 --- a/app/integ_app_test.go +++ b/app/integ_app_test.go @@ -12,7 +12,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" - dnConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/common_vm" "github.com/dfinance/dnode/x/vm" "github.com/dfinance/dnode/x/vm/client/vm_client" @@ -138,7 +138,7 @@ func TestIntegApp_Crisis(t *testing.T) { } getXfiBtcAccCoins := func(addr sdk.AccAddress) (sdk.Coin, sdk.Coin) { - xfiCoin := sdk.NewCoin(dnConfig.MainDenom, sdk.ZeroInt()) + xfiCoin := sdk.NewCoin(defaults.MainDenom, sdk.ZeroInt()) btcCoin := sdk.NewCoin("btc", sdk.ZeroInt()) acc := GetAccountCheckTx(app, addr) for _, coin := range acc.GetCoins() { diff --git a/app/integ_gov_test.go b/app/integ_gov_test.go index 9aea205f..96b9ef75 100644 --- a/app/integ_gov_test.go +++ b/app/integ_gov_test.go @@ -11,7 +11,7 @@ import ( "github.com/dfinance/glav" "github.com/stretchr/testify/require" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/helpers/tests" cliTester "github.com/dfinance/dnode/helpers/tests/clitester" "github.com/dfinance/dnode/x/common_vm" @@ -136,22 +136,22 @@ func TestIntegGov_StdlibUpdate(t *testing.T) { { // invalid from { - tx := ct.TxVmStdlibUpdateProposal("invalid_address", moduleV1BytecodePath, "http://ya.ru", "Desc", 50, config.GovMinDeposit) + tx := ct.TxVmStdlibUpdateProposal("invalid_address", moduleV1BytecodePath, "http://ya.ru", "Desc", 50, defaults.GovMinDepositCoin) tx.CheckFailedWithErrorSubstring("keyring") } // invalid file path { - tx := ct.TxVmStdlibUpdateProposal(senderAddr, "invalid_path", "http://ya.ru", "Desc", 50, config.GovMinDeposit) + tx := ct.TxVmStdlibUpdateProposal(senderAddr, "invalid_path", "http://ya.ru", "Desc", 50, defaults.GovMinDepositCoin) tx.CheckFailedWithErrorSubstring("moveFile") } // invalid blockHeight { - tx1 := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Desc", 0, config.GovMinDeposit) + tx1 := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Desc", 0, defaults.GovMinDepositCoin) tx1.CheckFailedWithErrorSubstring("height") - tx2 := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Desc", 0, config.GovMinDeposit) + tx2 := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Desc", 0, defaults.GovMinDepositCoin) tx2.ChangeCmdArg("0", "abc") tx2.CheckFailedWithErrorSubstring("ParseInt") } @@ -159,7 +159,7 @@ func TestIntegGov_StdlibUpdate(t *testing.T) { // Add DVM stdlib update proposal for module version 1 (cover the min deposit) { - tx := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Foo module V1 added", -1, config.GovMinDeposit) + tx := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV1BytecodePath, "http://ya.ru", "Foo module V1 added", -1, defaults.GovMinDepositCoin) ct.SubmitAndConfirmProposal(tx, true) } @@ -182,7 +182,7 @@ func TestIntegGov_StdlibUpdate(t *testing.T) { // Add DVM stdlib update proposal for module version 2 { - tx := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV2BytecodePath, "http://ya.ru", "Foo module V2 added", -1, config.GovMinDeposit) + tx := ct.TxVmStdlibUpdateProposal(senderAddr, moduleV2BytecodePath, "http://ya.ru", "Foo module V2 added", -1, defaults.GovMinDepositCoin) ct.SubmitAndConfirmProposal(tx, true) } @@ -222,27 +222,27 @@ func TestIntegGov_RegisterCurrency(t *testing.T) { { // invalid from { - tx := ct.TxCCAddCurrencyProposal("invalid_from", crDenom, crBalancePathHex, crInfoPathHex, crDecimals, config.GovMinDeposit) + tx := ct.TxCCAddCurrencyProposal("invalid_from", crDenom, crBalancePathHex, crInfoPathHex, crDecimals, defaults.GovMinDepositCoin) tx.CheckFailedWithErrorSubstring("keyring") } // invalid denom { - tx := ct.TxCCAddCurrencyProposal(senderAddr, "invalid1", crBalancePathHex, crInfoPathHex, crDecimals, config.GovMinDeposit) + tx := ct.TxCCAddCurrencyProposal(senderAddr, "invalid1", crBalancePathHex, crInfoPathHex, crDecimals, defaults.GovMinDepositCoin) tx.CheckFailedWithErrorSubstring("denom") } // invalid path { - tx1 := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, "zzvv", crInfoPathHex, crDecimals, config.GovMinDeposit) + tx1 := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, "zzvv", crInfoPathHex, crDecimals, defaults.GovMinDepositCoin) tx1.CheckFailedWithErrorSubstring("vmBalancePathHex") - tx2 := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, "abc", crDecimals, config.GovMinDeposit) + tx2 := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, "abc", crDecimals, defaults.GovMinDepositCoin) tx2.CheckFailedWithErrorSubstring("vmInfoPathHex") } // invalid decimals { - tx := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, crInfoPathHex, crDecimals, config.GovMinDeposit) + tx := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, crInfoPathHex, crDecimals, defaults.GovMinDepositCoin) tx.ChangeCmdArg("8", "abc") tx.CheckFailedWithErrorSubstring("decimals") } @@ -250,7 +250,7 @@ func TestIntegGov_RegisterCurrency(t *testing.T) { // Add proposal { - tx := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, crInfoPathHex, crDecimals, config.GovMinDeposit) + tx := ct.TxCCAddCurrencyProposal(senderAddr, crDenom, crBalancePathHex, crInfoPathHex, crDecimals, defaults.GovMinDepositCoin) ct.SubmitAndConfirmProposal(tx, false) } diff --git a/app/unit_distribution_test.go b/app/unit_distribution_test.go index e754b57d..2f0b1c95 100644 --- a/app/unit_distribution_test.go +++ b/app/unit_distribution_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" ) // Check disabled distribution transactions. @@ -46,7 +46,7 @@ func TestDistribution_MessagesNotWorking(t *testing.T) { // check fund community pool. { senderAcc, senderPrivKey := GetAccountCheckTx(app, nodeAddress), nodePrivKey - withdrawComissionMsg := distribution.NewMsgFundPublicTreasuryPool(sdk.NewCoins(sdk.NewCoin(config.MainDenom, sdk.NewInt(1))), nodeAddress) + withdrawComissionMsg := distribution.NewMsgFundPublicTreasuryPool(sdk.NewCoins(sdk.NewCoin(defaults.MainDenom, sdk.NewInt(1))), nodeAddress) tx := GenTx([]sdk.Msg{withdrawComissionMsg}, []uint64{senderAcc.GetAccountNumber()}, []uint64{senderAcc.GetSequence()}, senderPrivKey) CheckDeliverSpecificErrorTx(t, app, tx, errors.ErrUnknownRequest) } diff --git a/cmd/config/bech_config.go b/cmd/config/bech_config.go new file mode 100644 index 00000000..040b15a7 --- /dev/null +++ b/cmd/config/bech_config.go @@ -0,0 +1,20 @@ +package config + +import sdk "github.com/cosmos/cosmos-sdk/types" + +const ( + MainPrefix = "wallet" // Main prefix for all addresses. + Bech32PrefixAccAddr = MainPrefix // Bech32 prefix for account addresses. + Bech32PrefixAccPub = MainPrefix + sdk.PrefixPublic // Bech32 prefix for accounts pub keys. + Bech32PrefixValAddr = MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator // Bech32 prefix for validators addresses. + Bech32PrefixValPub = MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic // Bech32 prefix for validator pub keys. + Bech32PrefixConsAddr = MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus // Bech32 prefix for consensus addresses. + Bech32PrefixConsPub = MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic // Bech32 prefix for consensus pub keys. +) + +// Initializing DN custom prefixes. +func InitBechPrefixes(config *sdk.Config) { + config.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub) + config.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub) + config.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub) +} diff --git a/cmd/config/cli_config.go b/cmd/config/cli_config.go index bb5c17fc..135572b4 100644 --- a/cmd/config/cli_config.go +++ b/cmd/config/cli_config.go @@ -15,8 +15,7 @@ import ( ) const ( - flagGet = "get" - DefaultCompilerAddr = "tcp://127.0.0.1:50051" + flagGet = "get" ) var configDefaults = map[string]string{ diff --git a/cmd/config/config.go b/cmd/config/config.go deleted file mode 100644 index eb56a2de..00000000 --- a/cmd/config/config.go +++ /dev/null @@ -1,125 +0,0 @@ -// Configuration for DNode and DNCli. -package config - -import ( - "bytes" - "os" - "path/filepath" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/viper" - tmOs "github.com/tendermint/tendermint/libs/os" -) - -const ( - LiquidityProviderDenom = "lpt" - MainDenom = "xfi" - StakingDenom = "sxfi" - DefaultFeeAmount = "100000000000000" - DefaultFee = DefaultFeeAmount + MainDenom - MainPrefix = "wallet" // Main prefix for all addresses. - Bech32PrefixAccAddr = MainPrefix // Bech32 prefix for account addresses. - Bech32PrefixAccPub = MainPrefix + sdk.PrefixPublic // Bech32 prefix for accounts pub keys. - Bech32PrefixValAddr = MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator // Bech32 prefix for validators addresses. - Bech32PrefixValPub = MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic // Bech32 prefix for validator pub keys. - Bech32PrefixConsAddr = MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus // Bech32 prefix for consensus addresses. - Bech32PrefixConsPub = MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic // Bech32 prefix for consensus pub keys. - - VMConfigFile = "vm.toml" // Default file to store config. - ConfigDir = "config" // Default directory to store all configurations. - - // VM configs. - DefaultVMAddress = "tcp://127.0.0.1:50051" // Default virtual machine address to connect from Cosmos SDK. - DefaultDataListen = "tcp://127.0.0.1:50052" // Default data server address to listen for connections from VM. - - // Default retry configs. - DefaultMaxAttempts = 0 // Default maximum attempts for retry. - DefaultReqTimeout = 0 // Default request timeout per attempt [ms]. - - // Default governance params. - DefaultGovMinDepositAmount = "100000000000000000000" // 100 sxfi - - // Invariants check period for crisis module (in blocks) - DefInvCheckPeriod = 10 - - // Default staking validator minSelfDelegation amount - DefMinSelfDelegation = "250000000000000000000000" // 250000 sxfi -) - -var ( - GovMinDeposit sdk.Coin -) - -// Virtual machine connection config (see config/vm.toml). -type VMConfig struct { - Address string `mapstructure:"vm_address"` // address of virtual machine. - DataListen string `mapstructure:"vm_data_listen"` // data listen. - - // Retry policy - MaxAttempts uint `mapstructure:"vm_retry_max_attempts"` // maximum attempts for retry (0 - infinity) - ReqTimeoutInMs uint `mapstructure:"vm_retry_req_timeout_ms"` // request timeout per attempt (0 - infinity) [ms] -} - -// Default VM configuration. -func DefaultVMConfig() *VMConfig { - return &VMConfig{ - Address: DefaultVMAddress, - DataListen: DefaultDataListen, - MaxAttempts: DefaultMaxAttempts, - ReqTimeoutInMs: DefaultReqTimeout, - } -} - -// Initializing DN custom prefixes. -func InitBechPrefixes(config *sdk.Config) { - config.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub) - config.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub) - config.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub) -} - -// Write VM config file in configuration directory. -func WriteVMConfig(rootDir string, vmConfig *VMConfig) { - configFilePath := filepath.Join(rootDir, ConfigDir, VMConfigFile) - - var buffer bytes.Buffer - - if err := configTemplate.Execute(&buffer, vmConfig); err != nil { - panic(err) - } - - tmOs.MustWriteFile(configFilePath, buffer.Bytes(), 0644) -} - -// Read VM config file from configuration directory. -func ReadVMConfig(rootDir string) (*VMConfig, error) { - configFilePath := filepath.Join(rootDir, ConfigDir, VMConfigFile) - - if _, err := os.Stat(configFilePath); os.IsNotExist(err) { - config := DefaultVMConfig() - WriteVMConfig(rootDir, config) - return config, nil - } - - viper.SetConfigFile(configFilePath) - - if err := viper.ReadInConfig(); err != nil { - panic(err) - } - - // read config - config := DefaultVMConfig() - if err := viper.Unmarshal(config); err != nil { - panic(err) - } - - return config, nil -} - -func init() { - minDepositAmount, ok := sdk.NewIntFromString(DefaultGovMinDepositAmount) - if !ok { - panic("governance genesisState: minDeposit convertation failed") - } - - GovMinDeposit = sdk.NewCoin(StakingDenom, minDepositAmount) -} diff --git a/cmd/config/gen_init.go b/cmd/config/gen_init.go deleted file mode 100644 index 29d5854e..00000000 --- a/cmd/config/gen_init.go +++ /dev/null @@ -1,211 +0,0 @@ -package config - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/x/crisis" - "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/cosmos/cosmos-sdk/x/gov" - "github.com/cosmos/cosmos-sdk/x/mint" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/viper" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/libs/cli" - tmos "github.com/tendermint/tendermint/libs/os" - tmrand "github.com/tendermint/tendermint/libs/rand" - tmTypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/genutil" -) - -const ( - flagOverwrite = "overwrite" - maxGas = 10000000 -) - -type printInfo struct { - Moniker string `json:"moniker" yaml:"moniker"` - ChainID string `json:"chain_id" yaml:"chain_id"` - NodeID string `json:"node_id" yaml:"node_id"` - GenTxsDir string `json:"gentxs_dir" yaml:"gentxs_dir"` - AppMessage json.RawMessage `json:"app_message" yaml:"app_message"` -} - -func newPrintInfo(moniker, chainID, nodeID, genTxsDir string, - appMessage json.RawMessage) printInfo { - - return printInfo{ - Moniker: moniker, - ChainID: chainID, - NodeID: nodeID, - GenTxsDir: genTxsDir, - AppMessage: appMessage, - } -} - -func displayInfo(cdc *codec.Codec, info printInfo) error { - out, err := codec.MarshalJSONIndent(cdc, info) - if err != nil { - return err - } - - _, err = fmt.Fprintf(os.Stderr, "%s\n", string(sdk.MustSortJSON(out))) - return err -} - -// InitCmd returns a command that initializes all files needed for Tendermint -// and the respective application. -func InitCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, - defaultNodeHome string) *cobra.Command { // nolint: golint - cmd := &cobra.Command{ - Use: "init [moniker]", - Short: "Initialize private validator, p2p, genesis, and application configuration files", - Long: `Initialize validators's and node's configuration files.`, - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, args []string) error { - config := ctx.Config - config.SetRoot(viper.GetString(cli.HomeFlag)) - - chainID := viper.GetString(flags.FlagChainID) - if chainID == "" { - chainID = fmt.Sprintf("test-chain-%v", tmrand.Str(6)) - } - - nodeID, _, err := genutil.InitializeNodeValidatorFiles(config) - if err != nil { - return err - } - - config.Moniker = args[0] - - genFile := config.GenesisFile() - if !viper.GetBool(flagOverwrite) && tmos.FileExists(genFile) { - return fmt.Errorf("genesis.json file already exists: %v", genFile) - } - - appGenState := mbm.DefaultGenesis() - - // Change default staking params: denom, minSelfDelegation - minSelfDelegation, ok := sdk.NewIntFromString(DefMinSelfDelegation) - if !ok { - return fmt.Errorf("staking genState: default minSelfDelegation convertion failed: %s", DefMinSelfDelegation) - } - - stakingDataBz := appGenState[staking.ModuleName] - var stakingGenState staking.GenesisState - - cdc.MustUnmarshalJSON(stakingDataBz, &stakingGenState) - stakingGenState.Params.BondDenom = StakingDenom - stakingGenState.Params.LPDenom = LiquidityProviderDenom - stakingGenState.Params.MinSelfDelegationLvl = minSelfDelegation - appGenState[staking.ModuleName] = cdc.MustMarshalJSON(stakingGenState) - - // Change default mint params - mintDataBz := appGenState[mint.ModuleName] - var mintGenState mint.GenesisState - - cdc.MustUnmarshalJSON(mintDataBz, &mintGenState) - mintGenState.Params.MintDenom = StakingDenom - // - mintGenState.Params.InflationMax = sdk.NewDecWithPrec(50, 2) // 50% - mintGenState.Params.InflationMin = sdk.NewDecWithPrec(1776, 4) // 17.76% - // - mintGenState.Params.FeeBurningRatio = sdk.NewDecWithPrec(50, 2) // 50% - mintGenState.Params.InfPwrBondedLockedRatio = sdk.NewDecWithPrec(4, 1) // 40% - mintGenState.Params.FoundationAllocationRatio = sdk.NewDecWithPrec(45, 2) // 45% - // - mintGenState.Params.AvgBlockTimeWindow = 100 // 100 blocks - appGenState[mint.ModuleName] = cdc.MustMarshalJSON(mintGenState) - - // Change default distribution params - distDataBz := appGenState[distribution.ModuleName] - var distGenState distribution.GenesisState - - cdc.MustUnmarshalJSON(distDataBz, &distGenState) - distGenState.Params.ValidatorsPoolTax = sdk.NewDecWithPrec(4825, 4) // 48.25% - distGenState.Params.LiquidityProvidersPoolTax = sdk.NewDecWithPrec(4825, 4) // 48.25% - distGenState.Params.PublicTreasuryPoolTax = sdk.NewDecWithPrec(15, 3) // 1.5% - distGenState.Params.HARPTax = sdk.NewDecWithPrec(2, 2) // 2% - // - distGenState.Params.PublicTreasuryPoolCapacity = sdk.NewInt(250000) // 250K (doesn't include currency decimals) - // - distGenState.Params.BaseProposerReward = sdk.NewDecWithPrec(1, 2) // 1% - distGenState.Params.BonusProposerReward = sdk.NewDecWithPrec(4, 2) // 4% - // - distGenState.Params.WithdrawAddrEnabled = true - appGenState[distribution.ModuleName] = cdc.MustMarshalJSON(distGenState) - - // Change default minimal governance deposit coin - govDataBz := appGenState[gov.ModuleName] - var govGenState gov.GenesisState - - cdc.MustUnmarshalJSON(govDataBz, &govGenState) - govGenState.DepositParams.MinDeposit = sdk.NewCoins(GovMinDeposit) - appGenState[gov.ModuleName] = cdc.MustMarshalJSON(govGenState) - - // Change default crisis constant fee - crisisDataBz := appGenState[crisis.ModuleName] - var crisisGenState crisis.GenesisState - - cdc.MustUnmarshalJSON(crisisDataBz, &crisisGenState) - defFeeAmount, _ := sdk.NewIntFromString(DefaultFeeAmount) - crisisGenState.ConstantFee.Denom = MainDenom - crisisGenState.ConstantFee.Amount = defFeeAmount - appGenState[crisis.ModuleName] = cdc.MustMarshalJSON(crisisGenState) - - // Prepare genesis state - appState, err := codec.MarshalJSONIndent(cdc, appGenState) - if err != nil { - return errors.Wrap(err, "Failed to marshall default genesis state") - } - - genDoc := &tmTypes.GenesisDoc{} - if _, err := os.Stat(genFile); err != nil { - if !os.IsNotExist(err) { - return err - } - } else { - genDoc, err = tmTypes.GenesisDocFromFile(genFile) - if err != nil { - return errors.Wrap(err, "Failed to read genesis doc from file") - } - } - - genDoc.ChainID = chainID - genDoc.Validators = nil - genDoc.AppState = appState - - // Setup max gas - if genDoc.ConsensusParams == nil { - genDoc.ConsensusParams = tmTypes.DefaultConsensusParams() - } - - genDoc.ConsensusParams.Block.MaxGas = maxGas - - if err = genutil.ExportGenesisFile(genDoc, genFile); err != nil { - return errors.Wrap(err, "Failed to export gensis file") - } - - toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState) - - cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) - return displayInfo(cdc, toPrint) - }, - } - - cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory") - cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") - cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") - - return cmd -} diff --git a/cmd/config/genesis/cmd_init.go b/cmd/config/genesis/cmd_init.go new file mode 100644 index 00000000..52f2bb98 --- /dev/null +++ b/cmd/config/genesis/cmd_init.go @@ -0,0 +1,140 @@ +package genesis + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/cli" + tmos "github.com/tendermint/tendermint/libs/os" + tmrand "github.com/tendermint/tendermint/libs/rand" + tmTypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/genutil" + + "github.com/dfinance/dnode/cmd/config/genesis/defaults" +) + +const ( + flagOverwrite = "overwrite" +) + +type printInfo struct { + Moniker string `json:"moniker" yaml:"moniker"` + ChainID string `json:"chain_id" yaml:"chain_id"` + NodeID string `json:"node_id" yaml:"node_id"` + GenTxsDir string `json:"gentxs_dir" yaml:"gentxs_dir"` + AppMessage json.RawMessage `json:"app_message" yaml:"app_message"` +} + +func newPrintInfo(moniker, chainID, nodeID, genTxsDir string, appMessage json.RawMessage) printInfo { + return printInfo{ + Moniker: moniker, + ChainID: chainID, + NodeID: nodeID, + GenTxsDir: genTxsDir, + AppMessage: appMessage, + } +} + +func displayInfo(cdc *codec.Codec, info printInfo) error { + out, err := codec.MarshalJSONIndent(cdc, info) + if err != nil { + return err + } + + _, err = fmt.Fprintf(os.Stderr, "%s\n", string(sdk.MustSortJSON(out))) + return err +} + +// InitCmd returns a command that initializes all files needed for Tendermint +// and the respective application. +func InitCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, + defaultNodeHome string) *cobra.Command { // nolint: golint + cmd := &cobra.Command{ + Use: "init [moniker]", + Short: "Initialize private validator, p2p, genesis, and application configuration files", + Long: `Initialize validators's and node's configuration files.`, + Args: cobra.ExactArgs(1), + RunE: func(_ *cobra.Command, args []string) error { + config := ctx.Config + config.SetRoot(viper.GetString(cli.HomeFlag)) + + chainID := viper.GetString(flags.FlagChainID) + if chainID == "" { + chainID = fmt.Sprintf("test-chain-%v", tmrand.Str(6)) + } + + nodeID, _, err := genutil.InitializeNodeValidatorFiles(config) + if err != nil { + return err + } + + config.Moniker = args[0] + + // Prepare genesis state + appGenState, err := OverrideGenesisStateDefaults(cdc, mbm.DefaultGenesis()) + if err != nil { + return fmt.Errorf("app genesis state overwrite: %v", err) + } + + appState, err := codec.MarshalJSONIndent(cdc, appGenState) + if err != nil { + return errors.Wrap(err, "failed to marshall app genesis state") + } + + // Prepare genesis file + genFile := config.GenesisFile() + if !viper.GetBool(flagOverwrite) && tmos.FileExists(genFile) { + return fmt.Errorf("genesis.json file already exists: %v", genFile) + } + + genDoc := &tmTypes.GenesisDoc{} + if _, err := os.Stat(genFile); err != nil { + if !os.IsNotExist(err) { + return err + } + } else { + genDoc, err = tmTypes.GenesisDocFromFile(genFile) + if err != nil { + return errors.Wrap(err, "failed to read genesis doc from file") + } + } + + genDoc.ChainID = chainID + genDoc.Validators = nil + genDoc.AppState = appState + + // Setup max gas + if genDoc.ConsensusParams == nil { + genDoc.ConsensusParams = tmTypes.DefaultConsensusParams() + } + genDoc.ConsensusParams.Block.MaxGas = defaults.MaxGas + + if err = genutil.ExportGenesisFile(genDoc, genFile); err != nil { + return errors.Wrap(err, "Failed to export gensis file") + } + + toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState) + + cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) + return displayInfo(cdc, toPrint) + }, + } + + cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory") + cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") + cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") + + return cmd +} diff --git a/cmd/config/genesis/defaults/common_defaults.go b/cmd/config/genesis/defaults/common_defaults.go new file mode 100644 index 00000000..1a86cf13 --- /dev/null +++ b/cmd/config/genesis/defaults/common_defaults.go @@ -0,0 +1,53 @@ +// Commonly used default values. +// Moved to a separate pkg to prevent circular dependency. +package defaults + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + MainDenom = "xfi" + StakingDenom = "sxfi" + LiquidityProviderDenom = "lpt" + + FeeAmount = "100000000000000" // 0.0001 + GovMinDepositAmount = "1000000000000000000000" // 1000.0 + MinSelfDelegationAmount = "2500000000000000000000" // 2500.0 + InvariantCheckAmount = "1000000000000000000000" // 1000.0 + + MaxGas = 10000000 +) + +var ( + FeeCoin sdk.Coin + GovMinDepositCoin sdk.Coin + MinSelfDelegationCoin sdk.Coin + InvariantCheckCoin sdk.Coin +) + +func init() { + if value, ok := sdk.NewIntFromString(FeeAmount); !ok { + panic("defaults: FeeAmount conversion failed") + } else { + FeeCoin = sdk.NewCoin(MainDenom, value) + } + + if value, ok := sdk.NewIntFromString(GovMinDepositAmount); !ok { + panic("governance defaults: GovMinDepositAmount conversion failed") + } else { + GovMinDepositCoin = sdk.NewCoin(StakingDenom, value) + } + + if value, ok := sdk.NewIntFromString(MinSelfDelegationAmount); !ok { + panic("staking defaults: MinSelfDelegationAmount conversion failed") + } else { + MinSelfDelegationCoin = sdk.NewCoin(StakingDenom, value) + } + + if value, ok := sdk.NewIntFromString(InvariantCheckAmount); !ok { + panic("crisis defaults: InvariantCheckAmount conversion failed") + } else { + InvariantCheckCoin = sdk.NewCoin(MainDenom, value) + } +} diff --git a/cmd/config/genesis/genesis.go b/cmd/config/genesis/genesis.go new file mode 100644 index 00000000..6d6e214d --- /dev/null +++ b/cmd/config/genesis/genesis.go @@ -0,0 +1,279 @@ +package genesis + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/crisis" + "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/evidence" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/mint" + "github.com/cosmos/cosmos-sdk/x/slashing" + "github.com/cosmos/cosmos-sdk/x/staking" + + "github.com/dfinance/dnode/cmd/config/genesis/defaults" + "github.com/dfinance/dnode/x/multisig" + "github.com/dfinance/dnode/x/oracle" + "github.com/dfinance/dnode/x/poa" +) + +const ( + AvgYearDur = time.Duration(60*60*8766) * time.Second // 365.25 days + DayDur = 24 * time.Hour +) + +// OverrideGenesisStateDefaults takes default app genesis state and overwrites Cosmos SDK / Dfinance params. +func OverrideGenesisStateDefaults(cdc *codec.Codec, genState map[string]json.RawMessage) (map[string]json.RawMessage, error) { + // Mint module params + { + moduleName, moduleState := mint.ModuleName, mint.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.MintDenom = defaults.StakingDenom + // + moduleState.Params.InflationMax = sdk.NewDecWithPrec(50, 2) // 50% + moduleState.Params.InflationMin = sdk.NewDecWithPrec(1776, 4) // 17.76% + // + moduleState.Params.FeeBurningRatio = sdk.NewDecWithPrec(50, 2) // 50% + moduleState.Params.InfPwrBondedLockedRatio = sdk.NewDecWithPrec(4, 1) // 40% + moduleState.Params.FoundationAllocationRatio = sdk.NewDecWithPrec(15, 2) // 15% + // + moduleState.Params.AvgBlockTimeWindow = 100 // 100 blocks + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Distribution module params + { + moduleName, moduleState := distribution.ModuleName, distribution.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.ValidatorsPoolTax = sdk.NewDecWithPrec(4825, 4) // 48.25% + moduleState.Params.LiquidityProvidersPoolTax = sdk.NewDecWithPrec(4825, 4) // 48.25% + moduleState.Params.PublicTreasuryPoolTax = sdk.NewDecWithPrec(15, 3) // 1.5% + moduleState.Params.HARPTax = sdk.NewDecWithPrec(2, 2) // 2% + // + moduleState.Params.PublicTreasuryPoolCapacity = sdk.NewInt(250000) // 250000.0 + // + moduleState.Params.BaseProposerReward = sdk.NewDecWithPrec(1, 2) // 1% + moduleState.Params.BonusProposerReward = sdk.NewDecWithPrec(4, 2) // 4% + // + moduleState.Params.LockedRatio = sdk.NewDecWithPrec(5, 1) // 50% + moduleState.Params.LockedDuration = AvgYearDur // 1 year + // + moduleState.Params.WithdrawAddrEnabled = true + moduleState.Params.FoundationNominees = []sdk.AccAddress{} + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Staking module params + { + moduleName, moduleState := staking.ModuleName, staking.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.UnbondingTime = 7 * DayDur + moduleState.Params.ScheduledUnbondDelayTime = 3 * DayDur + // + moduleState.Params.MaxValidators = 31 + moduleState.Params.MaxEntries = 7 + moduleState.Params.HistoricalEntries = 0 + // + moduleState.Params.BondDenom = defaults.StakingDenom + moduleState.Params.LPDenom = defaults.LiquidityProviderDenom + // + moduleState.Params.MinSelfDelegationLvl = defaults.MinSelfDelegationCoin.Amount // 2500.0 + moduleState.Params.MaxDelegationsRatio = sdk.NewDecWithPrec(10, 0) // 10.0 + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Slashing module params + { + moduleName, moduleState := slashing.ModuleName, slashing.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.SignedBlocksWindow = 100 + moduleState.Params.MinSignedPerWindow = sdk.NewDecWithPrec(5, 1) + // + moduleState.Params.DowntimeJailDuration = 10 * time.Minute + // + moduleState.Params.SlashFractionDoubleSign = sdk.NewDec(1).Quo(sdk.NewDec(20)) // 1.0 / 20.0 + moduleState.Params.SlashFractionDowntime = sdk.NewDec(1).Quo(sdk.NewDec(100)) // 1.0 / 100.0 + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Evidence module params + { + moduleName, moduleState := evidence.ModuleName, evidence.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.MaxEvidenceAge = 2 * time.Minute + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Crisis module params + { + moduleName, moduleState := crisis.ModuleName, crisis.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.ConstantFee.Denom = defaults.InvariantCheckCoin.Denom // xfi + moduleState.ConstantFee.Amount = defaults.InvariantCheckCoin.Amount // 1000.0 + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Gov module params + { + moduleName, moduleState := gov.ModuleName, gov.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.VotingParams.VotingPeriod = 6 * time.Hour + // + moduleState.TallyParams.Quorum = sdk.NewDecWithPrec(334, 3) // 33.4% + moduleState.TallyParams.Threshold = sdk.NewDecWithPrec(5, 1) // 50% + moduleState.TallyParams.Veto = sdk.NewDecWithPrec(334, 3) // 33.4% + // + moduleState.DepositParams.MinDeposit = sdk.NewCoins(defaults.GovMinDepositCoin) // 1000.0sxfi + moduleState.DepositParams.MaxDepositPeriod = 3 * time.Hour + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Auth module params + { + moduleName, moduleState := auth.ModuleName, auth.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.MaxMemoCharacters = 256 + moduleState.Params.TxSigLimit = 7 + moduleState.Params.TxSizeCostPerByte = 10 + moduleState.Params.SigVerifyCostED25519 = 590 + moduleState.Params.SigVerifyCostSecp256k1 = 1000 + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Bank module genesis + { + moduleName, moduleState := bank.ModuleName, bank.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.SendEnabled = true + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // PoA module params + { + moduleName, moduleState := poa.ModuleName, poa.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Parameters.MaxValidators = 11 + moduleState.Parameters.MinValidators = 1 + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // MultiSig module params + { + moduleName, moduleState := multisig.ModuleName, multisig.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Parameters.IntervalToExecute = 86400 // 6 days approx. + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + // Oracle module params + { + moduleName, moduleState := oracle.ModuleName, oracle.GenesisState{} + if err := cdc.UnmarshalJSON(genState[moduleName], &moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON unmarshal: %v", moduleName, err) + } + + moduleState.Params.PostPrice.ReceivedAtDiffInS = 360 // 1 hour + + if moduleStateBz, err := cdc.MarshalJSON(moduleState); err != nil { + return nil, fmt.Errorf("%s module: JSON marshal: %v", moduleName, err) + } else { + genState[moduleName] = moduleStateBz + } + } + + return genState, nil +} diff --git a/cmd/config/restrictions/restrictions.go b/cmd/config/restrictions/restrictions.go index 76e10e06..b8678efa 100644 --- a/cmd/config/restrictions/restrictions.go +++ b/cmd/config/restrictions/restrictions.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/currencies" ) @@ -58,19 +58,20 @@ func GetAppRestrictions() AppRestrictions { params.RestrictedParam{Subspace: distribution.ModuleName, Key: string(distribution.ParamKeyHARPTax)}, params.RestrictedParam{Subspace: distribution.ModuleName, Key: string(distribution.ParamKeyFoundationNominees)}, params.RestrictedParam{Subspace: mint.ModuleName, Key: string(mint.KeyFoundationAllocationRatio)}, + params.RestrictedParam{Subspace: mint.ModuleName, Key: string(mint.KeyStakingTotalSupplyShift)}, }, CustomMsgVerifiers: func(msg sdk.Msg) error { switch msg := msg.(type) { case bank.MsgSend: for i := range msg.Amount { - if msg.Amount.GetDenomByIndex(i) == config.StakingDenom || msg.Amount.GetDenomByIndex(i) == config.LiquidityProviderDenom { + if msg.Amount.GetDenomByIndex(i) == defaults.StakingDenom || msg.Amount.GetDenomByIndex(i) == defaults.LiquidityProviderDenom { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "bank transactions are disallowed for %s token", msg.Amount.GetDenomByIndex(i)) } } case gov.MsgDeposit: for i := range msg.Amount { - if msg.Amount.GetDenomByIndex(i) != config.StakingDenom { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "gov deposit only allowed for %s token", config.StakingDenom) + if msg.Amount.GetDenomByIndex(i) != defaults.StakingDenom { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "gov deposit only allowed for %s token", defaults.StakingDenom) } } } diff --git a/cmd/config/vm_config.go b/cmd/config/vm_config.go new file mode 100644 index 00000000..246d6942 --- /dev/null +++ b/cmd/config/vm_config.go @@ -0,0 +1,85 @@ +package config + +import ( + "bytes" + "os" + "path/filepath" + + "github.com/spf13/viper" + tmOs "github.com/tendermint/tendermint/libs/os" +) + +const ( + VMConfigFile = "vm.toml" // Default file to store config. + ConfigDir = "config" // Default directory to store all configurations. + + // VM configs. + DefaultVMAddress = "tcp://127.0.0.1:50051" // Default virtual machine address to connect from Cosmos SDK. + DefaultDataListen = "tcp://127.0.0.1:50052" // Default data server address to listen for connections from VM. + DefaultCompilerAddr = DefaultVMAddress + + // Default retry configs. + DefaultMaxAttempts = 0 // Default maximum attempts for retry. + DefaultReqTimeout = 0 // Default request timeout per attempt [ms]. + + // Invariants check period for crisis module (in blocks) + DefInvCheckPeriod = 10 +) + +// Virtual machine connection config (see config/vm.toml). +type VMConfig struct { + Address string `mapstructure:"vm_address"` // address of virtual machine. + DataListen string `mapstructure:"vm_data_listen"` // data listen. + + // Retry policy + MaxAttempts uint `mapstructure:"vm_retry_max_attempts"` // maximum attempts for retry (0 - infinity) + ReqTimeoutInMs uint `mapstructure:"vm_retry_req_timeout_ms"` // request timeout per attempt (0 - infinity) [ms] +} + +// Default VM configuration. +func DefaultVMConfig() *VMConfig { + return &VMConfig{ + Address: DefaultVMAddress, + DataListen: DefaultDataListen, + MaxAttempts: DefaultMaxAttempts, + ReqTimeoutInMs: DefaultReqTimeout, + } +} + +// Write VM config file in configuration directory. +func WriteVMConfig(rootDir string, vmConfig *VMConfig) { + configFilePath := filepath.Join(rootDir, ConfigDir, VMConfigFile) + + var buffer bytes.Buffer + + if err := configTemplate.Execute(&buffer, vmConfig); err != nil { + panic(err) + } + + tmOs.MustWriteFile(configFilePath, buffer.Bytes(), 0644) +} + +// Read VM config file from configuration directory. +func ReadVMConfig(rootDir string) (*VMConfig, error) { + configFilePath := filepath.Join(rootDir, ConfigDir, VMConfigFile) + + if _, err := os.Stat(configFilePath); os.IsNotExist(err) { + config := DefaultVMConfig() + WriteVMConfig(rootDir, config) + return config, nil + } + + viper.SetConfigFile(configFilePath) + + if err := viper.ReadInConfig(); err != nil { + panic(err) + } + + // read config + config := DefaultVMConfig() + if err := viper.Unmarshal(config); err != nil { + panic(err) + } + + return config, nil +} diff --git a/cmd/dncli/main.go b/cmd/dncli/main.go index 417393b1..3bf751f6 100644 --- a/cmd/dncli/main.go +++ b/cmd/dncli/main.go @@ -23,6 +23,7 @@ import ( "github.com/dfinance/dnode/app" dnConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/cmd/config/restrictions" "github.com/dfinance/dnode/helpers/logger" "github.com/dfinance/dnode/helpers/swagger" @@ -121,11 +122,11 @@ func queryCmd(cdc *amino.Codec) *cobra.Command { // Set default gas for tx commands. func SetDefaultFeeForTxCmd(cmd *cobra.Command) { if feesFlag := cmd.Flag(flags.FlagFees); feesFlag != nil { - feesFlag.DefValue = dnConfig.DefaultFee - feesFlag.Usage = "Fees to pay along with transaction; eg: " + dnConfig.DefaultFee + feesFlag.DefValue = defaults.FeeCoin.String() + feesFlag.Usage = "Fees to pay along with transaction; eg: " + defaults.FeeCoin.String() if feesFlag.Value.String() == "" { - err := feesFlag.Value.Set(dnConfig.DefaultFee) + err := feesFlag.Value.Set(defaults.FeeCoin.String()) if err != nil { panic(err) } @@ -137,8 +138,8 @@ func SetDefaultFeeForTxCmd(cmd *cobra.Command) { return fmt.Errorf("can't parse fees value to coins: %v", err) } - if coin.Denom != dnConfig.MainDenom { - return fmt.Errorf("fees must be paid only in %q, current fees in are %q", dnConfig.MainDenom, coin.Denom) + if coin.Denom != defaults.MainDenom { + return fmt.Errorf("fees must be paid only in %q, current fees in are %q", defaults.MainDenom, coin.Denom) } return nil diff --git a/cmd/dnode/main.go b/cmd/dnode/main.go index caffeb1b..876e288e 100644 --- a/cmd/dnode/main.go +++ b/cmd/dnode/main.go @@ -22,6 +22,7 @@ import ( "github.com/dfinance/dnode/app" dnConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis" "github.com/dfinance/dnode/cmd/config/restrictions" "github.com/dfinance/dnode/helpers/logger" ccsCli "github.com/dfinance/dnode/x/ccstorage/client/cli" @@ -76,7 +77,6 @@ func main() { oracleCli.AddAssetGenCmd(ctx, cdc, app.DefaultNodeHome, app.DefaultCLIHome), marketsCli.AddMarketGenCmd(ctx, cdc, app.DefaultNodeHome), migrationCli.MigrateGenesisCmd(ctx, cdc), - testnetCmd(ctx, cdc, app.ModuleBasics, genaccounts.AppModuleBasic{}), ) server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators) @@ -132,7 +132,7 @@ func exportAppStateAndTMValidators( // Init cmd together with VM configruation. // nolint func InitCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, defaultNodeHome string) *cobra.Command { // nolint: golint - cmd := dnConfig.InitCmd(ctx, cdc, mbm, defaultNodeHome) + cmd := genesis.InitCmd(ctx, cdc, mbm, defaultNodeHome) cmd.PersistentPostRun = func(cmd *cobra.Command, args []string) { dnConfig.ReadVMConfig(viper.GetString(cli.HomeFlag)) diff --git a/cmd/dnode/testnet.go b/cmd/dnode/testnet.go deleted file mode 100644 index 0b659e6a..00000000 --- a/cmd/dnode/testnet.go +++ /dev/null @@ -1,410 +0,0 @@ -package main - -import ( - "bufio" - "encoding/json" - "fmt" - "net" - "os" - "path" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/server" - sdkSrvConfig "github.com/cosmos/cosmos-sdk/server/config" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutilTypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/spf13/cobra" - "github.com/spf13/viper" - tmConfig "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto" - tmOs "github.com/tendermint/tendermint/libs/os" - tmRand "github.com/tendermint/tendermint/libs/rand" - tmTypes "github.com/tendermint/tendermint/types" - tmTime "github.com/tendermint/tendermint/types/time" - - dnConfig "github.com/dfinance/dnode/cmd/config" - "github.com/dfinance/dnode/x/genaccounts" - "github.com/dfinance/dnode/x/oracle" -) - -// DONTCOVER - -var ( - flagNodeDirPrefix = "node-dir-prefix" - flagNumValidators = "v" - flagOutputDir = "output-dir" - flagNodeDaemonHome = "node-daemon-home" - flagNodeCLIHome = "node-cli-home" - flagStartingIPAddress = "starting-ip-address" - flagComissionRate = "comission-rate" - flagComissionMaxRate = "comission-max-rate" - flagComissionMaxChangeRate = "comission-max-change-rate" -) - -type cliFlags struct { - outputDir string - chainID string - minGasPrices string - nodeDirPrefix string - nodeDaemonHome string - nodeCLIHome string - startingIPAddress string - numValidators int - comissionRate sdk.Dec - comissionMaxRate sdk.Dec - comissionMaxChangeRate sdk.Dec -} - -// get cmd to initialize all files for tendermint testnet and application -func testnetCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, genAccIterator genutilTypes.GenesisAccountsIterator) *cobra.Command { - cmd := &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a Dnode testnet", - Long: `testnet will create "v" number of directories and populate each with -necessary files (private validator, genesis, config, etc.). - -Note, strict routability for addresses is turned off in the config file. - -Example: - dnode testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 - `, - RunE: func(cmd *cobra.Command, _ []string) error { - config := ctx.Config - - cf := cliFlags{ - outputDir: viper.GetString(flagOutputDir), - chainID: viper.GetString(flags.FlagChainID), - minGasPrices: viper.GetString(server.FlagMinGasPrices), - nodeDirPrefix: viper.GetString(flagNodeDirPrefix), - nodeDaemonHome: viper.GetString(flagNodeDaemonHome), - nodeCLIHome: viper.GetString(flagNodeCLIHome), - startingIPAddress: viper.GetString(flagStartingIPAddress), - numValidators: viper.GetInt(flagNumValidators), - } - var err error - cf.comissionRate, err = sdk.NewDecFromStr(viper.GetString(flagComissionRate)) - if err != nil { - return err - } - cf.comissionMaxRate, err = sdk.NewDecFromStr(viper.GetString(flagComissionMaxRate)) - if err != nil { - return err - } - cf.comissionMaxChangeRate, err = sdk.NewDecFromStr(viper.GetString(flagComissionMaxChangeRate)) - if err != nil { - return err - } - - return InitTestnet(cmd, config, cdc, mbm, genAccIterator, &cf) - }, - } - - cmd.Flags().Int(flagNumValidators, 4, - "Number of validators to initialize the testnet with") - cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", - "Directory to store initialization data for the testnet") - cmd.Flags().String(flagNodeDirPrefix, "node", - "Prefix the directory name for each node with (node results in node0, node1, ...)") - cmd.Flags().String(flagNodeDaemonHome, "dnode", - "Home directory of the node's daemon configuration") - cmd.Flags().String(flagNodeCLIHome, "dncli", - "Home directory of the node's cli configuration") - cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", - "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") - cmd.Flags().String(flags.FlagChainID, "", - "genesis file chain-id, if left blank will be randomly created") - cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("1%s", dnConfig.MainDenom), - "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") - cmd.Flags().String(flagComissionRate, "0.100000000000000000", - "Comission rate") - cmd.Flags().String(flagComissionMaxRate, "0.200000000000000000", - "Comission rate") - cmd.Flags().String(flagComissionMaxChangeRate, "0.010000000000000000", - "Comission max change rate") - //cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, - // "Select keyring's backend (os|file|test)") - - return cmd -} - -const nodeDirPerm = 0755 - -// Initialize the testnet -func InitTestnet(cmd *cobra.Command, config *tmConfig.Config, cdc *codec.Codec, mbm module.BasicManager, genAccIterator genutilTypes.GenesisAccountsIterator, cf *cliFlags) error { - if cf.chainID == "" { - cf.chainID = "chain-" + tmRand.Str(6) - } - - monikers := make([]string, cf.numValidators) - nodeIDs := make([]string, cf.numValidators) - valPubKeys := make([]crypto.PubKey, cf.numValidators) - - dnCfg := sdkSrvConfig.DefaultConfig() - dnCfg.MinGasPrices = cf.minGasPrices - - // nolint:prealloc - var ( - genAccounts genaccounts.GenesisAccounts - genFiles []string - ) - - // generate private keys, node IDs, and initial transactions - for i := 0; i < cf.numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", cf.nodeDirPrefix, i) - nodeDir := path.Join(cf.outputDir, nodeDirName, cf.nodeDaemonHome) - clientDir := path.Join(cf.outputDir, nodeDirName, cf.nodeCLIHome) - gentxsDir := path.Join(cf.outputDir, "gentxs") - - config.SetRoot(nodeDir) - config.RPC.ListenAddress = "tcp://0.0.0.0:26657" - - if err := os.MkdirAll(path.Join(nodeDir, "config"), nodeDirPerm); err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - if err := os.MkdirAll(clientDir, nodeDirPerm); err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - monikers = append(monikers, nodeDirName) - config.Moniker = nodeDirName - - ip, err := getIP(i, cf.startingIPAddress) - if err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(config) - if err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) - genFiles = append(genFiles, config.GenesisFile()) - - kb, err := keys.NewKeyBaseFromDir(clientDir) - if err != nil { - return err - } - - keyPass := keys.DefaultKeyPass - addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, keyPass, true) - if err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - info := map[string]string{"secret": secret} - - cliPrint, err := json.Marshal(info) - if err != nil { - return err - } - - // save private key seed words - if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint); err != nil { - return err - } - - accStakingTokens := sdk.TokensFromConsensusPower(500000000000) - coins := sdk.Coins{ - sdk.NewCoin(dnConfig.MainDenom, accStakingTokens), - } - - genAccounts = append(genAccounts, genaccounts.NewGenesisAccountRaw(addr, coins.Sort(), "")) - - valTokens := sdk.TokensFromConsensusPower(500000) - msg := staking.NewMsgCreateValidator( - sdk.ValAddress(addr), - valPubKeys[i], - sdk.NewCoin(dnConfig.MainDenom, valTokens), - staking.NewDescription(nodeDirName, "", "", "", ""), - staking.NewCommissionRates(cf.comissionRate, cf.comissionMaxRate, cf.comissionMaxChangeRate), - sdk.OneInt(), - ) - - inBuf := bufio.NewReader(cmd.InOrStdin()) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithChainID(cf.chainID).WithMemo(memo).WithKeybase(kb) - tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{Gas: 200000}, []auth.StdSignature{}, memo) - - signedTx, err := txBldr.SignStdTx(nodeDirName, keys.DefaultKeyPass, tx, false) - if err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - txBytes, err := cdc.MarshalJSON(signedTx) - if err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - // gather gentxs folder - if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes); err != nil { - _ = os.RemoveAll(cf.outputDir) - return err - } - - // TODO: Rename config file to server.toml as it's not particular to Dn - // (REF: https://github.com/cosmos/cosmos-sdk/issues/4125). - dnConfigpath := path.Join(nodeDir, "config/app.toml") - sdkSrvConfig.WriteConfigFile(dnConfigpath, dnCfg) - } - - if err := initGenFiles(cdc, mbm, cf.chainID, genAccounts, genFiles, cf.numValidators); err != nil { - return err - } - - err := collectGenFiles( - cdc, config, cf.chainID, monikers, nodeIDs, valPubKeys, cf.numValidators, - cf.outputDir, cf.nodeDirPrefix, cf.nodeDaemonHome, genAccIterator, - ) - if err != nil { - return err - } - - cmd.PrintErrf("Successfully initialized %d node directories\n", cf.numValidators) - return nil -} - -func initGenFiles( - cdc *codec.Codec, mbm module.BasicManager, chainID string, - genAccounts genaccounts.GenesisAccounts, genFiles []string, numValidators int, -) error { - - appGenState := mbm.DefaultGenesis() - - // set the accounts in the genesis state - appGenState[genaccounts.ModuleName] = cdc.MustMarshalJSON(genAccounts) - - stakingDataBz := appGenState[staking.ModuleName] - var stakingGenState staking.GenesisState - cdc.MustUnmarshalJSON(stakingDataBz, &stakingGenState) - stakingGenState.Params.BondDenom = dnConfig.MainDenom - appGenState[staking.ModuleName] = cdc.MustMarshalJSON(stakingGenState) - - oracleDataBz := appGenState[oracle.ModuleName] - var oracleGenState oracle.GenesisState - cdc.MustUnmarshalJSON(oracleDataBz, &oracleGenState) - nominees := make([]string, len(genAccounts)) - for i, ga := range genAccounts { - nominees[i] = ga.BaseAccount.Address.String() - } - oracleGenState.Params.Nominees = nominees - appGenState[oracle.ModuleName] = cdc.MustMarshalJSON(oracleGenState) - - appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState) - if err != nil { - return err - } - - genDoc := tmTypes.GenesisDoc{ - ChainID: chainID, - AppState: appGenStateJSON, - Validators: nil, - } - - // generate empty genesis files for each validator and save - for i := 0; i < numValidators; i++ { - if err := genDoc.SaveAs(genFiles[i]); err != nil { - return err - } - } - return nil -} - -func collectGenFiles( - cdc *codec.Codec, config *tmConfig.Config, chainID string, - monikers, nodeIDs []string, valPubKeys []crypto.PubKey, - numValidators int, outputDir, nodeDirPrefix, nodeDaemonHome string, - genAccIterator genutilTypes.GenesisAccountsIterator) error { - - var appState json.RawMessage - genTime := tmTime.Now() - - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := path.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := path.Join(outputDir, "gentxs") - moniker := monikers[i] - config.Moniker = nodeDirName - - config.SetRoot(nodeDir) - - nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - initCfg := genutil.NewInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey) - - genDoc, err := tmTypes.GenesisDocFromFile(config.GenesisFile()) - if err != nil { - return err - } - - nodeAppState, err := genutil.GenAppStateFromConfig(cdc, config, initCfg, *genDoc, genAccIterator) - if err != nil { - return err - } - - if appState == nil { - // set the canonical application state (they should not differ) - appState = nodeAppState - } - - genFile := config.GenesisFile() - - // overwrite each validator's genesis file to have a canonical genesis time - if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { - return err - } - } - - return nil -} - -func getIP(i int, startingIPAddr string) (ip string, err error) { - if len(startingIPAddr) == 0 { - ip, err = server.ExternalIP() - if err != nil { - return "", err - } - return ip, nil - } - return calculateIP(startingIPAddr, i) -} - -func calculateIP(ip string, i int) (string, error) { - ipv4 := net.ParseIP(ip).To4() - if ipv4 == nil { - return "", fmt.Errorf("%v: non ipv4 address", ip) - } - - for j := 0; j < i; j++ { - ipv4[3]++ - } - - return ipv4.String(), nil -} - -func writeFile(name string, dir string, contents []byte) error { - writePath := path.Join(dir) - file := path.Join(writePath, name) - - if err := tmOs.EnsureDir(writePath, 0700); err != nil { - return err - } - - if err := tmOs.WriteFile(file, contents, 0600); err != nil { - return err - } - - return nil -} diff --git a/go.mod b/go.mod index 430c9606..55f57d85 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,11 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk +//replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk require ( github.com/99designs/keyring v1.1.3 diff --git a/go.sum b/go.sum index 39101f49..46e9fad1 100644 --- a/go.sum +++ b/go.sum @@ -152,6 +152,8 @@ github.com/dfinance/cosmos-sdk v0.38.4-0.20201002002655-db666862c14b h1:0z853VXV github.com/dfinance/cosmos-sdk v0.38.4-0.20201002002655-db666862c14b/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4 h1:sUQDCT0ddxJH14HssQkmA+TbX4PqEhHXK/py/RmaucU= github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09 h1:hNzQYh6QR6K097fL0HYDtgfyN2KgUXLu17/zRxSJezc= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= diff --git a/helpers/tests/clitester/cli_tester_configs.go b/helpers/tests/clitester/cli_tester_configs.go index 4d8ce5d3..20f9f2a2 100644 --- a/helpers/tests/clitester/cli_tester_configs.go +++ b/helpers/tests/clitester/cli_tester_configs.go @@ -14,7 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" "github.com/dfinance/glav" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/ccstorage" "github.com/dfinance/dnode/x/orders" ) @@ -131,91 +131,91 @@ func NewAccountMap() (accounts map[string]*CLIAccount, retErr error) { accounts["pos"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - DenomSXFI: sdk.NewCoin(DenomSXFI, bigAmount), - config.MainDenom: sdk.NewCoin(config.MainDenom, bigAmount), + DenomSXFI: sdk.NewCoin(DenomSXFI, bigAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, bigAmount), }, } accounts["bank"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, bigAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, bigAmount), }, } accounts["validator1"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), - DenomSXFI: sdk.NewCoin(DenomSXFI, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), + DenomSXFI: sdk.NewCoin(DenomSXFI, smallAmount), }, IsPOAValidator: true, } accounts["validator2"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsPOAValidator: true, } accounts["validator3"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsPOAValidator: true, } accounts["validator4"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsPOAValidator: true, } accounts["validator5"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsPOAValidator: true, } accounts["nominee"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsOracleNominee: true, } accounts["oracle1"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsOracle: true, } accounts["oracle2"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsOracle: false, } accounts["oracle3"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsOracle: false, } accounts["plain"] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, } accounts[orders.ModuleName] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsModuleAcc: true, } accounts[gov.ModuleName] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), }, IsModuleAcc: true, } accounts[DenomSXFI] = &CLIAccount{ Coins: map[string]sdk.Coin{ - config.MainDenom: sdk.NewCoin(config.MainDenom, smallAmount), - DenomSXFI: sdk.NewCoin(DenomSXFI, smallAmount), + defaults.MainDenom: sdk.NewCoin(defaults.MainDenom, smallAmount), + DenomSXFI: sdk.NewCoin(DenomSXFI, smallAmount), }, } diff --git a/helpers/tests/clitester/cli_tester_init.go b/helpers/tests/clitester/cli_tester_init.go index a99ed654..52f454b3 100644 --- a/helpers/tests/clitester/cli_tester_init.go +++ b/helpers/tests/clitester/cli_tester_init.go @@ -6,13 +6,12 @@ import ( "strings" sdkKeys "github.com/cosmos/cosmos-sdk/crypto/keys" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/spf13/viper" "github.com/stretchr/testify/require" - "github.com/dfinance/dnode/cmd/config" dnConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" ) func (ct *CLITester) initChain() { @@ -161,18 +160,15 @@ func (ct *CLITester) initChain() { // validator genTX { - minSelfDelegation, ok := sdk.NewIntFromString(dnConfig.DefMinSelfDelegation) - require.True(ct.t, ok, "DefMinSelfDelegation conversion failed") - - stakingCoin := ct.Accounts["pos"].Coins[config.StakingDenom] - stakingCoin.Amount = minSelfDelegation + stakingCoin := ct.Accounts["pos"].Coins[defaults.StakingDenom] + stakingCoin.Amount = defaults.MinSelfDelegationCoin.Amount cmd := ct.newWbdCmd(). AddArg("", "gentx"). AddArg("home-client", ct.Dirs.DncliDir). AddArg("name", "pos"). AddArg("amount", stakingCoin.String()). - AddArg("min-self-delegation", minSelfDelegation.String()). + AddArg("min-self-delegation", defaults.MinSelfDelegationCoin.Amount.String()). AddArg("keyring-backend", string(ct.keyringBackend)) cmd.CheckSuccessfulExecute(nil, ct.AccountPassphrase, ct.AccountPassphrase, ct.AccountPassphrase) diff --git a/helpers/tests/clitester/cli_tester_rest.go b/helpers/tests/clitester/cli_tester_rest.go index fb1929f1..d12886e5 100644 --- a/helpers/tests/clitester/cli_tester_rest.go +++ b/helpers/tests/clitester/cli_tester_rest.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/require" tmCoreTypes "github.com/tendermint/tendermint/rpc/core/types" - dnConfig "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" dnTypes "github.com/dfinance/dnode/helpers/types" "github.com/dfinance/dnode/x/ccstorage" "github.com/dfinance/dnode/x/currencies" @@ -34,17 +34,13 @@ import ( // buildBaseReq returns BaseReq used to prepare REST Tx send. func (ct *CLITester) buildBaseReq(accName, memo string) restTypes.BaseReq { - feeAmount, ok := sdk.NewIntFromString(dnConfig.DefaultFeeAmount) - require.True(ct.t, ok, "fee coin amount parsing") - feeCoin := sdk.NewCoin(dnConfig.MainDenom, feeAmount) - accInfo, ok := ct.Accounts[accName] require.True(ct.t, ok, "account %q: not found", accName) return restTypes.BaseReq{ ChainID: ct.IDs.ChainID, From: accInfo.Address, - Fees: sdk.Coins{feeCoin}, + Fees: sdk.Coins{defaults.FeeCoin}, Gas: strconv.Itoa(DefaultGas), Memo: memo, } @@ -57,7 +53,7 @@ func (ct *CLITester) newRestTxRequest(accName string, acc *auth.BaseAccount, msg func (ct *CLITester) newRestTxRequestRaw(accName string, accNumber, accSequence uint64, msg sdk.Msg, isSync bool) (r *RestRequest, txResp *sdk.TxResponse) { // build broadcast Tx request txFee := auth.StdFee{ - Amount: sdk.Coins{{Denom: dnConfig.MainDenom, Amount: sdk.NewInt(1)}}, + Amount: sdk.Coins{{Denom: defaults.MainDenom, Amount: sdk.NewInt(1)}}, Gas: DefaultGas, } txMemo := "restTxMemo" diff --git a/helpers/tests/clitester/types_tx.go b/helpers/tests/clitester/types_tx.go index bcff4a82..f31da768 100644 --- a/helpers/tests/clitester/types_tx.go +++ b/helpers/tests/clitester/types_tx.go @@ -11,7 +11,7 @@ import ( sdkErrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" ) type TxRequest struct { @@ -36,7 +36,7 @@ func (r *TxRequest) SetCmd(module, fromAddress string, args ...string) { } r.cmd.AddArg("broadcast-mode", "block") r.cmd.AddArg("node", r.nodeRpcAddress) - r.cmd.AddArg("fees", config.DefaultFee) + r.cmd.AddArg("fees", defaults.FeeCoin.String()) r.cmd.AddArg("gas", strconv.FormatUint(r.gas, 10)) r.cmd.AddArg("", "--yes") } diff --git a/helpers/tests/simulator/inflation_test.go b/helpers/tests/simulator/inflation_test.go index ccd36f13..35da2711 100644 --- a/helpers/tests/simulator/inflation_test.go +++ b/helpers/tests/simulator/inflation_test.go @@ -7,46 +7,130 @@ import ( "io/ioutil" "net/http" _ "net/http/pprof" + "os" "path" + "strings" "testing" "time" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" ) -func TestSimInflation(t *testing.T) { +type SimProfile struct { + ID string + SimDuration time.Duration + // + BlockTimeMin time.Duration + BlockTimeMax time.Duration + // + MainTokensBalanceWODec int64 + BondingTokensBalanceWODec int64 + LPTokensBalanceWODec int64 + // + Accounts uint + POAValidators uint + TMValidatorsTotal uint + TMValidatorsActive uint + // + OpCreateValidator time.Duration + // + OpDelegateBonding time.Duration + OpDelegateBondingAmountRatio sdk.Dec + OpDelegateBondingMaxSupplyRatio sdk.Dec + // + OpDelegateLP time.Duration + OpDelegateLPAmountRatio sdk.Dec + OpDelegateLPMaxSupplyRatio sdk.Dec + // + OpRedelegateBonding time.Duration + OpRedelegateBondingAmountRatio sdk.Dec + // + OpRedelegateLP time.Duration + OpRedelegateLPAmountRatio sdk.Dec + // + OpUndelegateBonding time.Duration + OpUndelegateBondingAmountRatio sdk.Dec + // + OpUndelegateLP time.Duration + OpUndelegateLPAmountRatio sdk.Dec + // + OpGetValidatorRewards time.Duration + OpGetDelegatorRewards time.Duration + // + OpLockRewards time.Duration + OpLockRewardsRatio sdk.Dec +} + +func (p SimProfile) String() string { + str := strings.Builder{} + str.WriteString("Simulation:\n") + str.WriteString(fmt.Sprintf(" - ID: %s\n", p.ID)) + str.WriteString(fmt.Sprintf(" - SimDuration: %s\n", FormatDuration(p.SimDuration))) + str.WriteString(fmt.Sprintf(" - BlockTimeMin: %s\n", FormatDuration(p.BlockTimeMin))) + str.WriteString(fmt.Sprintf(" - BlockTimeMax: %s\n", FormatDuration(p.BlockTimeMax))) + str.WriteString("Initial balances:\n") + str.WriteString(fmt.Sprintf(" - MainTokens: %d.0%s\n", p.MainTokensBalanceWODec, defaults.MainDenom)) + str.WriteString(fmt.Sprintf(" - StakingTokens: %d.0%s\n", p.BondingTokensBalanceWODec, defaults.StakingDenom)) + str.WriteString(fmt.Sprintf(" - LPTokens: %d.0%s\n", p.LPTokensBalanceWODec, defaults.LiquidityProviderDenom)) + str.WriteString("Total number of:\n") + str.WriteString(fmt.Sprintf(" - Account: %d\n", p.Accounts)) + str.WriteString(fmt.Sprintf(" - PoA validators: %d\n", p.POAValidators)) + str.WriteString(fmt.Sprintf(" - TM validators (total): %d\n", p.TMValidatorsTotal)) + str.WriteString(fmt.Sprintf(" - TM validators (active): %d\n", p.TMValidatorsActive)) + str.WriteString("Operations:\n") + str.WriteString(fmt.Sprintf(" - Create validators: %s\n", FormatDuration(p.OpCreateValidator))) + str.WriteString(fmt.Sprintf(" - Delegate bonding tokens: %s\n", FormatDuration(p.OpDelegateBonding))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpDelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" Max limit ratio: %s\n", p.OpDelegateBondingMaxSupplyRatio)) + str.WriteString(fmt.Sprintf(" - Delegate LP tokens: %s\n", FormatDuration(p.OpDelegateLP))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpDelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" Max limit ratio: %s\n", p.OpDelegateLPMaxSupplyRatio)) + str.WriteString(fmt.Sprintf(" - Redelegate bonding tokens: %s\n", FormatDuration(p.OpRedelegateBonding))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpRedelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" - Redelegate LP tokens: %s\n", FormatDuration(p.OpRedelegateLP))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpRedelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" - Undelegate bonding tokens: %s\n", FormatDuration(p.OpUndelegateBonding))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpUndelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" - Undelegate LP tokens: %s\n", FormatDuration(p.OpUndelegateLP))) + str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpUndelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" - Withdraw validator comission: %s\n", FormatDuration(p.OpGetValidatorRewards))) + str.WriteString(fmt.Sprintf(" - Withdraw delegator reward: %s\n", FormatDuration(p.OpGetDelegatorRewards))) + str.WriteString(fmt.Sprintf(" - Lock rewards: %s\n", FormatDuration(p.OpLockRewards))) + str.WriteString(fmt.Sprintf(" Ratio: %s\n", p.OpLockRewardsRatio)) + + return str.String() +} + +func simulate(t *testing.T, profile SimProfile) { go http.ListenAndServe(":8090", nil) - expSimDur := 24 * 30 * 24 * time.Hour + t.Logf(profile.String()) // create a tmp directory - workingDir, err := ioutil.TempDir("/tmp", fmt.Sprintf("dnode-simulator-%s-", t.Name())) + workingDir, err := ioutil.TempDir("/tmp", fmt.Sprintf("dnode-simulator-%s-", profile.ID)) require.NoError(t, err) - // genesis accounts balance (1M xfi, 1M sxfi) - genAmount, ok := sdk.NewIntFromString("1000000000000000000000000") - require.True(t, ok) + // genesis accounts balance + amtDecimals := sdk.NewInt(1000000000000000000) genCoins := sdk.NewCoins( - sdk.NewCoin(config.MainDenom, genAmount), - sdk.NewCoin(config.StakingDenom, genAmount), + sdk.NewCoin(defaults.MainDenom, sdk.NewInt(profile.MainTokensBalanceWODec).Mul(amtDecimals)), + sdk.NewCoin(defaults.StakingDenom, sdk.NewInt(profile.BondingTokensBalanceWODec).Mul(amtDecimals)), + sdk.NewCoin(defaults.LiquidityProviderDenom, sdk.NewInt(profile.LPTokensBalanceWODec).Mul(amtDecimals)), ) - // custom distribution params - treasuryCapacity, ok := sdk.NewIntFromString("250000000000000000000000") - require.True(t, ok) - distParams := distribution.DefaultParams() - distParams.PublicTreasuryPoolCapacity = treasuryCapacity - - // custom staking params - stakingParams := staking.DefaultParams() - stakingParams.UnbondingTime = 24 * time.Hour - stakingParams.MaxValidators = 100 + // write profile to file + { + f, err := os.Create(path.Join(workingDir, "profile.txt")) + require.NoError(t, err) + _, err = f.WriteString(profile.String()) + require.NoError(t, err) + f.Close() + } // CSV report writer reportWriter, writerClose := NewSimReportCSVWriter(t, path.Join(workingDir, "report.csv")) @@ -55,15 +139,18 @@ func TestSimInflation(t *testing.T) { // create simulator s := NewSimulator(t, workingDir, NewDefferOps(), //InMemoryDBOption(), - BlockTimeOption(60*time.Second, 65*time.Second), - GenerateWalletAccountsOption(500, 3, 150, genCoins), + BlockTimeOption(profile.BlockTimeMin, profile.BlockTimeMax), + GenerateWalletAccountsOption(profile.Accounts, profile.POAValidators, genCoins), LogOption(log.AllowInfoWith("module", "x/staking")), LogOption(log.AllowInfoWith("module", "x/mint")), LogOption(log.AllowInfoWith("module", "x/distribution")), LogOption(log.AllowInfoWith("module", "x/slashing")), LogOption(log.AllowInfoWith("module", "x/evidence")), - StakingParamsOption(stakingParams), - DistributionParamsOption(distParams), + StakingParamsOption(func(state *staking.GenesisState) { + state.Params.UnbondingTime = 24 * time.Hour + state.Params.MaxValidators = uint16(profile.TMValidatorsActive) + state.Params.MaxDelegationsRatio = sdk.NewDecWithPrec(1000, 0) + }), InvariantCheckPeriodOption(1000), OperationsOption( NewSimInvariantsOp(1*time.Hour), @@ -71,13 +158,17 @@ func TestSimInflation(t *testing.T) { // NewReportOp(24*time.Hour, false, NewSimReportConsoleWriter(), reportWriter), // - NewCreateValidatorOp(2*24*time.Hour), - NewDelegateOp(8*time.Hour, sdk.NewDecWithPrec(40, 2)), // 40 % - NewRedelegateOp(20*time.Hour, sdk.NewDecWithPrec(20, 2)), // 20 % - NewUndelegateOp(48*time.Hour, sdk.NewDecWithPrec(25, 2)), // 25 % + NewCreateValidatorOp(profile.OpCreateValidator, profile.TMValidatorsTotal), + NewDelegateBondingOp(profile.OpDelegateBonding, profile.OpDelegateBondingAmountRatio, profile.OpDelegateBondingMaxSupplyRatio), + NewDelegateLPOp(profile.OpDelegateLP, profile.OpDelegateLPAmountRatio, profile.OpDelegateLPMaxSupplyRatio), + NewRedelegateBondingOp(profile.OpRedelegateBonding, profile.OpRedelegateBondingAmountRatio), + NewRedelegateLPOp(profile.OpRedelegateLP, profile.OpRedelegateLPAmountRatio), + NewUndelegateBondingOp(profile.OpUndelegateBonding, profile.OpUndelegateBondingAmountRatio), + NewUndelegateLPOp(profile.OpUndelegateLP, profile.OpUndelegateLPAmountRatio), // - NewGetDelRewardOp(120*time.Hour), - NewGetValRewardOp(72*time.Hour), + NewGetValidatorRewardOp(profile.OpGetValidatorRewards), + NewGetDelegatorRewardOp(profile.OpGetDelegatorRewards), + NewLockValidatorRewardsOp(profile.OpLockRewards, profile.OpLockRewardsRatio), ), ) @@ -85,9 +176,58 @@ func TestSimInflation(t *testing.T) { // work loop _, simDur := s.SimulatedDur() - for simDur < expSimDur { + for simDur < profile.SimDuration { s.Next() - _, simDur = s.SimulatedDur() } + + t.Logf("Simulation is done, output dir: %s", s.workingDir) +} + +func TestSimInflation(t *testing.T) { + profile := SimProfile{ + ID: "low_staking", + SimDuration: 1*Year + 6*Month, + BlockTimeMin: 120 * time.Second, + BlockTimeMax: 125 * time.Second, + // + MainTokensBalanceWODec: 50000, + BondingTokensBalanceWODec: 500000, + LPTokensBalanceWODec: 100000, + // + Accounts: 300, + POAValidators: 3, + TMValidatorsTotal: 150, + TMValidatorsActive: 100, + // + OpCreateValidator: 3 * time.Hour, + // + OpDelegateBonding: 6 * time.Hour, + OpDelegateBondingAmountRatio: sdk.NewDecWithPrec(40, 2), + OpDelegateBondingMaxSupplyRatio: sdk.NewDecWithPrec(30, 2), + // + OpDelegateLP: 1 * Day, + OpDelegateLPAmountRatio: sdk.NewDecWithPrec(40, 2), + OpDelegateLPMaxSupplyRatio: sdk.NewDecWithPrec(30, 2), + // + OpRedelegateBonding: 4 * Day, + OpRedelegateBondingAmountRatio: sdk.NewDecWithPrec(30, 2), + // + OpRedelegateLP: 8 * Day, + OpRedelegateLPAmountRatio: sdk.NewDecWithPrec(30, 2), + // + OpUndelegateBonding: 2 * Day, + OpUndelegateBondingAmountRatio: sdk.NewDecWithPrec(15, 2), + // + OpUndelegateLP: 4 * Day, + OpUndelegateLPAmountRatio: sdk.NewDecWithPrec(15, 2), + // + OpGetValidatorRewards: 1 * Week, + OpGetDelegatorRewards: 1 * Day, + // + OpLockRewards: 1 * Week, + OpLockRewardsRatio: sdk.NewDecWithPrec(30, 2), + } + + simulate(t, profile) } diff --git a/helpers/tests/simulator/sim.go b/helpers/tests/simulator/sim.go index fd496b20..5e47bf73 100644 --- a/helpers/tests/simulator/sim.go +++ b/helpers/tests/simulator/sim.go @@ -11,9 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/crisis" "github.com/cosmos/cosmos-sdk/x/genutil" - "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -23,6 +21,8 @@ import ( "github.com/dfinance/dnode/app" "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/cmd/config/restrictions" "github.com/dfinance/dnode/x/genaccounts" "github.com/dfinance/dnode/x/poa" @@ -34,16 +34,16 @@ var ( type Simulator struct { // configurable settings - genesisState map[string]json.RawMessage - invariantCheckPeriod uint - logOptions []log.Option - minSelfDelegationLvl sdk.Int - nodeValidatorConfig SimValidatorConfig - operations []*SimOperation - accounts []*SimAccount - useInMemDB bool - minBlockDur time.Duration - maxBlockDur time.Duration + genesisState map[string]json.RawMessage + invariantCheckPeriod uint + logOptions []log.Option + minSelfDelegationCoin sdk.Coin + nodeValidatorConfig SimValidatorConfig + operations []*SimOperation + accounts SimAccounts + useInMemDB bool + minBlockDur time.Duration + maxBlockDur time.Duration // predefined settings chainID string monikerID string @@ -53,6 +53,7 @@ type Simulator struct { unbondingDur time.Duration mainDenom string stakingDenom string + lpDenom string mainDenomDecimals uint8 stakingDenomDecimals uint8 workingDir string @@ -70,13 +71,17 @@ type Simulator struct { } type Counter struct { - Delegations int64 - Undelegations int64 - Redelegations int64 + BDelegations int64 + BUndelegations int64 + BRedelegations int64 + LPDelegations int64 + LPUndelegations int64 + LPRedelegations int64 + LockedRewards int64 Rewards int64 Commissions int64 - RewardsCollected sdk.Int - CommissionsCollected sdk.Int + RewardsCollected sdk.Coins + CommissionsCollected sdk.Coins } // BuildTmpFilePath builds file name inside of the Simulator working dir. @@ -90,7 +95,7 @@ func (s *Simulator) Start() { // generate wallet accounts genAccs := make(genaccounts.GenesisState, 0) - poaAccs := make([]*SimAccount, 0) + poaAccs := make(SimAccounts, 0) for accIdx := 0; accIdx < len(s.accounts); accIdx++ { acc := s.accounts[accIdx] @@ -147,6 +152,7 @@ func (s *Simulator) Start() { EthAddress: "0x17f7D1087971dF1a0E6b8Dae7428E97484E32615", }) } + s.genesisState[poa.ModuleName] = codec.MustMarshalJSONIndent(s.cdc, poa.GenesisState{ Parameters: poa.DefaultParams(), Validators: validators, @@ -157,49 +163,19 @@ func (s *Simulator) Start() { state := staking.GenesisState{} s.cdc.MustUnmarshalJSON(s.genesisState[staking.ModuleName], &state) - state.Params.BondDenom = s.stakingDenom - state.Params.MinSelfDelegationLvl = s.minSelfDelegationLvl - - s.genesisState[staking.ModuleName] = codec.MustMarshalJSONIndent(s.cdc, state) - s.unbondingDur = state.Params.UnbondingTime } - // mint - { - state := mint.GenesisState{} - s.cdc.MustUnmarshalJSON(s.genesisState[mint.ModuleName], &state) - - state.Params.MintDenom = s.stakingDenom - - s.genesisState[mint.ModuleName] = codec.MustMarshalJSONIndent(s.cdc, state) - } - // crisis - { - state := crisis.GenesisState{} - s.cdc.MustUnmarshalJSON(s.genesisState[crisis.ModuleName], &state) - - defFeeAmount, ok := sdk.NewIntFromString(config.DefaultFeeAmount) - require.True(s.t, ok) - - state.ConstantFee.Denom = s.mainDenom - state.ConstantFee.Amount = defFeeAmount - - s.genesisState[crisis.ModuleName] = codec.MustMarshalJSONIndent(s.cdc, state) - - s.defFee = sdk.NewCoin(s.mainDenom, defFeeAmount) - } // genutil, create node validator { nodeAcc := s.accounts[0] - selfDelegation := sdk.NewCoin(s.stakingDenom, s.minSelfDelegationLvl) msg := staking.NewMsgCreateValidator( nodeAcc.Address.Bytes(), nodeAcc.PublicKey, - selfDelegation, + s.minSelfDelegationCoin, staking.NewDescription(s.monikerID, "", "", "", ""), s.nodeValidatorConfig.Commission, - s.minSelfDelegationLvl, + s.minSelfDelegationCoin.Amount, ) tx := s.GenTxAdvanced(msg, 0, 0, nodeAcc.PublicKey, nodeAcc.PrivateKey) @@ -223,11 +199,10 @@ func (s *Simulator) Start() { // get node validator validators := s.QueryStakeValidators(1, 10, sdk.BondStatusBonded) require.Len(s.t, validators, 1) - s.accounts[0].OperatedValidator = &validators[0] + s.accounts[0].OperatedValidator = NewSimValidator(validators[0]) // update node account delegations - delegation := s.QueryStakeDelegation(s.accounts[0], s.accounts[0].OperatedValidator) - s.accounts[0].Delegations = append(s.accounts[0].Delegations, delegation) + s.UpdateAccount(s.accounts[0]) s.t.Logf("Simulator working / output directory: %s", s.workingDir) } @@ -252,7 +227,18 @@ func (s *Simulator) Next() { blockCreated := false for _, op := range s.operations { - blockCreated = op.Exec(s, s.prevBlockTime) + opReport := op.Exec(s, s.prevBlockTime) + if msg := opReport.String(); msg != "" { + if opReport.Executed { + s.logger.Info(msg) + } else { + s.logger.Error(msg) + } + } + + if opReport.Executed { + blockCreated = true + } } if !blockCreated { @@ -281,8 +267,8 @@ func (s *Simulator) beginBlock() { for _, val := range validators { lastCommitInfo.Votes = append(lastCommitInfo.Votes, abci.VoteInfo{ Validator: abci.Validator{ - Address: val.ConsPubKey.Address(), - Power: val.GetConsensusPower(), + Address: val.Validator.ConsPubKey.Address(), + Power: val.Validator.GetConsensusPower(), }, SignedLastBlock: true, }) @@ -293,7 +279,7 @@ func (s *Simulator) beginBlock() { ChainID: s.chainID, Height: nextHeight, Time: nextBlockTime, - ProposerAddress: proposer.ConsPubKey.Address(), + ProposerAddress: proposer.Validator.ConsPubKey.Address(), }, LastCommitInfo: lastCommitInfo, }) @@ -308,9 +294,6 @@ func (s *Simulator) endBlock() { // NewSimulator creates a new Simulator. func NewSimulator(t *testing.T, workingDir string, defferQueue *DefferOps, options ...SimOption) *Simulator { // defaults init - minSelfDelegation, ok := sdk.NewIntFromString(config.DefMinSelfDelegation) - require.True(t, ok) - nodeValCommissionRate, err := sdk.NewDecFromStr("0.100000000000000000") require.NoError(t, err) @@ -321,10 +304,9 @@ func NewSimulator(t *testing.T, workingDir string, defferQueue *DefferOps, optio require.NoError(t, err) s := &Simulator{ - genesisState: app.ModuleBasics.DefaultGenesis(), - invariantCheckPeriod: 1, - logOptions: make([]log.Option, 0), - minSelfDelegationLvl: minSelfDelegation, + invariantCheckPeriod: 1, + logOptions: make([]log.Option, 0), + minSelfDelegationCoin: defaults.MinSelfDelegationCoin, nodeValidatorConfig: SimValidatorConfig{ Commission: staking.CommissionRates{ Rate: nodeValCommissionRate, @@ -332,16 +314,18 @@ func NewSimulator(t *testing.T, workingDir string, defferQueue *DefferOps, optio MaxChangeRate: nodeValCommissionMaxChangeRate, }, }, - accounts: make([]*SimAccount, 0), + accounts: make(SimAccounts, 0), minBlockDur: 5 * time.Second, maxBlockDur: 6 * time.Second, // chainID: "simChainID", monikerID: "simMoniker", - defGas: 500000, + defFee: defaults.FeeCoin, + defGas: defaults.MaxGas, // - mainDenom: config.MainDenom, - stakingDenom: config.StakingDenom, + mainDenom: defaults.MainDenom, + stakingDenom: defaults.StakingDenom, + lpDenom: defaults.LiquidityProviderDenom, mainDenomDecimals: 18, stakingDenomDecimals: 18, mainAmountDecimalsRatio: sdk.NewDecWithPrec(1, 0), @@ -354,8 +338,12 @@ func NewSimulator(t *testing.T, workingDir string, defferQueue *DefferOps, optio cdc: app.MakeCodec(), defferQueue: defferQueue, } - s.counter.RewardsCollected = sdk.ZeroInt() - s.counter.CommissionsCollected = sdk.ZeroInt() + s.counter.RewardsCollected = sdk.NewCoins() + s.counter.CommissionsCollected = sdk.NewCoins() + + defaultGenesis, err := genesis.OverrideGenesisStateDefaults(s.cdc, app.ModuleBasics.DefaultGenesis()) + require.NoError(t, err) + s.genesisState = defaultGenesis for _, option := range options { option(s) diff --git a/helpers/tests/simulator/sim_account.go b/helpers/tests/simulator/sim_account.go index 792f6616..fc7398e8 100644 --- a/helpers/tests/simulator/sim_account.go +++ b/helpers/tests/simulator/sim_account.go @@ -1,8 +1,12 @@ package simulator import ( + "math/rand" + "sort" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" ) @@ -15,11 +19,15 @@ type SimAccount struct { PublicKey crypto.PubKey Coins sdk.Coins IsPoAValidator bool - CreateValidator bool - OperatedValidator *staking.Validator + OperatedValidator *SimValidator Delegations []staking.DelegationResponse } +// IsValOperator checks if account is a validator operator. +func (a *SimAccount) IsValOperator() bool { + return a.OperatedValidator != nil +} + // HasDelegation checks if account has already delegated to the specified validator. func (a *SimAccount) HasDelegation(valAddress sdk.ValAddress) bool { for _, del := range a.Delegations { @@ -30,3 +38,98 @@ func (a *SimAccount) HasDelegation(valAddress sdk.ValAddress) bool { return false } + +// GetSortedDelegations returns delegations sorted by tokens balance list. +func (a *SimAccount) GetSortedDelegations(bondingTokens, desc bool) staking.DelegationResponses { + tmpDels := make(staking.DelegationResponses, len(a.Delegations)) + copy(tmpDels, a.Delegations) + + sort.Slice(tmpDels, func(i, j int) bool { + if bondingTokens { + if tmpDels[i].BondingBalance.Amount.GT(tmpDels[j].BondingBalance.Amount) { + return desc + } + return !desc + } + + if tmpDels[i].LPBalance.Amount.GT(tmpDels[j].LPBalance.Amount) { + return desc + } + return !desc + }) + + return tmpDels +} + +// GetShuffledDelegations returns shuffled delegations list. +func (a *SimAccount) GetShuffledDelegations(bondingTokens bool) staking.DelegationResponses { + tmpDels := make(staking.DelegationResponses, len(a.Delegations)) + copy(tmpDels, a.Delegations) + + for i := range tmpDels { + j := rand.Intn(i + 1) + tmpDels[i], tmpDels[j] = tmpDels[j], tmpDels[i] + } + + return tmpDels +} + +type SimAccounts []*SimAccount + +// GetByAddress returns account by address. +func (a SimAccounts) GetByAddress(address sdk.AccAddress) *SimAccount { + for _, acc := range a { + if acc.Address.Equals(address) { + return acc + } + } + + return nil +} + +// GetRandom returns randomly selected account. +func (a SimAccounts) GetRandom() *SimAccount { + aMaxIndex := len(a) - 1 + + return a[rand.Intn(aMaxIndex)] +} + +// GetShuffled returns random sorted accounts list. +func (a SimAccounts) GetShuffled() SimAccounts { + tmpAcc := make(SimAccounts, len(a)) + copy(tmpAcc, a) + + for i := range tmpAcc { + j := rand.Intn(i + 1) + tmpAcc[i], tmpAcc[j] = tmpAcc[j], tmpAcc[i] + } + + return tmpAcc +} + +// GetAccountsSortedByBalance returns account sorted by staking denom list. +func (a SimAccounts) GetSortedByBalance(denom string, desc bool) SimAccounts { + tmpAccs := make(SimAccounts, len(a)) + copy(tmpAccs, a) + + sort.Slice(tmpAccs, func(i, j int) bool { + iBalance := tmpAccs[i].Coins.AmountOf(denom) + jBalance := tmpAccs[j].Coins.AmountOf(denom) + + if iBalance.GT(jBalance) { + return desc + } + return !desc + }) + + return tmpAccs +} + +// UpdateAccount updates account balance and active delegations. +func (s *Simulator) UpdateAccount(simAcc *SimAccount) { + require.NotNil(s.t, simAcc) + + updAcc := s.QueryAuthAccount(simAcc.Address) + simAcc.Coins = updAcc.GetCoins() + simAcc.Delegations = s.QueryStakeDelDelegations(simAcc.Address) +} diff --git a/helpers/tests/simulator/sim_helpers.go b/helpers/tests/simulator/sim_helpers.go index 485f5272..d165df73 100644 --- a/helpers/tests/simulator/sim_helpers.go +++ b/helpers/tests/simulator/sim_helpers.go @@ -1,62 +1,44 @@ package simulator import ( - "math/rand" - "sort" + "strings" + "time" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/stretchr/testify/require" ) -func (s *Simulator) GetRandomAccount() *SimAccount { - aMaxIndex := len(s.accounts) - 1 - return s.accounts[rand.Intn(aMaxIndex)] -} - -// UpdateAccount updates account balance and active delegations. -func (s *Simulator) UpdateAccount(simAcc *SimAccount) { - require.NotNil(s.t, simAcc) +const ( + Day = 24 * time.Hour + Week = 7 * Day + Month = 4 * Week + Year = 12 * Month +) - updAcc := s.QueryAuthAccount(simAcc.Address) - simAcc.Coins = updAcc.GetCoins() - simAcc.Delegations = s.QueryStakeDelDelegations(simAcc.Address) +// GetAllAccounts returns all known to Simulator accounts. +func (s *Simulator) GetAllAccounts() SimAccounts { + return s.accounts } -// GetValidatorByAddress returns validator. -func (s *Simulator) GetValidatorByAddress(address sdk.ValAddress) *staking.Validator { +// GetAllValidators returns all known to Simulator validators. +func (s *Simulator) GetAllValidators() SimValidators { + validators := make(SimValidators, 0) for _, acc := range s.accounts { - if acc.OperatedValidator != nil { - if acc.OperatedValidator.OperatorAddress.Equals(address) { - return acc.OperatedValidator - } + if !acc.IsValOperator() { + continue } + validators = append(validators, acc.OperatedValidator) } - return nil -} - -// UpdateValidator updates validator status. -func (s *Simulator) UpdateValidator(val *staking.Validator) { - require.NotNil(s.t, val) - - updVal := s.QueryStakeValidator(val.OperatorAddress) - val.Status = updVal.Status - val.Jailed = updVal.Jailed - val.Bonding = updVal.Bonding - val.LP = updVal.LP - val.UnbondingHeight = updVal.UnbondingHeight - val.UnbondingCompletionTime = updVal.UnbondingCompletionTime + return validators } -// GetValidators returns all known to Simulator validators. -func (s *Simulator) GetValidators(bonded, unbonding, unbonded bool) []*staking.Validator { - validators := make([]*staking.Validator, 0) +// GetValidators returns known to Simulator validators filtered by status. +func (s *Simulator) GetValidators(bonded, unbonding, unbonded bool) SimValidators { + validators := make(SimValidators, 0) for _, acc := range s.accounts { if acc.OperatedValidator != nil { add := false - switch acc.OperatedValidator.Status { + switch acc.OperatedValidator.GetStatus() { case sdk.Bonded: if bonded { add = true @@ -80,41 +62,22 @@ func (s *Simulator) GetValidators(bonded, unbonding, unbonded bool) []*staking.V return validators } -// GetShuffledAccounts returns random sorted account list. -func (s Simulator) GetShuffledAccounts() []*SimAccount { - tmpAcc := make([]*SimAccount, len(s.accounts)) - copy(tmpAcc, s.accounts) - - for i := range tmpAcc { - j := rand.Intn(i + 1) - tmpAcc[i], tmpAcc[j] = tmpAcc[j], tmpAcc[i] - } - - return tmpAcc +// FormatCoin formats coin to decimal string. +func (s *Simulator) FormatCoin(coin sdk.Coin) string { + return s.FormatIntDecimals(coin.Amount, s.stakingAmountDecimalsRatio) + coin.Denom } -// GetAccountsSortedByBalance returns account sorted by staking denom list. -func (s Simulator) GetAccountsSortedByBalance(desc bool) []*SimAccount { - tmpAccs := make([]*SimAccount, len(s.accounts)) - copy(tmpAccs, s.accounts) - - sort.Slice(tmpAccs, func(i, j int) bool { - iBalance := tmpAccs[i].Coins.AmountOf(s.stakingDenom) - jBalance := tmpAccs[j].Coins.AmountOf(s.stakingDenom) - - if iBalance.GT(jBalance) { - return desc - } - return !desc - }) - - return tmpAccs -} +// FormatCoins formats coins to decimal string. +func (s *Simulator) FormatCoins(coins sdk.Coins) string { + out := make([]string, 0, len(coins)) + for _, coin := range coins { + out = append(out, s.FormatIntDecimals(coin.Amount, s.stakingAmountDecimalsRatio)+coin.Denom) + } -func (s *Simulator) FormatStakingCoin(coin sdk.Coin) string { - return s.FormatIntDecimals(coin.Amount, s.stakingAmountDecimalsRatio) + s.stakingDenom + return strings.Join(out, ",") } +// FormatIntDecimals converts sdk.Int to sdk.Dec using convert ratio and returns a string representation. func (s *Simulator) FormatIntDecimals(value sdk.Int, decRatio sdk.Dec) string { valueDec := sdk.NewDecFromInt(value) fixedDec := valueDec.Mul(decRatio) @@ -127,53 +90,3 @@ func (s *Simulator) FormatDecDecimals(value sdk.Dec, decRatio sdk.Dec) string { return fixedDec.String() } - -// GetSortedByStakeValidator returns validators sorted by stake. -func GetSortedByStakeValidator(validators []*staking.Validator, desc bool) []*staking.Validator { - sort.Slice(validators, func(i, j int) bool { - if validators[i].Bonding.Tokens.GT(validators[j].Bonding.Tokens) { - return desc - } - return !desc - }) - - return validators -} - -// GetSortedDelegation returns delegation sorted list. -func GetSortedDelegation(responses staking.DelegationResponses, desc bool) staking.DelegationResponses { - sort.Slice(responses, func(i, j int) bool { - if responses[i].BondingBalance.Amount.GT(responses[j].BondingBalance.Amount) { - return desc - } - return !desc - }) - - return responses -} - -// GetShuffledDelegations returns delegations in the random order. -func GetShuffledDelegations(delegations staking.DelegationResponses) staking.DelegationResponses { - tmp := make(staking.DelegationResponses, len(delegations)) - copy(tmp, delegations) - - for i := range tmp { - j := rand.Intn(i + 1) - tmp[i], tmp[j] = tmp[j], tmp[i] - } - - return tmp -} - -// ShuffleRewards returns rewards in the random order. -func ShuffleRewards(rewards []distribution.DelegationDelegatorReward) []distribution.DelegationDelegatorReward { - tmp := make([]distribution.DelegationDelegatorReward, len(rewards)) - copy(tmp, rewards) - - for i := range tmp { - j := rand.Intn(i + 1) - tmp[i], tmp[j] = tmp[j], tmp[i] - } - - return tmp -} diff --git a/helpers/tests/simulator/sim_invariant.go b/helpers/tests/simulator/sim_invariant.go index abce3b25..224cd018 100644 --- a/helpers/tests/simulator/sim_invariant.go +++ b/helpers/tests/simulator/sim_invariant.go @@ -8,53 +8,52 @@ import ( // NewSimInvariantsOp checks inner simulator state integrity. func NewSimInvariantsOp(period time.Duration) *SimOperation { - handler := func(s *Simulator) bool { + id := "InvariantsOp" + + handler := func(s *Simulator) (bool, string) { // check validator owner has exactly one self-delegation - for _, acc := range s.accounts { - if acc.OperatedValidator != nil { + for _, acc := range s.GetAllAccounts() { + if acc.IsValOperator() { selfDelCnt := 0 for _, del := range acc.Delegations { - if del.ValidatorAddress.Equals(acc.OperatedValidator.OperatorAddress) { + if del.ValidatorAddress.Equals(acc.OperatedValidator.GetAddress()) { selfDelCnt++ } } - require.Equal(s.t, 1, selfDelCnt, "simInvariants: invalid number of selfDelegations found for: %s", acc.Address) + require.Equal(s.t, 1, selfDelCnt, "%s: invalid number of selfDelegations found for: %s", id, acc.Address) } } // check for duplicated validators validatorsMap := make(map[string]bool, len(s.accounts)) - for _, acc := range s.accounts { - if acc.OperatedValidator != nil { - valAddrStr := acc.OperatedValidator.OperatorAddress.String() - found := validatorsMap[valAddrStr] - require.False(s.t, found, "duplicated validator found: %s", valAddrStr) + for _, val := range s.GetAllValidators() { + valAddrStr := val.GetAddress().String() + found := validatorsMap[valAddrStr] + require.False(s.t, found, "%s: duplicated validator found: %s", id, valAddrStr) - validatorsMap[valAddrStr] = true - } + validatorsMap[valAddrStr] = true } - return true + return true, "" } - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) } // NewForceUpdateOp updates various simulator states for consistency. func NewForceUpdateOp(period time.Duration) *SimOperation { - handler := func(s *Simulator) bool { - for _, acc := range s.accounts { - accValidator := acc.OperatedValidator - if accValidator == nil { - continue - } + id := "ForceUpdateOp" - s.UpdateValidator(accValidator) + handler := func(s *Simulator) (bool, string) { + for _, val := range s.GetAllValidators() { + s.UpdateValidator(val) } - return true + s.counter.LockedRewards = int64(len(s.GetAllValidators().GetLocked())) + + return true, "" } - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) } diff --git a/helpers/tests/simulator/sim_operation.go b/helpers/tests/simulator/sim_operation.go index 7b259923..7c62e97c 100644 --- a/helpers/tests/simulator/sim_operation.go +++ b/helpers/tests/simulator/sim_operation.go @@ -1,6 +1,11 @@ package simulator -import "time" +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) // SimOperationNextExecFn returns next execution time for SimOperation. type SimOperationNextExecFn func(curTime time.Time, period time.Duration) time.Time @@ -13,11 +18,12 @@ func NewPeriodicNextExecFn() SimOperationNextExecFn { } // SimOperationHandler handles operation using Simulator infra. -type SimOperationHandler func(s *Simulator) bool +type SimOperationHandler func(s *Simulator) (executed bool, message string) // SimOperation keeps operation state and handlers. // CONTRACT: operation must update changed Simulator state (account balance, modified validator, new delegation, etc). type SimOperation struct { + id string handlerFn SimOperationHandler nextExecFn SimOperationNextExecFn period time.Duration @@ -25,10 +31,28 @@ type SimOperation struct { execCounter int } +// SimOperationReport contains SimOperation execution report. +type SimOperationReport struct { + ID string + Executed bool + Duration time.Duration + LogMessage string +} + +func (r SimOperationReport) String() string { + if r.LogMessage == "" { + return "" + } + + return fmt.Sprintf("%s [%v]: %s", r.ID, r.Duration.Truncate(time.Millisecond), r.LogMessage) +} + // Exec executes the operation if its time has come. -func (op *SimOperation) Exec(s *Simulator, curTime time.Time) (executed bool) { +func (op *SimOperation) Exec(s *Simulator, curTime time.Time) (report SimOperationReport) { + report.ID = op.id + defer func() { - if !executed { + if !report.Executed { return } @@ -37,23 +61,37 @@ func (op *SimOperation) Exec(s *Simulator, curTime time.Time) (executed bool) { }() if op.nextExecTime.IsZero() { - executed = true + report.Executed = true op.execCounter-- return } if curTime.After(op.nextExecTime) { - executed = op.handlerFn(s) + opStart := time.Now() + report.Executed, report.LogMessage = op.handlerFn(s) + report.Duration = time.Since(opStart) } return } // NewSimOperation creates a new SimOperation. -func NewSimOperation(period time.Duration, nextExecFn SimOperationNextExecFn, handlerFn SimOperationHandler) *SimOperation { +func NewSimOperation(id string, period time.Duration, nextExecFn SimOperationNextExecFn, handlerFn SimOperationHandler) *SimOperation { return &SimOperation{ + id: id, handlerFn: handlerFn, nextExecFn: nextExecFn, period: period, } } + +// checkRatioArg checks SimOperation ratio coef input (0 < value <= 1.0). +func checkRatioArg(opName, argName string, argValue sdk.Dec) { + errMsgPrefix := fmt.Sprintf("%s: %s: ", opName, argName) + if argValue.LTE(sdk.ZeroDec()) { + panic(fmt.Errorf("%s: LTE 0", errMsgPrefix)) + } + if argValue.GT(sdk.OneDec()) { + panic(fmt.Errorf("%s: GE 1", errMsgPrefix)) + } +} diff --git a/helpers/tests/simulator/sim_ops.go b/helpers/tests/simulator/sim_ops.go deleted file mode 100644 index 02980b0d..00000000 --- a/helpers/tests/simulator/sim_ops.go +++ /dev/null @@ -1,362 +0,0 @@ -package simulator - -import ( - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/stretchr/testify/require" -) - -// NewCreateValidatorOp creates validator for account which is not an operator already. -func NewCreateValidatorOp(period time.Duration) *SimOperation { - handler := func(s *Simulator) bool { - // find account without validator - var simAcc *SimAccount - for _, acc := range s.accounts { - if !acc.CreateValidator { - continue - } - - if acc.OperatedValidator == nil { - simAcc = acc - break - } - } - if simAcc == nil { - return true - } - - // define commissions - comRate, err := sdk.NewDecFromStr("0.100000000000000000") - require.NoError(s.t, err) - - comMaxRate, err := sdk.NewDecFromStr("0.200000000000000000") - require.NoError(s.t, err) - - comMaxChangeRate, err := sdk.NewDecFromStr("0.010000000000000000") - require.NoError(s.t, err) - - // create - s.TxStakingCreateValidator(simAcc, staking.NewCommissionRates(comRate, comMaxRate, comMaxChangeRate)) - s.beginBlock() - s.endBlock() - - // update account - validator := s.QueryStakeValidator(sdk.ValAddress(simAcc.Address)) - s.UpdateAccount(simAcc) - simAcc.OperatedValidator = &validator - - s.logger.Info(fmt.Sprintf("ValidatorOp: %s (%s) created for %s", validator.OperatorAddress, validator.GetConsAddr(), simAcc.Address)) - - return true - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -// NewDelegateOp picks a validator and searches for account to delegate. -// SelfStake increment is allowed. -// Delegation amount = current account balance * ratioCoef. -// Op priorities: -// validator: -// - bonded; -// - lowest tokens amount; -// account - random, enough coins; -func NewDelegateOp(period time.Duration, delegateRatio sdk.Dec) *SimOperation { - checkRatioArg("DelegateOp", "delegateRatio", delegateRatio) - - handler := func(s *Simulator) bool { - // pick a validator with the lowest tokens amount - validators := GetSortedByStakeValidator(s.GetValidators(true, false, false), false) - if len(validators) == 0 { - return false - } - validator := validators[0] - - // pick a target account with enough coins - var delAmt sdk.Int - var targetAcc *SimAccount - for _, acc := range s.GetAccountsSortedByBalance(true) { - // estimate delegation amount - accCoinAmtDec := sdk.NewDecFromInt(acc.Coins.AmountOf(s.stakingDenom)) - delAmt = accCoinAmtDec.Mul(delegateRatio).TruncateInt() - if delAmt.IsZero() { - continue - } - - targetAcc = acc - } - if targetAcc == nil { - return false - } - - // delegate - coin := sdk.NewCoin(s.stakingDenom, delAmt) - s.TxStakingDelegate(targetAcc, validator, coin) - - // update account - s.UpdateAccount(targetAcc) - // update validator - s.UpdateValidator(validator) - // update stats - s.counter.Delegations++ - - s.logger.Info(fmt.Sprintf("DelegateOp: %s: %s -> %s", targetAcc.Address, s.FormatStakingCoin(coin), validator.OperatorAddress)) - - return true - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -// NewRedelegateOp picks a validator and redelegate tokens to an other validator. -// Redelegation amount = current account delegation amount * ratioCoef. -// Op priorities: -// dstValidator: -// - bonded; -// - lowest tokens amount; -// srcValidator - highest account delegation shares; -// account: -// - random; -// - has no active redelegations with srcValidator and dstValidator; -// - has enough coins; -// - not a dstValidator owner; -func NewRedelegateOp(period time.Duration, redelegateRatio sdk.Dec) *SimOperation { - checkRatioArg("RedelegateOp", "redelegateRatio", redelegateRatio) - - handler := func(s *Simulator) bool { - // pick a dstValidator with the lowest tokens amount - validators := GetSortedByStakeValidator(s.GetValidators(true, false, false), true) - if len(validators) == 0 { - return false - } - dstValidator := validators[0] - - rdInProcess := func(accAddr sdk.AccAddress, srcValAddr, dstValAddr sdk.ValAddress) bool { - for _, rd := range s.QueryStakeRedelegations(accAddr, sdk.ValAddress{}, sdk.ValAddress{}) { - if rd.ValidatorSrcAddress.Equals(srcValAddr) || rd.ValidatorDstAddress.Equals(srcValAddr) { - return true - } - - if rd.ValidatorSrcAddress.Equals(dstValAddr) || rd.ValidatorDstAddress.Equals(dstValAddr) { - return true - } - } - - return false - } - - // pick a target account - for _, acc := range s.GetShuffledAccounts() { - accValAddr := sdk.ValAddress{} - if acc.OperatedValidator != nil { - accValAddr = acc.OperatedValidator.OperatorAddress - } - - // check not redelegating to the account owned validator - if dstValidator.OperatorAddress.Equals(accValAddr) { - continue - } - - // pick a delegation with the highest share - for _, delegation := range GetSortedDelegation(acc.Delegations, true) { - srcValidator := s.GetValidatorByAddress(delegation.ValidatorAddress) - - if srcValidator.OperatorAddress.Equals(dstValidator.OperatorAddress) { - continue - } - - // check not redelegating from the account owned validator - if srcValidator.OperatorAddress.Equals(accValAddr) { - continue - } - - // check if an other redelegation is in progress for the selected account - if rdInProcess(acc.Address, srcValidator.OperatorAddress, dstValidator.OperatorAddress) { - continue - } - - // estimate redelegation amount - rdAmtDec := sdk.NewDecFromInt(delegation.BondingBalance.Amount) - rdAmt := rdAmtDec.Mul(redelegateRatio).TruncateInt() - if rdAmt.IsZero() { - continue - } - - // redelegate - coin := sdk.NewCoin(delegation.BondingBalance.Denom, rdAmt) - s.TxStakingRedelegate(acc, srcValidator.OperatorAddress, dstValidator.OperatorAddress, coin) - - // update validators - s.UpdateValidator(srcValidator) - s.UpdateValidator(dstValidator) - // update account - s.UpdateAccount(acc) - // update stats - s.counter.Redelegations++ - - s.logger.Info(fmt.Sprintf("RedelegateOp: %s: %s -> %s -> %s", acc.Address, srcValidator.OperatorAddress, s.FormatStakingCoin(coin), dstValidator.OperatorAddress)) - - return true - } - } - - return true - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -// NewUndelegateOp picks a validator and undelegates tokens. -// Undelegation amount = current account delegation amount * ratioCoef. -// Op priorities: -// validator - highest tokens amount; -// account: -// - random; -// - has a validators delegation; -// - not a validator owner; -func NewUndelegateOp(period time.Duration, undelegateRatio sdk.Dec) *SimOperation { - checkRatioArg("UndelegateOp", "undelegateRatio", undelegateRatio) - - handler := func(s *Simulator) bool { - // pick a validator with the highest tokens amount; - validators := GetSortedByStakeValidator(s.GetValidators(true, true, true), true) - if len(validators) == 0 { - return false - } - validator := validators[0] - - for _, acc := range s.GetShuffledAccounts() { - accValAddr := sdk.ValAddress{} - if acc.OperatedValidator != nil { - accValAddr = acc.OperatedValidator.OperatorAddress - } - - for _, delegation := range acc.Delegations { - // check if account did delegate to the selected validator - if !validator.OperatorAddress.Equals(delegation.ValidatorAddress) { - continue - } - - // check not undelegating from the account owned validator - if accValAddr.Equals(validator.OperatorAddress) { - continue - } - - // estimate undelegation amount - udAmtDec := sdk.NewDecFromInt(delegation.BondingBalance.Amount) - udAmt := udAmtDec.Mul(undelegateRatio).TruncateInt() - if udAmt.IsZero() { - continue - } - - // undelegate - coin := sdk.NewCoin(delegation.BondingBalance.Denom, udAmt) - s.TxStakingUndelegate(acc, validator.OperatorAddress, coin) - - // update validator - s.UpdateValidator(validator) - // update account - s.UpdateAccount(acc) - // update stats - s.counter.Undelegations++ - - s.defferQueue.Add(s.prevBlockTime.Add(s.unbondingDur+5*time.Minute), func() { - s.UpdateAccount(acc) - }) - - s.logger.Info(fmt.Sprintf("UndelegateOp: %s: %s -> %s", acc.Address, validator.OperatorAddress, s.FormatStakingCoin(coin))) - - return true - } - } - - return false - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -// NewGetDelRewardOp take delegator rewards. -// Op priority: -// account; -// - random; -// - has delegations; -// validator - random account delegation; -func NewGetDelRewardOp(period time.Duration) *SimOperation { - handler := func(s *Simulator) bool { - for _, acc := range s.GetShuffledAccounts() { - if len(acc.Delegations) == 0 { - continue - } - targetDelegation := GetShuffledDelegations(acc.Delegations)[0] - - rewardsDec := s.QueryDistDelReward(acc.Address, targetDelegation.ValidatorAddress) - rewards := rewardsDec.AmountOf(s.stakingDenom).TruncateInt() - rewardsCoin := sdk.NewCoin(s.stakingDenom, rewards) - - // distribute - s.TxDistributionReward(acc, targetDelegation.ValidatorAddress) - - // update account - s.UpdateAccount(acc) - // update stats - s.counter.Rewards++ - s.counter.RewardsCollected = s.counter.RewardsCollected.Add(rewards) - - s.logger.Info(fmt.Sprintf("DelRewardOp: %s from %s: %s", acc.Address, targetDelegation.ValidatorAddress, s.FormatStakingCoin(rewardsCoin))) - - return true - } - - return false - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -// NewGetValRewardOp takes validator commissions rewards. -// Op priority: -// validator - random; -func NewGetValRewardOp(period time.Duration) *SimOperation { - handler := func(s *Simulator) bool { - for _, acc := range s.GetShuffledAccounts() { - if acc.OperatedValidator == nil { - continue - } - - rewardsDec := s.QueryDistrValCommission(acc.OperatedValidator.OperatorAddress) - rewards := rewardsDec.AmountOf(s.stakingDenom).TruncateInt() - rewardsCoin := sdk.NewCoin(s.stakingDenom, rewards) - - // distribute - s.TxDistributionCommission(acc, acc.OperatedValidator.OperatorAddress) - - // update account - s.UpdateAccount(acc) - // update stats - s.counter.Commissions++ - s.counter.CommissionsCollected = s.counter.CommissionsCollected.Add(rewards) - - s.logger.Info(fmt.Sprintf("ValRewardOp: %s for %s: %s", acc.OperatedValidator.OperatorAddress, acc.Address, s.FormatStakingCoin(rewardsCoin))) - - return true - } - - return false - } - - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) -} - -func checkRatioArg(opName, argName string, argValue sdk.Dec) { - errMsgPrefix := fmt.Sprintf("%s: %s: ", opName, argName) - if argValue.LTE(sdk.ZeroDec()) { - panic(fmt.Errorf("%s: LTE 0", errMsgPrefix)) - } - if argValue.GT(sdk.OneDec()) { - panic(fmt.Errorf("%s: GE 1", errMsgPrefix)) - } -} diff --git a/helpers/tests/simulator/sim_ops_create_validator.go b/helpers/tests/simulator/sim_ops_create_validator.go new file mode 100644 index 00000000..4711a8a3 --- /dev/null +++ b/helpers/tests/simulator/sim_ops_create_validator.go @@ -0,0 +1,83 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/stretchr/testify/require" +) + +// NewCreateValidatorOp creates validator for an account which is not an operator yet and has enough coins. +func NewCreateValidatorOp(period time.Duration, maxValidators uint) *SimOperation { + id := "ValidatorOp" + handler := func(s *Simulator) (bool, string) { + if createValidatorOpCheckInput(s, maxValidators) { + return true, "" + } + + targetAcc := createValidatorOpFindTarget(s) + if targetAcc == nil { + return true, "target not found" + } + createValidatorOpHandle(s, targetAcc) + + createdVal := createValidatorOpPost(s, targetAcc) + msg := fmt.Sprintf("%s (%s) created for %s", createdVal.GetAddress(), createdVal.Validator.GetConsAddr(), targetAcc.Address) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func createValidatorOpCheckInput(s *Simulator, maxValidators uint) (stop bool) { + // check limit is reached + return len(s.GetAllValidators()) >= int(maxValidators) +} + +func createValidatorOpFindTarget(s *Simulator) (targetAcc *SimAccount) { + // pick an account without a validator + for _, acc := range s.GetAllAccounts().GetShuffled() { + if acc.IsValOperator() { + continue + } + + // check balance + if acc.Coins.AmountOf(s.stakingDenom).LT(s.minSelfDelegationCoin.Amount) { + continue + } + + targetAcc = acc + break + } + + return +} + +func createValidatorOpHandle(s *Simulator, targetAcc *SimAccount) { + // define commissions + comRate, err := sdk.NewDecFromStr("0.100000000000000000") + require.NoError(s.t, err) + + comMaxRate, err := sdk.NewDecFromStr("0.200000000000000000") + require.NoError(s.t, err) + + comMaxChangeRate, err := sdk.NewDecFromStr("0.010000000000000000") + require.NoError(s.t, err) + + // create a new validator with min self-delegation + s.TxStakeCreateValidator(targetAcc, staking.NewCommissionRates(comRate, comMaxRate, comMaxChangeRate)) + s.beginBlock() + s.endBlock() +} + +func createValidatorOpPost(s *Simulator, targetAcc *SimAccount) (createdVal *SimValidator) { + // update account + validator := s.QueryStakeValidator(sdk.ValAddress(targetAcc.Address)) + s.UpdateAccount(targetAcc) + targetAcc.OperatedValidator = NewSimValidator(validator) + + return targetAcc.OperatedValidator +} diff --git a/helpers/tests/simulator/sim_ops_delegate.go b/helpers/tests/simulator/sim_ops_delegate.go new file mode 100644 index 00000000..ac138aed --- /dev/null +++ b/helpers/tests/simulator/sim_ops_delegate.go @@ -0,0 +1,156 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +// NewDelegateBondingOp picks a validator and searches for an account to delegate bonding tokens. +// SelfStake increment is allowed. +// Delegation amount = current account balance * {delegateRatio}. +// Delegation is allowed if ratio (current staking bonding pools supply / total bonding tokens supply) < {maxBondingRatio}. +// Op priorities: +// validator: +// - bonded; +// - lowest bonding tokens amount; +// account: +// - highest bonding tokens balance; +// - enough coins; +func NewDelegateBondingOp(period time.Duration, delegateRatio, maxBondingRatio sdk.Dec) *SimOperation { + id := "DelegateBondingOp" + checkRatioArg(id, "delegateRatio", delegateRatio) + checkRatioArg(id, "maxBondingRatio", maxBondingRatio) + + handler := func(s *Simulator) (bool, string) { + if delegateOpCheckInput(s, true, maxBondingRatio) { + return true, "" + } + + targetVal, targetAcc, delCoin := delegateOpFindTarget(s, true, delegateRatio) + if targetVal == nil || targetAcc == nil { + return false, "target not found" + } + + if delegateOpHandle(s, targetVal, targetAcc, delCoin) { + return false, fmt.Sprintf("DelegateBondingOp: %s: overflow", targetVal.GetAddress()) + } + + delegateOpPost(s, targetVal, targetAcc, true) + msg := fmt.Sprintf("%s: %s -> %s", targetAcc.Address, s.FormatCoin(delCoin), targetVal.GetAddress()) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +// NewDelegateLPOp picks a validator and searches for an account to delegate LP tokens. +// Delegation amount = current account balance * {delegateRatio}. +// Delegation is allowed if ratio (current staking LP pool supply / total LP tokens supply) < {maxBondingRatio}. +// Op priorities: +// validator: +// - bonded; +// - lowest LP tokens amount; +// account: +// - highest LP tokens balance; +// - enough coins; +func NewDelegateLPOp(period time.Duration, delegateRatio, maxBondingRatio sdk.Dec) *SimOperation { + id := "DelegateLPOp" + checkRatioArg(id, "delegateRatio", delegateRatio) + checkRatioArg(id, "maxBondingRatio", maxBondingRatio) + + handler := func(s *Simulator) (bool, string) { + if delegateOpCheckInput(s, false, maxBondingRatio) { + return true, "" + } + + targetVal, targetAcc, delCoin := delegateOpFindTarget(s, false, delegateRatio) + if targetVal == nil || targetAcc == nil { + return false, "target not found" + } + + if overflow := delegateOpHandle(s, targetVal, targetAcc, delCoin); overflow { + require.False(s.t, overflow) + } + + delegateOpPost(s, targetVal, targetAcc, false) + msg := fmt.Sprintf("%s: %s -> %s", targetAcc.Address, s.FormatCoin(delCoin), targetVal.GetAddress()) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func delegateOpCheckInput(s *Simulator, bondingD bool, maxRatio sdk.Dec) (stop bool) { + pool := s.QueryStakePools() + + var stakingSupply, totalSupply sdk.Int + if bondingD { + stakingSupply = pool.BondedTokens.Add(pool.NotBondedTokens) + totalSupply = s.QuerySupplyTotal().AmountOf(s.stakingDenom) + } else { + stakingSupply = pool.LiquidityTokens + totalSupply = s.QuerySupplyTotal().AmountOf(s.lpDenom) + } + + // check staking pool total supply to all tokens supply ratio + curRatio := stakingSupply.ToDec().Quo(totalSupply.ToDec()) + + return curRatio.GT(maxRatio) +} + +func delegateOpFindTarget(s *Simulator, bondingD bool, delegateRatio sdk.Dec) (targetVal *SimValidator, targetAcc *SimAccount, delCoin sdk.Coin) { + denom := s.stakingDenom + if !bondingD { + denom = s.lpDenom + } + + // pick a bonded validator with the lowest tokens amount + validators := s.GetValidators(true, false, false).GetSortedByTokens(bondingD, false) + if len(validators) == 0 { + return + } + targetVal = validators[0] + + // pick an account with max tokens + var delAmt sdk.Int + for _, acc := range s.GetAllAccounts().GetSortedByBalance(denom, true) { + // estimate delegation amount + accCoinAmtDec := sdk.NewDecFromInt(acc.Coins.AmountOf(denom)) + delAmt = accCoinAmtDec.Mul(delegateRatio).TruncateInt() + if delAmt.IsZero() { + continue + } + + targetAcc = acc + delCoin = sdk.NewCoin(denom, delAmt) + } + + return +} + +func delegateOpHandle(s *Simulator, targetVal *SimValidator, targetAcc *SimAccount, delCoin sdk.Coin) (stop bool) { + overflow := s.TxStakeDelegate(targetAcc, targetVal, delCoin) + if overflow { + stop = true + } + + return +} + +func delegateOpPost(s *Simulator, targetVal *SimValidator, targetAcc *SimAccount, bondingD bool) { + // update account + s.UpdateAccount(targetAcc) + // update validator + s.UpdateValidator(targetVal) + // update stats + if bondingD { + s.counter.BDelegations++ + } else { + s.counter.LPDelegations++ + } +} diff --git a/helpers/tests/simulator/sim_ops_redelegate.go b/helpers/tests/simulator/sim_ops_redelegate.go new file mode 100644 index 00000000..03f62115 --- /dev/null +++ b/helpers/tests/simulator/sim_ops_redelegate.go @@ -0,0 +1,172 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewRedelegateBondingOp picks a validator and redelegate bonding tokens to an other validator. +// Redelegation amount = current account delegation amount * {redelegateRatio}. +// Op priorities: +// dstValidator: +// - bonded; +// - lowest bonding tokens amount; +// srcValidator - highest account delegation bonding shares; +// account: +// - random; +// - has no active redelegations with srcValidator and dstValidator; +// - has enough bonding coins; +// - not a dstValidator owner; +func NewRedelegateBondingOp(period time.Duration, redelegateRatio sdk.Dec) *SimOperation { + id := "RedelegateBondingOp" + checkRatioArg(id, "redelegateRatio", redelegateRatio) + + handler := func(s *Simulator) (bool, string) { + targetAcc, srcValidator, dstValidator, rdCoin := redelegateOpFindTarget(s, true, redelegateRatio) + if srcValidator == nil || dstValidator == nil { + return false, "target not found" + } + redelegateOpHandle(s, targetAcc, srcValidator, dstValidator, rdCoin) + + redelegateOpPost(s, targetAcc, srcValidator, dstValidator, true) + msg := fmt.Sprintf("%s: %s -> %s -> %s", targetAcc.Address, srcValidator.GetAddress(), s.FormatCoin(rdCoin), dstValidator.GetAddress()) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +// NewRedelegateLPOp picks a validator and redelegate LP tokens to an other validator. +// Redelegation amount = current account delegation amount * {redelegateRatio}. +// Op priorities: +// dstValidator: +// - bonded; +// - lowest LP tokens amount; +// srcValidator - highest account delegation LP shares; +// account: +// - random; +// - has no active redelegations with srcValidator and dstValidator; +// - has enough LP coins; +// - not a dstValidator owner; +func NewRedelegateLPOp(period time.Duration, redelegateRatio sdk.Dec) *SimOperation { + id := "RedelegateLPOp" + checkRatioArg(id, "redelegateRatio", redelegateRatio) + + handler := func(s *Simulator) (bool, string) { + targetAcc, srcValidator, dstValidator, rdCoin := redelegateOpFindTarget(s, false, redelegateRatio) + if srcValidator == nil || dstValidator == nil { + return false, "target not found" + } + redelegateOpHandle(s, targetAcc, srcValidator, dstValidator, rdCoin) + + redelegateOpPost(s, targetAcc, srcValidator, dstValidator, false) + msg := fmt.Sprintf("%s: %s -> %s -> %s", targetAcc.Address, srcValidator.GetAddress(), s.FormatCoin(rdCoin), dstValidator.GetAddress()) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func redelegateOpFindTarget(s *Simulator, bondingRD bool, rdRatio sdk.Dec) (targetAcc *SimAccount, srcValidator, dstValidator *SimValidator, rdCoin sdk.Coin) { + denom := s.stakingDenom + if !bondingRD { + denom = s.lpDenom + } + + // pick a bonded dstValidator with the lowest tokens amount + validators := s.GetValidators(true, false, false).GetSortedByTokens(bondingRD, false) + if len(validators) == 0 { + return + } + dstValidator = validators[0] + + rdInProgress := func(accAddr sdk.AccAddress, srcValAddr, dstValAddr sdk.ValAddress) bool { + for _, rd := range s.QueryStakeRedelegations(accAddr, sdk.ValAddress{}, sdk.ValAddress{}) { + if rd.ValidatorSrcAddress.Equals(srcValAddr) || rd.ValidatorDstAddress.Equals(srcValAddr) { + return true + } + + if rd.ValidatorSrcAddress.Equals(dstValAddr) || rd.ValidatorDstAddress.Equals(dstValAddr) { + return true + } + } + return false + } + + // pick a target account + for _, acc := range s.GetAllAccounts().GetShuffled() { + accValAddr := sdk.ValAddress{} + if acc.IsValOperator() { + accValAddr = acc.OperatedValidator.GetAddress() + } + + // check not redelegating to the account owned validator + if dstValidator.GetAddress().Equals(accValAddr) { + continue + } + + // pick a delegation with the highest share + for _, delegation := range acc.GetSortedDelegations(bondingRD, true) { + srcValidatorApplicant := validators.GetByAddress(delegation.ValidatorAddress) + + // check if applicant was found (that validator can be unbonded by now) + if srcValidatorApplicant == nil { + continue + } + + // check not the one picked above + if srcValidatorApplicant.GetAddress().Equals(dstValidator.GetAddress()) { + continue + } + + // check not redelegating from the account owned validator + if srcValidatorApplicant.GetAddress().Equals(accValAddr) { + continue + } + + // check if an other redelegation is in progress for the selected account + if rdInProgress(acc.Address, srcValidatorApplicant.GetAddress(), dstValidator.GetAddress()) { + continue + } + + // estimate redelegation amount + rdAmtDec := sdk.NewDecFromInt(delegation.BondingBalance.Amount) + if !bondingRD { + rdAmtDec = sdk.NewDecFromInt(delegation.LPBalance.Amount) + } + rdAmt := rdAmtDec.Mul(rdRatio).TruncateInt() + if rdAmt.IsZero() { + continue + } + + targetAcc = acc + srcValidator = srcValidatorApplicant + rdCoin = sdk.NewCoin(denom, rdAmt) + return + } + } + + return +} + +func redelegateOpHandle(s *Simulator, targetAcc *SimAccount, srcValidator, dstValidator *SimValidator, rdCoin sdk.Coin) { + s.TxStakeRedelegate(targetAcc, srcValidator.GetAddress(), dstValidator.GetAddress(), rdCoin) +} + +func redelegateOpPost(s *Simulator, targetAcc *SimAccount, srcValidator, dstValidator *SimValidator, bondingRD bool) { + // update validators + s.UpdateValidator(srcValidator) + s.UpdateValidator(dstValidator) + // update account + s.UpdateAccount(targetAcc) + // update stats + if bondingRD { + s.counter.BRedelegations++ + } else { + s.counter.LPRedelegations++ + } +} diff --git a/helpers/tests/simulator/sim_ops_rewards_delegator.go b/helpers/tests/simulator/sim_ops_rewards_delegator.go new file mode 100644 index 00000000..f75f8821 --- /dev/null +++ b/helpers/tests/simulator/sim_ops_rewards_delegator.go @@ -0,0 +1,78 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewGetDelegatorRewardOp takes delegator rewards. +// Op priority: +// account; +// - random; +// - has delegations; +// validator +// - random account delegation; +// - rewards are not locked; +func NewGetDelegatorRewardOp(period time.Duration) *SimOperation { + id := "DelegatorRewardOp" + + handler := func(s *Simulator) (bool, string) { + targetAcc, targetVal, rewardCoins := getDelegatorRewardOpFindTarget(s) + if targetAcc == nil || targetVal == nil { + return false, "target not found" + } + getDelegatorRewardOpHandle(s, targetAcc, targetVal) + + getDelegatorRewardOpPost(s, targetAcc, rewardCoins) + msg := fmt.Sprintf("%s from %s: %s", targetAcc.Address, targetVal.GetAddress(), s.FormatCoins(rewardCoins)) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func getDelegatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator, rewardCoins sdk.Coins) { + rewardCoins = sdk.NewCoins() + validators := s.GetAllValidators() + + for _, acc := range s.GetAllAccounts().GetShuffled() { + for _, delegation := range acc.GetShuffledDelegations(true) { + validator := validators.GetByAddress(delegation.ValidatorAddress) + if validator.RewardsLocked() { + continue + } + + // estimate reward coins + for _, decCoin := range s.QueryDistDelReward(acc.Address, delegation.ValidatorAddress) { + coin, _ := decCoin.TruncateDecimal() + rewardCoins = rewardCoins.Add(coin) + } + + // check there are some rewards + if rewardCoins.Empty() { + continue + } + + targetAcc = acc + targetVal = validator + return + } + } + + return +} + +func getDelegatorRewardOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator) { + s.TxDistDelegatorRewards(targetAcc, targetVal.GetAddress()) +} + +func getDelegatorRewardOpPost(s *Simulator, targetAcc *SimAccount, rewardCoins sdk.Coins) { + // update account + s.UpdateAccount(targetAcc) + // update stats + s.counter.Rewards++ + s.counter.RewardsCollected = s.counter.RewardsCollected.Add(rewardCoins...) +} diff --git a/helpers/tests/simulator/sim_ops_rewards_lock.go b/helpers/tests/simulator/sim_ops_rewards_lock.go new file mode 100644 index 00000000..f97cbcf2 --- /dev/null +++ b/helpers/tests/simulator/sim_ops_rewards_lock.go @@ -0,0 +1,76 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewGetValidatorRewardOp takes validator commissions rewards. +// Op priority: +// validator - random; +func NewLockValidatorRewardsOp(period time.Duration, maxLockedRatio sdk.Dec) *SimOperation { + id := "LockValidatorRewardsOp" + + handler := func(s *Simulator) (bool, string) { + if lockValidatorRewardsOpCheckInput(s, maxLockedRatio) { + return true, "" + } + + targetAcc, targetVal := lockValidatorRewardsOpFindTarget(s) + if targetAcc == nil || targetVal == nil { + return false, "target not found" + } + lockValidatorRewardsOpHandle(s, targetAcc, targetVal) + + lockValidatorRewardsOpPost(s, targetVal) + msg := fmt.Sprintf("%s for %s", targetVal.GetAddress(), targetAcc.Address) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func lockValidatorRewardsOpCheckInput(s *Simulator, maxRatio sdk.Dec) (stop bool) { + // check current locked ratio + validators := s.GetValidators(true, false, false) + locked := len(validators.GetLocked()) + total := len(validators) + + curRatio := sdk.NewDec(int64(locked)).Quo(sdk.NewDec(int64(total))) + if curRatio.GT(maxRatio) { + stop = true + return + } + + return +} + +func lockValidatorRewardsOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator) { + for _, val := range s.GetAllValidators().GetShuffled() { + if val.RewardsLocked() { + continue + } + + targetAcc = s.GetAllAccounts().GetByAddress(val.GetOperatorAddress()) + targetVal = val + break + } + + return +} + +func lockValidatorRewardsOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator) { + // lock and disable auto-renewal + s.TxDistLockRewards(targetAcc, targetVal.GetAddress()) + s.TxDistDisableAutoRenewal(targetAcc, targetVal.GetAddress()) +} + +func lockValidatorRewardsOpPost(s *Simulator, targetVal *SimValidator) { + // update validator + s.UpdateValidator(targetVal) + // update stats + s.counter.LockedRewards++ +} diff --git a/helpers/tests/simulator/sim_ops_rewards_validator.go b/helpers/tests/simulator/sim_ops_rewards_validator.go new file mode 100644 index 00000000..1cfcb9e3 --- /dev/null +++ b/helpers/tests/simulator/sim_ops_rewards_validator.go @@ -0,0 +1,73 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewGetValidatorRewardOp takes validator commissions rewards. +// Op priority: +// validator - random; +func NewGetValidatorRewardOp(period time.Duration) *SimOperation { + id := "ValidatorRewardOp" + + handler := func(s *Simulator) (bool, string) { + targetAcc, targetVal, rewardCoins := getValidatorRewardOpFindTarget(s) + if targetAcc == nil || targetVal == nil { + return false, "target not found" + } + + if getValidatorRewardOpHandle(s, targetAcc, targetVal) { + msg := fmt.Sprintf("can't withdraw %s validator commission", targetVal.GetAddress()) + return false, msg + } + + getValidatorRewardOpPost(s, targetAcc, rewardCoins) + msg := fmt.Sprintf("%s for %s: %s", targetVal.GetAddress(), targetAcc.Address, s.FormatCoins(rewardCoins)) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func getValidatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator, rewardCoins sdk.Coins) { + rewardCoins = sdk.NewCoins() + + for _, val := range s.GetAllValidators().GetShuffled() { + // check there are some commission rewards available + decCoins := s.QueryDistValCommission(val.GetAddress()) + if decCoins.Empty() { + continue + } + + // estimate reward coins + for _, decCoin := range decCoins { + coin, _ := decCoin.TruncateDecimal() + rewardCoins = rewardCoins.Add(coin) + } + + targetVal = val + targetAcc = s.GetAllAccounts().GetByAddress(targetVal.GetOperatorAddress()) + } + + return +} + +func getValidatorRewardOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator) (stop bool) { + if s.TxDistValidatorCommission(targetAcc, targetVal.GetAddress()) { + stop = true + } + + return +} + +func getValidatorRewardOpPost(s *Simulator, targetAcc *SimAccount, rewardCoins sdk.Coins) { + // update account + s.UpdateAccount(targetAcc) + // update stats + s.counter.Commissions++ + s.counter.CommissionsCollected = s.counter.CommissionsCollected.Add(rewardCoins...) +} diff --git a/helpers/tests/simulator/sim_ops_undelegate.go b/helpers/tests/simulator/sim_ops_undelegate.go new file mode 100644 index 00000000..ed41b3bc --- /dev/null +++ b/helpers/tests/simulator/sim_ops_undelegate.go @@ -0,0 +1,134 @@ +package simulator + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewUndelegateBondingOp picks a validator and undelegates bonding tokens. +// Undelegation amount = current account delegation amount * {undelegateRatio}. +// Op priorities: +// validator - highest bonding tokens amount (all statuses); +// account: +// - random; +// - has a validators bonding delegation; +// - not a validator owner; +func NewUndelegateBondingOp(period time.Duration, undelegateRatio sdk.Dec) *SimOperation { + id := "UndelegateBondingOp" + checkRatioArg(id, "undelegateRatio", undelegateRatio) + + handler := func(s *Simulator) (bool, string) { + targetAcc, targetVal, udCoin := undelegateOpFindTarget(s, true, undelegateRatio) + if targetAcc == nil || targetVal == nil { + return false, "target not found" + } + undelegateOpHandle(s, targetAcc, targetVal, udCoin) + + undelegateOpPost(s, targetAcc, targetVal, true) + msg := fmt.Sprintf("%s: %s -> %s", targetAcc.Address, targetVal.GetAddress(), s.FormatCoin(udCoin)) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +// NewUndelegateLPOp picks a validator and undelegates LP tokens. +// Undelegation amount = current account delegation amount * {undelegateRatio}. +// Op priorities: +// validator - highest LP tokens amount (all statuses); +// account: +// - random; +// - has a validators LP delegation; +// - not a validator owner; +func NewUndelegateLPOp(period time.Duration, undelegateRatio sdk.Dec) *SimOperation { + id := "UndelegateLPOp" + checkRatioArg(id, "undelegateRatio", undelegateRatio) + + handler := func(s *Simulator) (bool, string) { + targetAcc, targetVal, udCoin := undelegateOpFindTarget(s, false, undelegateRatio) + if targetAcc == nil || targetVal == nil { + return false, "target not found" + } + undelegateOpHandle(s, targetAcc, targetVal, udCoin) + + undelegateOpPost(s, targetAcc, targetVal, false) + msg := fmt.Sprintf("%s: %s -> %s", targetAcc.Address, targetVal.GetAddress(), s.FormatCoin(udCoin)) + + return true, msg + } + + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) +} + +func undelegateOpFindTarget(s *Simulator, bondingUD bool, udRatio sdk.Dec) (targetAcc *SimAccount, targetVal *SimValidator, udCoin sdk.Coin) { + denom := s.stakingDenom + if !bondingUD { + denom = s.lpDenom + } + + // pick a validator with the highest tokens amount (all statuses) + for _, val := range s.GetAllValidators().GetSortedByTokens(bondingUD, true) { + // pick a random account + for _, acc := range s.GetAllAccounts().GetShuffled() { + accValAddr := sdk.ValAddress{} + if acc.IsValOperator() { + accValAddr = acc.OperatedValidator.GetAddress() + } + + // pick a corresponding delegation (targetValidator) + for _, delegation := range acc.Delegations { + // check if account did delegate to the selected validator + if !val.GetAddress().Equals(delegation.ValidatorAddress) { + continue + } + + // check not undelegating from the account owned validator + if accValAddr.Equals(val.GetAddress()) { + continue + } + + // estimate undelegation amount + udAmtDec := sdk.NewDecFromInt(delegation.BondingBalance.Amount) + if !bondingUD { + udAmtDec = sdk.NewDecFromInt(delegation.LPBalance.Amount) + } + + udAmt := udAmtDec.Mul(udRatio).TruncateInt() + if udAmt.IsZero() { + continue + } + + targetAcc = acc + targetVal = val + udCoin = sdk.NewCoin(denom, udAmt) + return + } + } + } + + return +} + +func undelegateOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator, udCoin sdk.Coin) { + s.TxStakeUndelegate(targetAcc, targetVal.GetAddress(), udCoin) +} + +func undelegateOpPost(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator, bondingUD bool) { + // update validator + s.UpdateValidator(targetVal) + // update account + s.UpdateAccount(targetAcc) + // update stats + if bondingUD { + s.counter.BUndelegations++ + } else { + s.counter.LPUndelegations++ + } + + s.defferQueue.Add(s.prevBlockTime.Add(s.unbondingDur+5*time.Minute), func() { + s.UpdateAccount(targetAcc) + }) +} diff --git a/helpers/tests/simulator/sim_options.go b/helpers/tests/simulator/sim_options.go index 68de2ebd..00e01f97 100644 --- a/helpers/tests/simulator/sim_options.go +++ b/helpers/tests/simulator/sim_options.go @@ -44,7 +44,7 @@ func OperationsOption(ops ...*SimOperation) SimOption { } } -func GenerateWalletAccountsOption(walletsQuantity, poaValidatorsQuantity, tmValidatorQuantity uint, genCoins sdk.Coins) SimOption { +func GenerateWalletAccountsOption(walletsQuantity, poaValidatorsQuantity uint, genCoins sdk.Coins) SimOption { return func(s *Simulator) { for i := uint(0); i < walletsQuantity; i++ { acc := &SimAccount{ @@ -55,9 +55,6 @@ func GenerateWalletAccountsOption(walletsQuantity, poaValidatorsQuantity, tmVali acc.IsPoAValidator = true poaValidatorsQuantity-- } - if tmValidatorQuantity > 0 { - acc.CreateValidator = true - } s.accounts = append(s.accounts, acc) } @@ -70,35 +67,35 @@ func NodeValidatorConfigOption(config SimValidatorConfig) SimOption { } } -func MintParamsOption(params mint.Params) SimOption { +func MintParamsOption(modifier func(state *mint.GenesisState)) SimOption { return func(s *Simulator) { state := mint.GenesisState{} stateBz := s.genesisState[mint.ModuleName] s.cdc.MustUnmarshalJSON(stateBz, &state) - state.Params = params + modifier(&state) s.genesisState[mint.ModuleName] = s.cdc.MustMarshalJSON(state) } } -func StakingParamsOption(params staking.Params) SimOption { +func StakingParamsOption(modifier func(state *staking.GenesisState)) SimOption { return func(s *Simulator) { state := staking.GenesisState{} stateBz := s.genesisState[staking.ModuleName] s.cdc.MustUnmarshalJSON(stateBz, &state) - state.Params = params + modifier(&state) s.genesisState[staking.ModuleName] = s.cdc.MustMarshalJSON(state) } } -func DistributionParamsOption(params distribution.Params) SimOption { +func DistributionParamsOption(modifier func(state *distribution.GenesisState)) SimOption { return func(s *Simulator) { state := distribution.GenesisState{} stateBz := s.genesisState[distribution.ModuleName] s.cdc.MustUnmarshalJSON(stateBz, &state) - state.Params = params + modifier(&state) s.genesisState[distribution.ModuleName] = s.cdc.MustMarshalJSON(state) } } diff --git a/helpers/tests/simulator/sim_queries.go b/helpers/tests/simulator/sim_queries.go index 1e6bbcc6..2602660a 100644 --- a/helpers/tests/simulator/sim_queries.go +++ b/helpers/tests/simulator/sim_queries.go @@ -261,8 +261,8 @@ func (s *Simulator) QueryDistDelRewards(acc sdk.AccAddress) (res distribution.Qu return } -// QueryDistrValCommission queries current validator commission rewards. -func (s *Simulator) QueryDistrValCommission(val sdk.ValAddress) (res distribution.ValidatorAccumulatedCommission) { +// QueryDistValCommission queries current validator commission rewards. +func (s *Simulator) QueryDistValCommission(val sdk.ValAddress) (res distribution.ValidatorAccumulatedCommission) { resp := s.RunQuery( distribution.QueryValidatorCommissionParams{ ValidatorAddress: val, @@ -275,6 +275,20 @@ func (s *Simulator) QueryDistrValCommission(val sdk.ValAddress) (res distributio return res } +// QueryDistLockState queries current validator locked rewards state. +func (s *Simulator) QueryDistLockState(val sdk.ValAddress) (res distribution.QueryLockedRewardsStateResponse) { + resp := s.RunQuery( + distribution.QueryLockedRewardsStateParams{ + ValidatorAddress: val, + }, + "/custom/"+distribution.QuerierRoute+"/"+distribution.QueryLockedRewardsState, + &res, + ) + require.True(s.t, resp.IsOK()) + + return res +} + // QueryDistPool queries supply total supply. func (s *Simulator) QuerySupplyTotal() (res sdk.Coins) { resp := s.RunQuery( diff --git a/helpers/tests/simulator/sim_report.go b/helpers/tests/simulator/sim_report.go index 16f7aedf..2078e42a 100644 --- a/helpers/tests/simulator/sim_report.go +++ b/helpers/tests/simulator/sim_report.go @@ -25,6 +25,7 @@ type SimReportItem struct { // StakingBonded sdk.Int // bonded tokens (staking pool) StakingNotBonded sdk.Int // not bonded tokens (staking pool) + StakingLPs sdk.Int // bonded LP tokens (LPs pool) RedelegationsInProcess int // redelegations in progress // MintMinInflation sdk.Dec // annual min inflation @@ -39,20 +40,24 @@ type SimReportItem struct { // SupplyTotalMain sdk.Int // total supply [main denom] SupplyTotalStaking sdk.Int // total supply [staking denom] + SupplyTotalLP sdk.Int // total supply [LP denom] // StatsBondedRatio sdk.Dec // BondedTokens / TotalSupply ratio [staking denom] + StatsLPRatio sdk.Dec // BondedTokens / TotalSupply ratio [LP denom] // Counters Counter // - formatIntDecimals func(value sdk.Int) string - formatDecDecimals func(value sdk.Dec) string + formatIntDecimals func(value sdk.Int) string + formatDecDecimals func(value sdk.Dec) string + formatCoinsDecimals func(coins sdk.Coins) string } // NewReportOp captures report. func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) *SimOperation { + id := "ReportOp" reportItemIdx := 1 - handler := func(s *Simulator) bool { + handler := func(s *Simulator) (bool, string) { // gather the data // simulation @@ -102,6 +107,7 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * // StakingBonded: stakingPool.BondedTokens, StakingNotBonded: stakingPool.NotBondedTokens, + StakingLPs: stakingPool.LiquidityTokens, RedelegationsInProcess: acitveRedelegations, // MintMinInflation: mintParams.InflationMin, @@ -116,6 +122,7 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * // SupplyTotalMain: totalSupply.AmountOf(s.mainDenom), SupplyTotalStaking: totalSupply.AmountOf(s.stakingDenom), + SupplyTotalLP: totalSupply.AmountOf(s.lpDenom), // Counters: s.counter, // @@ -125,10 +132,14 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * formatDecDecimals: func(value sdk.Dec) string { return s.FormatDecDecimals(value, s.mainAmountDecimalsRatio) }, + formatCoinsDecimals: func(coins sdk.Coins) string { + return s.FormatCoins(coins) + }, } // calculate statistics - item.StatsBondedRatio = sdk.NewDecFromInt(item.StakingBonded).Quo(sdk.NewDecFromInt(item.SupplyTotalStaking)) + item.StatsBondedRatio = sdk.NewDecFromInt(item.StakingBonded.Add(item.StakingNotBonded)).Quo(sdk.NewDecFromInt(item.SupplyTotalStaking)) + item.StatsLPRatio = sdk.NewDecFromInt(item.StakingLPs).Quo(sdk.NewDecFromInt(item.SupplyTotalLP)) reportItemIdx++ for _, writer := range writers { @@ -140,10 +151,10 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * fmt.Println(debugItem.String()) } - return true + return true, "" } - return NewSimOperation(period, NewPeriodicNextExecFn(), handler) + return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) } type SimReportConsoleWriter struct { @@ -175,15 +186,23 @@ func (w *SimReportConsoleWriter) Write(item SimReportItem) { str.WriteString(fmt.Sprintf(" Dist: HARP: %s\n", item.formatDecDecimals(item.DistHARP))) str.WriteString(fmt.Sprintf(" Supply: TotalMain: %s\n", item.formatIntDecimals(item.SupplyTotalMain))) str.WriteString(fmt.Sprintf(" Supply: TotalStaking: %s\n", item.formatIntDecimals(item.SupplyTotalStaking))) - str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply: %s\n", item.StatsBondedRatio)) + str.WriteString(fmt.Sprintf(" Supply: LPs: %s\n", item.formatIntDecimals(item.SupplyTotalLP))) + str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply [B]: %s\n", item.StatsBondedRatio)) + str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply [LP]: %s\n", item.StatsLPRatio)) str.WriteString(" Counters:\n") - str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.Delegations)) - str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.Redelegations)) - str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.Undelegations)) + str.WriteString(" Bonding:\n") + str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.BDelegations)) + str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.BRedelegations)) + str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.BUndelegations)) + str.WriteString(" LP:\n") + str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.LPDelegations)) + str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.LPRedelegations)) + str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.LPUndelegations)) str.WriteString(fmt.Sprintf(" Rewards: %d\n", item.Counters.Rewards)) - str.WriteString(fmt.Sprintf(" RewardsCollected: %s\n", item.formatIntDecimals(item.Counters.RewardsCollected))) + str.WriteString(fmt.Sprintf(" RewardsCollected: %s\n", item.formatCoinsDecimals(item.Counters.RewardsCollected))) str.WriteString(fmt.Sprintf(" Commissions: %d\n", item.Counters.Commissions)) - str.WriteString(fmt.Sprintf(" CommissionsCollected: %s\n", item.formatIntDecimals(item.Counters.CommissionsCollected))) + str.WriteString(fmt.Sprintf(" CommissionsCollected: %s\n", item.formatCoinsDecimals(item.Counters.CommissionsCollected))) + str.WriteString(fmt.Sprintf(" Locked rewards: %d\n", item.Counters.LockedRewards)) fmt.Println(str.String()) } @@ -200,27 +219,22 @@ func NewSimReportConsoleWriter() *SimReportConsoleWriter { // 1.2.1 years -> 1 year, 2 months and 1 week // 5.30 hours -> 5 hours and 30 minutes func FormatDuration(dur time.Duration) string { - const ( - dayDur = 24 * time.Hour - weekDur = 7 * dayDur - monthDur = 4 * weekDur - yearDur = 12 * monthDur - ) - dur = dur.Round(time.Minute) - years := dur / yearDur - dur -= years * yearDur - months := dur / monthDur - dur -= months * monthDur - weeks := dur / weekDur - dur -= weeks * weekDur + years := dur / Year + dur -= years * Year + months := dur / Month + dur -= months * Month + weeks := dur / Week + dur -= weeks * Week + days := dur / Day + dur -= days * Day hours := dur / time.Hour dur -= hours * time.Hour mins := dur / time.Minute str := strings.Builder{} - str.WriteString(fmt.Sprintf("%d.%d.%d years ", years, months, weeks)) + str.WriteString(fmt.Sprintf("%d years %d months %d weeks %d days ", years, months, weeks, days)) str.WriteString(fmt.Sprintf("%d.%d hours", hours, mins)) return str.String() diff --git a/helpers/tests/simulator/sim_report_csv.go b/helpers/tests/simulator/sim_report_csv.go index 989c207c..c1a08aa7 100644 --- a/helpers/tests/simulator/sim_report_csv.go +++ b/helpers/tests/simulator/sim_report_csv.go @@ -24,6 +24,7 @@ var Headers = []string{ "Validators: Unbonded", "Staking: Bonded", "Staking: NotBonded", + "Staking: LPs", "Staking: ActiveRedelegations", "Mint: MinInflation", "Mint: MaxInflation", @@ -35,14 +36,20 @@ var Headers = []string{ "Dist: HARP", "Supply: Total [main]", "Supply: Total [staking]", - "Stats: Bonded/TotalSupply", - "Counters: Delegations:", - "Counters: Redelegations:", - "Counters: Undelegations:", - "Counters: Rewards:", - "Counters: RewardsCollected:", - "Counters: Commissions:", - "Counters: CommissionsCollected:", + "Supply: Total [LP]", + "Stats: Bonded/TotalSupply [bonding]", + "Stats: Bonded/TotalSupply [LPs]", + "Counters: Bonding: Delegations", + "Counters: Bonding: Redelegations", + "Counters: Bonding: Undelegations", + "Counters: LP: Delegations", + "Counters: LP: Redelegations", + "Counters: LP: Undelegations", + "Counters: Rewards", + "Counters: RewardsCollected", + "Counters: Commissions", + "Counters: CommissionsCollected", + "Counters: LockedRewards", } func NewSimReportCSVWriter(t *testing.T, filePath string) (*SimReportCSVWriter, CSVWriterClose) { @@ -74,6 +81,7 @@ func (w *SimReportCSVWriter) Write(item SimReportItem) { strconv.Itoa(item.ValidatorsUnbonded), item.StakingBonded.String(), item.StakingNotBonded.String(), + item.StakingLPs.String(), strconv.Itoa(item.RedelegationsInProcess), item.MintMinInflation.String(), item.MintMaxInflation.String(), @@ -85,14 +93,20 @@ func (w *SimReportCSVWriter) Write(item SimReportItem) { item.DistHARP.String(), item.SupplyTotalMain.String(), item.SupplyTotalStaking.String(), + item.SupplyTotalLP.String(), item.StatsBondedRatio.String(), - strconv.FormatInt(item.Counters.Delegations, 10), - strconv.FormatInt(item.Counters.Redelegations, 10), - strconv.FormatInt(item.Counters.Undelegations, 10), + item.StatsLPRatio.String(), + strconv.FormatInt(item.Counters.BDelegations, 10), + strconv.FormatInt(item.Counters.BRedelegations, 10), + strconv.FormatInt(item.Counters.BUndelegations, 10), + strconv.FormatInt(item.Counters.LPDelegations, 10), + strconv.FormatInt(item.Counters.LPRedelegations, 10), + strconv.FormatInt(item.Counters.LPUndelegations, 10), strconv.FormatInt(item.Counters.Rewards, 10), item.Counters.RewardsCollected.String(), strconv.FormatInt(item.Counters.Commissions, 10), item.Counters.CommissionsCollected.String(), + strconv.FormatInt(item.Counters.LockedRewards, 10), } _ = w.writer.Write(data) diff --git a/helpers/tests/simulator/sim_report_debug.go b/helpers/tests/simulator/sim_report_debug.go index acac0166..bc34e759 100644 --- a/helpers/tests/simulator/sim_report_debug.go +++ b/helpers/tests/simulator/sim_report_debug.go @@ -78,7 +78,7 @@ func BuildDebugReportItem(s *Simulator) SimDebugReportItem { }) } - for _, acc := range s.GetAccountsSortedByBalance(true) { + for _, acc := range s.GetAllAccounts().GetSortedByBalance(s.stakingDenom, true) { r.Accounts = append(r.Accounts, DebugAccoutData{ Address: acc.Address, MainCoinBalance: acc.Coins.AmountOf(s.mainDenom), diff --git a/helpers/tests/simulator/sim_txs.go b/helpers/tests/simulator/sim_txs.go index 277cbd95..d0f4acbd 100644 --- a/helpers/tests/simulator/sim_txs.go +++ b/helpers/tests/simulator/sim_txs.go @@ -47,6 +47,20 @@ func (s *Simulator) GenTx(msg sdk.Msg, simAcc *SimAccount) auth.StdTx { return s.GenTxAdvanced(msg, acc.GetAccountNumber(), acc.GetSequence(), simAcc.PublicKey, simAcc.PrivateKey) } +// CheckTx checks Tx and parses the result. +func (s *Simulator) CheckTx(tx auth.StdTx, responseValue interface{}) error { + _, res, err := s.app.Check(tx) + if err != nil { + return err + } + + if responseValue != nil { + s.cdc.MustUnmarshalJSON(res.Data, responseValue) + } + + return nil +} + // DeliverTx delivers Tx and parses the result. func (s *Simulator) DeliverTx(tx auth.StdTx, responseValue interface{}) { s.beginBlock() @@ -61,37 +75,48 @@ func (s *Simulator) DeliverTx(tx auth.StdTx, responseValue interface{}) { } } -// TxStakingCreateValidator creates a new validator operated by simAcc with min self delegation. -func (s *Simulator) TxStakingCreateValidator(simAcc *SimAccount, commissions staking.CommissionRates) { +// TxStakeCreateValidator creates a new validator operated by simAcc with min self delegation. +func (s *Simulator) TxStakeCreateValidator(simAcc *SimAccount, commissions staking.CommissionRates) { require.NotNil(s.t, simAcc) - selfDelegation := sdk.NewCoin(s.stakingDenom, s.minSelfDelegationLvl) msg := staking.NewMsgCreateValidator( simAcc.Address.Bytes(), simAcc.PublicKey, - selfDelegation, + s.minSelfDelegationCoin, staking.NewDescription(simAcc.Address.String(), "", "", "", ""), commissions, - s.minSelfDelegationLvl, + s.minSelfDelegationCoin.Amount, ) s.DeliverTx(s.GenTx(msg, simAcc), nil) } -// TxStakingDelegate delegates amount from delegator to validator. -func (s *Simulator) TxStakingDelegate(simAcc *SimAccount, validator *staking.Validator, amount sdk.Coin) { +// TxStakeDelegate delegates amount from delegator to validator. +func (s *Simulator) TxStakeDelegate(simAcc *SimAccount, simVal *SimValidator, amount sdk.Coin) (delegationsOverflow bool) { require.NotNil(s.t, simAcc) - require.NotNil(s.t, validator) + require.NotNil(s.t, simVal) msg := staking.MsgDelegate{ DelegatorAddress: simAcc.Address, - ValidatorAddress: validator.OperatorAddress, + ValidatorAddress: simVal.GetAddress(), Amount: amount, } - s.DeliverTx(s.GenTx(msg, simAcc), nil) + tx := s.GenTx(msg, simAcc) + + if err := s.CheckTx(tx, nil); err != nil { + if staking.ErrMaxDelegationsLimit.Is(err) { + delegationsOverflow = true + return + } + require.NoError(s.t, err) + } + + s.DeliverTx(tx, nil) + + return } -// TxStakingRedelegate redelegates amount from one validator to other. -func (s *Simulator) TxStakingRedelegate(simAcc *SimAccount, valSrc, valDst sdk.ValAddress, amount sdk.Coin) { +// TxStakeRedelegate redelegates amount from one validator to other. +func (s *Simulator) TxStakeRedelegate(simAcc *SimAccount, valSrc, valDst sdk.ValAddress, amount sdk.Coin) { require.NotNil(s.t, simAcc) msg := staking.MsgBeginRedelegate{ @@ -103,8 +128,8 @@ func (s *Simulator) TxStakingRedelegate(simAcc *SimAccount, valSrc, valDst sdk.V s.DeliverTx(s.GenTx(msg, simAcc), nil) } -// TxStakingUndelegate undelegates amount from validator. -func (s *Simulator) TxStakingUndelegate(simAcc *SimAccount, validatorAddr sdk.ValAddress, amount sdk.Coin) { +// TxStakeUndelegate undelegates amount from validator. +func (s *Simulator) TxStakeUndelegate(simAcc *SimAccount, validatorAddr sdk.ValAddress, amount sdk.Coin) { require.NotNil(s.t, simAcc) msg := staking.MsgUndelegate{ @@ -115,8 +140,8 @@ func (s *Simulator) TxStakingUndelegate(simAcc *SimAccount, validatorAddr sdk.Va s.DeliverTx(s.GenTx(msg, simAcc), nil) } -// TxDistributionReward taking reward. -func (s *Simulator) TxDistributionReward(simAcc *SimAccount, validatorAddr sdk.ValAddress) { +// TxDistDelegatorRewards withdraws delegator rewards. +func (s *Simulator) TxDistDelegatorRewards(simAcc *SimAccount, validatorAddr sdk.ValAddress) { require.NotNil(s.t, simAcc) msg := distribution.MsgWithdrawDelegatorReward{ @@ -127,13 +152,48 @@ func (s *Simulator) TxDistributionReward(simAcc *SimAccount, validatorAddr sdk.V s.DeliverTx(s.GenTx(msg, simAcc), nil) } -// TxDistributionReward taking reward. -func (s *Simulator) TxDistributionCommission(simAcc *SimAccount, validatorAddr sdk.ValAddress) { +// TxDistValidatorCommission withdraws validator commission rewards. +func (s *Simulator) TxDistValidatorCommission(simAcc *SimAccount, validatorAddr sdk.ValAddress) (noCommission bool) { require.NotNil(s.t, simAcc) msg := distribution.MsgWithdrawValidatorCommission{ ValidatorAddress: validatorAddr, } + tx := s.GenTx(msg, simAcc) + + if err := s.CheckTx(tx, nil); err != nil { + if distribution.ErrNoValidatorCommission.Is(err) { + noCommission = true + return + } + require.NoError(s.t, err) + } + + s.DeliverTx(s.GenTx(msg, simAcc), nil) + + return +} + +// TxDistLockRewards locks validator rewards. +func (s *Simulator) TxDistLockRewards(simAcc *SimAccount, validatorAddr sdk.ValAddress) { + require.NotNil(s.t, simAcc) + + msg := distribution.MsgLockValidatorRewards{ + ValidatorAddress: validatorAddr, + SenderAddress: simAcc.Address, + } + + s.DeliverTx(s.GenTx(msg, simAcc), nil) +} + +// TxDistDisableAutoRenewal disables validator rewards lock auto-renewal. +func (s *Simulator) TxDistDisableAutoRenewal(simAcc *SimAccount, validatorAddr sdk.ValAddress) { + require.NotNil(s.t, simAcc) + + msg := distribution.MsgDisableLockedRewardsAutoRenewal{ + ValidatorAddress: validatorAddr, + SenderAddress: simAcc.Address, + } s.DeliverTx(s.GenTx(msg, simAcc), nil) } diff --git a/helpers/tests/simulator/sim_validator.go b/helpers/tests/simulator/sim_validator.go index 2d0d017c..01756581 100644 --- a/helpers/tests/simulator/sim_validator.go +++ b/helpers/tests/simulator/sim_validator.go @@ -1,7 +1,138 @@ package simulator -import "github.com/cosmos/cosmos-sdk/x/staking" +import ( + "math/rand" + "sort" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/stretchr/testify/require" +) type SimValidatorConfig struct { Commission staking.CommissionRates } + +type SimValidator struct { + Validator staking.Validator + RewardsLockedUntil time.Time +} + +// GetAddress returns validator address. +func (v *SimValidator) GetAddress() sdk.ValAddress { + return v.Validator.OperatorAddress +} + +// GetOperatorAddress returns validator operator address. +func (v *SimValidator) GetOperatorAddress() sdk.AccAddress { + return sdk.AccAddress(v.Validator.OperatorAddress) +} + +// GetStatus returns validator bonding status. +func (v *SimValidator) GetStatus() sdk.BondStatus { + return v.Validator.Status +} + +// RewardsLocked check if validator rewards are locked. +func (v *SimValidator) RewardsLocked() bool { + return !v.RewardsLockedUntil.IsZero() +} + +// LockRewards updates locked rewards state. +func (v *SimValidator) LockRewards(until time.Time) { + v.RewardsLockedUntil = until +} + +// UnlockRewards updates locked rewards state. +func (v *SimValidator) UnlockRewards() { + v.RewardsLockedUntil = time.Time{} +} + +// NewSimValidator createes a new SimValidator object. +func NewSimValidator(val staking.Validator) *SimValidator { + return &SimValidator{ + Validator: val, + RewardsLockedUntil: time.Time{}, + } +} + +type SimValidators []*SimValidator + +// GetByAddress returns validator by address. +func (v SimValidators) GetByAddress(address sdk.ValAddress) *SimValidator { + for _, val := range v { + if val.GetAddress().Equals(address) { + return val + } + } + + return nil +} + +// GetShuffled returns random sorted validators list. +func (v SimValidators) GetShuffled() SimValidators { + tmpVal := make(SimValidators, len(v)) + copy(tmpVal, v) + + for i := range tmpVal { + j := rand.Intn(i + 1) + tmpVal[i], tmpVal[j] = tmpVal[j], tmpVal[i] + } + + return tmpVal +} + +// GetSortedByTokens returns validators list sorted by tokens amount. +func (v SimValidators) GetSortedByTokens(bondingTokens, desc bool) SimValidators { + tmpVals := make(SimValidators, len(v)) + copy(tmpVals, v) + + sort.Slice(tmpVals, func(i, j int) bool { + if bondingTokens { + if tmpVals[i].Validator.GetBondingTokens().GT(tmpVals[j].Validator.GetBondingTokens()) { + return desc + } + return !desc + } + + if tmpVals[i].Validator.GetLPTokens().GT(tmpVals[j].Validator.GetLPTokens()) { + return desc + } + return !desc + }) + + return tmpVals +} + +// GetLocked returns validators list with locked rewards. +func (v SimValidators) GetLocked() SimValidators { + tmpVals := make(SimValidators, 0, len(v)) + for _, val := range v { + if val.RewardsLocked() { + tmpVals = append(tmpVals, val) + } + } + + return tmpVals +} + +// UpdateValidator updates validator status. +func (s *Simulator) UpdateValidator(val *SimValidator) { + require.NotNil(s.t, val) + + updVal := s.QueryStakeValidator(val.GetAddress()) + val.Validator.Status = updVal.Status + val.Validator.Jailed = updVal.Jailed + val.Validator.Bonding = updVal.Bonding + val.Validator.LP = updVal.LP + val.Validator.UnbondingHeight = updVal.UnbondingHeight + val.Validator.UnbondingCompletionTime = updVal.UnbondingCompletionTime + + updLState := s.QueryDistLockState(val.GetAddress()) + if updLState.Enabled { + val.LockRewards(updLState.UnlocksAt) + } else { + val.UnlockRewards() + } +} diff --git a/x/ccstorage/internal/types/genesis.go b/x/ccstorage/internal/types/genesis.go index d17ac0b4..9737f607 100644 --- a/x/ccstorage/internal/types/genesis.go +++ b/x/ccstorage/internal/types/genesis.go @@ -72,6 +72,10 @@ func DefaultGenesisState() GenesisState { Denom: "btc", Decimals: 8, }, + { + Denom: "lpt", + Decimals: 18, + }, }, } diff --git a/x/core/ante_decor_common.go b/x/core/ante_decor_common.go index ef8b643e..a0171a0d 100644 --- a/x/core/ante_decor_common.go +++ b/x/core/ante_decor_common.go @@ -6,12 +6,12 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/vmauth" ) var ( - DefaultFees = sdk.Coins{sdk.NewCoin(config.MainDenom, sdk.NewInt(1))} + DefaultFees = sdk.Coins{sdk.NewCoin(defaults.MainDenom, sdk.NewInt(1))} // simulation signature values used to estimate gas consumption simSecp256k1Pubkey secp256k1.PubKeySecp256k1 simSecp256k1Sig [64]byte diff --git a/x/core/ante_decor_denom.go b/x/core/ante_decor_denom.go index 3133bd9d..97e99569 100644 --- a/x/core/ante_decor_denom.go +++ b/x/core/ante_decor_denom.go @@ -5,7 +5,7 @@ import ( sdkErrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/dfinance/dnode/cmd/config" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" ) // DenomDecorator catches and prevents transactions without fees and fees not in "xfi" currency @@ -30,7 +30,7 @@ func (dd DenomDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, n } if !stdTx.Fee.Amount.DenomsSubsetOf(DefaultFees) { - return auth.SetGasMeter(simulate, ctx, 0), sdkErrors.Wrap(ErrWrongFeeDenom, config.MainDenom) + return auth.SetGasMeter(simulate, ctx, 0), sdkErrors.Wrap(ErrWrongFeeDenom, defaults.MainDenom) } } From 2494e111e719df074f10de8540e5518a49f22c01 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Wed, 7 Oct 2020 15:15:35 +0300 Subject: [PATCH 02/20] genesis: PublicTreasuryPool capacity default value fix; DVM stdlib v0.7 update (#213) (cherry picked from commit 4096f033da617b6403c281aa3091b48b6c105d09) --- .../genesis/defaults/common_defaults.go | 27 +++++--- cmd/config/genesis/genesis.go | 3 +- x/vm/internal/keeper/genesis_ws.json | 61 ++++++++++--------- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/cmd/config/genesis/defaults/common_defaults.go b/cmd/config/genesis/defaults/common_defaults.go index 1a86cf13..5c29507a 100644 --- a/cmd/config/genesis/defaults/common_defaults.go +++ b/cmd/config/genesis/defaults/common_defaults.go @@ -11,19 +11,26 @@ const ( StakingDenom = "sxfi" LiquidityProviderDenom = "lpt" - FeeAmount = "100000000000000" // 0.0001 - GovMinDepositAmount = "1000000000000000000000" // 1000.0 + // Min TX fee + FeeAmount = "100000000000000" // 0.0001 + // Governance: deposit amount + GovMinDepositAmount = "1000000000000000000000" // 1000.0 + // Staking: min self-delegation amount MinSelfDelegationAmount = "2500000000000000000000" // 2500.0 - InvariantCheckAmount = "1000000000000000000000" // 1000.0 + // Crisis: invariants check TX fee + InvariantCheckAmount = "1000000000000000000000" // 1000.0 + // Distribution: PublicTreasuryPool capacity + PublicTreasuryPoolAmount = "250000000000000000000000" // 250000.0 MaxGas = 10000000 ) var ( - FeeCoin sdk.Coin - GovMinDepositCoin sdk.Coin - MinSelfDelegationCoin sdk.Coin - InvariantCheckCoin sdk.Coin + FeeCoin sdk.Coin + GovMinDepositCoin sdk.Coin + MinSelfDelegationCoin sdk.Coin + InvariantCheckCoin sdk.Coin + PublicTreasuryPoolCapacity sdk.Int ) func init() { @@ -50,4 +57,10 @@ func init() { } else { InvariantCheckCoin = sdk.NewCoin(MainDenom, value) } + + if value, ok := sdk.NewIntFromString(PublicTreasuryPoolAmount); !ok { + panic("distribution defaults: PublicTreasuryPoolAmount conversion failed") + } else { + PublicTreasuryPoolCapacity = value + } } diff --git a/cmd/config/genesis/genesis.go b/cmd/config/genesis/genesis.go index 6d6e214d..85ea04be 100644 --- a/cmd/config/genesis/genesis.go +++ b/cmd/config/genesis/genesis.go @@ -67,7 +67,7 @@ func OverrideGenesisStateDefaults(cdc *codec.Codec, genState map[string]json.Raw moduleState.Params.PublicTreasuryPoolTax = sdk.NewDecWithPrec(15, 3) // 1.5% moduleState.Params.HARPTax = sdk.NewDecWithPrec(2, 2) // 2% // - moduleState.Params.PublicTreasuryPoolCapacity = sdk.NewInt(250000) // 250000.0 + moduleState.Params.PublicTreasuryPoolCapacity = defaults.PublicTreasuryPoolCapacity // 250000.0 // moduleState.Params.BaseProposerReward = sdk.NewDecWithPrec(1, 2) // 1% moduleState.Params.BonusProposerReward = sdk.NewDecWithPrec(4, 2) // 4% @@ -101,6 +101,7 @@ func OverrideGenesisStateDefaults(cdc *codec.Codec, genState map[string]json.Raw // moduleState.Params.BondDenom = defaults.StakingDenom moduleState.Params.LPDenom = defaults.LiquidityProviderDenom + moduleState.Params.LPDistrRatio = sdk.NewDecWithPrec(1, 0) // 100% // moduleState.Params.MinSelfDelegationLvl = defaults.MinSelfDelegationCoin.Amount // 2500.0 moduleState.Params.MaxDelegationsRatio = sdk.NewDecWithPrec(10, 0) // 10.0 diff --git a/x/vm/internal/keeper/genesis_ws.json b/x/vm/internal/keeper/genesis_ws.json index 89011db2..d01a7ffa 100644 --- a/x/vm/internal/keeper/genesis_ws.json +++ b/x/vm/internal/keeper/genesis_ws.json @@ -2,58 +2,58 @@ "write_set": [ { "address": "0000000000000000000000000000000000000001", - "path": "00f291acfb65d0f093d26ad997ca99c2e14150a49953d95c8304a63701ca7de4f1", - "value": "a11ceb0b010000000d010008020816031e8b0104a9012005c901950107de02bd03089b061406af06040ab306280bdb06020cdd0695030df209020ef409020000000100020003000401010100050200000602000007010001070101010308000100020902030102010a03040101010b05030101010c06070101010d08090101010e03090101000f0003010100100007010100110107010100120103000013010301010014010a00000b0b03010100150c03010100160d03010100170d03010100180a03000019010e00001a010e0101001b0f030101001c10030101001d11090101001e120901010613091304130f130d1310130213011513130b1303130116151317130513161301060c010502060c090000010a0202070b040109000b0401090001060b04010900010402070b0401090004010b04010900010c03060c050b0401090002060c0b0401090004060c050b040109000a02010103060c050404060c05040a0202070b000109000402060c040109000f040a02070b00010900010304050a020a02060c040a020a0205060c01080201080101070b00010900074163636f756e74084466696e616e6365054576656e74065369676e65720742616c616e63651452656365697665645061796d656e744576656e741053656e745061796d656e744576656e7401540a616464726573735f6f6604656d69740564656e6f6d076465706f7369740576616c7565087769746864726177047a65726f066163636570740762616c616e63650b62616c616e63655f666f720e6372656174655f6163636f756e740e6372656174655f62616c616e63650d6372656174655f7369676e6572116465706f7369745f746f5f73656e646572156465706f7369745f776974685f6d65746164617461206465706f7369745f776974685f73656e6465725f616e645f6d657461646174610e64657374726f795f7369676e65720b6861735f6163636f756e740b6861735f62616c616e63650f7061795f66726f6d5f73656e6465721d7061795f66726f6d5f73656e6465725f776974685f6d657461646174611577697468647261775f66726f6d5f62616c616e63651477697468647261775f66726f6d5f73656e64657204636f696e06616d6f756e74057061796572086d657461646174610570617965650b64756d6d795f6669656c6400000000000000000000000000000000000000010a0201000002011f0b0401090001020420040a0a022105220a0202020420040a0a022305220a020302012401001307010003050b00380039003f00020801010003040b0011003801020901010003050a003d0037003802020a00000a0a0a00110c0c010e010912032d030b011111020b00000a0a0a00110c0c010e01380039003f000b011111020c02000d01010003060b000a010b0207003803020e01010003060a000b0011000b013804020f01010003060b000a010b020b033805021000010014480e0238020c040a043200000000000000000000000000000000240c070b07030d0b00010607000000000000002738060c050a000c0d0a040c090a010c0a0a050c0b0a030c0c0b0d0b090b0b0b0a0b0c120238070a01380820032505270a0138090a01111220032c052e0a01110a0a013c000c060b0636000b02380a0a000c120a040c0e0b050c0f0b030c100b0011000c110b120b0e0b0f0b110b101201380b0211020012010003030a0029030213010003030a003b00021401010003060b000a010a020700380c021501010003080a000a010b000a02380d0b0338030216000003050b0036000a01380e021701010017080b0011003c000c020b020a01380f020000001300" + "path": "009cb04857956873d52372bd369d73c8042b81cdf4913d838e55867ea219afb01c", + "value": "a11ceb0b010000000d01000402040a030e68047606057c7507f101d50108c6031406da03160af003130b8304040c870488030d8f070c0e9b070c0000000100020101010003010101010400010000050002000006010300000702040101000802050101000906020101000a030200000b02070101000c08090101000d02010101000e0a020101000f0b02010300100c08010100110d0901030012020e010100130f0e0101001410090101001502090101051210120b1201060c010500010c0102010a0202070b010109000b010109000101020b010109000b01010900010b0101090003060c0a0202010b00010900020b010109000404060c04020a02010401060b0101090002070b0101090004020103010900060a0202050401060c090b000109000501030a0202050401084466696e616e6365065369676e657204496e666f01540a616464726573735f6f66186173736572745f63616e5f72656769737465725f636f696e0d6372656174655f7369676e657208646563696d616c730564656e6f6d076465706f7369740e64657374726f795f7369676e65720869735f746f6b656e046a6f696e056f776e65720d72656769737465725f636f696e1372656769737465725f746f6b656e5f696e666f0573706c697408746f6b656e697a650c746f74616c5f737570706c790576616c7565087769746864726177047a65726f000000000000000000000000000000000000000105140000000000000000000000000000000000000001000205080a0207020b010d051204010201130400120112010000110a0b0011000700210c010b010309060100000000000000270202020003010100020507003d003700140204010100020507003d00370114020501000e0c0b013a010c020a003702140a02160b003602150206020007010100020507003d003703140208010002050d000b0138000b000209010100020507003d00370414020a010013110a0011010b000c080b010c030a020c040b080b030b04090700320000000000000000000000000000000039003f00020b00000309070011020c010e010b003f000b011106020c010009070d000a0138010c020b000b02020d0100141f0b0011000c0507003b00200c060b06030b060100000000000000270b030c080a020c090a050c0a0a010c0b0b080b09080b0a0b0b39000c040b0438020a013901020e010100020507003d00370514020f010002040b003702140210010011170a003702140a01260c020b02030c0b0001060a00000000000000270a003702140a01170b003602150a013901021101000203320000000000000000000000000000000039010200010000010000020003000400120112021203120412051200" }, { "address": "0000000000000000000000000000000000000001", - "path": "001e71f6df00e48c8c254cd583d3dc45937e436997cfae0dbe3b8c2345b7159e09", - "value": "a11ceb0b0100000006010002030206050806070e0b0819140c2d03000000010001010202060c090000054576656e7404656d6974000000000000000000000000000000000000000100030000" + "path": "008696ee9de913cfa23cf7d81b8dc4f5b9c880a27d9989dd9553e53b861bdff8cf", + "value": "a11ceb0b0100000006010002030206050807070f0d081c140c3003000000010001010101060900010a02034c435308746f5f6279746573000000000000000000000000000000000000000100030000" }, { "address": "0000000000000000000000000000000000000001", - "path": "00bece7868df537350b30aecfd94ecceac4ff0f4e589ab16605cc55e72a783856d", - "value": "a11ceb0b010000000601000203020a050c090715210836140c4a0e00000001000100000200020001060c010501060500065369676e65720a616464726573735f6f660e626f72726f775f61646472657373000000000000000000000000000000000000000100010003040b001101140201030000" + "path": "0020b5dde2cb71801be4d554a2d7f1b1063f527aa8990f5fd08a097f3d8b9fd50b", + "value": "a11ceb0b01000000050100020202040706120818140a2c050000000102000358464901540b64756d6d795f6669656c640000000000000000000000000000000000000001000201020100" }, { "address": "0000000000000000000000000000000000000001", - "path": "009934e51f2eb6b334a0111bc088588497e2a304aac277526593fd68f816c20417", - "value": "a11ceb0b010000000a010002020204030605050b03070e340842140656160a6c050c710e0d7f02000000010100000200010000010305426c6f636b0d426c6f636b4d65746164617461186765745f63757272656e745f626c6f636b5f68656967687406686569676874000000000000000000000000000000000000000105140000000000000000000000000000000000000001000201030300010100000507002b0010001402000000" + "path": "00645941518552d45ce5aa55b54db8723702ca0c0ecaa3fb36df0cedd4fc63d439", + "value": "a11ceb0b0100000009010002020204030619051f17073666089c01140ab001050cb501ac010de102020000000102000002000100000302010000040302000005010200000603020002030301080001030203080006040404010301000204040c4669786564506f696e7433320154146372656174655f66726f6d5f726174696f6e616c156372656174655f66726f6d5f7261775f76616c75650a6469766964655f7536340d6765745f7261775f76616c75650c6d756c7469706c795f7536340576616c75650000000000000000000000000000000000000001000201070300010004240a003531402f0c040a013531202f0c030a040a031a0c020a0232000000000000000000000000000000002203130516080c07051a0a00060000000000000000210c070b070c050b050320061000000000000000270a023412000201010005030a00120002020100060f0a003531202f0c030a030e01100014351a0c020a02340203010005040e0010001402040100060f0a00350e0110001435180c030a033120300c020a023402000000" }, { "address": "0000000000000000000000000000000000000001", - "path": "00322e5b50f94d3df7f68f08779d754435119f50ee6ec03f726051d408c6f1d8f6", - "value": "a11ceb0b010000000b01000402040503091d05261d07433e088101140a9501080b9d01020c9f01680d8702020e890202000000010002010101010300010000030101010100040203010100050104010100060506010101060c010503060c09000500010102060c050109000605090005010301054f66666572065369676e657201540a616464726573735f6f6606637265617465096578697374735f61740672656465656d076f66666572656403666f720000000000000000000000000000000000000001000202070900080500060101010003050a003d003700140202010003060b000b010a0239003f000203010003030a003b000204010100071c0a013e003a000c020c030b0011000c040a040a0221030d0510080c0705140a040a01210c070b070c050b05031a060b00000000000000270b03020001000600" + "path": "001e71f6df00e48c8c254cd583d3dc45937e436997cfae0dbe3b8c2345b7159e09", + "value": "a11ceb0b0100000006010002030206050806070e0b0819140c2d03000000010001010202060c090000054576656e7404656d6974000000000000000000000000000000000000000100030000" }, { "address": "0000000000000000000000000000000000000001", - "path": "009cb04857956873d52372bd369d73c8042b81cdf4913d838e55867ea219afb01c", - "value": "a11ceb0b010000000d01000402040a030e68047606057c7507f101d50108c6031406da03160af003130b8304040c870488030d8f070c0e9b070c0000000100020101010003010101010400010000050002000006010300000702040101000802050101000906020101000a030200000b02070101000c08090101000d02010101000e0a020101000f0b02010300100c08010100110d0901030012020e010100130f0e0101001410090101001502090101051210120b1201060c010500010c0102010a0202070b010109000b010109000101020b010109000b01010900010b0101090003060c0a0202010b00010900020b010109000404060c04020a02010401060b0101090002070b0101090004020103010900060a0202050401060c090b000109000501030a0202050401084466696e616e6365065369676e657204496e666f01540a616464726573735f6f66186173736572745f63616e5f72656769737465725f636f696e0d6372656174655f7369676e657208646563696d616c730564656e6f6d076465706f7369740e64657374726f795f7369676e65720869735f746f6b656e046a6f696e056f776e65720d72656769737465725f636f696e1372656769737465725f746f6b656e5f696e666f0573706c697408746f6b656e697a650c746f74616c5f737570706c790576616c7565087769746864726177047a65726f000000000000000000000000000000000000000105140000000000000000000000000000000000000001000205080a0207020b010d051204010201130400120112010000110a0b0011000700210c010b010309060100000000000000270202020003010100020507003d003700140204010100020507003d00370114020501000e0c0b013a010c020a003702140a02160b003602150206020007010100020507003d003703140208010002050d000b0138000b000209010100020507003d00370414020a010013110a0011010b000c080b010c030a020c040b080b030b04090700320000000000000000000000000000000039003f00020b00000309070011020c010e010b003f000b011106020c010009070d000a0138010c020b000b02020d0100141f0b0011000c0507003b00200c060b06030b060100000000000000270b030c080a020c090a050c0a0a010c0b0b080b09080b0a0b0b39000c040b0438020a013901020e010100020507003d00370514020f010002040b003702140210010011170a003702140a01260c020b02030c0b0001060a00000000000000270a003702140a01170b003602150a013901021101000203320000000000000000000000000000000039010200010000010000020003000400120112021203120412051200" + "path": "00d35c97ec98d9b737c66f0d5a6acf89644c8818196f1bb071e14971072c0d1427", + "value": "a11ceb0b010000000701000203025404561005665607bc01800108bc02140cd002890300000001000101010002020301010003040501010004060701010005080101010006010801010007090701010008090a010100090b0c0101000a0d010101000b040c0101000c0b010101000d0e010101000e040c01010b0c060c080c090c040c070c010c0c0c02070a09000a09000002060a0900030106090002070a0900030107090002060a09000609000101010a090001060a0900010301070a090001090002070a0900090003070a09000303020303030303070a09000303030306566563746f7206617070656e6406626f72726f770a626f72726f775f6d757408636f6e7461696e730d64657374726f795f656d70747905656d7074790869735f656d707479066c656e67746808706f705f6261636b09707573685f6261636b0672656d6f7665077265766572736504737761700b737761705f72656d6f7665000000000000000000000000000000000000000100010001110d0138000e013801200307050c0a000d013802380305020b00010b013804020103000203000301000f220600000000000000000c020a0038050c030a020a0323030a051c0a000a0238060a0121031105170b00010b010108020a02060100000000000000160c0205050b00010b0101090204030005030006010001050b00380506000000000000000021020703000803000903000a010010260a002e38050c020a010a02260309050d0b0001060a00000000000000270a02060100000000000000170c020a010a0223031605230a000c040a010c030a01060100000000000000160c010b040b030a01380705110b003802020b010011270a002e38050c030a03060000000000000000210309050c0b0001020600000000000000000c020a03060100000000000000170c010a020a0123031705240a000a020a0138070a02060100000000000000160c020a01060100000000000000170c0105120b0001020c03000d01000a0d0a002e3805060100000000000000170c020a000a010a0238070b0038020200" }, { "address": "0000000000000000000000000000000000000001", - "path": "00645941518552d45ce5aa55b54db8723702ca0c0ecaa3fb36df0cedd4fc63d439", - "value": "a11ceb0b0100000009010002020204030619051f17073666089c01140ab001050cb501ac010de102020000000102000002000100000302010000040302000005010200000603020002030301080001030203080006040404010301000204040c4669786564506f696e7433320154146372656174655f66726f6d5f726174696f6e616c156372656174655f66726f6d5f7261775f76616c75650a6469766964655f7536340d6765745f7261775f76616c75650c6d756c7469706c795f7536340576616c75650000000000000000000000000000000000000001000201070300010004240a003531402f0c040a013531202f0c030a040a031a0c020a0232000000000000000000000000000000002203130516080c07051a0a00060000000000000000210c070b070c050b050320061000000000000000270a023412000201010005030a00120002020100060f0a003531202f0c030a030e01100014351a0c020a02340203010005040e0010001402040100060f0a00350e0110001435180c030a033120300c020a023402000000" + "path": "009934e51f2eb6b334a0111bc088588497e2a304aac277526593fd68f816c20417", + "value": "a11ceb0b010000000a010002020204030605050b03070e340842140656160a6c050c710e0d7f02000000010100000200010000010305426c6f636b0d426c6f636b4d65746164617461186765745f63757272656e745f626c6f636b5f68656967687406686569676874000000000000000000000000000000000000000105140000000000000000000000000000000000000001000201030300010100000507002b0010001402000000" }, { "address": "0000000000000000000000000000000000000001", - "path": "00d35c97ec98d9b737c66f0d5a6acf89644c8818196f1bb071e14971072c0d1427", - "value": "a11ceb0b010000000701000203025404561005665607bc01800108bc02140cd002890300000001000101010002020301010003040501010004060701010005080101010006010801010007090701010008090a010100090b0c0101000a0d010101000b040c0101000c0b010101000d0e010101000e040c01010b0c060c080c090c040c070c010c0c0c02070a09000a09000002060a0900030106090002070a0900030107090002060a09000609000101010a090001060a0900010301070a090001090002070a0900090003070a09000303020303030303070a09000303030306566563746f7206617070656e6406626f72726f770a626f72726f775f6d757408636f6e7461696e730d64657374726f795f656d70747905656d7074790869735f656d707479066c656e67746808706f705f6261636b09707573685f6261636b0672656d6f7665077265766572736504737761700b737761705f72656d6f7665000000000000000000000000000000000000000100010001110d0138000e013801200307050c0a000d013802380305020b00010b013804020103000203000301000f220600000000000000000c020a0038050c030a020a0323030a051c0a000a0238060a0121031105170b00010b010108020a02060100000000000000160c0205050b00010b0101090204030005030006010001050b00380506000000000000000021020703000803000903000a010010260a002e38050c020a010a02260309050d0b0001060a00000000000000270a02060100000000000000170c020a010a0223031605230a000c040a010c030a01060100000000000000160c010b040b030a01380705110b003802020b010011270a002e38050c030a03060000000000000000210309050c0b0001020600000000000000000c020a03060100000000000000170c010a020a0123031705240a000a020a0138070a02060100000000000000160c020a01060100000000000000170c0105120b0001020c03000d01000a0d0a002e3805060100000000000000170c020a000a010a0238070b0038020200" + "path": "00f291acfb65d0f093d26ad997ca99c2e14150a49953d95c8304a63701ca7de4f1", + "value": "a11ceb0b010000000d010008020816031e8b0104a9012005c901950107de02bd03089b061406af06040ab306280bdb06020cdd0695030df209020ef409020000000100020003000401010100050200000602000007010001070101010308000100020902030102010a03040101010b05030101010c06070101010d08090101010e03090101000f0003010100100007010100110107010100120103000013010301010014010a00000b0b03010100150c03010100160d03010100170d03010100180a03000019010e00001a010e0101001b0f030101001c10030101001d11090101001e120901010613091304130f130d1310130213011513130b1303130116151317130513161301060c010502060c090000010a0202070b040109000b0401090001060b04010900010402070b0401090004010b04010900010c03060c050b0401090002060c0b0401090004060c050b040109000a02010103060c050404060c05040a0202070b000109000402060c040109000f040a02070b00010900010304050a020a02060c040a020a0205060c01080201080101070b00010900074163636f756e74084466696e616e6365054576656e74065369676e65720742616c616e63651452656365697665645061796d656e744576656e741053656e745061796d656e744576656e7401540a616464726573735f6f6604656d69740564656e6f6d076465706f7369740576616c7565087769746864726177047a65726f066163636570740762616c616e63650b62616c616e63655f666f720e6372656174655f6163636f756e740e6372656174655f62616c616e63650d6372656174655f7369676e6572116465706f7369745f746f5f73656e646572156465706f7369745f776974685f6d65746164617461206465706f7369745f776974685f73656e6465725f616e645f6d657461646174610e64657374726f795f7369676e65720b6861735f6163636f756e740b6861735f62616c616e63650f7061795f66726f6d5f73656e6465721d7061795f66726f6d5f73656e6465725f776974685f6d657461646174611577697468647261775f66726f6d5f62616c616e63651477697468647261775f66726f6d5f73656e64657204636f696e06616d6f756e74057061796572086d657461646174610570617965650b64756d6d795f6669656c6400000000000000000000000000000000000000010a0201000002011f0b0401090001020420040a0a022105220a0202020420040a0a022305220a020302012401001307010003050b00380039003f00020801010003040b0011003801020901010003050a003d0037003802020a00000a0a0a00110c0c010e010912032d030b011111020b00000a0a0a00110c0c010e01380039003f000b011111020c02000d01010003060b000a010b0207003803020e01010003060a000b0011000b013804020f01010003060b000a010b020b033805021000010014480e0238020c040a043200000000000000000000000000000000240c070b07030d0b00010607000000000000002738060c050a000c0d0a040c090a010c0a0a050c0b0a030c0c0b0d0b090b0b0b0a0b0c120238070a01380820032505270a0138090a01111220032c052e0a01110a0a013c000c060b0636000b02380a0a000c120a040c0e0b050c0f0b030c100b0011000c110b120b0e0b0f0b110b101201380b0211020012010003030a0029030213010003030a003b00021401010003060b000a010a020700380c021501010003080a000a010b000a02380d0b0338030216000003050b0036000a01380e021701010017080b0011003c000c020b020a01380f020000001300" }, { "address": "0000000000000000000000000000000000000001", - "path": "001d38630b3873058ea4c0226b90ccd36a175559a7f8652bf4f9b2633d9afc756a", - "value": "a11ceb0b010000000601000203020a050c140720320852140c6606000000010001000002020300040a020a020a020a020103030a020a020a020101095369676e617475726518656432353531395f7468726573686f6c645f7665726966790e656432353531395f766572696679000000000000000000000000000000000000000100030001030000" + "path": "00dc548635f2b6e528d101e0832fb78622d940f8510d04cc16fc576f6139b4c84a", + "value": "a11ceb0b010000000801000202020403063205380e074649088f01140aa301060ca9011e000000000200000100010000020102000003010300000401040000050001000006020100000703010000080401000009000100000a00010002080008000108000104010301020455323536036164640761735f753132380661735f7536340561735f7538036469760966726f6d5f753132380866726f6d5f7536340766726f6d5f7538036d756c037375620376616c00000000000000000000000000000000000000010002010b0a0200030001030002030003030004030005030006030007030008030009030000" }, { "address": "0000000000000000000000000000000000000001", - "path": "00386c247ee0ae4587fc3b7ad2364518bf679ff7681dbbbb0d8a165a0c6d7ec1d6", - "value": "a11ceb0b010000000c01000202021203140e05220a072c3f086b14067f160a9501140ba901020cab01180dc301020ec50102000000010200000202000003010201010004020000050001020101000600020201010001040101020900090105436f696e7303425443034554480550726963650455534454096765745f7072696365096861735f70726963650b64756d6d795f6669656c640576616c75650000000000000000000000000000000000000001051400000000000000000000000000000000000000010002010701010201070102020108040302010701020300010102000507003d0037001402010100000307003b00020200000300" + "path": "0041f3acd295ef0cbb729b138715119833fb8cc7f40d70ed6796b5737d4832f194", + "value": "a11ceb0b010000000601000203020b050d0507121e0830140c4406000000010001010100020101000106090000054465627567057072696e74117072696e745f737461636b5f7472616365000000000000000000000000000000000000000100030001030000" }, { "address": "0000000000000000000000000000000000000001", - "path": "0041f3acd295ef0cbb729b138715119833fb8cc7f40d70ed6796b5737d4832f194", - "value": "a11ceb0b010000000601000203020b050d0507121e0830140c4406000000010001010100020101000106090000054465627567057072696e74117072696e745f737461636b5f7472616365000000000000000000000000000000000000000100030001030000" + "path": "001d38630b3873058ea4c0226b90ccd36a175559a7f8652bf4f9b2633d9afc756a", + "value": "a11ceb0b010000000601000203020a050c140720320852140c6606000000010001000002020300040a020a020a020a020103030a020a020a020101095369676e617475726518656432353531395f7468726573686f6c645f7665726966790e656432353531395f766572696679000000000000000000000000000000000000000100030001030000" }, { "address": "0000000000000000000000000000000000000001", @@ -62,18 +62,23 @@ }, { "address": "0000000000000000000000000000000000000001", - "path": "008696ee9de913cfa23cf7d81b8dc4f5b9c880a27d9989dd9553e53b861bdff8cf", - "value": "a11ceb0b0100000006010002030206050807070f0d081c140c3003000000010001010101060900010a02034c435308746f5f6279746573000000000000000000000000000000000000000100030000" + "path": "00bece7868df537350b30aecfd94ecceac4ff0f4e589ab16605cc55e72a783856d", + "value": "a11ceb0b010000000601000203020a050c090715210836140c4a0e00000001000100000200020001060c010501060500065369676e65720a616464726573735f6f660e626f72726f775f61646472657373000000000000000000000000000000000000000100010003040b001101140201030000" }, { "address": "0000000000000000000000000000000000000001", - "path": "00d6aa4796d52dcb4ad53952e57d14185c187f13ffbb3f0e402dc6da3c9c85b688", - "value": "a11ceb0b010000000701000403041b041f04052327074a3a088401140c9801e901000000010102000101010103020301010004040500000506050000060705000105000502060a0900030106090001060a0900010302060a02060a0201020203030202020502030302010007436f6d7061726506566563746f7206626f72726f77066c656e6774680d636d705f6c63735f627974657307636d705f75363406636d705f75380000000000000000000000000000000000000001020100083d0a0038000c030a0138000c040a030a0411030c050a0306000000000000000024030f05140a04060000000000000000240c060516090c060b06031905370a03060100000000000000170c030a04060100000000000000170c040a000a033801140a010a0438011411040c020a02310022033005360b01010b00010a0202050a0b01010b00010a050203000007160a000a01210305050831000c0305140a000a0123030d051031010c02051231020c020b020c030b030204000007160a000a01210305050831000c0305140a000a0123030d051031010c02051231020c020b020c030b030200" + "path": "00386c247ee0ae4587fc3b7ad2364518bf679ff7681dbbbb0d8a165a0c6d7ec1d6", + "value": "a11ceb0b010000000c01000202021203140e05220a072c3f086b14067f160a9501140ba901020cab01180dc301020ec50102000000010200000202000003010201010004020000050001020101000600020201010001040101020900090105436f696e7303425443034554480550726963650455534454096765745f7072696365096861735f70726963650b64756d6d795f6669656c640576616c75650000000000000000000000000000000000000001051400000000000000000000000000000000000000010002010701010201070102020108040302010701020300010102000507003d0037001402010100000307003b00020200000300" }, { "address": "0000000000000000000000000000000000000001", - "path": "0020b5dde2cb71801be4d554a2d7f1b1063f527aa8990f5fd08a097f3d8b9fd50b", - "value": "a11ceb0b01000000050100020202040706120818140a2c050000000102000358464901540b64756d6d795f6669656c640000000000000000000000000000000000000001000201020100" + "path": "00322e5b50f94d3df7f68f08779d754435119f50ee6ec03f726051d408c6f1d8f6", + "value": "a11ceb0b010000000b01000402040503091d05261d07433e088101140a9501080b9d01020c9f01680d8702020e890202000000010002010101010300010000030101010100040203010100050104010100060506010101060c010503060c09000500010102060c050109000605090005010301054f66666572065369676e657201540a616464726573735f6f6606637265617465096578697374735f61740672656465656d076f66666572656403666f720000000000000000000000000000000000000001000202070900080500060101010003050a003d003700140202010003060b000b010a0239003f000203010003030a003b000204010100071c0a013e003a000c020c030b0011000c040a040a0221030d0510080c0705140a040a01210c070b070c050b05031a060b00000000000000270b03020001000600" + }, + { + "address": "0000000000000000000000000000000000000001", + "path": "00d6aa4796d52dcb4ad53952e57d14185c187f13ffbb3f0e402dc6da3c9c85b688", + "value": "a11ceb0b010000000701000403041b041f04052327074a3a088401140c9801e901000000010102000101010103020301010004040500000506050000060705000105000502060a0900030106090001060a0900010302060a02060a0201020203030202020502030302010007436f6d7061726506566563746f7206626f72726f77066c656e6774680d636d705f6c63735f627974657307636d705f75363406636d705f75380000000000000000000000000000000000000001020100083d0a0038000c030a0138000c040a030a0411030c050a0306000000000000000024030f05140a04060000000000000000240c060516090c060b06031905370a03060100000000000000170c030a04060100000000000000170c040a000a033801140a010a0438011411040c020a02310022033005360b01010b00010a0202050a0b01010b00010a050203000007160a000a01210305050831000c0305140a000a0123030d051031010c02051231020c020b020c030b030204000007160a000a01210305050831000c0305140a000a0123030d051031010c02051231020c020b020c030b030200" } ] } \ No newline at end of file From 19b6b849d893fbb8525d47e81fa27cb0012c5d18 Mon Sep 17 00:00:00 2001 From: Boris Povod Date: Thu, 8 Oct 2020 20:53:08 +0300 Subject: [PATCH 03/20] infinity gas meter for check (#214) --- x/multisig/internal/keeper/call.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/multisig/internal/keeper/call.go b/x/multisig/internal/keeper/call.go index 8a2e8c3c..6a810c98 100644 --- a/x/multisig/internal/keeper/call.go +++ b/x/multisig/internal/keeper/call.go @@ -29,7 +29,9 @@ func (k Keeper) SubmitCall(ctx sdk.Context, msg msmodule.MsMsg, uniqueID string, return sdkErrors.Wrapf(types.ErrWrongMsgRoute, "%q not found", msg.Route()) } + // TODO: solve do we need it at all during mainnet, probably we don't. cacheCtx, _ := ctx.CacheContext() + cacheCtx = cacheCtx.WithGasMeter(sdk.NewInfiniteGasMeter()) handler := k.router.GetRoute(msg.Route()) if err := handler(cacheCtx, msg); err != nil { return err From fa06394da9443dc7711af91d50c7318852a056ed Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Mon, 12 Oct 2020 15:15:14 +0300 Subject: [PATCH 04/20] [Release] Cosmos SDK version bump (#217) * simulator: readme added, refactoring, new Cosmos SDK query results added to the report * Cosmos SDK version bump * genesis update: LPRation 1.0 -> 2.0 --- cmd/config/genesis/genesis.go | 2 +- go.mod | 2 +- go.sum | 2 + helpers/tests/simulator/README.md | 148 ++++++++++++++++++ helpers/tests/simulator/inflation_test.go | 70 ++++----- helpers/tests/simulator/sim.go | 30 ++-- helpers/tests/simulator/sim_ops_delegate.go | 4 +- helpers/tests/simulator/sim_ops_redelegate.go | 6 +- .../simulator/sim_ops_rewards_delegator.go | 60 +++---- .../tests/simulator/sim_ops_rewards_lock.go | 3 +- .../simulator/sim_ops_rewards_validator.go | 53 ++++--- helpers/tests/simulator/sim_ops_undelegate.go | 6 +- helpers/tests/simulator/sim_queries.go | 24 +++ helpers/tests/simulator/sim_report.go | 59 +++++-- helpers/tests/simulator/sim_report_csv.go | 73 ++++++--- 15 files changed, 406 insertions(+), 136 deletions(-) create mode 100644 helpers/tests/simulator/README.md diff --git a/cmd/config/genesis/genesis.go b/cmd/config/genesis/genesis.go index 85ea04be..8b254f89 100644 --- a/cmd/config/genesis/genesis.go +++ b/cmd/config/genesis/genesis.go @@ -101,7 +101,7 @@ func OverrideGenesisStateDefaults(cdc *codec.Codec, genState map[string]json.Raw // moduleState.Params.BondDenom = defaults.StakingDenom moduleState.Params.LPDenom = defaults.LiquidityProviderDenom - moduleState.Params.LPDistrRatio = sdk.NewDecWithPrec(1, 0) // 100% + moduleState.Params.LPDistrRatio = sdk.NewDecWithPrec(2, 0) // 200% // moduleState.Params.MinSelfDelegationLvl = defaults.MinSelfDelegationCoin.Amount // 2500.0 moduleState.Params.MaxDelegationsRatio = sdk.NewDecWithPrec(10, 0) // 10.0 diff --git a/go.mod b/go.mod index 55f57d85..57951703 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201009185146-b579213ebb05 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index 46e9fad1..3a09ec5c 100644 --- a/go.sum +++ b/go.sum @@ -154,6 +154,8 @@ github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4 h1:sUQDCT0d github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09 h1:hNzQYh6QR6K097fL0HYDtgfyN2KgUXLu17/zRxSJezc= github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201008094428-b46810ed3864/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201009185146-b579213ebb05/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= diff --git a/helpers/tests/simulator/README.md b/helpers/tests/simulator/README.md new file mode 100644 index 00000000..494fbc92 --- /dev/null +++ b/helpers/tests/simulator/README.md @@ -0,0 +1,148 @@ +# Simulation parameters + +Simulation: +* `ID` - simulation id; +* `SimDuration` - simulation duration; +* `BlockTimeMin` - minimum block duration; +* `BlockTimeMax` - maximum block duration; + +Account balances: +* `MainTokens` - initial account balance for main tokens (`xfi`); +* `StakingTokens` - initial account balance for staking tokens (`sxfi`); +* `LPTokens` - initial account balance for LP tokens (`lpt`); + +Validators: +* `PoA validator` - number of PegZone validators, ATM has no influence on simulation; +* `TM validators (total)` - total number of PoS validators (some of them might become `unbonded`); +* `TM validators (active)` - number of active PoS validators (they would be `bonded`); + +`DelegateBondingOp` / `DelegateLPOp` operation: +* `Delegate bonding/LP tokens every` - period of operation in simulated time; +* `Delegate amount ratio (of acc balance)` - % of account balance for delegation; +* `Max limit ratio (staked ratio)` - operation limit: % of staked tokens to total tokens supply; + +`RedelegateBondingOp` / `RedelegateLPOp` operation: +* `Redelegate bonding/LP tokens every` - period of operation in simulated time; +* `Redelegate amount ratio (of del shares)` - % of delegation shares for redelegation; + +`UndelegateBondingOp` / `UndelegateLPOp` operation: +* `Undelegate bonding/LP tokens every` - period of operation in simulated time; +* `Undelegate amount ratio (of del shares)` - % of delegation shares for undelegation; + +`ValidatorRewardOp` operation: +* `Withdraw all validators comissions every` - period of operation in simulated time; + +`DelegatorRewardOp` operation: +* `Withdraw all delegators rewards every` - period of operation in simulated time; + +`LockValidatorRewardsOp` operation: +* `Lock rewards every` - period of operation in simulated time; +* `Ratio of all validators` - operation limit: % of all validators to lock rewards; + +# Operations + +## `DelegateBondingOp` / `DelegateLPOp` operation + +Picks a validator and searches for an account to delegate bonding tokens. +* SelfStake increment is allowed; +* Delegation amount = current account balance * {delegateRatio}; +* Delegation is allowed if ratio (current staking bonding pools supply / total bonding tokens supply) < {maxBondingRatio}; + +Op priorities: +- validator: + - bonded; + - lowest bonding tokens amount; +- account: + - highest bonding tokens balance; + - enough coins; + +## `RedelegateBondingOp` / `RedelegateLPOp` operation + +* Picks a validator and redelegate bonding tokens to an other validator; +* Redelegation amount = current account delegation amount * {redelegateRatio}; + +Op priorities: +- dstValidator: + - bonded; + - lowest bonding tokens amount; +- srcValidator - highest account delegation bonding shares; +- account: + - random; + - has no active redelegations with srcValidator and dstValidator; + - has enough bonding coins; + - not a dstValidator owner; + +## `UndelegateBondingOp` / `UndelegateLPOp` operation + +Picks a validator and undelegates bonding tokens. +* Undelegation amount = current account delegation amount * {undelegateRatio}. + +Op priorities: +- validator - highest bonding tokens amount (all statuses); +- account: + - random; + - has a validators bonding delegation; + - not a validator owner; + +## `ValidatorRewardOp` operation + +Takes all validators commissions rewards. + +## `DelegatorRewardOp` operation + +Takes all delegators rewards (excluding locked ones). + +## `LockValidatorRewardsOp` operation + +Takes validator commissions rewards. + +Op priority: +- validator - random; + +# CSV report + +Report item is generated every simulated day. + +* `BlockHeight` - block height; +* `BlockTime` - block time; +* `SimDuration` - simulation time (real world time); +* `Validators: Bonded` - number of `bonded` PoS validator; +* `Validators: Unbonding` - number of `unbonding` PoS validator;; +* `Validators: Unbonded` - number of `unbonded` PoS validator;; +* `Staking: Bonded` - amount of bonded staking tokens (`bonded` validators); +* `Staking: NotBonded` - amount of not-bonded staking tokens (`unbonding`/`unbonded` validators); +* `Staking: LPs` - amount of staked LP tokens; +* `Staking: ActiveRedelegations` - number of current redelegations; +* `Mint: MinInflation` - minimum inflation rate; +* `Mint: MaxInflation` - maximum inflation rate; +* `Mint: AnnualProvision` - annual minted tokens estimation (tokens per year); +* `Mint: BlocksPerYear` - number of blocks per year estimation; +* `Dist: FoundationPool` - FoundationPool supply (decimals); +* `Dist: PTreasuryPool` - PublicTreasuryPool supply (decimals); +* `Dist: LiquidityPPool` - LiquidityProvidersPool supply (decimals); +* `Dist: HARP` - HARP supply (decimals); +* `Dist: MAccBalance [main]` - rewards balance keeped by the distribution module (mail tokens); +* `Dist: MAccBalance [staking]` - rewards balance keeped by the distribution module (staking tokens); +* `Dist: BankBalance [main]` - rewards balance keeped by the distribution bank (mail tokens); +* `Dist: BankBalance [staking]` - rewards balance keeped by the distribution bank (staking tokens); +* `Dist: LockedRatio` - rate of bonded delegated tokens for locked validators to all bonded delegated tokens; +* `Supply: Total [main]` - total tokens supply (main tokens); +* `Supply: Total [staking]` - total tokens supply (staking tokens); +* `Supply: Total [LP]` - total tokens supply (LP tokens); +* `Stats: Staked/TotalSupply [staking]` - rate of (bonded + not-bonded tokens) to total supply of staking tokens; +* `Stats: Staked/TotalSupply [LPs]` - rate of staked LP tokens to total supply; +* `Accounts: TotalBalance [main]` - sum of all accounts balances (main tokens); +* `Accounts: TotalBalance [staking]` - sum of all accounts balances (staking tokens); +* `Counters: Bonding: Delegations` - number of bonding delegation operations; +* `Counters: Bonding: Redelegations` - number of bonding redelegation operations; +* `Counters: Bonding: Undelegations` - number of bonding undelegation operations; +* `Counters: LP: Delegations` - number of LP delegation operations; +* `Counters: LP: Redelegations` - number of LP redelegation operations; +* `Counters: LP: Undelegations` - number of LP undelegation operations; +* `Counters: RewardWithdraws` - number of delegators rewards withdraw operations; +* `Counters: RewardsCollected [main]` - accumulated amount of delegators rewards collected (main tokens); +* `Counters: RewardsCollected [staking]` - accumulated amount of delegators rewards collected (staking tokens); +* `Counters: CommissionWithdraws` - number of validators commission rewards operations; +* `Counters: CommissionsCollected [main]` - accumulated amount of validators commission rewards collected (main tokens); +* `Counters: CommissionsCollected [staking]` - accumulated amount of validators commission rewards collected (staking tokens); +* `Counters: LockedRewards` - number of validators rewards lock operations; diff --git a/helpers/tests/simulator/inflation_test.go b/helpers/tests/simulator/inflation_test.go index 35da2711..e1e91fd3 100644 --- a/helpers/tests/simulator/inflation_test.go +++ b/helpers/tests/simulator/inflation_test.go @@ -70,38 +70,38 @@ func (p SimProfile) String() string { str := strings.Builder{} str.WriteString("Simulation:\n") str.WriteString(fmt.Sprintf(" - ID: %s\n", p.ID)) - str.WriteString(fmt.Sprintf(" - SimDuration: %s\n", FormatDuration(p.SimDuration))) - str.WriteString(fmt.Sprintf(" - BlockTimeMin: %s\n", FormatDuration(p.BlockTimeMin))) - str.WriteString(fmt.Sprintf(" - BlockTimeMax: %s\n", FormatDuration(p.BlockTimeMax))) + str.WriteString(fmt.Sprintf(" - SimDuration: %v\n", p.SimDuration)) + str.WriteString(fmt.Sprintf(" - BlockTimeMin: %v\n", p.BlockTimeMin)) + str.WriteString(fmt.Sprintf(" - BlockTimeMax: %v\n", p.BlockTimeMax)) str.WriteString("Initial balances:\n") str.WriteString(fmt.Sprintf(" - MainTokens: %d.0%s\n", p.MainTokensBalanceWODec, defaults.MainDenom)) str.WriteString(fmt.Sprintf(" - StakingTokens: %d.0%s\n", p.BondingTokensBalanceWODec, defaults.StakingDenom)) str.WriteString(fmt.Sprintf(" - LPTokens: %d.0%s\n", p.LPTokensBalanceWODec, defaults.LiquidityProviderDenom)) str.WriteString("Total number of:\n") - str.WriteString(fmt.Sprintf(" - Account: %d\n", p.Accounts)) + str.WriteString(fmt.Sprintf(" - Accounts: %d\n", p.Accounts)) str.WriteString(fmt.Sprintf(" - PoA validators: %d\n", p.POAValidators)) str.WriteString(fmt.Sprintf(" - TM validators (total): %d\n", p.TMValidatorsTotal)) str.WriteString(fmt.Sprintf(" - TM validators (active): %d\n", p.TMValidatorsActive)) str.WriteString("Operations:\n") - str.WriteString(fmt.Sprintf(" - Create validators: %s\n", FormatDuration(p.OpCreateValidator))) - str.WriteString(fmt.Sprintf(" - Delegate bonding tokens: %s\n", FormatDuration(p.OpDelegateBonding))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpDelegateBondingAmountRatio)) - str.WriteString(fmt.Sprintf(" Max limit ratio: %s\n", p.OpDelegateBondingMaxSupplyRatio)) - str.WriteString(fmt.Sprintf(" - Delegate LP tokens: %s\n", FormatDuration(p.OpDelegateLP))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpDelegateLPAmountRatio)) - str.WriteString(fmt.Sprintf(" Max limit ratio: %s\n", p.OpDelegateLPMaxSupplyRatio)) - str.WriteString(fmt.Sprintf(" - Redelegate bonding tokens: %s\n", FormatDuration(p.OpRedelegateBonding))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpRedelegateBondingAmountRatio)) - str.WriteString(fmt.Sprintf(" - Redelegate LP tokens: %s\n", FormatDuration(p.OpRedelegateLP))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpRedelegateLPAmountRatio)) - str.WriteString(fmt.Sprintf(" - Undelegate bonding tokens: %s\n", FormatDuration(p.OpUndelegateBonding))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpUndelegateBondingAmountRatio)) - str.WriteString(fmt.Sprintf(" - Undelegate LP tokens: %s\n", FormatDuration(p.OpUndelegateLP))) - str.WriteString(fmt.Sprintf(" Amount ratio: %s\n", p.OpUndelegateLPAmountRatio)) - str.WriteString(fmt.Sprintf(" - Withdraw validator comission: %s\n", FormatDuration(p.OpGetValidatorRewards))) - str.WriteString(fmt.Sprintf(" - Withdraw delegator reward: %s\n", FormatDuration(p.OpGetDelegatorRewards))) - str.WriteString(fmt.Sprintf(" - Lock rewards: %s\n", FormatDuration(p.OpLockRewards))) - str.WriteString(fmt.Sprintf(" Ratio: %s\n", p.OpLockRewardsRatio)) + str.WriteString(fmt.Sprintf(" - Create validator every: %s\n", FormatDuration(p.OpCreateValidator))) + str.WriteString(fmt.Sprintf(" - Delegate bonding tokens every: %s\n", FormatDuration(p.OpDelegateBonding))) + str.WriteString(fmt.Sprintf(" Delegate amount ratio (of acc balance): %s\n", p.OpDelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" Max limit ratio (staked ratio): %s\n", p.OpDelegateBondingMaxSupplyRatio)) + str.WriteString(fmt.Sprintf(" - Delegate LP tokens every: %s\n", FormatDuration(p.OpDelegateLP))) + str.WriteString(fmt.Sprintf(" Delegate amount ratio (of acc balance): %s\n", p.OpDelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" Max limit ratio (staked ratio): %s\n", p.OpDelegateLPMaxSupplyRatio)) + str.WriteString(fmt.Sprintf(" - Redelegate bonding tokens every: %s\n", FormatDuration(p.OpRedelegateBonding))) + str.WriteString(fmt.Sprintf(" Redelegate amount ratio (of del shares): %s\n", p.OpRedelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" - Redelegate LP tokens every: %s\n", FormatDuration(p.OpRedelegateLP))) + str.WriteString(fmt.Sprintf(" Redelegate amount ratio (of del shares): %s\n", p.OpRedelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" - Undelegate bonding tokens every: %s\n", FormatDuration(p.OpUndelegateBonding))) + str.WriteString(fmt.Sprintf(" Undelegate amount ratio (of del shares): %s\n", p.OpUndelegateBondingAmountRatio)) + str.WriteString(fmt.Sprintf(" - Undelegate LP tokens every: %s\n", FormatDuration(p.OpUndelegateLP))) + str.WriteString(fmt.Sprintf(" Undelegate amount ratio (of del shares): %s\n", p.OpUndelegateLPAmountRatio)) + str.WriteString(fmt.Sprintf(" - Withdraw all validators comissions every: %s\n", FormatDuration(p.OpGetValidatorRewards))) + str.WriteString(fmt.Sprintf(" - Withdraw all delegators rewards every: %s\n", FormatDuration(p.OpGetDelegatorRewards))) + str.WriteString(fmt.Sprintf(" - Lock rewards every: %s\n", FormatDuration(p.OpLockRewards))) + str.WriteString(fmt.Sprintf(" Ratio of all validators: %s\n", p.OpLockRewardsRatio)) return str.String() } @@ -187,27 +187,27 @@ func simulate(t *testing.T, profile SimProfile) { func TestSimInflation(t *testing.T) { profile := SimProfile{ ID: "low_staking", - SimDuration: 1*Year + 6*Month, - BlockTimeMin: 120 * time.Second, - BlockTimeMax: 125 * time.Second, + SimDuration: 3*Month, + BlockTimeMin: 300 * time.Second, + BlockTimeMax: 305 * time.Second, // MainTokensBalanceWODec: 50000, BondingTokensBalanceWODec: 500000, LPTokensBalanceWODec: 100000, // - Accounts: 300, + Accounts: 150, POAValidators: 3, - TMValidatorsTotal: 150, + TMValidatorsTotal: 110, TMValidatorsActive: 100, // OpCreateValidator: 3 * time.Hour, // - OpDelegateBonding: 6 * time.Hour, - OpDelegateBondingAmountRatio: sdk.NewDecWithPrec(40, 2), + OpDelegateBonding: 2 * time.Hour, + OpDelegateBondingAmountRatio: sdk.NewDecWithPrec(50, 2), OpDelegateBondingMaxSupplyRatio: sdk.NewDecWithPrec(30, 2), // - OpDelegateLP: 1 * Day, - OpDelegateLPAmountRatio: sdk.NewDecWithPrec(40, 2), + OpDelegateLP: 4 * time.Hour, + OpDelegateLPAmountRatio: sdk.NewDecWithPrec(50, 2), OpDelegateLPMaxSupplyRatio: sdk.NewDecWithPrec(30, 2), // OpRedelegateBonding: 4 * Day, @@ -222,10 +222,10 @@ func TestSimInflation(t *testing.T) { OpUndelegateLP: 4 * Day, OpUndelegateLPAmountRatio: sdk.NewDecWithPrec(15, 2), // - OpGetValidatorRewards: 1 * Week, - OpGetDelegatorRewards: 1 * Day, + OpGetValidatorRewards: 1 * Month, + OpGetDelegatorRewards: 1 * Month, // - OpLockRewards: 1 * Week, + OpLockRewards: 4 * Day, OpLockRewardsRatio: sdk.NewDecWithPrec(30, 2), } diff --git a/helpers/tests/simulator/sim.go b/helpers/tests/simulator/sim.go index 5e47bf73..4373a6df 100644 --- a/helpers/tests/simulator/sim.go +++ b/helpers/tests/simulator/sim.go @@ -71,17 +71,19 @@ type Simulator struct { } type Counter struct { - BDelegations int64 - BUndelegations int64 - BRedelegations int64 - LPDelegations int64 - LPUndelegations int64 - LPRedelegations int64 - LockedRewards int64 - Rewards int64 - Commissions int64 - RewardsCollected sdk.Coins - CommissionsCollected sdk.Coins + BDelegations int64 + BUndelegations int64 + BRedelegations int64 + LPDelegations int64 + LPUndelegations int64 + LPRedelegations int64 + LockedRewards int64 + RewardsWithdraws int64 + CommissionWithdraws int64 + RewardsCollectedMain sdk.Int + RewardsCollectedStaking sdk.Int + CommissionsCollectedMain sdk.Int + CommissionsCollectedStaking sdk.Int } // BuildTmpFilePath builds file name inside of the Simulator working dir. @@ -338,8 +340,10 @@ func NewSimulator(t *testing.T, workingDir string, defferQueue *DefferOps, optio cdc: app.MakeCodec(), defferQueue: defferQueue, } - s.counter.RewardsCollected = sdk.NewCoins() - s.counter.CommissionsCollected = sdk.NewCoins() + s.counter.RewardsCollectedMain = sdk.ZeroInt() + s.counter.RewardsCollectedStaking = sdk.ZeroInt() + s.counter.CommissionsCollectedMain = sdk.ZeroInt() + s.counter.CommissionsCollectedStaking = sdk.ZeroInt() defaultGenesis, err := genesis.OverrideGenesisStateDefaults(s.cdc, app.ModuleBasics.DefaultGenesis()) require.NoError(t, err) diff --git a/helpers/tests/simulator/sim_ops_delegate.go b/helpers/tests/simulator/sim_ops_delegate.go index ac138aed..49e6b366 100644 --- a/helpers/tests/simulator/sim_ops_delegate.go +++ b/helpers/tests/simulator/sim_ops_delegate.go @@ -118,7 +118,8 @@ func delegateOpFindTarget(s *Simulator, bondingD bool, delegateRatio sdk.Dec) (t // pick an account with max tokens var delAmt sdk.Int - for _, acc := range s.GetAllAccounts().GetSortedByBalance(denom, true) { + accs := s.GetAllAccounts().GetSortedByBalance(denom, true) + for _, acc := range accs { // estimate delegation amount accCoinAmtDec := sdk.NewDecFromInt(acc.Coins.AmountOf(denom)) delAmt = accCoinAmtDec.Mul(delegateRatio).TruncateInt() @@ -128,6 +129,7 @@ func delegateOpFindTarget(s *Simulator, bondingD bool, delegateRatio sdk.Dec) (t targetAcc = acc delCoin = sdk.NewCoin(denom, delAmt) + return } return diff --git a/helpers/tests/simulator/sim_ops_redelegate.go b/helpers/tests/simulator/sim_ops_redelegate.go index 03f62115..6c051c9c 100644 --- a/helpers/tests/simulator/sim_ops_redelegate.go +++ b/helpers/tests/simulator/sim_ops_redelegate.go @@ -98,7 +98,8 @@ func redelegateOpFindTarget(s *Simulator, bondingRD bool, rdRatio sdk.Dec) (targ } // pick a target account - for _, acc := range s.GetAllAccounts().GetShuffled() { + accs := s.GetAllAccounts().GetShuffled() + for _, acc := range accs { accValAddr := sdk.ValAddress{} if acc.IsValOperator() { accValAddr = acc.OperatedValidator.GetAddress() @@ -110,7 +111,8 @@ func redelegateOpFindTarget(s *Simulator, bondingRD bool, rdRatio sdk.Dec) (targ } // pick a delegation with the highest share - for _, delegation := range acc.GetSortedDelegations(bondingRD, true) { + delegations := acc.GetSortedDelegations(bondingRD, true) + for _, delegation := range delegations { srcValidatorApplicant := validators.GetByAddress(delegation.ValidatorAddress) // check if applicant was found (that validator can be unbonded by now) diff --git a/helpers/tests/simulator/sim_ops_rewards_delegator.go b/helpers/tests/simulator/sim_ops_rewards_delegator.go index f75f8821..d61b3b88 100644 --- a/helpers/tests/simulator/sim_ops_rewards_delegator.go +++ b/helpers/tests/simulator/sim_ops_rewards_delegator.go @@ -7,26 +7,24 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// NewGetDelegatorRewardOp takes delegator rewards. -// Op priority: -// account; -// - random; -// - has delegations; -// validator -// - random account delegation; -// - rewards are not locked; +type delegatorRewardOpTarget struct { + Acc *SimAccount + Val *SimValidator +} + +// NewGetDelegatorRewardOp takes all delegators rewards (excluding locked ones). func NewGetDelegatorRewardOp(period time.Duration) *SimOperation { id := "DelegatorRewardOp" handler := func(s *Simulator) (bool, string) { - targetAcc, targetVal, rewardCoins := getDelegatorRewardOpFindTarget(s) - if targetAcc == nil || targetVal == nil { + targets, rewardCoins := getDelegatorRewardOpFindTarget(s) + if len(targets) == 0 { return false, "target not found" } - getDelegatorRewardOpHandle(s, targetAcc, targetVal) + getDelegatorRewardOpHandle(s, targets) - getDelegatorRewardOpPost(s, targetAcc, rewardCoins) - msg := fmt.Sprintf("%s from %s: %s", targetAcc.Address, targetVal.GetAddress(), s.FormatCoins(rewardCoins)) + getDelegatorRewardOpPost(s, targets, rewardCoins) + msg := fmt.Sprintf("total from %d targets: %s", len(targets), s.FormatCoins(rewardCoins)) return true, msg } @@ -34,11 +32,11 @@ func NewGetDelegatorRewardOp(period time.Duration) *SimOperation { return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) } -func getDelegatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator, rewardCoins sdk.Coins) { +func getDelegatorRewardOpFindTarget(s *Simulator) (targets []delegatorRewardOpTarget, rewardCoins sdk.Coins) { rewardCoins = sdk.NewCoins() validators := s.GetAllValidators() - for _, acc := range s.GetAllAccounts().GetShuffled() { + for _, acc := range s.GetAllAccounts() { for _, delegation := range acc.GetShuffledDelegations(true) { validator := validators.GetByAddress(delegation.ValidatorAddress) if validator.RewardsLocked() { @@ -46,33 +44,41 @@ func getDelegatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, target } // estimate reward coins + curRewardCoins := sdk.NewCoins() for _, decCoin := range s.QueryDistDelReward(acc.Address, delegation.ValidatorAddress) { coin, _ := decCoin.TruncateDecimal() - rewardCoins = rewardCoins.Add(coin) + curRewardCoins = curRewardCoins.Add(coin) } // check there are some rewards - if rewardCoins.Empty() { + if curRewardCoins.Empty() { continue } - targetAcc = acc - targetVal = validator - return + targets = append(targets, delegatorRewardOpTarget{ + Acc: acc, + Val: validator, + }) + rewardCoins = rewardCoins.Add(curRewardCoins...) } } return } -func getDelegatorRewardOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator) { - s.TxDistDelegatorRewards(targetAcc, targetVal.GetAddress()) +func getDelegatorRewardOpHandle(s *Simulator, targets []delegatorRewardOpTarget) { + for _, target := range targets { + s.TxDistDelegatorRewards(target.Acc, target.Val.GetAddress()) + } } -func getDelegatorRewardOpPost(s *Simulator, targetAcc *SimAccount, rewardCoins sdk.Coins) { - // update account - s.UpdateAccount(targetAcc) +func getDelegatorRewardOpPost(s *Simulator, targets []delegatorRewardOpTarget, rewardCoins sdk.Coins) { + // update accounts + for _, target := range targets { + s.UpdateAccount(target.Acc) + } // update stats - s.counter.Rewards++ - s.counter.RewardsCollected = s.counter.RewardsCollected.Add(rewardCoins...) + s.counter.RewardsWithdraws += int64(len(targets)) + s.counter.RewardsCollectedMain = s.counter.RewardsCollectedMain.Add(rewardCoins.AmountOf(s.mainDenom)) + s.counter.RewardsCollectedStaking = s.counter.RewardsCollectedStaking.Add(rewardCoins.AmountOf(s.stakingDenom)) } diff --git a/helpers/tests/simulator/sim_ops_rewards_lock.go b/helpers/tests/simulator/sim_ops_rewards_lock.go index f97cbcf2..cfac3275 100644 --- a/helpers/tests/simulator/sim_ops_rewards_lock.go +++ b/helpers/tests/simulator/sim_ops_rewards_lock.go @@ -49,7 +49,8 @@ func lockValidatorRewardsOpCheckInput(s *Simulator, maxRatio sdk.Dec) (stop bool } func lockValidatorRewardsOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator) { - for _, val := range s.GetAllValidators().GetShuffled() { + vals := s.GetAllValidators().GetShuffled() + for _, val := range vals { if val.RewardsLocked() { continue } diff --git a/helpers/tests/simulator/sim_ops_rewards_validator.go b/helpers/tests/simulator/sim_ops_rewards_validator.go index 1cfcb9e3..de5463cf 100644 --- a/helpers/tests/simulator/sim_ops_rewards_validator.go +++ b/helpers/tests/simulator/sim_ops_rewards_validator.go @@ -7,25 +7,28 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// NewGetValidatorRewardOp takes validator commissions rewards. -// Op priority: -// validator - random; +type validatorRewardOp struct { + Acc *SimAccount + Val *SimValidator +} + +// NewGetValidatorRewardOp takes all validators commissions rewards. func NewGetValidatorRewardOp(period time.Duration) *SimOperation { id := "ValidatorRewardOp" handler := func(s *Simulator) (bool, string) { - targetAcc, targetVal, rewardCoins := getValidatorRewardOpFindTarget(s) - if targetAcc == nil || targetVal == nil { + targets, rewardCoins := getValidatorRewardOpFindTarget(s) + if len(targets) == 0 { return false, "target not found" } - if getValidatorRewardOpHandle(s, targetAcc, targetVal) { - msg := fmt.Sprintf("can't withdraw %s validator commission", targetVal.GetAddress()) + if stopMsg := getValidatorRewardOpHandle(s, targets); stopMsg != "" { + msg := fmt.Sprintf("withdraw validator commission failed: %s", stopMsg) return false, msg } - getValidatorRewardOpPost(s, targetAcc, rewardCoins) - msg := fmt.Sprintf("%s for %s: %s", targetVal.GetAddress(), targetAcc.Address, s.FormatCoins(rewardCoins)) + getValidatorRewardOpPost(s, targets, rewardCoins) + msg := fmt.Sprintf("total from %d targets: %s", len(targets), s.FormatCoins(rewardCoins)) return true, msg } @@ -33,7 +36,7 @@ func NewGetValidatorRewardOp(period time.Duration) *SimOperation { return NewSimOperation(id, period, NewPeriodicNextExecFn(), handler) } -func getValidatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, targetVal *SimValidator, rewardCoins sdk.Coins) { +func getValidatorRewardOpFindTarget(s *Simulator) (targets []validatorRewardOp, rewardCoins sdk.Coins) { rewardCoins = sdk.NewCoins() for _, val := range s.GetAllValidators().GetShuffled() { @@ -44,30 +47,40 @@ func getValidatorRewardOpFindTarget(s *Simulator) (targetAcc *SimAccount, target } // estimate reward coins + curRewardCoins := sdk.NewCoins() for _, decCoin := range decCoins { coin, _ := decCoin.TruncateDecimal() - rewardCoins = rewardCoins.Add(coin) + curRewardCoins = curRewardCoins.Add(coin) } - targetVal = val - targetAcc = s.GetAllAccounts().GetByAddress(targetVal.GetOperatorAddress()) + targets = append(targets, validatorRewardOp{ + Acc: s.GetAllAccounts().GetByAddress(val.GetOperatorAddress()), + Val: val, + }) + rewardCoins = rewardCoins.Add(curRewardCoins...) } return } -func getValidatorRewardOpHandle(s *Simulator, targetAcc *SimAccount, targetVal *SimValidator) (stop bool) { - if s.TxDistValidatorCommission(targetAcc, targetVal.GetAddress()) { - stop = true +func getValidatorRewardOpHandle(s *Simulator, targets []validatorRewardOp) (stopMsg string) { + for _, target := range targets { + if s.TxDistValidatorCommission(target.Acc, target.Val.GetAddress()) { + stopMsg = fmt.Sprintf("targetVal %s", target.Val.GetAddress()) + return + } } return } -func getValidatorRewardOpPost(s *Simulator, targetAcc *SimAccount, rewardCoins sdk.Coins) { +func getValidatorRewardOpPost(s *Simulator, targets []validatorRewardOp, rewardCoins sdk.Coins) { // update account - s.UpdateAccount(targetAcc) + for _, target := range targets { + s.UpdateAccount(target.Acc) + } // update stats - s.counter.Commissions++ - s.counter.CommissionsCollected = s.counter.CommissionsCollected.Add(rewardCoins...) + s.counter.CommissionWithdraws += int64(len(targets)) + s.counter.CommissionsCollectedMain = s.counter.CommissionsCollectedMain.Add(rewardCoins.AmountOf(s.mainDenom)) + s.counter.CommissionsCollectedStaking = s.counter.CommissionsCollectedStaking.Add(rewardCoins.AmountOf(s.stakingDenom)) } diff --git a/helpers/tests/simulator/sim_ops_undelegate.go b/helpers/tests/simulator/sim_ops_undelegate.go index ed41b3bc..437367c5 100644 --- a/helpers/tests/simulator/sim_ops_undelegate.go +++ b/helpers/tests/simulator/sim_ops_undelegate.go @@ -70,9 +70,11 @@ func undelegateOpFindTarget(s *Simulator, bondingUD bool, udRatio sdk.Dec) (targ } // pick a validator with the highest tokens amount (all statuses) - for _, val := range s.GetAllValidators().GetSortedByTokens(bondingUD, true) { + vals := s.GetAllValidators().GetSortedByTokens(bondingUD, true) + for _, val := range vals { // pick a random account - for _, acc := range s.GetAllAccounts().GetShuffled() { + accs := s.GetAllAccounts().GetShuffled() + for _, acc := range accs { accValAddr := sdk.ValAddress{} if acc.IsValOperator() { accValAddr = acc.OperatedValidator.GetAddress() diff --git a/helpers/tests/simulator/sim_queries.go b/helpers/tests/simulator/sim_queries.go index 2602660a..2a8840ef 100644 --- a/helpers/tests/simulator/sim_queries.go +++ b/helpers/tests/simulator/sim_queries.go @@ -289,6 +289,18 @@ func (s *Simulator) QueryDistLockState(val sdk.ValAddress) (res distribution.Que return res } +// QueryDistLockedRatio queries current locked ratio. +func (s *Simulator) QueryDistLockedRatio() (res sdk.Dec) { + resp := s.RunQuery( + nil, + "/custom/"+distribution.QuerierRoute+"/"+distribution.QueryLockedRatio, + &res, + ) + require.True(s.t, resp.IsOK()) + + return res +} + // QueryDistPool queries supply total supply. func (s *Simulator) QuerySupplyTotal() (res sdk.Coins) { resp := s.RunQuery( @@ -304,6 +316,18 @@ func (s *Simulator) QuerySupplyTotal() (res sdk.Coins) { return res } +// QuerySupplyModuleBalance queries module account balance. +func (s *Simulator) QuerySupplyModuleBalance(moduleName string) (res sdk.Coins) { + resp := s.RunQuery( + nil, + "/custom/"+supply.QuerierRoute+"/"+supply.QueryModuleBalance+"/"+moduleName, + &res, + ) + require.True(s.t, resp.IsOK()) + + return res +} + // QueryReadAllValidators reads out all validators independent of their status. func (s *Simulator) QueryReadAllValidators() (validators staking.Validators) { valsPage := 1 diff --git a/helpers/tests/simulator/sim_report.go b/helpers/tests/simulator/sim_report.go index 2078e42a..b1bb9b68 100644 --- a/helpers/tests/simulator/sim_report.go +++ b/helpers/tests/simulator/sim_report.go @@ -37,6 +37,11 @@ type SimReportItem struct { DistFoundationPool sdk.Dec // FoundationPool funds DistLiquidityProvidersPool sdk.Dec // LiquidityProvidersPool funds DistHARP sdk.Dec // HARP funds + DistModuleBalanceMain sdk.Int // Distribution module balance [main] + DistModuleBalanceStaking sdk.Int // Distribution module balance [staking] + DistBankBalanceMain sdk.Int // Distribution bank balance [main] + DistBankBalanceStaking sdk.Int // Distribution bank balance [staking] + DistLockedRatio sdk.Dec // Current locked ratio // SupplyTotalMain sdk.Int // total supply [main denom] SupplyTotalStaking sdk.Int // total supply [staking denom] @@ -45,6 +50,9 @@ type SimReportItem struct { StatsBondedRatio sdk.Dec // BondedTokens / TotalSupply ratio [staking denom] StatsLPRatio sdk.Dec // BondedTokens / TotalSupply ratio [LP denom] // + AccsBalanceMain sdk.Int + AccsBalanceStaking sdk.Int + // Counters Counter // formatIntDecimals func(value sdk.Int) string @@ -92,9 +100,19 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * foundationPool := s.QueryDistPool(distribution.FoundationPoolName) liquidityPool := s.QueryDistPool(distribution.LiquidityProvidersPoolName) harpPool := s.QueryDistPool(distribution.HARPName) + distrMAccBalance := s.QuerySupplyModuleBalance(distribution.ModuleName) + distrBankBalance := s.QuerySupplyModuleBalance(distribution.RewardsBankPoolName) + // supply totalSupply := s.QuerySupplyTotal() + // accounts + accsTotalMain, accsTotalStaking := sdk.ZeroInt(), sdk.ZeroInt() + for _, acc := range s.GetAllAccounts() { + accsTotalMain = accsTotalMain.Add(acc.Coins.AmountOf(s.mainDenom)) + accsTotalStaking = accsTotalStaking.Add(acc.Coins.AmountOf(s.stakingDenom)) + } + item := SimReportItem{ Index: reportItemIdx, BlockHeight: simBlockHeight, @@ -119,11 +137,19 @@ func NewReportOp(period time.Duration, debug bool, writers ...SimReportWriter) * DistFoundationPool: foundationPool.AmountOf(s.stakingDenom), DistLiquidityProvidersPool: liquidityPool.AmountOf(s.stakingDenom), DistHARP: harpPool.AmountOf(s.stakingDenom), + DistModuleBalanceMain: distrMAccBalance.AmountOf(s.mainDenom), + DistModuleBalanceStaking: distrMAccBalance.AmountOf(s.stakingDenom), + DistBankBalanceMain: distrBankBalance.AmountOf(s.mainDenom), + DistBankBalanceStaking: distrBankBalance.AmountOf(s.stakingDenom), + DistLockedRatio: s.QueryDistLockedRatio(), // SupplyTotalMain: totalSupply.AmountOf(s.mainDenom), SupplyTotalStaking: totalSupply.AmountOf(s.stakingDenom), SupplyTotalLP: totalSupply.AmountOf(s.lpDenom), // + AccsBalanceMain: accsTotalMain, + AccsBalanceStaking: accsTotalStaking, + // Counters: s.counter, // formatIntDecimals: func(value sdk.Int) string { @@ -184,25 +210,34 @@ func (w *SimReportConsoleWriter) Write(item SimReportItem) { str.WriteString(fmt.Sprintf(" Dist: PTreasuryPool: %s\n", item.formatDecDecimals(item.DistPublicTreasuryPool))) str.WriteString(fmt.Sprintf(" Dist: LiquidityPPool: %s\n", item.formatDecDecimals(item.DistLiquidityProvidersPool))) str.WriteString(fmt.Sprintf(" Dist: HARP: %s\n", item.formatDecDecimals(item.DistHARP))) + str.WriteString(fmt.Sprintf(" Dist: MAccBalance [m] %s\n", item.formatIntDecimals(item.DistModuleBalanceMain))) + str.WriteString(fmt.Sprintf(" Dist: MAccBalance [s] %s\n", item.formatIntDecimals(item.DistModuleBalanceStaking))) + str.WriteString(fmt.Sprintf(" Dist: BankBalance [m] %s\n", item.formatIntDecimals(item.DistBankBalanceMain))) + str.WriteString(fmt.Sprintf(" Dist: BankBalance [s] %s\n", item.formatIntDecimals(item.DistBankBalanceStaking))) + str.WriteString(fmt.Sprintf(" Dist: LockedRatio %s\n", item.DistLockedRatio)) str.WriteString(fmt.Sprintf(" Supply: TotalMain: %s\n", item.formatIntDecimals(item.SupplyTotalMain))) str.WriteString(fmt.Sprintf(" Supply: TotalStaking: %s\n", item.formatIntDecimals(item.SupplyTotalStaking))) str.WriteString(fmt.Sprintf(" Supply: LPs: %s\n", item.formatIntDecimals(item.SupplyTotalLP))) - str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply [B]: %s\n", item.StatsBondedRatio)) + str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply [s]: %s\n", item.StatsBondedRatio)) str.WriteString(fmt.Sprintf(" Stats: Bonded/TotalSupply [LP]: %s\n", item.StatsLPRatio)) + str.WriteString(fmt.Sprintf(" Accounts: Balance [m]: %s\n", item.formatIntDecimals(item.AccsBalanceMain))) + str.WriteString(fmt.Sprintf(" Accounts: Balance [s]: %s\n", item.formatIntDecimals(item.AccsBalanceStaking))) str.WriteString(" Counters:\n") str.WriteString(" Bonding:\n") - str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.BDelegations)) - str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.BRedelegations)) - str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.BUndelegations)) + str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.BDelegations)) + str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.BRedelegations)) + str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.BUndelegations)) str.WriteString(" LP:\n") - str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.LPDelegations)) - str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.LPRedelegations)) - str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.LPUndelegations)) - str.WriteString(fmt.Sprintf(" Rewards: %d\n", item.Counters.Rewards)) - str.WriteString(fmt.Sprintf(" RewardsCollected: %s\n", item.formatCoinsDecimals(item.Counters.RewardsCollected))) - str.WriteString(fmt.Sprintf(" Commissions: %d\n", item.Counters.Commissions)) - str.WriteString(fmt.Sprintf(" CommissionsCollected: %s\n", item.formatCoinsDecimals(item.Counters.CommissionsCollected))) - str.WriteString(fmt.Sprintf(" Locked rewards: %d\n", item.Counters.LockedRewards)) + str.WriteString(fmt.Sprintf(" Delegations: %d\n", item.Counters.LPDelegations)) + str.WriteString(fmt.Sprintf(" Redelegations: %d\n", item.Counters.LPRedelegations)) + str.WriteString(fmt.Sprintf(" Undelegations: %d\n", item.Counters.LPUndelegations)) + str.WriteString(fmt.Sprintf(" RewardWithdraws: %d\n", item.Counters.RewardsWithdraws)) + str.WriteString(fmt.Sprintf(" RewardsCollected [m]: %s\n", item.formatIntDecimals(item.Counters.RewardsCollectedMain))) + str.WriteString(fmt.Sprintf(" RewardsCollected [s]: %s\n", item.formatIntDecimals(item.Counters.RewardsCollectedStaking))) + str.WriteString(fmt.Sprintf(" CommissionWithdraws: %d\n", item.Counters.CommissionWithdraws)) + str.WriteString(fmt.Sprintf(" CommissionsCollected [m]: %s\n", item.formatIntDecimals(item.Counters.CommissionsCollectedMain))) + str.WriteString(fmt.Sprintf(" CommissionsCollected [s]: %s\n", item.formatIntDecimals(item.Counters.CommissionsCollectedStaking))) + str.WriteString(fmt.Sprintf(" Locked rewards: %d\n", item.Counters.LockedRewards)) fmt.Println(str.String()) } diff --git a/helpers/tests/simulator/sim_report_csv.go b/helpers/tests/simulator/sim_report_csv.go index c1a08aa7..41612a4d 100644 --- a/helpers/tests/simulator/sim_report_csv.go +++ b/helpers/tests/simulator/sim_report_csv.go @@ -34,21 +34,30 @@ var Headers = []string{ "Dist: PTreasuryPool", "Dist: LiquidityPPool", "Dist: HARP", + "Dist: MAccBalance [main]", + "Dist: MAccBalance [staking]", + "Dist: BankBalance [main]", + "Dist: BankBalance [staking]", + "Dist: LockedRatio", "Supply: Total [main]", "Supply: Total [staking]", "Supply: Total [LP]", - "Stats: Bonded/TotalSupply [bonding]", - "Stats: Bonded/TotalSupply [LPs]", + "Stats: Staked/TotalSupply [staking]", + "Stats: Staked/TotalSupply [LPs]", + "Accounts: TotalBalance [main]", + "Accounts: TotalBalance [staking]", "Counters: Bonding: Delegations", "Counters: Bonding: Redelegations", "Counters: Bonding: Undelegations", "Counters: LP: Delegations", "Counters: LP: Redelegations", "Counters: LP: Undelegations", - "Counters: Rewards", - "Counters: RewardsCollected", - "Counters: Commissions", - "Counters: CommissionsCollected", + "Counters: RewardWithdraws", + "Counters: RewardsCollected [main]", + "Counters: RewardsCollected [staking]", + "Counters: CommissionWithdraws", + "Counters: CommissionsCollected [main]", + "Counters: CommissionsCollected [staking]", "Counters: LockedRewards", } @@ -76,36 +85,58 @@ func (w *SimReportCSVWriter) Write(item SimReportItem) { strconv.FormatInt(item.BlockHeight, 10), item.BlockTime.Format("02.01.2006T15:04:05"), FormatDuration(item.SimulationDur), + // validators strconv.Itoa(item.ValidatorsBonded), strconv.Itoa(item.ValidatorsUnbonding), strconv.Itoa(item.ValidatorsUnbonded), - item.StakingBonded.String(), - item.StakingNotBonded.String(), - item.StakingLPs.String(), + // staking + item.formatIntDecimals(item.StakingBonded), + item.formatIntDecimals(item.StakingNotBonded), + item.formatIntDecimals(item.StakingLPs), strconv.Itoa(item.RedelegationsInProcess), + // mint item.MintMinInflation.String(), item.MintMaxInflation.String(), - item.MintAnnualProvisions.String(), + item.formatDecDecimals(item.MintAnnualProvisions), strconv.FormatUint(item.MintBlocksPerYear, 10), - item.DistFoundationPool.String(), - item.DistPublicTreasuryPool.String(), - item.DistLiquidityProvidersPool.String(), - item.DistHARP.String(), - item.SupplyTotalMain.String(), - item.SupplyTotalStaking.String(), - item.SupplyTotalLP.String(), + // distribution + item.formatDecDecimals(item.DistFoundationPool), + item.formatDecDecimals(item.DistPublicTreasuryPool), + item.formatDecDecimals(item.DistLiquidityProvidersPool), + item.formatDecDecimals(item.DistHARP), + item.formatIntDecimals(item.DistModuleBalanceMain), + item.formatIntDecimals(item.DistModuleBalanceStaking), + item.formatIntDecimals(item.DistBankBalanceMain), + item.formatIntDecimals(item.DistBankBalanceStaking), + item.DistLockedRatio.String(), + // supply + item.formatIntDecimals(item.SupplyTotalMain), + item.formatIntDecimals(item.SupplyTotalStaking), + item.formatIntDecimals(item.SupplyTotalLP), + // stats item.StatsBondedRatio.String(), item.StatsLPRatio.String(), + // accounts + item.formatIntDecimals(item.AccsBalanceMain), + item.formatIntDecimals(item.AccsBalanceStaking), + // counters + // - bonding strconv.FormatInt(item.Counters.BDelegations, 10), strconv.FormatInt(item.Counters.BRedelegations, 10), strconv.FormatInt(item.Counters.BUndelegations, 10), + // - LP strconv.FormatInt(item.Counters.LPDelegations, 10), strconv.FormatInt(item.Counters.LPRedelegations, 10), strconv.FormatInt(item.Counters.LPUndelegations, 10), - strconv.FormatInt(item.Counters.Rewards, 10), - item.Counters.RewardsCollected.String(), - strconv.FormatInt(item.Counters.Commissions, 10), - item.Counters.CommissionsCollected.String(), + // - rewards + strconv.FormatInt(item.Counters.RewardsWithdraws, 10), + item.formatIntDecimals(item.Counters.RewardsCollectedMain), + item.formatIntDecimals(item.Counters.RewardsCollectedStaking), + // - commissions + strconv.FormatInt(item.Counters.CommissionWithdraws, 10), + item.formatIntDecimals(item.Counters.CommissionsCollectedMain), + item.formatIntDecimals(item.Counters.CommissionsCollectedStaking), + // - locking strconv.FormatInt(item.Counters.LockedRewards, 10), } From 3cd4f7a78d681faeca77f7a23132b7d740916d8c Mon Sep 17 00:00:00 2001 From: Valeriy Kabisov Date: Wed, 14 Oct 2020 00:16:06 +0900 Subject: [PATCH 05/20] [DFI-753] migrate swagger to dfinance cosmos-sdk version (#218) * [DFI-753] migrate swagger to dfinance cosmos-sdk version * Cosmos SDK version bump, Swagger update * go mod tidy Co-authored-by: Mikhail Kornilov (cherry picked from commit c7eaa784f51df6add0d3e165ff806b8bbc98a465) --- Makefile | 6 +- cmd/dncli/docs/swagger.go | 2590 +++++++++++++++++++++++++++++-------- go.mod | 8 +- go.sum | 22 +- 4 files changed, 2032 insertions(+), 594 deletions(-) diff --git a/Makefile b/Makefile index c495b31e..71d72928 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ cosmos_dir=$(swagger_dir)/cosmos-sdk dnode = ./cmd/dnode dncli =./cmd/dncli -cosmos_version = v0.39.1 +cosmos_version = dfinance/launchpad all: install install: go.sum install-dnode install-dncli @@ -58,7 +58,7 @@ swagger-ui-deps: mkdir -p $(cosmos_dir) @echo "-> Cosmos-SDK $(cosmos_version) checkout" - git -C $(swagger_dir) clone --branch $(cosmos_version) https://github.com/cosmos/cosmos-sdk.git + git -C $(swagger_dir) clone --branch $(cosmos_version) https://github.com/dfinance/cosmos-sdk.git @echo "-> Fetching Golang libraries: swag, statik" go get -u github.com/swaggo/swag/cmd/swag @@ -71,7 +71,7 @@ swagger-ui-build: swag init --dir . --output $(swagger_dir) --generalInfo ./cmd/dnode/main.go --parseDependency @echo "-> Merging swagger files" - go-swagger-merger -o ./cmd/dncli/docs/swagger.yaml $(swagger_dir)/swagger.yaml $(cosmos_dir)/client/lcd/swagger-ui/swagger.yaml + go-swagger-merger -o ./cmd/dncli/docs/swagger.yaml $(swagger_dir)/swagger.yaml $(cosmos_dir)/client/lcd/swagger-auto/swagger.yaml @echo "-> Building swagger.go file" echo "// Code generated by Makefile. DO NOT EDIT.\n" > ./cmd/dncli/docs/swagger.go diff --git a/cmd/dncli/docs/swagger.go b/cmd/dncli/docs/swagger.go index ae868625..05ae8112 100644 --- a/cmd/dncli/docs/swagger.go +++ b/cmd/dncli/docs/swagger.go @@ -279,6 +279,61 @@ definitions: proposal_id: type: string type: object + DistributionParams: + properties: + base_proposer_reward: + description: Block proposer base reward ratio + example: "0.123" + format: number + type: string + bonus_proposer_reward: + description: Block proposer bonus reward ratio + example: "0.123" + format: number + type: string + foundation_nominees: + example: + - wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + items: + type: string + type: array + harp_tax: + description: Rewards distribution ratio for HARP + example: "0.123" + format: number + type: string + liquidity_providers_pool_tax: + description: Rewards distribution ratio for LiquidityProvidersPool + example: "0.123" + format: number + type: string + locked_dur: + description: Rewards lock duration + type: string + locked_ratio: + description: Validator distribution power calculation coefficient + example: "0.123" + format: number + type: string + public_treasury_pool_capacity: + description: PublicTreasuryPool max amount limit + example: "100" + format: integer + type: string + public_treasury_pool_tax: + description: Rewards distribution ratio for PublicTreasuryPool + example: "0.123" + format: number + type: string + validators_pool_tax: + description: Rewards distribution ratio for ValidatorsPool + example: "0.123" + format: number + type: string + withdraw_addr_enabled: + type: boolean + type: object Hash: example: EE5F3404034C524501629B56E0DDC38FAD651F04 type: string @@ -289,6 +344,46 @@ definitions: value: type: string type: object + MintParams: + properties: + avg_block_time_window: + description: Avg block time filter window size + type: integer + fee_burning_ratio: + description: '% of fees burned (per block)' + example: "0.123" + format: number + type: string + foundation_allocation_ratio: + description: Extra Foundation pool allocation inflation ratio + example: "0.123" + format: number + type: string + inflation_max: + description: Maximum inflation rate (annual) + example: "0.123" + format: number + type: string + inflation_min: + description: Minimum inflation rate (annual) + example: "0.123" + format: number + type: string + infpwr_bondedlocked_ratio: + description: Bonded, locked shoulders relation for inflation power calculation + example: "0.123" + format: number + type: string + mint_denom: + description: Type of coin to mint + example: stake + type: string + staking_total_supply_shift: + description: BondedRatio denominator (TotalSupply) shift coefficient + example: "100" + format: integer + type: string + type: object Msg: type: string PaginatedQueryTxs: @@ -378,6 +473,47 @@ definitions: start_height: type: string type: object + StakingParams: + properties: + bond_denom: + description: Bondable coin denomination + example: stake + type: string + historical_entries: + description: Number of historical entries to persist + type: integer + lp_denom: + description: Liquidity coin denomination + example: liqd + type: string + lp_distr_ratio: + description: Gov voting and distribution ratio between bonding tokens and liquidity tokens (BTokens + LPDistrRatio * LPTokens) + example: "0.123" + format: number + type: string + max_delegations_ratio: + description: Max delegations per validator is limited by (CurrentSelfDelegation * KeyMaxDelegationsRatio) + example: "0.123" + format: number + type: string + max_entries: + description: Max entries for either unbonding delegation or redelegation (per pair/trio) + type: integer + max_validators: + description: Maximum number of validators (max uint16 = 65535) + type: integer + min_self_delegation_lvl: + description: Min self delegation level for validator creation + example: "100" + format: integer + type: string + scheduled_unbond_delay: + description: Time duration of validator.ScheduledToUnbond to be raised up before forced unbonding is done + type: string + unbonding_time: + description: Time duration of unbonding + type: string + type: object StdTx: properties: fee: @@ -621,8 +757,16 @@ definitions: voter: type: string type: object + auth.StdFee: + $ref: '#/definitions/types.StdFee' + auth.StdSignature: + $ref: '#/definitions/types.StdSignature' auth.StdTx: $ref: '#/definitions/types.StdTx' + bytes.HexBytes: + items: + type: integer + type: array ccstorage.Currencies: $ref: '#/definitions/types.Currencies' ccstorage.Currency: @@ -728,6 +872,25 @@ definitions: format: string representation for big.Uint type: string type: object + rest.DelegateRequest: + properties: + amount: + $ref: '#/definitions/types.Coin' + type: object + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + delegator_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object rest.ErrorResponse: properties: code: @@ -931,6 +1094,10 @@ definitions: type: object rest.PostPriceReq: properties: + ask_price: + description: AskPrice in sdk.Int format + example: "100" + type: string asset_code: description: AssetCode example: btc_xfi @@ -938,9 +1105,9 @@ definitions: base_req: $ref: '#/definitions/rest.BaseReq' type: object - price: - description: Price in big.Int format - example: "100" + bid_price: + description: BidPrice in sdk.Int format + example: "99" type: string received_at: description: Timestamp price createdAt @@ -958,158 +1125,507 @@ definitions: format: HEX encoded byte code type: string type: object - rest.RevokeOrderMsg: + rest.QueryAddressResp: properties: - type: + height: + type: integer + result: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 type: string - value: - $ref: '#/definitions/types.MsgRevokeOrder' - type: object type: object - rest.RevokeOrderReq: + rest.QueryDecCoinsResp: properties: - base_req: - $ref: '#/definitions/rest.BaseReq' - type: object - order_id: - example: "100" + height: + type: integer + result: + items: + $ref: '#/definitions/types.DecCoin' + type: array + type: object + rest.QueryDecResp: + properties: + height: + type: integer + result: + example: "0.123" + format: number type: string type: object - rest.RevokeReq: + rest.QueryDelegationDelegatorRewardsResp: properties: - base_req: - $ref: '#/definitions/rest.BaseReq' + height: + type: integer + result: + items: + $ref: '#/definitions/types.DelegationDelegatorReward' + type: array + type: object + rest.QueryDelegationResp: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.Delegation' type: object - call_id: - description: Confirming CallID - example: "0" - format: string representation for big.Uint - type: string type: object - rest.SubmitIssueReq: + rest.QueryDelegationsResp: properties: - base_req: - $ref: '#/definitions/rest.BaseReq' + height: + type: integer + result: + items: + $ref: '#/definitions/types.DelegationResponse' + type: array + type: object + rest.QueryExtendedValidatorResp: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.ValidatorResp' type: object - coin: - $ref: '#/definitions/types.Coin' - description: Target currency issue coin + type: object + rest.QueryExtendedValidatorsResp: + properties: + height: + type: integer + result: + items: + $ref: '#/definitions/types.ValidatorResp' + type: array + type: object + rest.QueryHistoricalInfoResp: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.HistoricalInfo' type: object - id: - description: Issue unique ID (could be txHash of transaction in another blockchain) - type: string - payee: - description: Payee account (whose balance is increased) - example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h - format: bech32/hex - type: string type: object - rest.UnstakeReq: + rest.QueryMinterExtendedResp: properties: - base_req: - $ref: '#/definitions/rest.BaseReq' + height: + type: integer + result: + $ref: '#/definitions/types.MintInfo' type: object - id: - description: Unstake unique ID (could be txHash of transaction in another blockchain) - type: string - staker: - description: Staker account (whose balance is increased) - example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h - format: bech32/hex - type: string type: object - rest.VmData: + rest.QueryParamsResp: properties: height: type: integer result: - $ref: '#/definitions/types.ValueResp' + $ref: '#/definitions/StakingParams' type: object type: object - rest.VmRespCompile: + rest.QueryPoolResp: properties: height: type: integer result: - $ref: '#/definitions/vm_client.MoveFile' + $ref: '#/definitions/types.Pool' type: object type: object - rest.VmRespLcsView: + rest.QueryRedelegationsResp: properties: height: type: integer result: - $ref: '#/definitions/rest.LcsViewResp' + items: + $ref: '#/definitions/types.RedelegationResponse' + type: array + type: object + rest.QuerySwaggerValidatorDistInfoResp: + properties: + height: + type: integer + result: + properties: + operator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + self_bond_rewards: + $ref: '#/definitions/types.DecCoins' + type: object + validator_commission: + $ref: '#/definitions/types.DecCoins' + type: object type: object type: object - rest.VmRespStdTx: + rest.QueryUnbondingDelegationResp: properties: height: type: integer result: - $ref: '#/definitions/auth.StdTx' + $ref: '#/definitions/types.UnbondingDelegation' type: object type: object - rest.VmTxStatus: + rest.QueryUnbondingDelegationsResp: properties: height: type: integer result: - $ref: '#/definitions/types.TxVMStatus' + items: + $ref: '#/definitions/types.UnbondingDelegation' + type: array + type: object + rest.QueryValidatorResp: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.Validator' type: object type: object - rest.WithdrawReq: + rest.QueryValidatorsResp: + properties: + height: + type: integer + result: + items: + $ref: '#/definitions/types.Validator' + type: array + type: object + rest.RedelegateRequest: properties: + amount: + $ref: '#/definitions/types.Coin' + type: object base_req: $ref: '#/definitions/rest.BaseReq' type: object - coin: - $ref: '#/definitions/types.Coin' - description: Target currency withdraw coin - type: object - pegzone_chain_id: - description: 'Second blockchain: ID' + delegator_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 type: string - pegzone_payee: - description: 'Second blockchain: payee account (whose balance is increased)' + validator_dst_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_src_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 type: string type: object - types.AccAddress: - items: - type: integer - type: array - types.Asset: + rest.RevokeOrderMsg: properties: - active: - description: Not used ATM - type: boolean - asset_code: - description: Asset code - example: btc_xfi + type: type: string - oracles: - $ref: '#/definitions/types.Oracles' - description: List of registered RawPrice sources + value: + $ref: '#/definitions/types.MsgRevokeOrder' type: object type: object - types.Assets: - items: - $ref: '#/definitions/types.Asset' - type: array - types.Call: + rest.RevokeOrderReq: properties: - approved: - description: 'Call state: approved to execute' - type: boolean - creator: - description: Call creator address - example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h - format: bech32 + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + order_id: + example: "100" type: string - error: - description: Call fail reason + type: object + rest.RevokeReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + call_id: + description: Confirming CallID + example: "0" + format: string representation for big.Uint type: string - executed: + type: object + rest.SubmitIssueReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + coin: + $ref: '#/definitions/types.Coin' + description: Target currency issue coin + type: object + id: + description: Issue unique ID (could be txHash of transaction in another blockchain) + type: string + payee: + description: Payee account (whose balance is increased) + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32/hex + type: string + type: object + rest.TxBeginRedelegate: + properties: + fee: + $ref: '#/definitions/types.StdFee' + type: object + memo: + type: string + msg: + items: + $ref: '#/definitions/types.MsgBeginRedelegate' + type: array + signatures: + items: + $ref: '#/definitions/types.StdSignature' + type: array + type: object + rest.TxFundPublicTreasuryPool: + properties: + fee: + $ref: '#/definitions/types.StdFee' + type: object + memo: + type: string + msg: + items: + $ref: '#/definitions/types.MsgFundPublicTreasuryPool' + type: array + signatures: + items: + $ref: '#/definitions/types.StdSignature' + type: array + type: object + rest.TxSetWithdrawAddress: + properties: + fee: + $ref: '#/definitions/types.StdFee' + type: object + memo: + type: string + msg: + items: + $ref: '#/definitions/types.MsgSetWithdrawAddress' + type: array + signatures: + items: + $ref: '#/definitions/types.StdSignature' + type: array + type: object + rest.TxUndelegate: + properties: + fee: + $ref: '#/definitions/types.StdFee' + type: object + memo: + type: string + msg: + items: + $ref: '#/definitions/types.MsgUndelegate' + type: array + signatures: + items: + $ref: '#/definitions/types.StdSignature' + type: array + type: object + rest.TxWithdrawDelegatorReward: + properties: + fee: + $ref: '#/definitions/types.StdFee' + type: object + memo: + type: string + msg: + items: + $ref: '#/definitions/types.MsgWithdrawDelegatorReward' + type: array + signatures: + items: + $ref: '#/definitions/types.StdSignature' + type: array + type: object + rest.UndelegateRequest: + properties: + amount: + $ref: '#/definitions/types.Coin' + type: object + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + delegator_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_address: + description: in bech32 + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + rest.UnstakeReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + id: + description: Unstake unique ID (could be txHash of transaction in another blockchain) + type: string + staker: + description: Staker account (whose balance is increased) + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32/hex + type: string + type: object + rest.VmData: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.ValueResp' + type: object + type: object + rest.VmRespCompile: + properties: + height: + type: integer + result: + $ref: '#/definitions/vm_client.MoveFile' + type: object + type: object + rest.VmRespLcsView: + properties: + height: + type: integer + result: + $ref: '#/definitions/rest.LcsViewResp' + type: object + type: object + rest.VmRespStdTx: + properties: + height: + type: integer + result: + $ref: '#/definitions/auth.StdTx' + type: object + type: object + rest.VmTxStatus: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.TxVMStatus' + type: object + type: object + rest.WithdrawReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + coin: + $ref: '#/definitions/types.Coin' + description: Target currency withdraw coin + type: object + pegzone_chain_id: + description: 'Second blockchain: ID' + type: string + pegzone_payee: + description: 'Second blockchain: payee account (whose balance is increased)' + type: string + type: object + rest.fundPublicTreasuryPoolReq: + properties: + amount: + $ref: '#/definitions/types.Coins' + type: object + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + type: object + rest.setWithdrawalAddrReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + withdraw_address: + $ref: '#/definitions/types.AccAddress' + type: object + type: object + rest.withdrawRewardsReq: + properties: + base_req: + $ref: '#/definitions/rest.BaseReq' + type: object + type: object + staking.Commission: + $ref: '#/definitions/types.Commission' + staking.Description: + $ref: '#/definitions/types.Description' + types.ABCIMessageLog: + properties: + events: + $ref: '#/definitions/types.StringEvents' + description: |- + Events contains a slice of Event objects that were emitted during some + execution. + type: object + log: + type: string + msg_index: + type: integer + type: object + types.ABCIMessageLogs: + items: + $ref: '#/definitions/types.ABCIMessageLog' + type: array + types.AccAddress: + items: + type: integer + type: array + types.Address: + type: object + types.Asset: + properties: + active: + description: Not used ATM + type: boolean + asset_code: + description: Asset code + example: btc_xfi + type: string + oracles: + $ref: '#/definitions/types.Oracles' + description: List of registered RawPrice sources + type: object + type: object + types.Assets: + items: + $ref: '#/definitions/types.Asset' + type: array + types.Attribute: + properties: + key: + type: string + value: + type: string + type: object + types.BlockID: + properties: + hash: + $ref: '#/definitions/bytes.HexBytes' + type: object + parts: + $ref: '#/definitions/types.PartSetHeader' + type: object + type: object + types.Call: + properties: + approved: + description: 'Call state: approved to execute' + type: boolean + creator: + description: Call creator address + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + error: + description: Call fail reason + type: string + executed: description: 'Call state: executed' type: boolean failed: @@ -1163,13 +1679,15 @@ definitions: types.Coin: properties: amount: - $ref: '#/definitions/types.Int' description: |- To allow the use of unsigned integers (see: #1273) a larger refactor will need to be made. So we use signed integers for now with safety measures in place preventing negative values being used. - type: object + example: "100" + format: number + type: string denom: + example: stake type: string type: object types.Coins: @@ -1179,17 +1697,20 @@ definitions: types.Commission: properties: max_change_rate: - $ref: '#/definitions/types.Dec' description: maximum daily increase of the validator commission, as a fraction - type: object + example: "0.5" + format: number + type: string max_rate: - $ref: '#/definitions/types.Dec' description: maximum commission rate which validator can ever charge, as a fraction - type: object + example: "0.3" + format: number + type: string rate: - $ref: '#/definitions/types.Dec' description: the commission rate charged to delegators, as a fraction - type: object + example: "0.1" + format: number + type: string update_time: description: the last time the commission rate was changed type: string @@ -1215,12 +1736,16 @@ definitions: type: object types.CurrentPrice: properties: + ask_price: + description: AskPrice + example: "1000" + type: string asset_code: description: Asset code example: btc_xfi type: string - price: - description: Price + bid_price: + description: BidPrice example: "1000" type: string received_at: @@ -1234,15 +1759,69 @@ definitions: types.DecCoin: properties: amount: - $ref: '#/definitions/types.Dec' - type: object + example: "100" + format: number + type: string denom: + example: stake type: string type: object types.DecCoins: items: $ref: '#/definitions/types.DecCoin' type: array + types.Delegation: + properties: + bonding_shares: + example: "0.1" + format: number + type: string + delegator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + lp_shares: + example: "0.5" + format: number + type: string + validator_address: + example: walletval13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.DelegationDelegatorReward: + properties: + reward: + $ref: '#/definitions/types.DecCoins' + type: object + validator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.DelegationResponse: + properties: + bonding_balance: + type: string + bonding_shares: + example: "0.1" + format: number + type: string + delegator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + lp_balance: + type: string + lp_shares: + example: "0.5" + format: number + type: string + validator_address: + example: walletval13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object types.Description: properties: details: @@ -1261,6 +1840,68 @@ definitions: description: optional website link type: string type: object + types.Header: + properties: + app_hash: + $ref: '#/definitions/bytes.HexBytes' + description: state after txs from the previous block + type: object + chain_id: + type: string + consensus_hash: + $ref: '#/definitions/bytes.HexBytes' + description: consensus params for current block + type: object + data_hash: + $ref: '#/definitions/bytes.HexBytes' + description: transactions + type: object + evidence_hash: + $ref: '#/definitions/bytes.HexBytes' + description: consensus info + type: object + height: + type: integer + last_block_id: + $ref: '#/definitions/types.BlockID' + description: prev block info + type: object + last_commit_hash: + $ref: '#/definitions/bytes.HexBytes' + description: hashes of block data + type: object + last_results_hash: + $ref: '#/definitions/bytes.HexBytes' + description: root hash of all results from the txs from the previous block + type: object + next_validators_hash: + $ref: '#/definitions/bytes.HexBytes' + description: validators for the next block + type: object + proposer_address: + $ref: '#/definitions/types.Address' + description: original proposer of the block + type: object + time: + type: string + validators_hash: + $ref: '#/definitions/bytes.HexBytes' + description: hashes from the app output from the prev block + type: object + version: + $ref: '#/definitions/version.Consensus' + description: basic block info + type: object + type: object + types.HistoricalInfo: + properties: + header: + type: string + valset: + items: + $ref: '#/definitions/types.Validator' + type: array + type: object types.ID: $ref: '#/definitions/sdk.Uint' types.Int: @@ -1313,8 +1954,89 @@ definitions: items: $ref: '#/definitions/types.Market' type: array + types.MintInfo: + properties: + annual_provision_foundation: + $ref: '#/definitions/types.Dec' + type: object + annual_provision_main: + $ref: '#/definitions/types.Dec' + type: object + blocks_per_year_estimation: + type: integer + bonded_ratio: + $ref: '#/definitions/types.Dec' + type: object + foundation_allocation_ratio: + $ref: '#/definitions/types.Dec' + type: object + inflation_foundation: + $ref: '#/definitions/types.Dec' + type: object + inflation_main: + $ref: '#/definitions/types.Dec' + type: object + infpwr_bondedlocked_ratio: + $ref: '#/definitions/types.Dec' + type: object + locked_ratio: + $ref: '#/definitions/types.Dec' + type: object + max_inflation: + $ref: '#/definitions/types.Dec' + type: object + min_inflation: + $ref: '#/definitions/types.Dec' + type: object + next_annual_update: + type: string + staking_total_supply_shift: + $ref: '#/definitions/types.Int' + type: object + type: object types.Msg: type: object + types.MsgBeginRedelegate: + properties: + amount: + $ref: '#/definitions/types.Coin' + type: object + delegator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_dst_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_src_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.MsgDelegate: + properties: + amount: + $ref: '#/definitions/types.Coin' + type: object + delegator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.MsgFundPublicTreasuryPool: + properties: + amount: + $ref: '#/definitions/types.Coins' + type: object + depositor: + $ref: '#/definitions/types.AccAddress' + type: object + type: object types.MsgPostOrder: properties: asset_code: @@ -1343,6 +2065,38 @@ definitions: $ref: '#/definitions/types.AccAddress' type: object type: object + types.MsgSetWithdrawAddress: + properties: + delegator_address: + $ref: '#/definitions/types.AccAddress' + type: object + withdraw_address: + $ref: '#/definitions/types.AccAddress' + type: object + type: object + types.MsgUndelegate: + properties: + amount: + $ref: '#/definitions/types.Coin' + type: object + delegator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + validator_address: + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.MsgWithdrawDelegatorReward: + properties: + delegator_address: + $ref: '#/definitions/types.AccAddress' + type: object + validator_address: + $ref: '#/definitions/types.ValAddress' + type: object + type: object types.Oracle: properties: address: @@ -1402,26 +2156,150 @@ definitions: items: $ref: '#/definitions/types.Order' type: array + types.PartSetHeader: + properties: + hash: + $ref: '#/definitions/bytes.HexBytes' + type: object + total: + type: integer + type: object + types.Pool: + properties: + bonded_tokens: + description: Bonding tokens which are currently bonded to a validators + example: "50000" + format: integer + type: string + liquidity_tokens: + description: Liquidity tokens which are currently bonded to a validators + example: "10000" + format: integer + type: string + not_bonded_tokens: + description: Bonding tokens which are not bonded to a validators (unbonded or unbonding) + example: "500" + format: integer + type: string + type: object types.PostedPrice: properties: + ask_price: + description: AskPrice + example: "1000" + type: string asset_code: description: Asset code example: btc_xfi type: string + bid_price: + description: BidPrice + example: "1000" + type: string oracle_address: description: Source oracle address example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h type: string - price: - description: Price - example: "1000" + received_at: + description: UNIX Timestamp price receivedAt [sec] + example: "2020-03-27T13:45:15.293426Z" + format: RFC 3339 + type: string + type: object + types.RedelegationEntry: + properties: + completion_time: + description: Time at which the redelegation will complete + type: string + creation_height: + description: Height at which the redelegation took place + type: integer + initial_balance: + description: Initial balance when redelegation started + example: "100" + format: integer + type: string + op_type: + description: Operation type + example: bonding + type: string + shares_dst: + description: Amount of destination-validator shares created by redelegation + example: "0.1" + format: number + type: string + type: object + types.RedelegationEntryResponse: + properties: + balance: + format: integer + type: string + completion_time: + description: Time at which the redelegation will complete + type: string + creation_height: + description: Height at which the redelegation took place + type: integer + initial_balance: + description: Initial balance when redelegation started + example: "100" + format: integer + type: string + op_type: + description: Operation type + example: bonding + type: string + shares_dst: + description: Amount of destination-validator shares created by redelegation + example: "0.1" + format: number + type: string + type: object + types.RedelegationResponse: + properties: + delegator_address: + description: delegator + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + entries: + items: + $ref: '#/definitions/types.RedelegationEntryResponse' + type: array + validator_dst_address: + description: validator redelegation destination operator addr + example: walletval13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 type: string - received_at: - description: UNIX Timestamp price receivedAt [sec] - example: "2020-03-27T13:45:15.293426Z" - format: RFC 3339 + validator_src_address: + description: validator redelegation source operator addr + example: walletval13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 type: string type: object + types.SearchTxsResult: + properties: + count: + description: Count of txs in current page + type: integer + limit: + description: Max count txs per page + type: integer + page_number: + description: Index of current page, start from 1 + type: integer + page_total: + description: Count of total pages + type: integer + total_count: + description: Count of all txs + type: integer + txs: + description: List of txs in current page + items: + $ref: '#/definitions/types.TxResponse' + type: array + type: object types.StdFee: properties: amount: @@ -1453,6 +2331,50 @@ definitions: $ref: '#/definitions/types.StdSignature' type: array type: object + types.StringEvent: + properties: + attributes: + items: + $ref: '#/definitions/types.Attribute' + type: array + type: + type: string + type: object + types.StringEvents: + items: + $ref: '#/definitions/types.StringEvent' + type: array + types.Tx: + type: object + types.TxResponse: + properties: + code: + type: integer + codespace: + type: string + data: + type: string + gas_used: + type: integer + gas_wanted: + type: integer + height: + type: integer + info: + type: string + logs: + $ref: '#/definitions/types.ABCIMessageLogs' + type: object + raw_log: + type: string + timestamp: + type: string + tx: + $ref: '#/definitions/types.Tx' + type: object + txhash: + type: string + type: object types.TxVMStatus: properties: hash: @@ -1463,6 +2385,47 @@ definitions: type: object types.Uint: type: object + types.UnbondingDelegation: + properties: + delegator_address: + description: delegator + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + entries: + description: unbonding delegation entries + items: + $ref: '#/definitions/types.UnbondingDelegationEntry' + type: array + validator_address: + description: validator unbonding from operator addr + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + type: object + types.UnbondingDelegationEntry: + properties: + balance: + description: Tokens to receive at completion + example: "1000" + format: integer + type: string + completion_time: + description: Time at which the unbonding delegation will complete + type: string + creation_height: + description: Height which the unbonding took place + type: integer + initial_balance: + description: Tokens initially scheduled to receive at completion + example: "1000" + format: integer + type: string + op_type: + description: Operation type + example: bonding + type: string + type: object types.VMStatus: properties: major_code: @@ -1491,45 +2454,150 @@ definitions: type: array types.Validator: properties: + bonding: + $ref: '#/definitions/types.ValidatorTokens' + description: Delegated bonding tokens (incl. self-delegation) + type: object commission: $ref: '#/definitions/types.Commission' - description: commission parameters + description: Commission parameters type: object consensus_pubkey: - $ref: '#/definitions/crypto.PubKey' - description: the consensus public key of the validator; bech encoded in JSON - type: object - delegator_shares: - $ref: '#/definitions/types.Dec' - description: total shares issued to a validator's delegators - type: object + description: Consensus public key of the validator; bech encoded in JSON + type: string description: $ref: '#/definitions/types.Description' - description: description terms for the validator + description: Description terms for the validator type: object jailed: - description: has the validator been jailed from bonded status? + description: Has the validator been jailed from bonded status? type: boolean - min_self_delegation: - $ref: '#/definitions/types.Int' - description: validator's self declared minimum self delegation + lp: + $ref: '#/definitions/types.ValidatorTokens' + description: Delegated liquidity tokens type: object + min_self_delegation: + description: Validator's self declared minimum self delegation + example: "1000" + format: integer + type: string operator_address: - $ref: '#/definitions/types.ValAddress' - description: address of the validator's operator; bech encoded in JSON - type: object + description: Address of the validator's operator; bech encoded in JSON + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + scheduled_to_unbond: + description: Has the validator been scheduled to force unbond due to low SelfStake amount compared to TotalDelegationsAmount + type: boolean + scheduled_unbond_height: + description: If ScheduledToUnbond, height at which this schedule started + type: integer + scheduled_unbond_time: + description: Is ScheduledToUnbond, min time for the validator to begin force unbond + type: string status: - description: validator status (bonded/unbonding/unbonded) + description: Validator status (bonded/unbonding/unbonded) + example: bonded + type: string + unbonding_height: + description: If unbonding, height at which this validator has begun unbonding + type: integer + unbonding_time: + description: If unbonding, min time for the validator to complete unbonding + type: string + type: object + types.ValidatorResp: + properties: + bonding_delegator_shares: + description: 'Bondable tokens: total shares issued to a validator''s delegators' + example: "0.123" + format: number + type: string + bonding_distribution_power: + description: Bonding tokens rewards distribution power + type: integer + bonding_tokens: + description: 'Bondable tokens: delegated tokens (incl. self-delegation)' + example: "100" + format: integer + type: string + commission: + description: Commission parameters + type: string + consensus_pubkey: + description: Consensus public key of the validator; bech encoded in JSON + type: string + description: + description: Description terms for the validator + type: string + jailed: + description: Has the validator been jailed from bonded status? + type: boolean + lp_delegator_shares: + description: 'Liquidity tokens: total shares issued to a validator''s delegators' + example: "0.123" + format: number + type: string + lp_distribution_power: + description: LP tokens rewards distribution power + type: integer + lp_tokens: + description: 'Liquidity tokens: delegated tokens' + example: "100" + format: integer + type: string + max_bonding_delegations_lvl: + description: Max bonding delegations level + example: "1000" + format: integer + type: string + min_self_delegation: + description: Validator's self declared minimum self delegation + example: "1000" + format: integer + type: string + operator_address: + description: Address of the validator's operator; bech encoded in JSON + example: wallet13jyjuz3kkdvqw8u4qfkwd94emdl3vx394kn07h + format: bech32 + type: string + rewards_locked: + description: Rewards locked flag + type: boolean + rewards_unlock_time: + description: Rewards unlock time (if locked) + type: string + scheduled_to_unbond: + description: Has the validator been scheduled to force unbond due to low SelfStake amount compared to TotalDelegationsAmount + type: boolean + scheduled_unbond_height: + description: If ScheduledToUnbond, height at which this schedule started + type: integer + scheduled_unbond_time: + description: Is ScheduledToUnbond, min time for the validator to begin force unbond + type: string + status: + description: Validator status (bonded/unbonding/unbonded) + example: bonded type: string - tokens: - $ref: '#/definitions/types.Int' - description: delegated tokens (incl. self-delegation) - type: object unbonding_height: - description: if unbonding, height at which this validator has begun unbonding + description: If unbonding, height at which this validator has begun unbonding type: integer unbonding_time: - description: if unbonding, min time for the validator to complete unbonding + description: If unbonding, min time for the validator to complete unbonding + type: string + type: object + types.ValidatorTokens: + properties: + delegator_shares: + description: Total shares issued to a validator's delegators + example: "0.123" + format: number + type: string + tokens: + description: Delegated tokens (incl. self-delegation for bonding tokens) + example: "100" + format: integer type: string type: object types.Validators: @@ -1592,6 +2660,13 @@ definitions: items: $ref: '#/definitions/types.Withdraw' type: array + version.Consensus: + properties: + app: + type: integer + block: + type: integer + type: object vm_client.MoveFile: properties: code: @@ -1926,7 +3001,123 @@ paths: "200": description: OK schema: - $ref: '#/definitions/rest.CCRespGetWithdraw' + $ref: '#/definitions/rest.CCRespGetWithdraw' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get currency withdraw + tags: + - Currencies + /currencies/withdraws: + get: + consumes: + - application/json + description: Get array of Withdraw objects with pagination + operationId: currenciesGetWithdraws + parameters: + - description: 'page number (first page: 1)' + in: query + name: page + type: integer + - description: 'items per page (default: 100)' + in: query + name: limit + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.CCRespGetWithdraws' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get currency withdraws + tags: + - Currencies + /distribution/community_pool: + get: + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/Coin' + type: array + "500": + description: Internal Server Error + summary: Community pool parameters + tags: + - Distribution + /distribution/delegators/{delegatorAddr}/rewards: + get: + consumes: + - application/json + description: Get the sum of all the rewards earned by delegations by a single delegator + operationId: distributionGetDelegatorRewards + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.QueryDelegationDelegatorRewardsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get the total rewards balance from all delegations + tags: + - Distribution + post: + consumes: + - application/json + description: Withdraw all the delegator's delegation rewards + operationId: distributionPostWithdrawDelegatorRewards + parameters: + - description: WithdrawRewardsReq request with signed transaction + in: body + name: postRequest + required: true + schema: + $ref: '#/definitions/rest.withdrawRewardsReq' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/rest.TxWithdrawDelegatorReward' + type: array "400": description: Returned if the request doesn't have valid query params schema: @@ -1935,31 +3126,33 @@ paths: description: Returned on server error schema: $ref: '#/definitions/rest.ErrorResponse' - summary: Get currency withdraw + summary: Withdraw all the delegator's delegation rewards tags: - - Currencies - /currencies/withdraws: + - Distribution + /distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}: get: consumes: - application/json - description: Get array of Withdraw objects with pagination - operationId: currenciesGetWithdraws + description: Query a single delegation reward by a delegator + operationId: distributionGetDelegationRewards parameters: - - description: 'page number (first page: 1)' - in: query - name: page - type: integer - - description: 'items per page (default: 100)' - in: query - name: limit - type: integer + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/rest.CCRespGetWithdraws' + $ref: '#/definitions/rest.QueryDecCoinsResp' "400": description: Returned if the request doesn't have valid query params schema: @@ -1968,11 +3161,31 @@ paths: description: Returned on server error schema: $ref: '#/definitions/rest.ErrorResponse' - summary: Get currency withdraws + summary: Query a delegation reward tags: - - Currencies - /distribution/community_pool: - get: + - Distribution + post: + consumes: + - application/json + description: Withdraw a delegator's delegation reward from a single validator + operationId: distributionPostWithdrawDelegationRewards + parameters: + - description: WithdrawRewardsReq request with signed transaction + in: body + name: postRequest + required: true + schema: + $ref: '#/definitions/rest.withdrawRewardsReq' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: @@ -1980,67 +3193,66 @@ paths: description: OK schema: items: - $ref: '#/definitions/Coin' + $ref: '#/definitions/rest.TxWithdrawDelegatorReward' type: array + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Community pool parameters + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Withdraw a delegation reward tags: - Distribution - /distribution/delegators/{delegatorAddr}/rewards: + /distribution/delegators/{delegatorAddr}/withdraw_address: get: - description: Get the sum of all the rewards earned by delegations by a single delegator + consumes: + - application/json + description: Get the delegations' rewards withdrawal address. This is the address in which the user will receive the reward funds + operationId: distributionGetDelegatorWithdrawalAddr + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/DelegatorTotalRewards' + $ref: '#/definitions/rest.QueryAddressResp' "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Get the total rewards balance from all delegations + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get the rewards withdrawal address tags: - Distribution - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos167w96tdvmazakdwkw2u57227eduula2cy572lf post: consumes: - application/json - description: Withdraw all the delegator's delegation rewards + description: Withdraw a delegator's delegation reward from a single validator + operationId: distributionPostSetDelegatorWithdrawalAddr parameters: - - in: body - name: Withdraw request body + - description: SetWithdrawalAddrReq request with signed transaction + in: body + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/BroadcastTxCommitResult' - "400": - description: Invalid delegator address - "401": - description: Key password is wrong - "500": - description: Internal Server Error - summary: Withdraw all the delegator's delegation rewards - tags: - - Distribution - /distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}: - get: - description: Query a single delegation reward by a delegator + $ref: '#/definitions/rest.setWithdrawalAddrReq' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: @@ -2048,228 +3260,300 @@ paths: description: OK schema: items: - $ref: '#/definitions/Coin' + $ref: '#/definitions/rest.TxSetWithdrawAddress' type: array "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Query a delegation reward + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Withdraw a delegation reward tags: - Distribution - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l - post: + /distribution/parameters: + get: consumes: - application/json - description: Withdraw a delegator's delegation reward from a single validator - parameters: - - in: body - name: Withdraw request body - schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' + description: Fee distribution parameters + operationId: distributionGetParams produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/BroadcastTxCommitResult' + $ref: '#/definitions/rest.QueryParamsResp' "400": - description: Invalid delegator address or delegation body - "401": - description: Key password is wrong + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Withdraw a delegation reward + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Fee distribution parameters tags: - Distribution - /distribution/delegators/{delegatorAddr}/withdraw_address: + /distribution/pool/{poolName}: get: - description: Get the delegations' rewards withdrawal address. This is the address in which the user will receive the reward funds + consumes: + - application/json + description: Get the amount held in the specified pool + operationId: distributionPool + parameters: + - description: 'PoolName: LiquidityProvidersPool, FoundationPool, PublicTreasuryPool, HARP' + in: path + name: poolName + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/Address' + $ref: '#/definitions/rest.QueryDecCoinsResp' "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Get the rewards withdrawal address + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get the amount held in the specified pool tags: - Distribution - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos167w96tdvmazakdwkw2u57227eduula2cy572lf + /distribution/public_treasury_pool: post: consumes: - application/json - description: Replace the delegations' rewards withdrawal address for a new one. + description: Fund the public treasury pool + operationId: distributionPostFundPublicTreasuryPool parameters: - - in: body - name: Withdraw request body + - description: FundPublicTreasuryPoolReq request with signed transaction + in: body + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' - withdraw_address: - $ref: '#/definitions/Address' + $ref: '#/definitions/rest.fundPublicTreasuryPoolReq' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/BroadcastTxCommitResult' + items: + $ref: '#/definitions/rest.TxFundPublicTreasuryPool' + type: array "400": - description: Invalid delegator or withdraw address - "401": - description: Key password is wrong + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Replace the rewards withdrawal address + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Fund the public treasury pool tags: - Distribution - /distribution/parameters: + /distribution/validator_extended/{validatorAddr}: get: + consumes: + - application/json + description: Query the extended information from a single validator containing distribution params + operationId: distributionValidatorExtended + parameters: + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - properties: - base_proposer_reward: - type: string - bonus_proposer_reward: - type: string - community_tax: - type: string + $ref: '#/definitions/rest.QueryExtendedValidatorResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Fee distribution parameters + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Query the extended information from a single validator tags: - Distribution /distribution/validators/{validatorAddr}: get: + consumes: + - application/json description: Query the distribution information of a single validator + operationId: distributionGetValidatorInfo + parameters: + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/ValidatorDistInfo' + $ref: '#/definitions/rest.QuerySwaggerValidatorDistInfoResp' "400": - description: Invalid validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Validator distribution information tags: - Distribution - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /distribution/validators/{validatorAddr}/outstanding_rewards: get: + consumes: + - application/json + description: Fee distribution outstanding rewards of a single validator + operationId: distributionOutstandingRewards + parameters: + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Coin' - type: array + $ref: '#/definitions/rest.QueryDecCoinsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Fee distribution outstanding rewards of a single validator tags: - Distribution - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /distribution/validators/{validatorAddr}/rewards: get: - description: Query the commission and self-delegation rewards of validator. + consumes: + - application/json + description: Query the commission and self-delegation rewards of validator + operationId: distributionGetValidatorRewards + parameters: + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Coin' - type: array + $ref: '#/definitions/rest.QueryDecCoinsResp' "400": - description: Invalid validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Commission and self-delegation rewards of a single validator tags: - Distribution - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l post: consumes: - application/json description: Withdraw the validator's self-delegation and commissions rewards + operationId: distributionPostWithdrawValidatorRewards parameters: - - in: body - name: Withdraw request body + - description: WithdrawRewardsReq request with signed transaction + in: body + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' + $ref: '#/definitions/rest.withdrawRewardsReq' + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/BroadcastTxCommitResult' + items: + $ref: '#/definitions/types.StdTx' + type: array "400": - description: Invalid validator address - "401": - description: Key password is wrong + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Withdraw the validator's rewards tags: - Distribution + /distribution/validators_extended: + get: + consumes: + - application/json + description: Query the extended information from multiple validators containing distribution params + operationId: distributionValidatorsExtended + parameters: + - description: The validator bond status. Must be either 'bonded', 'unbonded', or 'unbonding' + in: query + name: status + type: string + - description: The page number + in: query + name: page + type: string + - description: The maximum number of items per page + in: query + name: limit + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.QueryExtendedValidatorsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Query the extended information from multiple validators + tags: + - Distribution /gov/parameters/deposit: get: description: Query governance deposit parameters. The max_deposit_period units are in nanoseconds. @@ -2809,55 +4093,97 @@ paths: - Markets /minting/annual-provisions: get: + consumes: + - application/json + description: Current minting annual provisions value + operationId: mintingGetAnnualProvisions produces: - application/json responses: "200": description: OK schema: - type: string + $ref: '#/definitions/rest.QueryDecResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Current minting annual provisions value tags: - Mint /minting/inflation: get: + consumes: + - application/json + description: Current minting inflation value + operationId: mintingGetInflation produces: - application/json responses: "200": description: OK schema: - type: string + $ref: '#/definitions/rest.QueryDecResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Current minting inflation value tags: - Mint + /minting/minter-extended: + get: + consumes: + - application/json + description: Current minting extended state + operationId: mintingGetExtendedState + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.QueryMinterExtendedResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Current minting extended state + tags: + - Mint /minting/parameters: get: + consumes: + - application/json + description: Minting module parameters + operationId: mintingGetParams produces: - application/json responses: "200": description: OK schema: - properties: - blocks_per_year: - type: string - goal_bonded: - type: string - inflation_max: - type: string - inflation_min: - type: string - inflation_rate_change: - type: string - mint_denom: - type: string + $ref: '#/definitions/rest.QueryParamsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Minting module parameters tags: - Mint @@ -3458,137 +4784,160 @@ paths: - Slashing /staking/delegators/{delegatorAddr}/delegations: get: + consumes: + - application/json + description: Get all delegations from a delegator + operationId: stakingGetDelegatorDelegations + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Delegation' - type: array + $ref: '#/definitions/rest.QueryDelegationsResp' "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Get all delegations from a delegator tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv post: consumes: - application/json + description: Submit delegation + operationId: stakingPostDelegatorDelegations parameters: - - description: The password of the account to remove from the KMS + - description: DelegateRequest request with signed transaction in: body - name: delegation + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' - delegation: - $ref: '#/definitions/Coin' - delegator_address: - $ref: '#/definitions/Address' - validator_address: - $ref: '#/definitions/ValidatorAddress' - type: object + $ref: '#/definitions/rest.DelegateRequest' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/BroadcastTxCommitResult' + items: + $ref: '#/definitions/types.MsgDelegate' + type: array "400": - description: Invalid delegator address or delegation request body - "401": - description: Key password is wrong + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Submit delegation tags: - Staking /staking/delegators/{delegatorAddr}/delegations/{validatorAddr}: get: + consumes: + - application/json + description: Query the current delegation between a delegator and a validator + operationId: stakingGetDelegaton + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/Delegation' + $ref: '#/definitions/rest.QueryDelegationResp' "400": - description: Invalid delegator address or validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Query the current delegation between a delegator and a validator tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /staking/delegators/{delegatorAddr}/redelegations: - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv post: consumes: - application/json + description: Submit a redelegation + operationId: stakingPostRedelegations parameters: - - description: The sender and tx information + - description: RedelegateRequest request with signed transaction in: body - name: delegation + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' - delegator_address: - $ref: '#/definitions/Address' - shares: - example: "100" - type: string - validator_dst_address: - $ref: '#/definitions/ValidatorAddress' - validator_src_addressess: - $ref: '#/definitions/ValidatorAddress' - type: object + $ref: '#/definitions/rest.RedelegateRequest' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": - description: Tx was succesfully generated + description: OK schema: - $ref: '#/definitions/StdTx' + items: + $ref: '#/definitions/rest.TxBeginRedelegate' + type: array "400": - description: Invalid delegator address or redelegation request body + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Submit a redelegation tags: - Staking - /staking/delegators/{delegatorAddr}/unbonding_delegations: + /staking/delegators/{delegatorAddr}/txs: get: + consumes: + - application/json + description: Query all staking txs (msgs) from a delegator + operationId: stakingGetDelegatorTxs + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: 'Unbonding types via space: bond unbond redelegate' + in: query + name: type + type: string produces: - application/json responses: @@ -3596,333 +4945,428 @@ paths: description: OK schema: items: - $ref: '#/definitions/UnbondingDelegation' + $ref: '#/definitions/types.SearchTxsResult' type: array "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Query all staking txs (msgs) from a delegator + tags: + - Staking + /staking/delegators/{delegatorAddr}/unbonding_delegations: + get: + consumes: + - application/json + description: Get all unbonding delegations from a delegator + operationId: stakingGetDelegatorUnbondingDelegations + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.QueryUnbondingDelegationsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Get all unbonding delegations from a delegator tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv post: consumes: - application/json + description: Submit an unbonding delegation + operationId: stakingPostUnbondingDelegations parameters: - - description: The password of the account to remove from the KMS + - description: RedelegateRequest request with signed transaction in: body - name: delegation + name: postRequest + required: true schema: - properties: - base_req: - $ref: '#/definitions/BaseReq' - delegator_address: - $ref: '#/definitions/Address' - shares: - example: "100" - type: string - validator_address: - $ref: '#/definitions/ValidatorAddress' - type: object + $ref: '#/definitions/rest.UndelegateRequest' + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/BroadcastTxCommitResult' + items: + $ref: '#/definitions/rest.TxUndelegate' + type: array "400": - description: Invalid delegator address or unbonding delegation request body - "401": - description: Key password is wrong + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Submit an unbonding delegation tags: - Staking /staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}: get: + consumes: + - application/json + description: Query all unbonding delegations between a delegator and a validator + operationId: stakingGetUnbondingDelegation + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: Bech32 OperatorAddress of validator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/UnbondingDelegationPair' + $ref: '#/definitions/rest.QueryUnbondingDelegationResp' "400": - description: Invalid delegator address or validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Query all unbonding delegations between a delegator and a validator tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /staking/delegators/{delegatorAddr}/validators: get: + consumes: + - application/json + description: Query all validators that a delegator is bonded to + operationId: stakingGetDelegatorValidators + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Validator' - type: array + $ref: '#/definitions/rest.QueryValidatorsResp' "400": - description: Invalid delegator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Query all validators that a delegator is bonded to tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv /staking/delegators/{delegatorAddr}/validators/{validatorAddr}: get: + consumes: + - application/json + description: Query a validator that a delegator is bonded to + operationId: stakingGetDelegatorValidator + parameters: + - description: Bech32 AccAddress of Delegator + in: path + name: delegatorAddr + required: true + type: string + - description: Bech32 ValAddress of Delegator + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/Validator' + $ref: '#/definitions/rest.QueryValidatorResp' "400": - description: Invalid delegator address or validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Query a validator that a delegator is bonded to tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: path - name: delegatorAddr - required: true - type: string - x-example: cosmos16xyempempp92x9hyzz9wrgf94r6j9h5f06pxxv - - description: Bech32 ValAddress of Delegator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l + /staking/historical_info/{height}: + get: + consumes: + - application/json + description: Query historical info at a given height + operationId: stakingGetHistoricalInfo + parameters: + - description: block height + in: path + name: height + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/rest.QueryHistoricalInfoResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' + "500": + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Query historical info at a given height + tags: + - Staking /staking/parameters: get: + consumes: + - application/json + description: Get the current staking parameter values + operationId: stakingGetParams produces: - application/json responses: "200": description: OK schema: - properties: - bond_denom: - type: string - goal_bonded: - type: string - inflation_max: - type: string - inflation_min: - type: string - inflation_rate_change: - type: string - max_validators: - type: integer - unbonding_time: - type: string - type: object + $ref: '#/definitions/rest.QueryParamsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Get the current staking parameter values tags: - Staking /staking/pool: get: + consumes: + - application/json + description: Get the current state of the staking pool + operationId: stakingGetPool produces: - application/json responses: "200": description: OK schema: - properties: - bonded_tokens: - type: string - date_last_commission_reset: - type: string - inflation: - type: string - inflation_last_time: - type: string - loose_tokens: - type: string - prev_bonded_shares: - type: string - type: object + $ref: '#/definitions/rest.QueryPoolResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Get the current state of the staking pool tags: - Staking /staking/redelegations: get: + consumes: + - application/json + description: Get all redelegations (filter by query params) + operationId: stakingGetRedelegations + parameters: + - description: Bech32 AccAddress of Delegator + in: query + name: delegator + type: string + - description: Bech32 AccAddress of SrcValidator + in: query + name: validator_from + type: string + - description: Bech32 AccAddress of DstValidator + in: query + name: validator_to + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Redelegation' - type: array + $ref: '#/definitions/rest.QueryRedelegationsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Get all redelegations (filter by query params) tags: - Staking - parameters: - - description: Bech32 AccAddress of Delegator - in: query - name: delegator - required: false - type: string - - description: Bech32 ValAddress of SrcValidator - in: query - name: validator_from - required: false - type: string - - description: Bech32 ValAddress of DstValidator - in: query - name: validator_to - required: false - type: string /staking/validators: get: + consumes: + - application/json + description: Get all validator candidates. By default it returns only the bonded validators + operationId: stakingGetValidators parameters: - - description: The validator bond status. Must be either 'bonded', 'unbonded', or 'unbonding'. + - description: The validator bond status. Must be either 'bonded', 'unbonded', or 'unbonding' in: query name: status type: string - x-example: bonded - - description: The page number. + - description: The page number in: query name: page - type: integer - x-example: 1 - - description: The maximum number of items per page. + type: string + - description: The maximum number of items per page in: query name: limit - type: integer - x-example: 1 + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Validator' - type: array + $ref: '#/definitions/rest.QueryValidatorsResp' + "400": + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Get all validator candidates. By default it returns only the bonded validators. + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get all validator candidates. By default it returns only the bonded validators tags: - Staking /staking/validators/{validatorAddr}: get: + consumes: + - application/json + description: Query the information from a single validator + operationId: stakingGetValidator + parameters: + - description: Bech32 ValAddress + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/Validator' + $ref: '#/definitions/rest.QueryValidatorResp' "400": - description: Invalid validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' summary: Query the information from a single validator tags: - Staking - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /staking/validators/{validatorAddr}/delegations: get: + consumes: + - application/json + description: Get the current delegations for the validator + operationId: stakingGetValidatorDelegations + parameters: + - description: Bech32 ValAddress + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/Delegation' - type: array + $ref: '#/definitions/rest.QueryDelegationsResp' "400": - description: Invalid validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Get all delegations from a validator + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get the current delegations for the validator tags: - Staking - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /staking/validators/{validatorAddr}/unbonding_delegations: get: + consumes: + - application/json + description: Get the current unbonding information for the validator + operationId: stakingGetValidatorUnbondingDelegation + parameters: + - description: Bech32 ValAddress + in: path + name: validatorAddr + required: true + type: string produces: - application/json responses: "200": description: OK schema: - items: - $ref: '#/definitions/UnbondingDelegation' - type: array + $ref: '#/definitions/rest.QueryUnbondingDelegationsResp' "400": - description: Invalid validator address + description: Returned if the request doesn't have valid query params + schema: + $ref: '#/definitions/rest.ErrorResponse' "500": - description: Internal Server Error - summary: Get all unbonding delegations from a validator + description: Returned on server error + schema: + $ref: '#/definitions/rest.ErrorResponse' + summary: Get the current unbonding information for the validator tags: - Staking - parameters: - - description: Bech32 OperatorAddress of validator - in: path - name: validatorAddr - required: true - type: string - x-example: cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l /supply/total: get: produces: diff --git a/go.mod b/go.mod index 57951703..31823705 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201009185146-b579213ebb05 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk @@ -34,6 +34,7 @@ require ( github.com/pelletier/go-toml v1.6.0 github.com/pkg/errors v0.9.1 github.com/rakyll/statik v0.1.7 // indirect + github.com/shopspring/decimal v1.2.0 github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 @@ -42,11 +43,10 @@ require ( github.com/swaggo/http-swagger v0.0.0-20200308142732-58ac5e232fba github.com/swaggo/swag v1.6.7 github.com/tendermint/go-amino v0.15.1 - github.com/shopspring/decimal v1.2.0 github.com/tendermint/tendermint v0.33.7 github.com/tendermint/tm-db v0.5.1 - golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect - golang.org/x/tools v0.0.0-20200909210914-44a2922940c2 // indirect + golang.org/x/net v0.0.0-20201010224723-4f7140c49acb // indirect + golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 // indirect google.golang.org/grpc v1.30.0 google.golang.org/protobuf v1.24.0 // indirect k8s.io/apimachinery v0.18.6 // indirect diff --git a/go.sum b/go.sum index 3a09ec5c..722b5c64 100644 --- a/go.sum +++ b/go.sum @@ -146,16 +146,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.38.4-0.20200923132321-0b40b40d3bf8 h1:yrj9oPb69gZhSa8Q8637HsRrN/5q4WhK20XUNLPyLig= -github.com/dfinance/cosmos-sdk v0.38.4-0.20200923132321-0b40b40d3bf8/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201002002655-db666862c14b h1:0z853VXVM/TAUaSAjNNlh5YdevVKfSjXxvuYHmhGsSs= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201002002655-db666862c14b/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4 h1:sUQDCT0ddxJH14HssQkmA+TbX4PqEhHXK/py/RmaucU= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201002151830-6c83c28b89f4/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09 h1:hNzQYh6QR6K097fL0HYDtgfyN2KgUXLu17/zRxSJezc= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201006151646-1ac22b3a4a09/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201008094428-b46810ed3864/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201009185146-b579213ebb05/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955 h1:v4W3rEu73BWKh3h72B0LcuW1UXgcIgtCB5IXDz5aeIc= +github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= @@ -855,8 +847,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -901,6 +893,8 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -935,8 +929,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200909210914-44a2922940c2 h1:daAzF/Ytp6YSqJDu1hZJthJIhOrsAa7UbIkziU1t0K4= -golang.org/x/tools v0.0.0-20200909210914-44a2922940c2/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 h1:kLBxO4OPBgPwjg8Vvu+/0DCHIfDwYIGNFcD66NU9kpo= +golang.org/x/tools v0.0.0-20201013053347-2db1cd791039/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= From af9d2edf8f4905f1786001170c0262b7c42a8ab1 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Wed, 14 Oct 2020 13:46:59 +0300 Subject: [PATCH 06/20] VM mod: request retry in process logs added (#219) (cherry picked from commit eda08294c15eb31dc9fc769fb1804ec3127c3406) --- x/vm/internal/keeper/keeper_ds.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/x/vm/internal/keeper/keeper_ds.go b/x/vm/internal/keeper/keeper_ds.go index 92e02589..7cd04193 100644 --- a/x/vm/internal/keeper/keeper_ds.go +++ b/x/vm/internal/keeper/keeper_ds.go @@ -59,6 +59,8 @@ func (k Keeper) CloseConnections() { // retryExecReq sends request with retry mechanism and waits for connection and execution. // Contract: either RawModule or RawScript must be specified for RetryExecReq. func (k Keeper) retryExecReq(ctx sdk.Context, req RetryExecReq) (retResp *vm_grpc.VMExecuteResponse, retErr error) { + const failedRetryLogPeriod = 100 + doneCh := make(chan bool) curAttempt := uint(0) reqTimeout := time.Duration(req.ReqTimeoutInMs) * time.Millisecond @@ -98,7 +100,7 @@ func (k Keeper) retryExecReq(ctx sdk.Context, req RetryExecReq) (retResp *vm_grp return } - if curAttempt == req.MaxAttempts { + if req.MaxAttempts != 0 && curAttempt == req.MaxAttempts { retResp, retErr = nil, err return } @@ -106,6 +108,11 @@ func (k Keeper) retryExecReq(ctx sdk.Context, req RetryExecReq) (retResp *vm_grp if curReqDur < reqTimeout { time.Sleep(reqTimeout - curReqDur) } + + if curAttempt % failedRetryLogPeriod == 0 { + msg := fmt.Sprintf("Failing VM request: attempt %d / %d with %v timeout: %v", curAttempt, req.MaxAttempts, reqTimeout, time.Since(reqStartedAt)) + k.GetLogger(ctx).Info(msg) + } } }() <-doneCh From 0b21520cd960146f5549bb0f95c273405fcb53ac Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Wed, 21 Oct 2020 18:31:37 +0300 Subject: [PATCH 07/20] [Release v0.7] [DFI-908,DFI-910] Cosmos SDK version fix, Swagger update (#227) * [DFI-908,DFI-910] Cosmos SDK version fix, Swagger update * go mod tidy * Switched CSDK to v0.39.1-0.2 which has no appHash changes --- Makefile | 8 +- cmd/dncli/docs/swagger.go | 59 +++++++-- go.mod | 19 +-- go.sum | 121 +++++++----------- .../simulator/sim_ops_rewards_delegator.go | 2 +- helpers/tests/simulator/sim_queries.go | 2 +- 6 files changed, 108 insertions(+), 103 deletions(-) diff --git a/Makefile b/Makefile index 71d72928..065a8d1e 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ cosmos_dir=$(swagger_dir)/cosmos-sdk dnode = ./cmd/dnode dncli =./cmd/dncli -cosmos_version = dfinance/launchpad +cosmos_version = $(shell awk '/replace github.com\/cosmos\/cosmos-sdk => github.com\/dfinance\/cosmos-sdk/ {print $$NF}' < go.mod) all: install install: go.sum install-dnode install-dncli @@ -51,17 +51,17 @@ go.sum: go.mod GO111MODULE=on go mod verify swagger-ui-deps: - @echo "--> Preparing deps fro building Swagger API specificaion" + @echo "--> Preparing deps for building Swagger API specificaion" @echo "-> Make tmp build folder" rm -rf $(swagger_dir) mkdir -p $(cosmos_dir) @echo "-> Cosmos-SDK $(cosmos_version) checkout" - git -C $(swagger_dir) clone --branch $(cosmos_version) https://github.com/dfinance/cosmos-sdk.git + git -C $(swagger_dir) clone --depth 1 --branch $(cosmos_version) https://github.com/dfinance/cosmos-sdk.git @echo "-> Fetching Golang libraries: swag, statik" - go get -u github.com/swaggo/swag/cmd/swag + go get -u github.com/swaggo/swag/cmd/swag@v1.6.7 go get github.com/g3co/go-swagger-merger swagger-ui-build: diff --git a/cmd/dncli/docs/swagger.go b/cmd/dncli/docs/swagger.go index 05ae8112..ca5c16b1 100644 --- a/cmd/dncli/docs/swagger.go +++ b/cmd/dncli/docs/swagger.go @@ -771,8 +771,8 @@ definitions: $ref: '#/definitions/types.Currencies' ccstorage.Currency: $ref: '#/definitions/types.Currency' - crypto.PubKey: - type: object + crypto.Address: + $ref: '#/definitions/bytes.HexBytes' markets.MarketExtended: $ref: '#/definitions/types.MarketExtended' msmodule.MsMsg: @@ -1152,21 +1152,20 @@ definitions: format: number type: string type: object - rest.QueryDelegationDelegatorRewardsResp: + rest.QueryDelegationResp: properties: height: type: integer result: - items: - $ref: '#/definitions/types.DelegationDelegatorReward' - type: array + $ref: '#/definitions/types.Delegation' + type: object type: object - rest.QueryDelegationResp: + rest.QueryDelegationRewardsResp: properties: height: type: integer result: - $ref: '#/definitions/types.Delegation' + $ref: '#/definitions/types.QueryDelegationRewardsResponse' type: object type: object rest.QueryDelegationsResp: @@ -1178,6 +1177,14 @@ definitions: $ref: '#/definitions/types.DelegationResponse' type: array type: object + rest.QueryDelegatorRewardsResp: + properties: + height: + type: integer + result: + $ref: '#/definitions/types.QueryDelegatorTotalRewardsResponse' + type: object + type: object rest.QueryExtendedValidatorResp: properties: height: @@ -1577,7 +1584,7 @@ definitions: type: integer type: array types.Address: - type: object + $ref: '#/definitions/crypto.Address' types.Asset: properties: active: @@ -2159,8 +2166,9 @@ definitions: types.PartSetHeader: properties: hash: - $ref: '#/definitions/bytes.HexBytes' - type: object + items: + type: integer + type: array total: type: integer type: object @@ -2206,6 +2214,31 @@ definitions: format: RFC 3339 type: string type: object + types.QueryDelegationRewardsResponse: + properties: + rewards: + $ref: '#/definitions/types.DelegationDelegatorReward' + description: Current rewards for a specific validator + type: object + total: + $ref: '#/definitions/types.DecCoins' + description: |- + All validators rewards accumulated on delegation modification events (shares change, undelegation, redelegation) + This truncated Int value would be transferred to the delegator account on withdraw_delegator_reward Tx + type: object + type: object + types.QueryDelegatorTotalRewardsResponse: + properties: + rewards: + description: Current rewards for all delegated validators + items: + $ref: '#/definitions/types.DelegationDelegatorReward' + type: array + total: + $ref: '#/definitions/types.DecCoins' + description: All validators rewards accumulated on delegations modification events (shares change, undelegation, redelegation) + type: object + type: object types.RedelegationEntry: properties: completion_time: @@ -3080,7 +3113,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/rest.QueryDelegationDelegatorRewardsResp' + $ref: '#/definitions/rest.QueryDelegatorRewardsResp' "400": description: Returned if the request doesn't have valid query params schema: @@ -3152,7 +3185,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/rest.QueryDecCoinsResp' + $ref: '#/definitions/rest.QueryDelegationRewardsResp' "400": description: Returned if the request doesn't have valid query params schema: diff --git a/go.mod b/go.mod index 31823705..6e4133ed 100644 --- a/go.mod +++ b/go.mod @@ -2,34 +2,31 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.2 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk //replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk +// Fix of OS X hostmachine test runs +// Source: https://github.com/ory/dockertest/issues/208 +replace golang.org/x/sys => golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 + require ( github.com/99designs/keyring v1.1.3 - github.com/Microsoft/hcsshim v0.8.7 // indirect github.com/OneOfOne/xxhash v1.2.7 github.com/atlassian/go-sentry-api v0.0.0-20200117001222-a9ccec16c98b - github.com/containerd/containerd v1.3.3 // indirect - github.com/containerd/continuity v0.0.0-20200228182428-0f16d7a0959c // indirect github.com/cosmos/cosmos-sdk v0.0.1 github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 github.com/dfinance/lcs v0.1.7-big - github.com/fsouza/go-dockerclient v1.6.3 + github.com/fsouza/go-dockerclient v1.6.6-0.20200910033347-214a51d9a1e5 github.com/getsentry/sentry-go v0.5.1 github.com/ghodss/yaml v1.0.0 - github.com/go-openapi/spec v0.19.9 // indirect - github.com/go-openapi/swag v0.19.9 // indirect github.com/gogo/protobuf v1.3.1 github.com/gorilla/handlers v1.4.2 - github.com/gorilla/mux v1.7.4 + github.com/gorilla/mux v1.8.0 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/mailru/easyjson v0.7.6 // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.4 github.com/pelletier/go-toml v1.6.0 github.com/pkg/errors v0.9.1 @@ -45,8 +42,6 @@ require ( github.com/tendermint/go-amino v0.15.1 github.com/tendermint/tendermint v0.33.7 github.com/tendermint/tm-db v0.5.1 - golang.org/x/net v0.0.0-20201010224723-4f7140c49acb // indirect - golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 // indirect google.golang.org/grpc v1.30.0 google.golang.org/protobuf v1.24.0 // indirect k8s.io/apimachinery v0.18.6 // indirect diff --git a/go.sum b/go.sum index 722b5c64..abff124f 100644 --- a/go.sum +++ b/go.sum @@ -19,10 +19,10 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c h1:YMP6olTU903X3gxQJckdmiP8/zkSMq4kN3uipsU9XjU= -github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c/go.mod h1:7xhjOwRV2+0HXGmM0jxaEu+ZiXJFoVZOTfL/dmqbrD8= -github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873 h1:93nQ7k53GjoMQ07HVP8g6Zj1fQZDDj7Xy2VkNNtvX8o= +github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.7 h1:fzrmmkskv067ZQbd9wERNGuxckWw67dyzoMG62p7LMo= @@ -73,7 +73,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= @@ -106,15 +105,13 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= -github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc= -github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI= +github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200228182428-0f16d7a0959c h1:8ahmSVELW1wghbjerVAyuEYD5+Dio66RYvSS0iGfL1M= -github.com/containerd/continuity v0.0.0-20200228182428-0f16d7a0959c/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb h1:nXPkFq8X1a9ycY3GYQpFNxHh3j2JgY7zDZfq2EXMIzk= +github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= @@ -140,14 +137,18 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955 h1:v4W3rEu73BWKh3h72B0LcuW1UXgcIgtCB5IXDz5aeIc= -github.com/dfinance/cosmos-sdk v0.38.4-0.20201013133805-612a04d62955/go.mod h1:6A7WcR5vEsVN5MSi5gkMJmJIMulHZftD7q63tBdt2r0= +github.com/dfinance/cosmos-sdk v0.39.1-0.1 h1:j74lAmeScm0z6Q7+oN50E86yMkFGmgt7X4x8uZC3bPI= +github.com/dfinance/cosmos-sdk v0.39.1-0.1/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.1-0.2 h1:FHTbw/wy/lWpVnMImSuU5Q3OurBo13GkiSrHD58mJE8= +github.com/dfinance/cosmos-sdk v0.39.1-0.2/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= @@ -160,8 +161,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23 h1:oqgGT9O61YAYvI41EBsLePOr+LE6roB0xY4gpkZuFSE= -github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible h1:ZxJX4ZSNg1LORBsStUojbrLfkrE3Ut122XhzyZnN110= +github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -202,8 +203,10 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/go-dockerclient v1.6.3 h1:VS/I3mxieZVIeaWXd57JKvSjheELafUJYtblGg75RIQ= -github.com/fsouza/go-dockerclient v1.6.3/go.mod h1:OiSy/IhZIF+zheikZkXK7LVpGzxWchJPJKGWhBqOK4M= +github.com/fsouza/go-dockerclient v1.6.6-0.20200910033347-214a51d9a1e5 h1:povIUEJkhqfRW9IFv1kilK2EOwhLy3Vf9iUJ2cPI508= +github.com/fsouza/go-dockerclient v1.6.6-0.20200910033347-214a51d9a1e5/go.mod h1:3/oRIWoe7uT6bwtAayj/EmJmepBjeL4pYvt7ZxC7Rnk= +github.com/g3co/go-swagger-merger v0.0.0-20200916115803-70f050d0cb09 h1:hivvvYOTeYy+Dm9nLesXatmELP5Q/4v8vyPrkZfjQs8= +github.com/g3co/go-swagger-merger v0.0.0-20200916115803-70f050d0cb09/go.mod h1:jvC3b+YoOx9/SJYqqo1pN1vJ31StlOCugGCyO3EW9XA= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.4.0/go.mod h1:xkGcb82SipKQloDNa5b7hTV4VdEyc2bhwd1/UczP52k= @@ -255,15 +258,15 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.9 h1:9z9cbFuZJ7AcvOHKIY+f6Aevb4vObNDkTEyoMfO7rAc= -github.com/go-openapi/spec v0.19.9/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= +github.com/go-openapi/spec v0.19.10 h1:pcNevfYytLaOQuTju0wm6OqcqU/E/pRwuSGigrLTI28= +github.com/go-openapi/spec v0.19.10/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= -github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.10 h1:A1SWXruroGP15P1sOiegIPbaKio+G9N5TwWTFaVPmAU= +github.com/go-openapi/swag v0.19.10/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -321,6 +324,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= @@ -341,6 +346,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -361,12 +368,10 @@ github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uM github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -496,6 +501,12 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/sys/mount v0.1.0 h1:Ytx78EatgFKtrqZ0BvJ0UtJE472ZvawVmil6pIfuCCU= +github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= +github.com/moby/sys/mountinfo v0.1.0 h1:r8vMRbMAFEAfiNptYVokP+nfxPJzvRuia5e2vzXtENo= +github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= +github.com/moby/term v0.0.0-20200429084858-129dac9f73f6 h1:3Y9aosU6S5Bo8GYH0s+t1ej4m30GuUKvQ3c9ZLqdL28= +github.com/moby/term v0.0.0-20200429084858-129dac9f73f6/go.mod h1:or9wGItza1sRcM4Wd3dIv8DsFHYQuFsMHEdxUIlUxms= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -504,8 +515,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= @@ -554,7 +563,6 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -612,12 +620,12 @@ github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLy github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -716,7 +724,6 @@ github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI= github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio= github.com/swaggo/swag v1.6.7 h1:e8GC2xDllJZr3omJkm9YfmK0Y56+rMO3cg0JBKNz09s= github.com/swaggo/swag v1.6.7/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG7Zc= -github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= @@ -751,6 +758,8 @@ github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -760,7 +769,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -799,8 +807,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= @@ -847,8 +853,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201020065357-d65d470038a5 h1:KrxvpY64uUzANd9wKWr6ZAsufiii93XnvXaeikyCJ2g= +golang.org/x/net v0.0.0-20201020065357-d65d470038a5/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -861,40 +867,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -924,13 +898,14 @@ golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 h1:kLBxO4OPBgPwjg8Vvu+/0DCHIfDwYIGNFcD66NU9kpo= -golang.org/x/tools v0.0.0-20201013053347-2db1cd791039/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201019175715-b894a3290fff h1:HiwHyqQ9ttqCHuTa++R4wNxOg6MY1hduSDT8j2aXoMM= +golang.org/x/tools v0.0.0-20201019175715-b894a3290fff/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -945,6 +920,7 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -955,8 +931,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= @@ -968,6 +942,7 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1018,6 +993,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/helpers/tests/simulator/sim_ops_rewards_delegator.go b/helpers/tests/simulator/sim_ops_rewards_delegator.go index d61b3b88..91df5302 100644 --- a/helpers/tests/simulator/sim_ops_rewards_delegator.go +++ b/helpers/tests/simulator/sim_ops_rewards_delegator.go @@ -45,7 +45,7 @@ func getDelegatorRewardOpFindTarget(s *Simulator) (targets []delegatorRewardOpTa // estimate reward coins curRewardCoins := sdk.NewCoins() - for _, decCoin := range s.QueryDistDelReward(acc.Address, delegation.ValidatorAddress) { + for _, decCoin := range s.QueryDistDelReward(acc.Address, delegation.ValidatorAddress).Total { coin, _ := decCoin.TruncateDecimal() curRewardCoins = curRewardCoins.Add(coin) } diff --git a/helpers/tests/simulator/sim_queries.go b/helpers/tests/simulator/sim_queries.go index 2a8840ef..610a794f 100644 --- a/helpers/tests/simulator/sim_queries.go +++ b/helpers/tests/simulator/sim_queries.go @@ -233,7 +233,7 @@ func (s *Simulator) QueryDistPool(poolName distribution.RewardPoolName) (res sdk } // QueryDistDelReward queries current delegator rewards for specified validator. -func (s *Simulator) QueryDistDelReward(accAddr sdk.AccAddress, valAddr sdk.ValAddress) (res sdk.DecCoins) { +func (s *Simulator) QueryDistDelReward(accAddr sdk.AccAddress, valAddr sdk.ValAddress) (res distribution.QueryDelegationRewardsResponse) { resp := s.RunQuery( distribution.QueryDelegationRewardsParams{ DelegatorAddress: accAddr, From ee82606b0c303f8b07d0dd7081fad084d4c15bb5 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Wed, 21 Oct 2020 19:19:05 +0300 Subject: [PATCH 08/20] CSDK version bump to v0.39.1-0.3: distribution mod ValidatorResp build crash fix --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6e4133ed..396bfa46 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.2 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.3 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index abff124f..15509292 100644 --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/dfinance/cosmos-sdk v0.39.1-0.1 h1:j74lAmeScm0z6Q7+oN50E86yMkFGmgt7X4 github.com/dfinance/cosmos-sdk v0.39.1-0.1/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/cosmos-sdk v0.39.1-0.2 h1:FHTbw/wy/lWpVnMImSuU5Q3OurBo13GkiSrHD58mJE8= github.com/dfinance/cosmos-sdk v0.39.1-0.2/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.1-0.3 h1:avPQ8i4mDItGcBsfTLyq4kQE0HsiClgf7GrCkB68kFs= +github.com/dfinance/cosmos-sdk v0.39.1-0.3/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= From 42209e7a4c8ac683369e30e995f68ec51c444e70 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Mon, 26 Oct 2020 03:53:24 -0700 Subject: [PATCH 09/20] [Release v0.7][DFI-924] Ledger cross build (#230) * fix ledger dncli builds * [DFI-924] Ledger cross-OS build using XGO Co-authored-by: borispovod --- Makefile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 065a8d1e..f89d9573 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include Makefile.ledger -git_tag=$(shell git describe --tags $(git rev-list --tags --max-count=1)) +git_tag=$(shell git describe --tags --abbrev=0) git_commit=$(shell git rev-list -1 HEAD) tags = -X github.com/cosmos/cosmos-sdk/version.Name=dfinance \ -X github.com/cosmos/cosmos-sdk/version.ServerName=dnode \ @@ -82,9 +82,15 @@ swagger-ui-build: ## binaries builds (xgo required: https://github.com/karalabe/xgo) binaries: go.sum + @echo ${git_tag} + @echo "Prepare XGO dependencies" mkdir -p ./builds - GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-darwin-amd64 ${dncli} - #GOOS=linux GOARCH=386 CGO_ENABLED=0 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-linux-386 ${dncli} - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-linux-amd64 ${dncli} - GOOS=windows GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-windows-amd64.exe ${dncli} - #GOOS=windows GOARCH=386 CGO_ENABLED=0 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-windows-386.exe ${dncli} + go get github.com/crazy-max/xgo + + @echo "Build targets (Go 1.14): windows/amd64, linux/amd64, darwin/amd64" + xgo -go 1.14.x --ldflags='$(tags)' --tags='ledger' --out='./builds/dncli-${git_tag}' -targets='windows/amd64,linux/amd64,darwin/amd64' ${dncli} + + ## Legacy builds (as a reference) + #GOOS=darwin GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-darwin-amd64 ${dncli} + #GOOS=linux GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-linux-amd64 ${dncli} + #GOOS=windows GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-windows-amd64.exe ${dncli} From 348d0a37f9d3fd67b8859b6602597e465fc6802d Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Thu, 29 Oct 2020 01:15:58 +0300 Subject: [PATCH 10/20] [DFI-929] appState export update to support zero-height genesis export --- app/app.go | 19 ------------ app/export.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 4 +-- 3 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 app/export.go diff --git a/app/app.go b/app/app.go index ea2d95c9..c6a90b9b 100644 --- a/app/app.go +++ b/app/app.go @@ -31,7 +31,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" tmOs "github.com/tendermint/tendermint/libs/os" - tmTypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" "google.golang.org/grpc" @@ -618,21 +617,3 @@ func (app *DnServiceApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) a func (app *DnServiceApp) LoadHeight(height int64) error { return app.LoadVersion(height, app.keys[bam.MainStoreKey]) } - -// Exports genesis and validators. -func (app *DnServiceApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, -) (appState json.RawMessage, validators []tmTypes.GenesisValidator, err error) { - - // as if they could withdraw from the start of the next block. - ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()}) - - genState := app.mm.ExportGenesis(ctx) - appState, err = codec.MarshalJSONIndent(app.cdc, genState) - if err != nil { - return nil, nil, err - } - - validators = staking.WriteValidators(ctx, app.stakingKeeper) - - return appState, validators, nil -} diff --git a/app/export.go b/app/export.go new file mode 100644 index 00000000..2e05c880 --- /dev/null +++ b/app/export.go @@ -0,0 +1,85 @@ +package app + +import ( + "encoding/json" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/slashing" + "github.com/cosmos/cosmos-sdk/x/staking" + abci "github.com/tendermint/tendermint/abci/types" + tmTypes "github.com/tendermint/tendermint/types" +) + +// Exports genesis and validators. +func (app *DnServiceApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, +) (appState json.RawMessage, validators []tmTypes.GenesisValidator, retErr error) { + + var err error + + // create a new context + ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()}) + + // zero-height squash + if forZeroHeight { + if err := app.prepareForZeroHeightGenesis(ctx); err != nil { + retErr = fmt.Errorf("preparing for zero-height: %w", err) + return + } + } + + // genesis export + genState := app.mm.ExportGenesis(ctx) + appState, err = codec.MarshalJSONIndent(app.cdc, genState) + if err != nil { + retErr = fmt.Errorf("genState JSON marshal: %w", err) + return + } + + validators = staking.WriteValidators(ctx, app.stakingKeeper) + + return appState, validators, nil +} + +func (app *DnServiceApp) checkInvariants(ctx sdk.Context) error { + for _, invRoute := range app.crisisKeeper.Routes() { + res, stop := invRoute.Invar(ctx) + if stop { + return fmt.Errorf("module %s (%s): %s", invRoute.ModuleName, invRoute.Route, res) + } + } + + return nil +} + +func (app *DnServiceApp) prepareForZeroHeightGenesis(ctx sdk.Context) error { + // Check invariants before + if err := app.checkInvariants(ctx); err != nil { + return fmt.Errorf("pre invariants check failed: %w", err) + } + + // Cosmos SDK modules + moduleName := distribution.ModuleName + if err := app.distrKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + + moduleName = staking.ModuleName + if err := app.stakingKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + + moduleName = slashing.ModuleName + if err := app.slashingKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + + // Check invariants after + if err := app.checkInvariants(ctx); err != nil { + return fmt.Errorf("post invariants check failed: %w", err) + } + + return nil +} diff --git a/go.mod b/go.mod index 396bfa46..60e15f5f 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,11 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.3 +//replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.3 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk -//replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk +replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk // Fix of OS X hostmachine test runs // Source: https://github.com/ory/dockertest/issues/208 From 902d7333061ce86ab37c9bfcfbff4e03bde49724 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Thu, 29 Oct 2020 01:56:31 +0300 Subject: [PATCH 11/20] [DFI-929] multisig, orderbook mods: PrepareForZeroHeight squash funcs added --- app/export.go | 14 +++++++++++ x/multisig/internal/keeper/squash.go | 22 +++++++++++++++++ x/orderbook/internal/keeper/squash.go | 35 +++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 x/multisig/internal/keeper/squash.go create mode 100644 x/orderbook/internal/keeper/squash.go diff --git a/app/export.go b/app/export.go index 2e05c880..ec752df7 100644 --- a/app/export.go +++ b/app/export.go @@ -11,6 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" abci "github.com/tendermint/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" + + "github.com/dfinance/dnode/x/multisig" + "github.com/dfinance/dnode/x/orderbook" ) // Exports genesis and validators. @@ -76,6 +79,17 @@ func (app *DnServiceApp) prepareForZeroHeightGenesis(ctx sdk.Context) error { return fmt.Errorf("module %s: %w", moduleName, err) } + // Dnode modules + moduleName = multisig.ModuleName + if err := app.msKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + + moduleName = orderbook.ModuleName + if err := app.orderBookKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + // Check invariants after if err := app.checkInvariants(ctx); err != nil { return fmt.Errorf("post invariants check failed: %w", err) diff --git a/x/multisig/internal/keeper/squash.go b/x/multisig/internal/keeper/squash.go new file mode 100644 index 00000000..e65521b8 --- /dev/null +++ b/x/multisig/internal/keeper/squash.go @@ -0,0 +1,22 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// PrepareForZeroHeight squashes current context state to fit zero-height (used on genesis export). +func (k Keeper) PrepareForZeroHeight(ctx sdk.Context) error { + // reset call objects and calls queue entries + // queue modifications resets call confirmation timeout + calls := k.getCalls(ctx) + for _, call := range calls { + // queue + k.RemoveCallFromQueue(ctx, call.ID, call.Height) + k.addCallToQueue(ctx, call.ID, 0) + // call + call.Height = 0 + k.StoreCall(ctx, call) + } + + return nil +} diff --git a/x/orderbook/internal/keeper/squash.go b/x/orderbook/internal/keeper/squash.go new file mode 100644 index 00000000..6769ca82 --- /dev/null +++ b/x/orderbook/internal/keeper/squash.go @@ -0,0 +1,35 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/dfinance/dnode/x/orderbook/internal/types" +) + +// PrepareForZeroHeight squashes current context state to fit zero-height (used on genesis export). +func (k Keeper) PrepareForZeroHeight(ctx sdk.Context) error { + store := ctx.KVStore(k.storeKey) + + historyItems, err := k.GetHistoryItemsList(ctx) + if err != nil { + return fmt.Errorf("retrieving HistoryItem list: %w", err) + } + + // remove all but the latest history item for each market + historyItemsSet := make(map[string]types.HistoryItem, 0) + for _, curItem := range historyItems { + existingItem, found := historyItemsSet[curItem.MarketID.String()] + if !found || curItem.BlockHeight > existingItem.BlockHeight { + historyItemsSet[curItem.MarketID.String()] = curItem + } + store.Delete(types.GetHistoryItemKey(curItem.MarketID, curItem.BlockHeight)) + } + for _, item := range historyItemsSet { + item.BlockHeight = 0 + k.SetHistoryItem(ctx, item) + } + + return nil +} From 205af8bff2330559105e4947aeb56be24855916b Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Thu, 29 Oct 2020 18:40:18 +0300 Subject: [PATCH 12/20] [DFI-929] multisig mod: call queue fix for genesis squash; app export refactoring, debug added --- app/export.go | 191 ++++++++++++++++++++++++--- x/multisig/internal/keeper/squash.go | 11 +- 2 files changed, 177 insertions(+), 25 deletions(-) diff --git a/app/export.go b/app/export.go index ec752df7..3d3b2939 100644 --- a/app/export.go +++ b/app/export.go @@ -6,12 +6,15 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/supply" abci "github.com/tendermint/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/multisig" "github.com/dfinance/dnode/x/orderbook" ) @@ -27,8 +30,8 @@ func (app *DnServiceApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhi // zero-height squash if forZeroHeight { - if err := app.prepareForZeroHeightGenesis(ctx); err != nil { - retErr = fmt.Errorf("preparing for zero-height: %w", err) + if err := app.prepareGenesisForZeroHeight(ctx, jailWhiteList); err != nil { + retErr = fmt.Errorf("preparing genesis for zero-height: %w", err) return } } @@ -57,37 +60,78 @@ func (app *DnServiceApp) checkInvariants(ctx sdk.Context) error { return nil } -func (app *DnServiceApp) prepareForZeroHeightGenesis(ctx sdk.Context) error { +// prepareGenesisForZeroHeight updates current context to fit zero-height genesis. +// Basically it "squashes" all height-dependent storage objects. +func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteList []string) error { // Check invariants before if err := app.checkInvariants(ctx); err != nil { return fmt.Errorf("pre invariants check failed: %w", err) } - // Cosmos SDK modules - moduleName := distribution.ModuleName - if err := app.distrKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) + // Prepare PrepareForZeroHeight module functions options + optsMap, err := prepareDefaultZeroHeightOptions(jailWhiteList) + if err != nil { + return fmt.Errorf("prepareDefaultZeroHeightOptions: %w", err) } - - moduleName = staking.ModuleName - if err := app.stakingKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) + optsMap, err = setDebugZeroHeightOptions(optsMap) + if err != nil { + return fmt.Errorf("setDebugZeroHeightOptions: %w", err) } - moduleName = slashing.ModuleName - if err := app.slashingKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) + // Cosmos SDK modules + // Supply + { + moduleName := supply.ModuleName + opts := optsMap[moduleName].(supply.SquashOptions) + if err := app.supplyKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } + // Auth + { + moduleName := auth.ModuleName + opts := optsMap[moduleName].(auth.SquashOptions) + if err := app.accountKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } + // Distribution + { + moduleName := distribution.ModuleName + if err := app.distrKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } + // Staking + { + moduleName := staking.ModuleName + opts := optsMap[moduleName].(staking.SquashOptions) + if err := app.stakingKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } + // Slashing + { + moduleName := slashing.ModuleName + if err := app.slashingKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } } // Dnode modules - moduleName = multisig.ModuleName - if err := app.msKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) + // MultiSig + { + moduleName := multisig.ModuleName + if err := app.msKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } } - - moduleName = orderbook.ModuleName - if err := app.orderBookKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) + // OrderBook + { + moduleName := orderbook.ModuleName + if err := app.orderBookKeeper.PrepareForZeroHeight(ctx); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } } // Check invariants after @@ -97,3 +141,108 @@ func (app *DnServiceApp) prepareForZeroHeightGenesis(ctx sdk.Context) error { return nil } + +// prepareDefaultZeroHeightOptions returns base (default) options map per module for PrepareForZeroHeight functions. +func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interface{}, error) { + optsMap := make(map[string]interface{}, 0) + + // Supply + { + moduleName := supply.ModuleName + opts := supply.NewEmptySquashOptions() + optsMap[moduleName] = opts + } + // Auth + { + moduleName := auth.ModuleName + opts := auth.NewEmptySquashOptions() + optsMap[moduleName] = opts + } + // Staking + { + moduleName := staking.ModuleName + opts := staking.NewEmptySquashOptions() + if err := opts.SetJailWhitelistSquashOption(jailWhiteList); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + + return optsMap, nil +} + +// setDebugZeroHeightOptions updates options map per module for debug purposes. +// Adds a fake validator jailing all the others. +// This mod is helpful to run exported genesis locally with one up and running validator. +func setDebugZeroHeightOptions(optsMap map[string]interface{}) (map[string]interface{}, error) { + const ( + // Values below are hardcoded according to bootstrap init_single_w_genesis.sh script values + fakeValOperatorAddress = "wallet17raernuazufad6q48uc5jdnqmuzsep5a03dc0n" + fakeValMoniker = "fakeVal" + fakeValPubKey = "walletvalconspub1zcjduepqu9mgrhdjfmwwalv86vdsavvvxfy8r4fmt4py8ehep252rs0acs5q93t5nm" + fakeValSelfDelegationAmount = "1000000000000000000000000" + ) + + // Supply + { + moduleName := supply.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(supply.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetDenomOp(defaults.StakingDenom, fakeValSelfDelegationAmount); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Auth + { + moduleName := auth.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(auth.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetAddAccountOp(fakeValOperatorAddress, fakeValSelfDelegationAmount+defaults.StakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Staking + { + moduleName := staking.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(staking.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + accAddr, err := sdk.AccAddressFromBech32(fakeValOperatorAddress) + if err != nil { + return nil, fmt.Errorf("module %s: invalid fakeValOperatorAddress (%s): %w", moduleName, fakeValOperatorAddress, err) + } + valAddr := sdk.ValAddress(accAddr) + + if err := opts.SetAddValidatorOp(fakeValOperatorAddress, fakeValMoniker, fakeValPubKey, fakeValSelfDelegationAmount); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetJailWhitelistSquashOption([]string{valAddr.String()}); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + + return optsMap, nil +} diff --git a/x/multisig/internal/keeper/squash.go b/x/multisig/internal/keeper/squash.go index e65521b8..d70a6ed7 100644 --- a/x/multisig/internal/keeper/squash.go +++ b/x/multisig/internal/keeper/squash.go @@ -10,10 +10,13 @@ func (k Keeper) PrepareForZeroHeight(ctx sdk.Context) error { // queue modifications resets call confirmation timeout calls := k.getCalls(ctx) for _, call := range calls { - // queue - k.RemoveCallFromQueue(ctx, call.ID, call.Height) - k.addCallToQueue(ctx, call.ID, 0) - // call + // add to the queue if call is not handled yet + if err := call.CanBeVoted(); err == nil { + k.RemoveCallFromQueue(ctx, call.ID, call.Height) + k.addCallToQueue(ctx, call.ID, 0) + } + + // update call call.Height = 0 k.StoreCall(ctx, call) } From 88e10916e5bc93273ab9ec686b4684ac0267cc8f Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Thu, 29 Oct 2020 18:42:19 +0300 Subject: [PATCH 13/20] [DFI-929] fixed CSDK version --- go.mod | 4 ++-- go.sum | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 60e15f5f..493b897c 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,11 @@ module github.com/dfinance/dnode go 1.14 -//replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.1-0.3 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk -replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk +//replace github.com/cosmos/cosmos-sdk => /Users/tiky/Go_Projects/src/github.com/dfinance/cosmos-sdk // Fix of OS X hostmachine test runs // Source: https://github.com/ory/dockertest/issues/208 diff --git a/go.sum b/go.sum index 15509292..56570cae 100644 --- a/go.sum +++ b/go.sum @@ -145,12 +145,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.1-0.1 h1:j74lAmeScm0z6Q7+oN50E86yMkFGmgt7X4x8uZC3bPI= -github.com/dfinance/cosmos-sdk v0.39.1-0.1/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= -github.com/dfinance/cosmos-sdk v0.39.1-0.2 h1:FHTbw/wy/lWpVnMImSuU5Q3OurBo13GkiSrHD58mJE8= -github.com/dfinance/cosmos-sdk v0.39.1-0.2/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= -github.com/dfinance/cosmos-sdk v0.39.1-0.3 h1:avPQ8i4mDItGcBsfTLyq4kQE0HsiClgf7GrCkB68kFs= -github.com/dfinance/cosmos-sdk v0.39.1-0.3/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f h1:Txb/AgExY0honI4pcWWcMOB5KFK6+rpnK2vnBgD6x04= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= From 386be7bad672bd23a91e92e481737352ac5e6eb6 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Fri, 30 Oct 2020 21:02:57 +0300 Subject: [PATCH 14/20] [DFI-929] ccstorage, vmauth mods: PrepareForZeroHeight added; mainnet export config added --- app/export.go | 163 ++++++++++++++++++++---- go.mod | 2 +- go.sum | 4 +- x/ccstorage/alias.go | 4 + x/ccstorage/internal/keeper/squash.go | 50 ++++++++ x/vmauth/alias.go | 4 + x/vmauth/internal/keeper/squash.go | 173 ++++++++++++++++++++++++++ 7 files changed, 374 insertions(+), 26 deletions(-) create mode 100644 x/ccstorage/internal/keeper/squash.go create mode 100644 x/vmauth/internal/keeper/squash.go diff --git a/app/export.go b/app/export.go index 3d3b2939..82ae4624 100644 --- a/app/export.go +++ b/app/export.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" @@ -14,9 +13,10 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" - "github.com/dfinance/dnode/cmd/config/genesis/defaults" + "github.com/dfinance/dnode/x/ccstorage" "github.com/dfinance/dnode/x/multisig" "github.com/dfinance/dnode/x/orderbook" + "github.com/dfinance/dnode/x/vmauth" ) // Exports genesis and validators. @@ -77,8 +77,19 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL if err != nil { return fmt.Errorf("setDebugZeroHeightOptions: %w", err) } + optsMap, err = setMainnetZeroHeightOptionsV10(optsMap) + if err != nil { + return fmt.Errorf("setMainnetZeroHeightOptionsV10: %w", err) + } - // Cosmos SDK modules + // CCStorage + { + moduleName := ccstorage.ModuleName + opts := optsMap[moduleName].(ccstorage.SquashOptions) + if err := app.ccsKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } // Supply { moduleName := supply.ModuleName @@ -87,21 +98,14 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("module %s: %w", moduleName, err) } } - // Auth + // VMAuth { - moduleName := auth.ModuleName - opts := optsMap[moduleName].(auth.SquashOptions) + moduleName := vmauth.ModuleName + opts := optsMap[moduleName].(vmauth.SquashOptions) if err := app.accountKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } } - // Distribution - { - moduleName := distribution.ModuleName - if err := app.distrKeeper.PrepareForZeroHeight(ctx); err != nil { - return fmt.Errorf("module %s: %w", moduleName, err) - } - } // Staking { moduleName := staking.ModuleName @@ -110,6 +114,14 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("module %s: %w", moduleName, err) } } + // Distribution + { + moduleName := distribution.ModuleName + opts := optsMap[moduleName].(distribution.SquashOptions) + if err := app.distrKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } // Slashing { moduleName := slashing.ModuleName @@ -117,8 +129,6 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("module %s: %w", moduleName, err) } } - - // Dnode modules // MultiSig { moduleName := multisig.ModuleName @@ -146,16 +156,22 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interface{}, error) { optsMap := make(map[string]interface{}, 0) + // CCStorage + { + moduleName := ccstorage.ModuleName + opts := ccstorage.NewEmptySquashOptions() + optsMap[moduleName] = opts + } // Supply { moduleName := supply.ModuleName opts := supply.NewEmptySquashOptions() optsMap[moduleName] = opts } - // Auth + // VMAuth { - moduleName := auth.ModuleName - opts := auth.NewEmptySquashOptions() + moduleName := vmauth.ModuleName + opts := vmauth.NewEmptySquashOptions() optsMap[moduleName] = opts } // Staking @@ -167,6 +183,105 @@ func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interfa } optsMap[moduleName] = opts } + // Distribution + { + moduleName := distribution.ModuleName + opts := distribution.NewEmptySquashOptions() + optsMap[moduleName] = opts + } + + return optsMap, nil +} + +// setMainnetZeroHeightOptionsV10 updates options map per module for Testnet v0.7 -> Mainnet v1.0 migration. +// Options removes all XFI tokens and renames SXFI -> XFI. +func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string]interface{}, error) { + const ( + denomToRemove = "xfi" + oldStakingDenom = "sxfi" + newStakingDenom = "xfi" + ) + + // Supply + { + moduleName := supply.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(supply.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetDenomOp(denomToRemove, true, "", "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetDenomOp(oldStakingDenom, false, newStakingDenom, "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // VMAuth + { + moduleName := vmauth.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(vmauth.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetAccountBalanceOp(denomToRemove, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetAccountBalanceOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Staking + { + moduleName := staking.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(staking.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Distribution + { + moduleName := distribution.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(distribution.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetSlashOp(true); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetDecCoinOp(denomToRemove, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetDecCoinOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } return optsMap, nil } @@ -181,6 +296,8 @@ func setDebugZeroHeightOptions(optsMap map[string]interface{}) (map[string]inter fakeValMoniker = "fakeVal" fakeValPubKey = "walletvalconspub1zcjduepqu9mgrhdjfmwwalv86vdsavvvxfy8r4fmt4py8ehep252rs0acs5q93t5nm" fakeValSelfDelegationAmount = "1000000000000000000000000" + // + stakingDenom = "sxfi" ) // Supply @@ -195,24 +312,24 @@ func setDebugZeroHeightOptions(optsMap map[string]interface{}) (map[string]inter return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) } - if err := opts.SetDenomOp(defaults.StakingDenom, fakeValSelfDelegationAmount); err != nil { + if err := opts.SetDenomOp(stakingDenom, false, "", fakeValSelfDelegationAmount); err != nil { return nil, fmt.Errorf("module %s: %w", moduleName, err) } optsMap[moduleName] = opts } - // Auth + // VMAuth { - moduleName := auth.ModuleName + moduleName := vmauth.ModuleName optsObj, found := optsMap[moduleName] if !found { return nil, fmt.Errorf("module %s: options not found", moduleName) } - opts, ok := optsObj.(auth.SquashOptions) + opts, ok := optsObj.(vmauth.SquashOptions) if !ok { return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) } - if err := opts.SetAddAccountOp(fakeValOperatorAddress, fakeValSelfDelegationAmount+defaults.StakingDenom); err != nil { + if err := opts.SetAddAccountOp(fakeValOperatorAddress, fakeValSelfDelegationAmount+stakingDenom); err != nil { return nil, fmt.Errorf("module %s: %w", moduleName, err) } optsMap[moduleName] = opts diff --git a/go.mod b/go.mod index 493b897c..e283deef 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index 56570cae..c0e3f368 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f h1:Txb/AgExY0honI4pcWWcMOB5KFK6+rpnK2vnBgD6x04= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201029153914-af99ef80ec9f/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639 h1:YgUNZg5brqNPEQngxxwZCA/H6Bpa0W+6hd1iNIkjjZI= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= diff --git a/x/ccstorage/alias.go b/x/ccstorage/alias.go index 38826717..521af356 100644 --- a/x/ccstorage/alias.go +++ b/x/ccstorage/alias.go @@ -15,6 +15,8 @@ type ( ResBalance = types.ResBalance Balance = types.Balance Balances = types.Balances + // + SquashOptions = keeper.SquashOptions ) const ( @@ -35,6 +37,8 @@ var ( // function aliases NewKeeper = keeper.NewKeeper DefaultGenesisState = types.DefaultGenesisState + // + NewEmptySquashOptions = keeper.NewEmptySquashOptions // perms requests RequestVMStoragePerms = types.RequestVMStoragePerms // errors diff --git a/x/ccstorage/internal/keeper/squash.go b/x/ccstorage/internal/keeper/squash.go new file mode 100644 index 00000000..ed91ec29 --- /dev/null +++ b/x/ccstorage/internal/keeper/squash.go @@ -0,0 +1,50 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // Operations order: + // 1: supplyOp + SquashOptions struct { + // Supply modification operations + supplyOps supplyOperation + } + + supplyOperation struct { + // Set supply amount to zero + SetToZero bool + } +) + +func (opts *SquashOptions) SetSupplyOperation(toZero bool) error { + op := supplyOperation{ + SetToZero: toZero, + } + opts.supplyOps = op + + return nil +} + +func NewEmptySquashOptions() SquashOptions { + return SquashOptions{ + supplyOps: supplyOperation{}, + } +} + +// PrepareForZeroHeight squashes current context state to fit zero-height (used on genesis export). +func (k Keeper) PrepareForZeroHeight(ctx sdk.Context, opts SquashOptions) error { + // supplyOps + { + if opts.supplyOps.SetToZero { + for _, cur := range k.GetCurrencies(ctx) { + cur.Supply = sdk.ZeroInt() + k.storeCurrency(ctx, cur) + k.storeResStdCurrencyInfo(ctx, cur) + } + } + } + + return nil +} diff --git a/x/vmauth/alias.go b/x/vmauth/alias.go index 54578324..34309185 100644 --- a/x/vmauth/alias.go +++ b/x/vmauth/alias.go @@ -13,6 +13,8 @@ import ( type ( Keeper = keeper.VMAccountKeeper GenesisState = authTypes.GenesisState + // + SquashOptions = keeper.SquashOptions ) const ( @@ -32,6 +34,8 @@ var ( GetTxCmd = authClientCli.GetTxCmd GetQueryCmd = authClientCli.GetQueryCmd DefaultGenesisState = authTypes.DefaultGenesisState + // + NewEmptySquashOptions = keeper.NewEmptySquashOptions // perms requests RequestCCStoragePerms = types.RequestCCStoragePerms ) diff --git a/x/vmauth/internal/keeper/squash.go b/x/vmauth/internal/keeper/squash.go new file mode 100644 index 00000000..13b29fde --- /dev/null +++ b/x/vmauth/internal/keeper/squash.go @@ -0,0 +1,173 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" +) + +type ( + // Operations order: + // 1: addAccountOps + // 2: accountBalanceOps + SquashOptions struct { + // Add account operations + addAccountOps []addAccountOperation + // Account balance modification operations + accountBalanceOps []accountBalanceOperation + } + + addAccountOperation struct { + // Account address + Address sdk.AccAddress + // Account balance + Coins sdk.Coins + } + + accountBalanceOperation struct { + // Coin denom + Denom string + // Remove coin balance + // 1st priority + Remove bool + // Rename coin / move balance (empty - no renaming) + // 2nd priority + RenameTo string + } +) + +func (opts *SquashOptions) SetAddAccountOp(addressRaw, coinsRaw string) error { + op := addAccountOperation{} + + addr, err := sdk.AccAddressFromBech32(addressRaw) + if err != nil { + return fmt.Errorf("address (%s): invalid AccAddress: %w", addressRaw, err) + } + op.Address = addr + + coins, err := sdk.ParseCoins(coinsRaw) + if err != nil { + return fmt.Errorf("coins (%s): sdk.Coins parsing failed: %w", coinsRaw, err) + } + op.Coins = coins + + opts.addAccountOps = append(opts.addAccountOps, op) + + return nil +} + +func (opts *SquashOptions) SetAccountBalanceOp(denomRaw string, remove bool, renameToRaw string) error { + op := accountBalanceOperation{} + op.Remove = remove + + if remove && renameToRaw != "" { + return fmt.Errorf("remove op can not coexist with rename op") + } + + if err := sdk.ValidateDenom(denomRaw); err != nil { + return fmt.Errorf("denom (%s): invalid: %w", denomRaw, err) + } + op.Denom = denomRaw + + if renameToRaw != "" { + if err := sdk.ValidateDenom(renameToRaw); err != nil { + return fmt.Errorf("renameTo denom (%s): invalid: %w", renameToRaw, err) + } + op.RenameTo = renameToRaw + } + + opts.accountBalanceOps = append(opts.accountBalanceOps, op) + + return nil +} + +func NewEmptySquashOptions() SquashOptions { + return SquashOptions{ + addAccountOps: nil, + accountBalanceOps: nil, + } +} + +// PrepareForZeroHeight squashes current context state to fit zero-height (used on genesis export). +func (k VMAccountKeeper) PrepareForZeroHeight(ctx sdk.Context, opts SquashOptions) error { + // addAccountOps + for i, accOpt := range opts.addAccountOps { + acc := k.NewAccountWithAddress(ctx, accOpt.Address) + if err := acc.SetCoins(accOpt.Coins); err != nil { + return fmt.Errorf("addAccountOps[%d]: SetCoins: %w", i, err) + } + k.SetAccount(ctx, acc) + } + + // accountBalanceOps + { + // remove ops + for i, op := range opts.accountBalanceOps { + if !op.Remove { + continue + } + + var opErr error + k.IterateAccounts(ctx, func(acc authexported.Account) (stop bool) { + coins := acc.GetCoins() + coinToDel := sdk.NewCoin(op.Denom, sdk.ZeroInt()) + for _, coin := range coins { + if coin.Denom != op.Denom { + continue + } + coinToDel.Amount = coin.Amount + break + } + + coins = coins.Sub(sdk.NewCoins(coinToDel)) + if err := acc.SetCoins(coins); err != nil { + opErr = fmt.Errorf("accountBalanceOps[%d] (%s) remove: SetCoins: %w", i, acc.GetAddress(), err) + return true + } + k.SetAccount(ctx, acc) + + return false + }) + if opErr != nil { + return opErr + } + } + + // rename ops + for i, op := range opts.accountBalanceOps { + if op.RenameTo == "" { + continue + } + + var opErr error + k.IterateAccounts(ctx, func(acc authexported.Account) (stop bool) { + coins := acc.GetCoins() + oldCoin := sdk.NewCoin(op.Denom, sdk.ZeroInt()) + for _, coin := range coins { + if coin.Denom != op.Denom { + continue + } + oldCoin.Amount = coin.Amount + break + } + newCoin := sdk.NewCoin(op.RenameTo, oldCoin.Amount) + + coins = coins.Sub(sdk.NewCoins(oldCoin)) + coins = coins.Add(newCoin) + if err := acc.SetCoins(coins); err != nil { + opErr = fmt.Errorf("accountBalanceOps[%d] (%s) rename: SetCoins: %w", i, acc.GetAddress(), err) + return true + } + k.SetAccount(ctx, acc) + + return false + }) + if opErr != nil { + return opErr + } + } + } + + return nil +} From 554e625697665db6a0a693793e383f39ca08c30b Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Fri, 30 Oct 2020 21:51:44 +0300 Subject: [PATCH 15/20] [DFI-929] mint mod PrepareForZeroHeight support added --- app/export.go | 32 ++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/export.go b/app/export.go index 82ae4624..09ff699d 100644 --- a/app/export.go +++ b/app/export.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" @@ -129,6 +130,14 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("module %s: %w", moduleName, err) } } + // Mint + { + moduleName := mint.ModuleName + opts := optsMap[moduleName].(mint.SquashOptions) + if err := app.mintKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } // MultiSig { moduleName := multisig.ModuleName @@ -189,6 +198,12 @@ func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interfa opts := distribution.NewEmptySquashOptions() optsMap[moduleName] = opts } + // Mint + { + moduleName := mint.ModuleName + opts := mint.NewEmptySquashOptions() + optsMap[moduleName] = opts + } return optsMap, nil } @@ -282,6 +297,23 @@ func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string] } optsMap[moduleName] = opts } + // Mint + { + moduleName := mint.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(mint.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } return optsMap, nil } diff --git a/go.mod b/go.mod index e283deef..4685c81e 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index c0e3f368..082e3da3 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639 h1:YgUNZg5brqNPEQngxxwZCA/H6Bpa0W+6hd1iNIkjjZI= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030180114-6685e0a9b639/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2 h1:PRytxg8t0FLtxhhFFqoh8xxG2CR26ZGLkfU5+nRs3jw= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= From 50704230d6fb68f8e451c8f412beb907bc60190d Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Fri, 30 Oct 2020 23:17:30 +0300 Subject: [PATCH 16/20] [DFI-929] gov mod PrepareForZeroHeight support added --- app/export.go | 33 +++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/app/export.go b/app/export.go index 09ff699d..f6f98006 100644 --- a/app/export.go +++ b/app/export.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" @@ -14,6 +15,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/ccstorage" "github.com/dfinance/dnode/x/multisig" "github.com/dfinance/dnode/x/orderbook" @@ -138,6 +140,14 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("module %s: %w", moduleName, err) } } + // Gov + { + moduleName := gov.ModuleName + opts := optsMap[moduleName].(gov.SquashOptions) + if err := app.govKeeper.PrepareForZeroHeight(ctx, opts); err != nil { + return fmt.Errorf("module %s: %w", moduleName, err) + } + } // MultiSig { moduleName := multisig.ModuleName @@ -204,6 +214,12 @@ func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interfa opts := mint.NewEmptySquashOptions() optsMap[moduleName] = opts } + // Gov + { + moduleName := gov.ModuleName + opts := gov.NewEmptySquashOptions() + optsMap[moduleName] = opts + } return optsMap, nil } @@ -314,6 +330,23 @@ func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string] } optsMap[moduleName] = opts } + // Gov + { + moduleName := gov.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(gov.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(defaults.GovMinDepositAmount + newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } return optsMap, nil } diff --git a/go.mod b/go.mod index 4685c81e..9d6bf110 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index 082e3da3..e4e4499d 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2 h1:PRytxg8t0FLtxhhFFqoh8xxG2CR26ZGLkfU5+nRs3jw= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030185043-886ecb0304e2/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819 h1:kVj744TV89zX3z0TmsIaKJS0/WCbGW7ME+7GBqX/qkA= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= From d0085eefd1c2895ea907756f4ace5d54f2ca7e5e Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Tue, 3 Nov 2020 17:27:30 +0300 Subject: [PATCH 17/20] [DFI-947] Mainnet v1.0 migration fixes and report generation --- app/export.go | 133 +--- app/export_v10.go | 726 +++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- x/currencies/internal/keeper/genesis.go | 2 +- x/currencies/internal/keeper/genesis_test.go | 8 +- x/currencies/internal/keeper/issue.go | 26 +- 7 files changed, 752 insertions(+), 149 deletions(-) create mode 100644 app/export_v10.go diff --git a/app/export.go b/app/export.go index f6f98006..e47a35eb 100644 --- a/app/export.go +++ b/app/export.go @@ -15,7 +15,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" - "github.com/dfinance/dnode/cmd/config/genesis/defaults" "github.com/dfinance/dnode/x/ccstorage" "github.com/dfinance/dnode/x/multisig" "github.com/dfinance/dnode/x/orderbook" @@ -168,6 +167,11 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL return fmt.Errorf("post invariants check failed: %w", err) } + // + if err := app.processMainnetSXFIBalance(ctx); err != nil { + return fmt.Errorf("mainnet v1.0 processing: %w", err) + } + return nil } @@ -224,133 +228,6 @@ func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interfa return optsMap, nil } -// setMainnetZeroHeightOptionsV10 updates options map per module for Testnet v0.7 -> Mainnet v1.0 migration. -// Options removes all XFI tokens and renames SXFI -> XFI. -func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string]interface{}, error) { - const ( - denomToRemove = "xfi" - oldStakingDenom = "sxfi" - newStakingDenom = "xfi" - ) - - // Supply - { - moduleName := supply.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(supply.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetDenomOp(denomToRemove, true, "", "0"); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - if err := opts.SetDenomOp(oldStakingDenom, false, newStakingDenom, "0"); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // VMAuth - { - moduleName := vmauth.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(vmauth.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetAccountBalanceOp(denomToRemove, true, ""); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - if err := opts.SetAccountBalanceOp(oldStakingDenom, false, newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Staking - { - moduleName := staking.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(staking.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Distribution - { - moduleName := distribution.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(distribution.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetSlashOp(true); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - if err := opts.SetDecCoinOp(denomToRemove, true, ""); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - if err := opts.SetDecCoinOp(oldStakingDenom, false, newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Mint - { - moduleName := mint.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(mint.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Gov - { - moduleName := gov.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(gov.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(defaults.GovMinDepositAmount + newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - - return optsMap, nil -} - // setDebugZeroHeightOptions updates options map per module for debug purposes. // Adds a fake validator jailing all the others. // This mod is helpful to run exported genesis locally with one up and running validator. diff --git a/app/export_v10.go b/app/export_v10.go new file mode 100644 index 00000000..7d038e8d --- /dev/null +++ b/app/export_v10.go @@ -0,0 +1,726 @@ +package app + +import ( + "encoding/csv" + "encoding/json" + "fmt" + "io" + "os" + "sort" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/mint" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/staking/exported" + "github.com/cosmos/cosmos-sdk/x/supply" + + "github.com/dfinance/dnode/cmd/config/genesis/defaults" + "github.com/dfinance/dnode/helpers" + "github.com/dfinance/dnode/x/ccstorage" + "github.com/dfinance/dnode/x/vmauth" +) + +// setMainnetZeroHeightOptionsV10 updates options map per module for Testnet v0.7 -> Mainnet v1.0 migration. +// Options removes all XFI tokens and renames SXFI -> XFI. +func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string]interface{}, error) { + const ( + oldStakingDenom = "sxfi" + newStakingDenom = "xfi" + ) + var ( + denomsToRemove = []string{"xfi", "usdt", "btc"} + ) + + // Supply + { + moduleName := supply.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(supply.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + for _, denom := range denomsToRemove { + if err := opts.SetDenomOp(denom, true, "", "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + } + if err := opts.SetDenomOp(oldStakingDenom, false, newStakingDenom, "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // VMAuth + { + moduleName := vmauth.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(vmauth.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + for _, denom := range denomsToRemove { + if err := opts.SetAccountBalanceOp(denom, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + } + if err := opts.SetAccountBalanceOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Staking + { + moduleName := staking.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(staking.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Distribution + { + moduleName := distribution.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(distribution.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetDecCoinOp(newStakingDenom, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetDecCoinOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Mint + { + moduleName := mint.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(mint.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Gov + { + moduleName := gov.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(gov.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(defaults.GovMinDepositAmount + newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // CCStorage + { + moduleName := ccstorage.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(ccstorage.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetSupplyOperation(true); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + + return optsMap, nil +} + +// SXFIBalanceReportItem keeps initial, staked and reward balances per account. +type SXFIBalanceReportItem struct { + AccAddress sdk.AccAddress + AccBalance sdk.Coins + IssueCoins sdk.Coins + RewardCoins sdk.Coins + DelBondingShares sdk.Dec + DelLPShares sdk.Dec + DelBondingTokens sdk.Dec + DelLPTokens sdk.Dec + GenCoins sdk.Coins + StakerReport *SXFIStakerReportItem + IssueBondingDenom string + IssueLPDenom string + BondingDenom string + LPDenom string +} + +// SXFIStakerReportItem is a parsed Staker CSV-report. +type SXFIStakerReportItem struct { + TxHash string + AccAddress sdk.AccAddress + EthAddress string + BondingAmount sdk.Int + LPAmount sdk.Int +} + +// GetInitialBondingBalance returns initial amount for BondingDenom (gen balance + issues). +func (i SXFIBalanceReportItem) GetInitialBondingBalance() sdk.Int { + genAmt := i.GenCoins.AmountOf(i.BondingDenom) + issuedAmt := i.IssueCoins.AmountOf(i.IssueBondingDenom) + if i.StakerReport == nil { + issuedAmt = sdk.ZeroInt() + } + + return genAmt.Add(issuedAmt) +} + +// GetIssueBondingBalance returns initial amount for LPDenom (gen balance + issues). +func (i SXFIBalanceReportItem) GetInitialLPBalance() sdk.Int { + genAmt := i.GenCoins.AmountOf(i.LPDenom) + issuedAmt := i.IssueCoins.AmountOf(i.IssueLPDenom) + if i.StakerReport == nil { + issuedAmt = sdk.ZeroInt() + } + + return genAmt.Add(issuedAmt) +} + +// GetCurrentBondingBalance returns final amount for BondingDenom (current balance + rewards + delegations). +func (i SXFIBalanceReportItem) GetCurrentBondingBalance() sdk.Int { + accBalanceAmt := i.AccBalance.AmountOf(i.BondingDenom) + rewardAmt := i.RewardCoins.AmountOf(i.BondingDenom) + delAmt := i.DelBondingTokens.TruncateInt() + + return accBalanceAmt.Add(rewardAmt).Add(delAmt) +} + +// GetCurrentLPBalance returns final amount for LPDenom (current balance + rewards + delegations). +func (i SXFIBalanceReportItem) GetCurrentLPBalance() sdk.Int { + accBalanceAmt := i.AccBalance.AmountOf(i.LPDenom) + rewardAmt := i.RewardCoins.AmountOf(i.LPDenom) + delAmt := i.DelLPTokens.TruncateInt() + + return accBalanceAmt.Add(rewardAmt).Add(delAmt) +} + +func NewSXFIBalanceReportItem(accAddr sdk.AccAddress, accCoins sdk.Coins, issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string) *SXFIBalanceReportItem { + return &SXFIBalanceReportItem{ + AccAddress: accAddr, + AccBalance: accCoins, + IssueCoins: sdk.NewCoins(), + RewardCoins: sdk.NewCoins(), + DelBondingShares: sdk.ZeroDec(), + DelLPShares: sdk.ZeroDec(), + DelBondingTokens: sdk.ZeroDec(), + DelLPTokens: sdk.ZeroDec(), + GenCoins: sdk.NewCoins(), + StakerReport: nil, + IssueBondingDenom: issueBondingDenom, + IssueLPDenom: issueLPDenom, + BondingDenom: bondingDenom, + LPDenom: lpDenom, + } +} + +type SXFIBalanceReportResult struct { + ReportItem SXFIBalanceReportItem + BondingDiff sdk.Int + LPDiff sdk.Int +} + +type SXFIBalanceReportResults []SXFIBalanceReportResult + +func (results SXFIBalanceReportResults) SaveToCSV(path string) error { + f, err := os.Create(path) + if err != nil { + return fmt.Errorf("creating file: %w", err) + } + defer f.Close() + csvWriter := csv.NewWriter(f) + + // Header + err = csvWriter.Write([]string{ + "AccAddress", + "GenCoins", + "IssueCoins", + "WalletCoins", + "RewardCoins", + "DelBondingTokens", + "DelLPTokens", + "BondingDiff", + "LPDiff", + }) + if err != nil { + return fmt.Errorf("header write: %w", err) + } + + // Entries + for i, result := range results { + err := csvWriter.Write([]string{ + result.ReportItem.AccAddress.String(), + result.ReportItem.GenCoins.String(), + result.ReportItem.IssueCoins.String(), + result.ReportItem.AccBalance.String(), + result.ReportItem.RewardCoins.String(), + result.ReportItem.DelBondingTokens.String(), + result.ReportItem.DelLPTokens.String(), + result.BondingDiff.String(), + result.LPDiff.String(), + }) + if err != nil { + return fmt.Errorf("entry %d: write: %w", i+1, err) + } + } + + csvWriter.Flush() + + return nil +} + +func (results SXFIBalanceReportResults) String() string { + decimalDec := sdk.NewDecWithPrec(1, 18) + + str := strings.Builder{} + str.WriteString("Mainnet SXFI-XFI relation report:\n") + for _, result := range results { + diffBondingDec, diffLPDec := result.BondingDiff.ToDec().Mul(decimalDec), result.LPDiff.ToDec().Mul(decimalDec) + str.WriteString(fmt.Sprintf(" - %s\n", result.ReportItem.AccAddress)) + str.WriteString(fmt.Sprintf(" BondingDiff: %s (%s)\n", diffBondingDec, result.BondingDiff)) + str.WriteString(fmt.Sprintf(" LPDiff: %s (%s)\n", diffLPDec, result.LPDiff)) + str.WriteString(fmt.Sprintf(" GenBalance: %s\n", result.ReportItem.GenCoins)) + str.WriteString(fmt.Sprintf(" AccBalance: %s\n", result.ReportItem.AccBalance)) + str.WriteString(fmt.Sprintf(" Issues: %s\n", result.ReportItem.IssueCoins)) + str.WriteString(fmt.Sprintf(" Rewards: %s\n", result.ReportItem.RewardCoins)) + str.WriteString(fmt.Sprintf(" BDel: %s (%s)\n", result.ReportItem.DelBondingTokens, result.ReportItem.DelBondingShares)) + str.WriteString(fmt.Sprintf(" LPDel: %s (%s)\n", result.ReportItem.DelLPTokens, result.ReportItem.DelLPShares)) + } + + return str.String() +} + +// SXFIBalanceReport contains initial and final Testnet (v0.7) sxfi balance for accounts. +// Key - account address. +type SXFIBalanceReport map[string]*SXFIBalanceReportItem + +// AppendGenesisBalances modifies a SXFIBalanceReport with genesis account balances. +func (r SXFIBalanceReport) AppendGenesisBalances( + ctx sdk.Context, app *DnServiceApp, + issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string, +) error { + + genBalances := []struct { + AccAddress string + BondingBalance string + LPBalance string + }{ + { + AccAddress: "wallet1wwmenr38hhrem2v3ue3gwdhj03ynzcvlxgc92u", + BondingBalance: "3400000000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1a6sd0y8l0ma0gnytacrnwlmnupm7ftnwxngalr", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1whpkntyj549f7euftgpng24k2we8legght4rzg", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1zwkqfm2sdgyx0g6h2dj9em4z4kjgy5lmtnmgjd", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet10a24shxzjtutj637rr8shwkwaxx8paplu4vc6f", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet19xshddf5ww7fhd53fumly2r7lqsszz63fxca9x", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1l9mukqvh0etam66dvgw99w9awv3jjv6tyh2hpc", + BondingBalance: "50000000000000000000000", + LPBalance: "0", + }, + } + + for i, genBalance := range genBalances { + accAddress, err := sdk.AccAddressFromBech32(genBalance.AccAddress) + if err != nil { + return fmt.Errorf("genBalance (%d): AccAddress (%s): invalid: %w", i, genBalance.AccAddress, err) + } + bondingAmt, ok := sdk.NewIntFromString(genBalance.BondingBalance) + if !ok { + return fmt.Errorf("genBalance (%d): BondingBalance (%s): invalid sdk.Int", i, genBalance.BondingBalance) + } + lpAmt, ok := sdk.NewIntFromString(genBalance.LPBalance) + if !ok { + return fmt.Errorf("genBalance (%d): LPBalance (%s): invalid sdk.Int", i, genBalance.LPBalance) + } + acc := app.accountKeeper.GetAccount(ctx, accAddress) + if acc == nil { + return fmt.Errorf("genBalance (%d): account (%s): not found", i, accAddress) + } + + reportItem := NewSXFIBalanceReportItem(accAddress, acc.GetCoins(), issueBondingDenom, issueLPDenom, bondingDenom, lpDenom) + reportItem.GenCoins = sdk.NewCoins( + sdk.NewCoin(bondingDenom, bondingAmt), + sdk.NewCoin(lpDenom, lpAmt), + ) + r[accAddress.String()] = reportItem + } + + return nil +} + +// AppendStakerCSVReport modifies a SXFIBalanceReport with staker CSV report data. +func (r SXFIBalanceReport) AppendStakerCSVReport(filePath string) error { + const ( + csvEntryColumns = 5 + ) + + f, err := os.Open(filePath) + if err != nil { + return fmt.Errorf("CSV staker report open: %w", err) + } + defer f.Close() + + csvReader := csv.NewReader(f) + entryIdx := 0 + for { + entryIdx++ + csvEntry, err := csvReader.Read() + if err != nil { + if err == io.EOF { + break + } + return fmt.Errorf("entry (%d): read failed: %w", entryIdx, err) + } + if entryIdx == 1 { + // skip the header + continue + } + + // parse + if len(csvEntry) != csvEntryColumns { + return fmt.Errorf("entry (%d): invalid number of columns: %d / %d", entryIdx, len(csvEntry), csvEntryColumns) + } + stakerTxHash := csvEntry[0] + if stakerTxHash == "" { + return fmt.Errorf("entry (%d): TxHash: emtpy", entryIdx) + } + stakerBondingAmt := sdk.ZeroInt() + if amtRaw := csvEntry[1]; amtRaw != "" { + amt, ok := sdk.NewIntFromString(amtRaw) + if !ok { + return fmt.Errorf("entry (%d): BondingAmount (%s): invalid sdk.Int", entryIdx, amtRaw) + } + stakerBondingAmt = amt + } + stakerAccAddress, err := sdk.AccAddressFromBech32(csvEntry[2]) + if err != nil { + return fmt.Errorf("entry (%d): AccAddress (%s): invalid sdk.AccAddress: %w", entryIdx, csvEntry[2], err) + } + stakerEthAddress := csvEntry[3] + if !helpers.IsEthereumAddress(stakerEthAddress) { + return fmt.Errorf("entry (%d): EthAddress (%s): invalid", entryIdx, stakerEthAddress) + } + stakerLPAmt := sdk.ZeroInt() + if amtRaw := csvEntry[4]; amtRaw != "" { + amt, ok := sdk.NewIntFromString(amtRaw) + if !ok { + return fmt.Errorf("entry (%d): LPAmount (%s): invalid sdk.Int", entryIdx, amtRaw) + } + stakerLPAmt = amt + } + + stakerReport := &SXFIStakerReportItem{ + TxHash: stakerTxHash, + AccAddress: stakerAccAddress, + EthAddress: stakerEthAddress, + BondingAmount: stakerBondingAmt, + LPAmount: stakerLPAmt, + } + reportItem, found := r[stakerReport.AccAddress.String()] + if !found { + return fmt.Errorf("entry (%d): reportEntry for AccAddress %s: not found", entryIdx, stakerReport.AccAddress) + } + if reportItem.StakerReport != nil { + return fmt.Errorf("entry (%d): reportEntry for AccAddress %s: StakerReport already exists", entryIdx, stakerReport.AccAddress) + } + + reportItem.StakerReport = stakerReport + } + + return nil +} + +// Verify compares issues data with Staker report data. +func (r SXFIBalanceReport) Verify() error { + for accAddr, reportItem := range r { + if reportItem.StakerReport == nil { + continue + } + + issuedBondingAmt := reportItem.IssueCoins.AmountOf(reportItem.IssueBondingDenom) + stakerBondingAmt := reportItem.StakerReport.BondingAmount + if !issuedBondingAmt.Equal(stakerBondingAmt) { + return fmt.Errorf("account %s: issued / staker Bonding amount mismatch: %s / %s", accAddr, issuedBondingAmt, stakerBondingAmt) + } + } + + return nil +} + +func (r SXFIBalanceReport) GetResults() SXFIBalanceReportResults { + results := make(SXFIBalanceReportResults, 0, len(r)) + for _, reportItem := range r { + diffBonding := reportItem.GetCurrentBondingBalance().Sub(reportItem.GetInitialBondingBalance()) + diffLP := reportItem.GetCurrentLPBalance().Sub(reportItem.GetInitialLPBalance()) + + results = append(results, SXFIBalanceReportResult{ + ReportItem: *reportItem, + BondingDiff: diffBonding, + LPDiff: diffLP, + }) + } + + sort.Slice(results, func(i, j int) bool { + return results[i].BondingDiff.LT(results[j].BondingDiff) + }) + + return results +} + +// getMainnetSXFIBalanceReport returns a SXFIBalanceReport report. +func (app *DnServiceApp) getMainnetSXFIBalanceReport(ctx sdk.Context, + issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string, + stakerCSVReportPath string, +) (SXFIBalanceReport, error) { + + cacheCtx, _ := ctx.CacheContext() + + // initialize report with genesis data + report := make(SXFIBalanceReport, 0) + if err := report.AppendGenesisBalances(ctx, app, issueBondingDenom, issueLPDenom, bondingDenom, lpDenom); err != nil { + return nil, fmt.Errorf("append genesis balances: %w", err) + } + + // iterate all issues and combine duplicate payees + for _, issue := range app.ccKeeper.GetGenesisIssues(cacheCtx) { + accAddr := issue.Payee + + reportItem, found := report[accAddr.String()] + if !found { + acc := app.accountKeeper.GetAccount(cacheCtx, accAddr) + if acc == nil { + return nil, fmt.Errorf("issue %s: getAccount for %s: not found", issue.ID, accAddr) + } + + reportItem = NewSXFIBalanceReportItem(accAddr, acc.GetCoins(), issueBondingDenom, issueLPDenom, bondingDenom, lpDenom) + } + + reportItem.IssueCoins = reportItem.IssueCoins.Add(issue.Coin) + report[accAddr.String()] = reportItem + } + + // withdraw all rewards + // as all rewards were transferred to rewards bank before, we only query the bank coins + for _, reportItem := range report { + accAddr := reportItem.AccAddress + reportItem.RewardCoins = app.distrKeeper.GetDelegatorRewardsBankCoins(cacheCtx, accAddr) + } + + // unbond all delegations + // no actual undelegation is done, we just calculate delegator tokens based on shares and validator tokens + { + for _, reportItem := range report { + accAddr := reportItem.AccAddress + var iterationErr error + app.stakingKeeper.IterateDelegations( + cacheCtx, accAddr, + func(_ int64, del exported.DelegationI) (stop bool) { + val, found := app.stakingKeeper.GetValidator(cacheCtx, del.GetValidatorAddr()) + if !found { + iterationErr = fmt.Errorf("account %s: get delegation validator %s: not found", accAddr, del.GetValidatorAddr()) + return true + } + + reportItem.DelBondingShares = reportItem.DelBondingShares.Add(del.GetBondingShares()) + if !del.GetBondingShares().IsZero() { + reportItem.DelBondingTokens = reportItem.DelBondingTokens.Add(val.BondingTokensFromSharesTruncated(del.GetBondingShares())) + } + reportItem.DelLPShares = reportItem.DelLPShares.Add(del.GetLPShares()) + if !del.GetLPShares().IsZero() { + reportItem.DelLPTokens = reportItem.DelLPTokens.Add(val.LPTokensFromSharesTruncated(del.GetLPShares())) + } + + return false + }, + ) + if iterationErr != nil { + return nil, iterationErr + } + } + } + + // update report with Staker CSV-report + if stakerCSVReportPath != "" { + if err := report.AppendStakerCSVReport(stakerCSVReportPath); err != nil { + return nil, fmt.Errorf("append append StakerCSVReport: %w", err) + } + } + + return report, nil +} + +type SXFIBalanceReportStats struct { + TotalNegativeBondingDiffs sdk.Dec + TotalPositiveBondingDiffs sdk.Dec + AccMints map[string]sdk.DecCoin +} + +// processMainnetSXFIBalance builds getMainnetSXFIBalanceReport and mints and transfers negative diffs. +func (app *DnServiceApp) processMainnetSXFIBalance(ctx sdk.Context) error { + const ( + issueDenom = "sxfi" + bondingDenom = "xfi" + lpDenom = "lpt" + ) + decimalDec := sdk.NewDecWithPrec(1, 18) + + stakerReportPath := os.Getenv("DN_ZHP_STAKERREPORT_PATH") + reportOutputPrefix := os.Getenv("DN_ZHP_REPORTOUTPUT_PREFIX") + if stakerReportPath == "" { + return fmt.Errorf("envVar %q: not set", "DN_ZHP_STAKERREPORT_PATH") + } + if reportOutputPrefix == "" { + return fmt.Errorf("envVar %q: not set", "DN_ZHP_REPORTOUTPUT_PREFIX") + } + + // build report + report, err := app.getMainnetSXFIBalanceReport( + ctx, + issueDenom, lpDenom, bondingDenom, lpDenom, + stakerReportPath, + ) + if err != nil { + return fmt.Errorf("getMainnetSXFIBalanceReport: %w", err) + } + if err := report.Verify(); err != nil { + return fmt.Errorf("report verification: %w", err) + } + + // save results + results := report.GetResults() + if err := results.SaveToCSV(reportOutputPrefix + "data.csv"); err != nil { + return fmt.Errorf("saving report results to CSV: %w", err) + } + + // calculate the mint amount + positiveDiffs, negativeDiffs := sdk.ZeroInt(), sdk.ZeroInt() + stats := SXFIBalanceReportStats{ + TotalNegativeBondingDiffs: sdk.ZeroDec(), + TotalPositiveBondingDiffs: sdk.ZeroDec(), + AccMints: make(map[string]sdk.DecCoin, len(report)), + } + for _, result := range results { + if !result.BondingDiff.IsNegative() { + positiveDiffs = positiveDiffs.Add(result.BondingDiff) + continue + } + negativeDiffs = negativeDiffs.Add(result.BondingDiff) + } + negativeDiffs = negativeDiffs.MulRaw(-1) + bondingMintCoin := sdk.NewCoin(bondingDenom, negativeDiffs) + // + stats.TotalPositiveBondingDiffs = positiveDiffs.ToDec().Mul(decimalDec) + stats.TotalNegativeBondingDiffs = negativeDiffs.ToDec().Mul(decimalDec) + + // mint + if err := app.mintKeeper.MintCoins(ctx, sdk.NewCoins(bondingMintCoin)); err != nil { + return fmt.Errorf("minting bonding coins: %w", err) + } + if err := app.ccsKeeper.IncreaseCurrencySupply(ctx, bondingMintCoin); err != nil { + return fmt.Errorf("increasing ccStorage supply: %w", err) + } + + // distribute minted coins + for _, result := range results { + diff := result.BondingDiff + if !diff.IsNegative() { + continue + } + + coin := sdk.NewCoin(bondingDenom, diff.MulRaw(-1)) + if err := app.supplyKeeper.SendCoinsFromModuleToAccount(ctx, mint.ModuleName, result.ReportItem.AccAddress, sdk.NewCoins(coin)); err != nil { + return fmt.Errorf("sending minted coins to %s: %w", result.ReportItem.AccAddress, err) + } + // + stats.AccMints[result.ReportItem.AccAddress.String()] = sdk.NewDecCoinFromDec( + coin.Denom, + coin.Amount.ToDec().Mul(decimalDec), + ) + } + + // save stats + statsBz, err := json.Marshal(stats) + if err != nil { + return fmt.Errorf("stats: JSON marshal: %w", err) + } + f, err := os.Create(reportOutputPrefix + "stats.json") + if err != nil { + return fmt.Errorf("stats: creating file: %w", err) + } + defer f.Close() + if _, err := f.Write(statsBz); err != nil { + return fmt.Errorf("stats: write to file: %w", err) + } + + // check the invariants + if err := app.checkInvariants(ctx); err != nil { + return fmt.Errorf("post invariants check: %w", err) + } + + return nil +} diff --git a/go.mod b/go.mod index 9d6bf110..04adb67c 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk diff --git a/go.sum b/go.sum index e4e4499d..c7665fd1 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819 h1:kVj744TV89zX3z0TmsIaKJS0/WCbGW7ME+7GBqX/qkA= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201030191351-da9fe8020819/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85 h1:E/IG4Fi01M2EglSmlGHtGaLsGlRglrhVO2H1h28f2Z0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc= diff --git a/x/currencies/internal/keeper/genesis.go b/x/currencies/internal/keeper/genesis.go index 64af3357..ce24b1b9 100644 --- a/x/currencies/internal/keeper/genesis.go +++ b/x/currencies/internal/keeper/genesis.go @@ -61,7 +61,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) json.RawMessage { } // issues - state.Issues = append(state.Issues, k.getGenesisIssues(ctx)...) + state.Issues = append(state.Issues, k.GetGenesisIssues(ctx)...) // withdraws state.Withdraws = append(state.Withdraws, k.getWithdraws(ctx)...) diff --git a/x/currencies/internal/keeper/genesis_test.go b/x/currencies/internal/keeper/genesis_test.go index 85edf7d7..308b4511 100644 --- a/x/currencies/internal/keeper/genesis_test.go +++ b/x/currencies/internal/keeper/genesis_test.go @@ -76,8 +76,8 @@ func TestCurrenciesKeeper_Genesis(t *testing.T) { // lastID require.Equal(t, state.LastWithdrawID.String(), keeper.getLastWithdrawID(ctx).String()) // issues - require.Len(t, keeper.getGenesisIssues(ctx), len(state.Issues)) - for i, getIssue := range keeper.getGenesisIssues(ctx) { + require.Len(t, keeper.GetGenesisIssues(ctx), len(state.Issues)) + for i, getIssue := range keeper.GetGenesisIssues(ctx) { require.EqualValues(t, state.Issues[i], getIssue) } // withdraws @@ -96,8 +96,8 @@ func TestCurrenciesKeeper_Genesis(t *testing.T) { require.NotNil(t, state.LastWithdrawID) require.Equal(t, keeper.getLastWithdrawID(ctx).String(), state.LastWithdrawID.String()) // issues - require.Len(t, keeper.getGenesisIssues(ctx), len(state.Issues)) - for i, getIssue := range keeper.getGenesisIssues(ctx) { + require.Len(t, keeper.GetGenesisIssues(ctx), len(state.Issues)) + for i, getIssue := range keeper.GetGenesisIssues(ctx) { require.EqualValues(t, getIssue, state.Issues[i]) } // withdraws diff --git a/x/currencies/internal/keeper/issue.go b/x/currencies/internal/keeper/issue.go index 4a39e3d5..19b6d8dc 100644 --- a/x/currencies/internal/keeper/issue.go +++ b/x/currencies/internal/keeper/issue.go @@ -75,19 +75,8 @@ func (k Keeper) GetIssue(ctx sdk.Context, id string) (types.Issue, error) { return k.getIssue(ctx, id), nil } -// getIssue returns issue from the storage. -func (k Keeper) getIssue(ctx sdk.Context, id string) types.Issue { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.GetIssuesKey(id)) - - issue := types.Issue{} - k.cdc.MustUnmarshalBinaryBare(bz, &issue) - - return issue -} - -// getGenesisIssues returns all registered issues with meta (GenesisIssue) from the storage. -func (k Keeper) getGenesisIssues(ctx sdk.Context) []types.GenesisIssue { +// GetGenesisIssues returns all registered issues with meta (GenesisIssue) from the storage. +func (k Keeper) GetGenesisIssues(ctx sdk.Context) []types.GenesisIssue { issues := make([]types.GenesisIssue, 0) store := ctx.KVStore(k.storeKey) @@ -108,6 +97,17 @@ func (k Keeper) getGenesisIssues(ctx sdk.Context) []types.GenesisIssue { return issues } +// getIssue returns issue from the storage. +func (k Keeper) getIssue(ctx sdk.Context, id string) types.Issue { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.GetIssuesKey(id)) + + issue := types.Issue{} + k.cdc.MustUnmarshalBinaryBare(bz, &issue) + + return issue +} + // storeIssue sets issue to the storage. func (k Keeper) storeIssue(ctx sdk.Context, id string, issue types.Issue) { store := ctx.KVStore(k.storeKey) From 13df53b9490ad8735215e5b2fe52f0fc483ee0d4 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Tue, 3 Nov 2020 18:31:40 +0300 Subject: [PATCH 18/20] [DFI-947] Debug validator disabled --- app/export.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/export.go b/app/export.go index e47a35eb..2b97f099 100644 --- a/app/export.go +++ b/app/export.go @@ -75,10 +75,10 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL if err != nil { return fmt.Errorf("prepareDefaultZeroHeightOptions: %w", err) } - optsMap, err = setDebugZeroHeightOptions(optsMap) - if err != nil { - return fmt.Errorf("setDebugZeroHeightOptions: %w", err) - } + //optsMap, err = setDebugZeroHeightOptions(optsMap) + //if err != nil { + // return fmt.Errorf("setDebugZeroHeightOptions: %w", err) + //} optsMap, err = setMainnetZeroHeightOptionsV10(optsMap) if err != nil { return fmt.Errorf("setMainnetZeroHeightOptionsV10: %w", err) From 12bf3244353cbc0d67b4b672a62ead0a18492f7f Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Tue, 3 Nov 2020 23:49:27 +0300 Subject: [PATCH 19/20] Linter fixes --- app/export.go | 2 +- app/export_v10.go | 2 +- x/orderbook/internal/keeper/squash.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/export.go b/app/export.go index 2b97f099..432a0089 100644 --- a/app/export.go +++ b/app/export.go @@ -177,7 +177,7 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // prepareDefaultZeroHeightOptions returns base (default) options map per module for PrepareForZeroHeight functions. func prepareDefaultZeroHeightOptions(jailWhiteList []string) (map[string]interface{}, error) { - optsMap := make(map[string]interface{}, 0) + optsMap := make(map[string]interface{}) // CCStorage { diff --git a/app/export_v10.go b/app/export_v10.go index 7d038e8d..bcc9e7a9 100644 --- a/app/export_v10.go +++ b/app/export_v10.go @@ -541,7 +541,7 @@ func (app *DnServiceApp) getMainnetSXFIBalanceReport(ctx sdk.Context, cacheCtx, _ := ctx.CacheContext() // initialize report with genesis data - report := make(SXFIBalanceReport, 0) + report := make(SXFIBalanceReport) if err := report.AppendGenesisBalances(ctx, app, issueBondingDenom, issueLPDenom, bondingDenom, lpDenom); err != nil { return nil, fmt.Errorf("append genesis balances: %w", err) } diff --git a/x/orderbook/internal/keeper/squash.go b/x/orderbook/internal/keeper/squash.go index 6769ca82..ccbc34ea 100644 --- a/x/orderbook/internal/keeper/squash.go +++ b/x/orderbook/internal/keeper/squash.go @@ -18,7 +18,7 @@ func (k Keeper) PrepareForZeroHeight(ctx sdk.Context) error { } // remove all but the latest history item for each market - historyItemsSet := make(map[string]types.HistoryItem, 0) + historyItemsSet := make(map[string]types.HistoryItem) for _, curItem := range historyItems { existingItem, found := historyItemsSet[curItem.MarketID.String()] if !found || curItem.BlockHeight > existingItem.BlockHeight { From 8f8da16461b4c7a593618265f24e0d90c7891222 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilov Date: Mon, 31 May 2021 19:07:59 +0300 Subject: [PATCH 20/20] Migration to v1.0 major refactoring: start from scratch with the new Dstation app --- Makefile | 4 + app/export.go | 80 ++-- app/export_mainnet_handlers.go | 133 ++++++ app/export_mainnet_opts.go | 164 ++++++++ app/export_mainnet_report.go | 559 +++++++++++++++++++++++++ app/export_v10.go | 726 --------------------------------- go.mod | 3 +- go.sum | 6 +- 8 files changed, 917 insertions(+), 758 deletions(-) create mode 100644 app/export_mainnet_handlers.go create mode 100644 app/export_mainnet_opts.go create mode 100644 app/export_mainnet_report.go delete mode 100644 app/export_v10.go diff --git a/Makefile b/Makefile index f89d9573..14f02225 100644 --- a/Makefile +++ b/Makefile @@ -94,3 +94,7 @@ binaries: go.sum #GOOS=darwin GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-darwin-amd64 ${dncli} #GOOS=linux GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-linux-amd64 ${dncli} #GOOS=windows GOARCH=amd64 GO111MODULE=on go build --ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dncli-${git_tag}-windows-amd64.exe ${dncli} + +export-deploy: + GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags "$(tags)" -tags "$(build_tags)" -o ./builds/dnode-v076-export $(dnode) + scp ./builds/dnode-v076-export root@157.245.70.193:/opt/dnode_export_home/ \ No newline at end of file diff --git a/app/export.go b/app/export.go index 432a0089..231abe42 100644 --- a/app/export.go +++ b/app/export.go @@ -32,13 +32,39 @@ func (app *DnServiceApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhi // zero-height squash if forZeroHeight { - if err := app.prepareGenesisForZeroHeight(ctx, jailWhiteList); err != nil { - retErr = fmt.Errorf("preparing genesis for zero-height: %w", err) + // build options + opts, err := prepareDefaultZeroHeightOptions(jailWhiteList) + if err != nil { + retErr = fmt.Errorf("prepareDefaultZeroHeightOptions: %w", err) + return + } + + opts, err = mainnetExportAddZeroHeightOptions(opts) + if err != nil { + retErr = fmt.Errorf("mainnetExportAddZeroHeightOptions: %w", err) + return + } + + // base prepare + if err := app.prepareGenesisForZeroHeight(ctx, jailWhiteList, opts); err != nil { + retErr = fmt.Errorf("prepareGenesisForZeroHeight: %w", err) + return + } + + // Mainnet handlers + if err := mainnetExportRemoveAllValidators(ctx, app); err != nil { + retErr = fmt.Errorf("mainnetExportRemoveAllValidators: %w", err) + return + } + + if err := mainnetExportProcessBalances(ctx, app); err != nil { + retErr = fmt.Errorf("mainnetExportProcessBalances: %w", err) return } } // genesis export + app.Logger().Info("Exporting genesis") genState := app.mm.ExportGenesis(ctx) appState, err = codec.MarshalJSONIndent(app.cdc, genState) if err != nil { @@ -64,30 +90,20 @@ func (app *DnServiceApp) checkInvariants(ctx sdk.Context) error { // prepareGenesisForZeroHeight updates current context to fit zero-height genesis. // Basically it "squashes" all height-dependent storage objects. -func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteList []string) error { +func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteList []string, opts map[string]interface{}) error { + app.Logger().Info("Preparing genesis for zero-height (for each module):") + // Check invariants before + app.Logger().Info(" Checking invariants (before)") if err := app.checkInvariants(ctx); err != nil { return fmt.Errorf("pre invariants check failed: %w", err) } - // Prepare PrepareForZeroHeight module functions options - optsMap, err := prepareDefaultZeroHeightOptions(jailWhiteList) - if err != nil { - return fmt.Errorf("prepareDefaultZeroHeightOptions: %w", err) - } - //optsMap, err = setDebugZeroHeightOptions(optsMap) - //if err != nil { - // return fmt.Errorf("setDebugZeroHeightOptions: %w", err) - //} - optsMap, err = setMainnetZeroHeightOptionsV10(optsMap) - if err != nil { - return fmt.Errorf("setMainnetZeroHeightOptionsV10: %w", err) - } - // CCStorage { moduleName := ccstorage.ModuleName - opts := optsMap[moduleName].(ccstorage.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(ccstorage.SquashOptions) if err := app.ccsKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -95,7 +111,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Supply { moduleName := supply.ModuleName - opts := optsMap[moduleName].(supply.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(supply.SquashOptions) if err := app.supplyKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -103,7 +120,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // VMAuth { moduleName := vmauth.ModuleName - opts := optsMap[moduleName].(vmauth.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(vmauth.SquashOptions) if err := app.accountKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -111,7 +129,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Staking { moduleName := staking.ModuleName - opts := optsMap[moduleName].(staking.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(staking.SquashOptions) if err := app.stakingKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -119,7 +138,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Distribution { moduleName := distribution.ModuleName - opts := optsMap[moduleName].(distribution.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(distribution.SquashOptions) if err := app.distrKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -127,6 +147,7 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Slashing { moduleName := slashing.ModuleName + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) if err := app.slashingKeeper.PrepareForZeroHeight(ctx); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -134,7 +155,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Mint { moduleName := mint.ModuleName - opts := optsMap[moduleName].(mint.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(mint.SquashOptions) if err := app.mintKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -142,7 +164,8 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // Gov { moduleName := gov.ModuleName - opts := optsMap[moduleName].(gov.SquashOptions) + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) + opts := opts[moduleName].(gov.SquashOptions) if err := app.govKeeper.PrepareForZeroHeight(ctx, opts); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -150,6 +173,7 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // MultiSig { moduleName := multisig.ModuleName + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) if err := app.msKeeper.PrepareForZeroHeight(ctx); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } @@ -157,20 +181,18 @@ func (app *DnServiceApp) prepareGenesisForZeroHeight(ctx sdk.Context, jailWhiteL // OrderBook { moduleName := orderbook.ModuleName + app.Logger().Info(fmt.Sprintf(" Module: %s", moduleName)) if err := app.orderBookKeeper.PrepareForZeroHeight(ctx); err != nil { return fmt.Errorf("module %s: %w", moduleName, err) } } // Check invariants after + app.Logger().Info(" Checking invariants (after)") if err := app.checkInvariants(ctx); err != nil { return fmt.Errorf("post invariants check failed: %w", err) } - - // - if err := app.processMainnetSXFIBalance(ctx); err != nil { - return fmt.Errorf("mainnet v1.0 processing: %w", err) - } + app.Logger().Info("Done") return nil } diff --git a/app/export_mainnet_handlers.go b/app/export_mainnet_handlers.go new file mode 100644 index 00000000..c65370e9 --- /dev/null +++ b/app/export_mainnet_handlers.go @@ -0,0 +1,133 @@ +package app + +import ( + "fmt" + "os" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint" + stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func mainnetExportRemoveAllValidators(ctx sdk.Context, app *DnServiceApp) error { + fakeTime := ctx.BlockTime().Add(stakingTypes.MaxUnbondingTime) + + app.Logger().Info("Removing all validators with delegations refund:") + + app.Logger().Info(" Stopping all active redelegations:") + reds := make([]stakingTypes.Redelegation, 0) + app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingTypes.Redelegation) (stop bool) { + reds = append(reds, red) + return false + }) + for redIdx, red := range reds { + app.Logger().Info(fmt.Sprintf(" RED [%d]: %s, %s -> %s", redIdx, red.DelegatorAddress, red.ValidatorSrcAddress, red.ValidatorDstAddress)) + if _, err := app.stakingKeeper.CompleteRedelegationWithAmount(ctx, red.DelegatorAddress, red.ValidatorSrcAddress, red.ValidatorDstAddress, fakeTime); err != nil { + return fmt.Errorf("stopping redelegation (%s, %s -> %s): %w", + red.DelegatorAddress, red.ValidatorSrcAddress, red.ValidatorDstAddress, err, + ) + } + } + + app.Logger().Info(" Removing all validators:") + for valIdx, val := range app.stakingKeeper.GetAllValidators(ctx) { + app.Logger().Info(fmt.Sprintf(" Validator [%d]: %s (%s):", valIdx, val.GetMoniker(), val.GetOperator())) + if err := app.stakingKeeper.ForceUnbondValidator(ctx, val); err != nil { + return fmt.Errorf("ForceUnbondValidator of %s (%s): %w", val.GetMoniker(), val.GetOperator(), err) + } + } + + app.Logger().Info(" Stopping all active undelegations:") + ubds := make([]stakingTypes.UnbondingDelegation, 0) + app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingTypes.UnbondingDelegation) (stop bool) { + ubds = append(ubds, ubd) + return false + }) + for ubdIdx, ubd := range ubds { + app.Logger().Info(fmt.Sprintf(" UBD [%d]: %s for %s", ubdIdx, ubd.DelegatorAddress, ubd.ValidatorAddress)) + if _, err := app.stakingKeeper.CompleteUnbondingWithAmount(ctx, ubd.DelegatorAddress, ubd.ValidatorAddress, fakeTime); err != nil { + return fmt.Errorf("stopping undelegation (%s, %s): %w", + ubd.DelegatorAddress, ubd.ValidatorAddress, err, + ) + } + } + + app.Logger().Info(" Applying validators set updates") + _ = app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + app.Logger().Info(" Checking invariants") + if err := app.checkInvariants(ctx); err != nil { + return fmt.Errorf("invariants check: %w", err) + } + + return nil +} + +// mainnetExportProcessBalances builds MainnetBalanceReport, mints and transfers negative diffs. +func mainnetExportProcessBalances(ctx sdk.Context, app *DnServiceApp) error { + const ( + issueDenom = "sxfi" + bondingDenom = "xfi" + lpDenom = "lpt" + ) + + app.Logger().Info("Initial vs current balance processing:") + + stakerReportPath := os.Getenv("DN_ZHP_STAKERREPORT_PATH") + reportOutputPrefix := os.Getenv("DN_ZHP_REPORTOUTPUT_PREFIX") + if stakerReportPath == "" { + app.Logger().Info(" WARN: Staker report path not provided, skipping it (DN_ZHP_STAKERREPORT_PATH)") + } + if reportOutputPrefix == "" { + return fmt.Errorf("envVar %q: not set", "DN_ZHP_REPORTOUTPUT_PREFIX") + } + + // build report + app.Logger().Info(" Report: build and validation") + report, err := NewMainnetBalanceReport(ctx, app, issueDenom, lpDenom, bondingDenom, lpDenom, stakerReportPath) + if err != nil { + return fmt.Errorf("NewMainnetBalanceReport: %w", err) + } + if err := report.Verify(); err != nil { + return fmt.Errorf("report validation: %w", err) + } + + // build results + app.Logger().Info(" Results: build and save") + results := report.GetResults() + if err := results.SaveToCSV(reportOutputPrefix + "data.csv"); err != nil { + return fmt.Errorf("report results CSV export: %w", err) + } + + // build stats + app.Logger().Info(" Stats: build and save") + stats := NewMainnetBalanceStats(ctx, app, results) + if err := stats.SaveToJSON(reportOutputPrefix + "stats.json"); err != nil { + return fmt.Errorf("report results stats JSON export: %w", err) + } + + // mint + app.Logger().Info(" Mint: mint and distribute compensations") + if err := app.mintKeeper.MintCoins(ctx, stats.GetTotalMintCoins()); err != nil { + return fmt.Errorf("minting bonding coins: %w", err) + } + + bondingSupply := sdk.NewCoin(bondingDenom, app.supplyKeeper.GetSupply(ctx).GetTotal().AmountOf(bondingDenom)) + if err := app.ccsKeeper.IncreaseCurrencySupply(ctx, bondingSupply); err != nil { + return fmt.Errorf("increasing ccStorage supply: %w", err) + } + + for _, acc := range stats.AccBondingMints { + if err := app.supplyKeeper.SendCoinsFromModuleToAccount(ctx, mint.ModuleName, acc.AccAddress, sdk.NewCoins(acc.MintCoin)); err != nil { + return fmt.Errorf("sending minted coins (%s) to (%s): %w", acc.MintCoin, acc.AccAddress, err) + } + } + + // check the invariants + app.Logger().Info(" Checking invariants") + if err := app.checkInvariants(ctx); err != nil { + return fmt.Errorf("post invariants check: %w", err) + } + + return nil +} diff --git a/app/export_mainnet_opts.go b/app/export_mainnet_opts.go new file mode 100644 index 00000000..48a226ab --- /dev/null +++ b/app/export_mainnet_opts.go @@ -0,0 +1,164 @@ +package app + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/mint" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/supply" + "github.com/dfinance/dnode/cmd/config/genesis/defaults" + "github.com/dfinance/dnode/x/ccstorage" + "github.com/dfinance/dnode/x/vmauth" +) + +// mainnetExportAddZeroHeightOptions updates options map per module for Mainnet v1.0 migration. +// Options removes all XFI tokens, renames SXFI -> XFI and withdraw all current rewards. +func mainnetExportAddZeroHeightOptions(optsMap map[string]interface{}) (map[string]interface{}, error) { + const ( + oldStakingDenom = "sxfi" + newStakingDenom = "xfi" + ) + var ( + denomsToRemove = []string{"xfi", "usdt", "btc"} + ) + + // Supply + { + moduleName := supply.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(supply.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + for _, denom := range denomsToRemove { + if err := opts.SetDenomOp(denom, true, "", "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + } + if err := opts.SetDenomOp(oldStakingDenom, false, newStakingDenom, "0"); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // VMAuth + { + moduleName := vmauth.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(vmauth.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + for _, denom := range denomsToRemove { + if err := opts.SetAccountBalanceOp(denom, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + } + if err := opts.SetAccountBalanceOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Staking + { + moduleName := staking.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(staking.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Distribution + { + moduleName := distribution.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(distribution.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetDecCoinOp(newStakingDenom, true, ""); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetDecCoinOp(oldStakingDenom, false, newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + if err := opts.SetRewardOps(true, true); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Mint + { + moduleName := mint.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(mint.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // Gov + { + moduleName := gov.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(gov.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetParamsOp(defaults.GovMinDepositAmount + newStakingDenom); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + // CCStorage + { + moduleName := ccstorage.ModuleName + optsObj, found := optsMap[moduleName] + if !found { + return nil, fmt.Errorf("module %s: options not found", moduleName) + } + opts, ok := optsObj.(ccstorage.SquashOptions) + if !ok { + return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) + } + + if err := opts.SetSupplyOperation(true); err != nil { + return nil, fmt.Errorf("module %s: %w", moduleName, err) + } + optsMap[moduleName] = opts + } + + return optsMap, nil +} diff --git a/app/export_mainnet_report.go b/app/export_mainnet_report.go new file mode 100644 index 00000000..fdf08f27 --- /dev/null +++ b/app/export_mainnet_report.go @@ -0,0 +1,559 @@ +package app + +import ( + "encoding/csv" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/distribution/types" + distTypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/dfinance/dnode/helpers" +) + +type ( + // MainnetBalanceReport contains initial and final (after the export) balances per accounts. + MainnetBalanceReport map[string]*MainnetBalanceReportItem // key: account address + + MainnetBalanceReportItem struct { + AccAddress sdk.AccAddress // account address + GenCoins sdk.Coins // account genesis balance + IssueCoins sdk.Coins // issued with Staker total coins + AccBalance sdk.Coins // account current balance (after the main export routines) + StakerEntry *StakerReportItem // Staker entry for issued coins (one per account) + // + IssueBondingDenom string // issued bonding coins denom + IssueLPDenom string // issued LP coins denom + BondingDenom string // final bonding coins denom + LPDenom string // final LP coins denom + } + + // StakerReportItem is a parsed Staker CSV-report. + StakerReportItem struct { + TxHash string `json:"txHash"` // Stake Tx hash + AccAddress sdk.AccAddress `json:"dfiAddr"` // Account address + EthAddress string `json:"ethAddr"` // SrcEthereum address + BondingAmount sdk.Int `json:"XFI"` // Bonding tokens stake amount + LPAmount sdk.Int `json:"LPT"` // LP tokens stake amount + Active bool `json:"active"` // true: deposited (stake is on balance) / false: withdrawn (shouldn't be on balance) + } +) + +type ( + // MainnetBalanceResults contains list of MainnetBalanceReport entries with estimated (current - initial) "loss" diffs. + MainnetBalanceResults []MainnetBalanceResult + + MainnetBalanceResult struct { + ReportItem MainnetBalanceReportItem + BondingDiff sdk.Int + LPDiff sdk.Int + } +) + +type ( + // MainnetBalanceStats contains MainnetBalanceResults minting stats with some extra meta. + MainnetBalanceStats struct { + // Total amount of bonding tokens that should be refunded [normalized decimals] + TotalNegativeBondingDiffs sdk.Dec `json:"total_negative_bonding_diffs"` + // Total amount of bonding tokens that all account have earned (comparing to their initial balance) [normalized decimals] + TotalPositiveBondingDiffs sdk.Dec `json:"total_positive_bonding_diffs"` + // Refund distribution data per account + AccBondingMints []MainnetBalanceAccMintStats `json:"acc_bonding_mints"` + // Sum of all current account bonding balances + total refund amount [normalized decimals] + TotalBondingSupply sdk.Dec `json:"total_bonding_supply"` + // Sum of all current account LP balances [normalized decimals] + TotalLPSupply sdk.Dec `json:"total_lp_supply"` + // Balances that are not included into current account balances (what is left after the migration) [normalized decimals] + Leftovers MainnetBalanceLeftoversStats `json:"leftovers"` + } + + MainnetBalanceAccMintStats struct { + // Account address + AccAddress sdk.AccAddress `json:"acc_address"` + // Refund coin + MintCoin sdk.Coin `json:"mint_coin"` + // Refund amount [normalized decimals] + DecAmount sdk.Dec `json:"dec_amount"` + } + + MainnetBalanceLeftoversStats struct { + OutstandingRewards sdk.DecCoins `json:"outstanding_rewards,omitempty"` + RewardPools distTypes.RewardPools `json:"reward_pools"` + } +) + +// AppendStakerJSONReport modifies a MainnetBalanceReport with staker JSON report data. +func (r MainnetBalanceReport) AppendStakerJSONReport(filePath string) error { + if filePath == "" { + return nil + } + + entriesBz, err := ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("report open: %w", err) + } + + entries := make([]StakerReportItem, 0) + if err := json.Unmarshal(entriesBz, &entries); err != nil { + return fmt.Errorf("report unmarshal: %w", err) + } + + for i := 0; i < len(entries); i++ { + if err := r.appendStakerReportItem(entries[i]); err != nil { + return fmt.Errorf("entry (%d): %w", i, err) + } + } + + return nil +} + +// AppendStakerCSVReport modifies a MainnetBalanceReport with staker CSV report data. +// +// Deprecated: Staker now exports a JSON. +func (r MainnetBalanceReport) AppendStakerCSVReport(filePath string) error { + const ( + csvEntryColumns = 5 + ) + + if filePath == "" { + return nil + } + + f, err := os.Open(filePath) + if err != nil { + return fmt.Errorf("report open: %w", err) + } + defer f.Close() + + csvReader := csv.NewReader(f) + entryIdx := 0 + for { + entryIdx++ + csvEntry, err := csvReader.Read() + if err != nil { + if err == io.EOF { + break + } + return fmt.Errorf("entry (%d): read failed: %w", entryIdx, err) + } + if entryIdx == 1 { + // skip the header + continue + } + + // parse + if len(csvEntry) != csvEntryColumns { + return fmt.Errorf("entry (%d): invalid number of columns: %d / %d", entryIdx, len(csvEntry), csvEntryColumns) + } + stakerTxHash := csvEntry[0] + if stakerTxHash == "" { + return fmt.Errorf("entry (%d): TxHash: emtpy", entryIdx) + } + stakerBondingAmt := sdk.ZeroInt() + if amtRaw := csvEntry[1]; amtRaw != "" { + amt, ok := sdk.NewIntFromString(amtRaw) + if !ok { + return fmt.Errorf("entry (%d): BondingAmount (%s): invalid sdk.Int", entryIdx, amtRaw) + } + stakerBondingAmt = amt + } + stakerAccAddress, err := sdk.AccAddressFromBech32(csvEntry[2]) + if err != nil { + return fmt.Errorf("entry (%d): AccAddress (%s): invalid sdk.AccAddress: %w", entryIdx, csvEntry[2], err) + } + stakerEthAddress := csvEntry[3] + if !helpers.IsEthereumAddress(stakerEthAddress) { + return fmt.Errorf("entry (%d): EthAddress (%s): invalid", entryIdx, stakerEthAddress) + } + stakerLPAmt := sdk.ZeroInt() + if amtRaw := csvEntry[4]; amtRaw != "" { + amt, ok := sdk.NewIntFromString(amtRaw) + if !ok { + return fmt.Errorf("entry (%d): LPAmount (%s): invalid sdk.Int", entryIdx, amtRaw) + } + stakerLPAmt = amt + } + + stakerReport := StakerReportItem{ + TxHash: stakerTxHash, + AccAddress: stakerAccAddress, + EthAddress: stakerEthAddress, + BondingAmount: stakerBondingAmt, + LPAmount: stakerLPAmt, + } + if err := r.appendStakerReportItem(stakerReport); err != nil { + return fmt.Errorf("entry (%d): %w", entryIdx, err) + } + } + + return nil +} + +// appendStakerReportItem adds Staker entry to MainnetBalanceReport. +func (r MainnetBalanceReport) appendStakerReportItem(entry StakerReportItem) error { + reportItem, found := r[entry.AccAddress.String()] + if !found { + return fmt.Errorf("reportEntry for AccAddress (%s): not found", entry.AccAddress) + } + if reportItem.StakerEntry != nil { + return fmt.Errorf("reportEntry for AccAddress (%s): duplicated", entry.AccAddress) + } + + if entry.BondingAmount.IsNil() { + entry.BondingAmount = sdk.ZeroInt() + } + if entry.LPAmount.IsNil() { + entry.LPAmount = sdk.ZeroInt() + } + + reportItem.StakerEntry = &entry + + return nil +} + +// Verify compares issues data with Staker report data. +func (r MainnetBalanceReport) Verify() error { + for accAddr, reportItem := range r { + if reportItem.StakerEntry == nil { + continue + } + + issuedBondingAmt := reportItem.IssueCoins.AmountOf(reportItem.IssueBondingDenom) + issuedLPAmt := reportItem.IssueCoins.AmountOf(reportItem.IssueLPDenom) + stakerBondingAmt := reportItem.StakerEntry.BondingAmount + stakerLPAmt := reportItem.StakerEntry.LPAmount + + if !issuedBondingAmt.Equal(stakerBondingAmt) { + return fmt.Errorf("account (%s): issued / staker Bonding amount mismatch: %s / %s", accAddr, issuedBondingAmt, stakerBondingAmt) + } + if !issuedLPAmt.Equal(stakerLPAmt) { + return fmt.Errorf("account (%s): issued / staker LP amount mismatch: %s / %s", accAddr, issuedLPAmt, stakerLPAmt) + } + } + + return nil +} + +// GetResults builds MainnetBalanceResults report. +func (r MainnetBalanceReport) GetResults() MainnetBalanceResults { + results := make(MainnetBalanceResults, 0, len(r)) + for _, reportItem := range r { + diffBonding := reportItem.GetCurrentBondingBalance().Sub(reportItem.GetInitialBondingBalance()) + diffLP := reportItem.GetCurrentLPBalance().Sub(reportItem.GetInitialLPBalance()) + + results = append(results, MainnetBalanceResult{ + ReportItem: *reportItem, + BondingDiff: diffBonding, + LPDiff: diffLP, + }) + } + + sort.Slice(results, func(i, j int) bool { + return results[i].ReportItem.GetCurrentBondingBalance().GTE(results[j].ReportItem.GetCurrentBondingBalance()) + }) + + return results +} + +// GetInitialBondingBalance returns initial amount for BondingDenom (gen balance + issues). +func (i MainnetBalanceReportItem) GetInitialBondingBalance() sdk.Int { + genAmt := i.GenCoins.AmountOf(i.BondingDenom) + issuedAmt := i.IssueCoins.AmountOf(i.IssueBondingDenom) + if i.StakerEntry != nil && !i.StakerEntry.Active { + issuedAmt = issuedAmt.Sub(i.StakerEntry.BondingAmount) + } + + return genAmt.Add(issuedAmt) +} + +// GetInitialLPBalance returns initial amount for LPDenom (gen balance + issues). +func (i MainnetBalanceReportItem) GetInitialLPBalance() sdk.Int { + genAmt := i.GenCoins.AmountOf(i.LPDenom) + issuedAmt := i.IssueCoins.AmountOf(i.IssueLPDenom) + if i.StakerEntry != nil && !i.StakerEntry.Active { + issuedAmt = issuedAmt.Sub(i.StakerEntry.LPAmount) + } + + return genAmt.Add(issuedAmt) +} + +// GetCurrentBondingBalance returns final amount for BondingDenom. +func (i MainnetBalanceReportItem) GetCurrentBondingBalance() sdk.Int { + return i.AccBalance.AmountOf(i.BondingDenom) +} + +// GetCurrentLPBalance returns final amount for LPDenom. +func (i MainnetBalanceReportItem) GetCurrentLPBalance() sdk.Int { + return i.AccBalance.AmountOf(i.LPDenom) +} + +// SaveToCSV saves MainnetBalanceResults to a CSV file. +func (r MainnetBalanceResults) SaveToCSV(path string) error { + f, err := os.Create(path) + if err != nil { + return fmt.Errorf("creating file: %w", err) + } + defer f.Close() + csvWriter := csv.NewWriter(f) + + // Header + err = csvWriter.Write([]string{ + "AccAddress", + "Genesis balance [xfi]", + "Genesis balance [lp]", + "Issued balance [xfi]", + "Issued balance [lp]", + "Current balance [xfi]", + "Current balance [lp]", + "Balance diff [xfi]", + "Balance diff [lp]", + }) + if err != nil { + return fmt.Errorf("header write: %w", err) + } + + // Entries + for i, result := range r { + issueBondDenom, issueLPDenom := result.ReportItem.IssueBondingDenom, result.ReportItem.IssueLPDenom + bondDenom, lpDenom := result.ReportItem.BondingDenom, result.ReportItem.LPDenom + + err := csvWriter.Write([]string{ + result.ReportItem.AccAddress.String(), + result.ReportItem.GenCoins.AmountOf(bondDenom).String(), + result.ReportItem.GenCoins.AmountOf(lpDenom).String(), + result.ReportItem.IssueCoins.AmountOf(issueBondDenom).String(), + result.ReportItem.IssueCoins.AmountOf(issueLPDenom).String(), + result.ReportItem.AccBalance.AmountOf(bondDenom).String(), + result.ReportItem.AccBalance.AmountOf(lpDenom).String(), + result.BondingDiff.String(), + result.LPDiff.String(), + }) + if err != nil { + return fmt.Errorf("entry %d: write: %w", i+1, err) + } + } + + csvWriter.Flush() + + return nil +} + +// SaveToJSON saves MainnetBalanceStats to a JSON file. +func (s MainnetBalanceStats) SaveToJSON(path string) error { + statsBz, err := json.MarshalIndent(s, "", " ") + if err != nil { + return fmt.Errorf("marshal: %w", err) + } + + f, err := os.Create(path) + if err != nil { + return fmt.Errorf("creating file: %w", err) + } + defer f.Close() + + if _, err := f.Write(statsBz); err != nil { + return fmt.Errorf("write to file: %w", err) + } + + return nil +} + +// GetTotalMintCoins returns sdk.Coins that need to be minted. +func (s MainnetBalanceStats) GetTotalMintCoins() sdk.Coins { + coins := sdk.NewCoins() + for _, acc := range s.AccBondingMints { + coins = coins.Add(acc.MintCoin) + } + + return coins +} + +func NewMainnetBalanceReport(ctx sdk.Context, app *DnServiceApp, + issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string, + stakerCSVReportPath string, +) (MainnetBalanceReport, error) { + + genBalances := []struct { + AccAddress string + BondingBalance string + LPBalance string + }{ + { + AccAddress: "wallet1wwmenr38hhrem2v3ue3gwdhj03ynzcvlxgc92u", + BondingBalance: "3400000000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet19xshddf5ww7fhd53fumly2r7lqsszz63fxca9x", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1l9mukqvh0etam66dvgw99w9awv3jjv6tyh2hpc", + BondingBalance: "50000000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1a6sd0y8l0ma0gnytacrnwlmnupm7ftnwxngalr", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1whpkntyj549f7euftgpng24k2we8legght4rzg", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet1zwkqfm2sdgyx0g6h2dj9em4z4kjgy5lmtnmgjd", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + { + AccAddress: "wallet10a24shxzjtutj637rr8shwkwaxx8paplu4vc6f", + BondingBalance: "2500000000000000000000", + LPBalance: "0", + }, + } + + report := make(MainnetBalanceReport) + + // iterate over all accounts and fill the report items + { + app.accountKeeper.IterateAccounts(ctx, func(acc exported.Account) (stop bool) { + report[acc.GetAddress().String()] = &MainnetBalanceReportItem{ + AccAddress: acc.GetAddress(), + GenCoins: sdk.NewCoins(), + IssueCoins: sdk.NewCoins(), + AccBalance: acc.GetCoins(), + StakerEntry: nil, + IssueBondingDenom: issueBondingDenom, + IssueLPDenom: issueLPDenom, + BondingDenom: bondingDenom, + LPDenom: lpDenom, + } + return false + }) + } + + // set genesis balances + { + for i, genBalance := range genBalances { + accAddress, err := sdk.AccAddressFromBech32(genBalance.AccAddress) + if err != nil { + return nil, fmt.Errorf("genBalance (%d): AccAddress (%s): invalid: %w", i, genBalance.AccAddress, err) + } + bondingAmt, ok := sdk.NewIntFromString(genBalance.BondingBalance) + if !ok { + return nil, fmt.Errorf("genBalance (%d): BondingBalance (%s): invalid sdk.Int", i, genBalance.BondingBalance) + } + lpAmt, ok := sdk.NewIntFromString(genBalance.LPBalance) + if !ok { + return nil, fmt.Errorf("genBalance (%d): LPBalance (%s): invalid sdk.Int", i, genBalance.LPBalance) + } + + reportItem, found := report[accAddress.String()] + if !found { + return nil, fmt.Errorf("genBalance (%d): account (%s): not found", i, accAddress) + } + reportItem.GenCoins = sdk.NewCoins( + sdk.NewCoin(bondingDenom, bondingAmt), + sdk.NewCoin(lpDenom, lpAmt), + ) + } + } + + // iterate over all issues and aggregate duplicate issues + for _, issue := range app.ccKeeper.GetGenesisIssues(ctx) { + accAddr := issue.Payee + + reportItem, found := report[accAddr.String()] + if !found { + return nil, fmt.Errorf("issue (%s): account (%s): not found", issue.ID, accAddr) + } + reportItem.IssueCoins = reportItem.IssueCoins.Add(issue.Coin) + } + + // update report with Staker CSV-report + if err := report.AppendStakerJSONReport(stakerCSVReportPath); err != nil { + return nil, fmt.Errorf("AppendStakerJSONReport: %w", err) + } + + return report, nil +} + +func NewMainnetBalanceStats(ctx sdk.Context, app *DnServiceApp, results MainnetBalanceResults) MainnetBalanceStats { + decimalDec := sdk.NewDecWithPrec(1, 18) + normalizeInt := func(v sdk.Int) sdk.Dec { + return v.ToDec().Mul(decimalDec) + } + normalizeDec := func(v sdk.Dec) sdk.Dec { + return v.Mul(decimalDec) + } + normalizeDecCoins := func(v sdk.DecCoins) sdk.DecCoins { + ret := make(sdk.DecCoins, 0, len(v)) + for _, coin := range v { + coin.Amount = normalizeDec(coin.Amount) + ret = append(ret, coin) + } + return ret + } + + // calculate total supply, total diffs and distribution amount per account + totalBonding, totalLP := sdk.ZeroInt(), sdk.ZeroInt() + totalPositiveDiffs, totalNegativeDiffs := sdk.ZeroInt(), sdk.ZeroInt() + accMints := make([]MainnetBalanceAccMintStats, 0, len(results)) + + for _, result := range results { + totalBonding = totalBonding.Add(result.ReportItem.GetCurrentBondingBalance()) + totalLP = totalLP.Add(result.ReportItem.GetCurrentLPBalance()) + + if !result.BondingDiff.IsNegative() { + totalPositiveDiffs = totalPositiveDiffs.Add(result.BondingDiff) + } else { + totalNegativeDiffs = totalNegativeDiffs.Add(result.BondingDiff) + + mintCoin := sdk.NewCoin(result.ReportItem.BondingDenom, result.BondingDiff.MulRaw(-1)) + accMints = append(accMints, MainnetBalanceAccMintStats{ + AccAddress: result.ReportItem.AccAddress, + MintCoin: mintCoin, + DecAmount: normalizeInt(mintCoin.Amount), + }) + } + } + totalBonding = totalBonding.Add(totalNegativeDiffs.MulRaw(-1)) + + sort.Slice(accMints, func(i, j int) bool { + return accMints[i].MintCoin.Amount.GTE(accMints[j].MintCoin.Amount) + }) + + // leftovers + leftoverOutstanding := sdk.NewDecCoins() + app.distrKeeper.IterateValidatorOutstandingRewards(ctx, func(_ sdk.ValAddress, rewards types.ValidatorOutstandingRewards) (stop bool) { + leftoverOutstanding = leftoverOutstanding.Add(rewards...) + return false + }) + + rewardPools := app.distrKeeper.GetRewardPools(ctx) + + return MainnetBalanceStats{ + TotalNegativeBondingDiffs: normalizeInt(totalNegativeDiffs), + TotalPositiveBondingDiffs: normalizeInt(totalPositiveDiffs), + AccBondingMints: accMints, + TotalBondingSupply: normalizeInt(totalBonding), + TotalLPSupply: normalizeInt(totalLP), + Leftovers: MainnetBalanceLeftoversStats{ + OutstandingRewards: normalizeDecCoins(leftoverOutstanding), + RewardPools: distTypes.RewardPools{ + LiquidityProvidersPool: normalizeDecCoins(rewardPools.LiquidityProvidersPool), + FoundationPool: normalizeDecCoins(rewardPools.FoundationPool), + PublicTreasuryPool: normalizeDecCoins(rewardPools.PublicTreasuryPool), + HARP: normalizeDecCoins(rewardPools.HARP), + }, + }, + } +} diff --git a/app/export_v10.go b/app/export_v10.go deleted file mode 100644 index bcc9e7a9..00000000 --- a/app/export_v10.go +++ /dev/null @@ -1,726 +0,0 @@ -package app - -import ( - "encoding/csv" - "encoding/json" - "fmt" - "io" - "os" - "sort" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/cosmos/cosmos-sdk/x/gov" - "github.com/cosmos/cosmos-sdk/x/mint" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/cosmos/cosmos-sdk/x/staking/exported" - "github.com/cosmos/cosmos-sdk/x/supply" - - "github.com/dfinance/dnode/cmd/config/genesis/defaults" - "github.com/dfinance/dnode/helpers" - "github.com/dfinance/dnode/x/ccstorage" - "github.com/dfinance/dnode/x/vmauth" -) - -// setMainnetZeroHeightOptionsV10 updates options map per module for Testnet v0.7 -> Mainnet v1.0 migration. -// Options removes all XFI tokens and renames SXFI -> XFI. -func setMainnetZeroHeightOptionsV10(optsMap map[string]interface{}) (map[string]interface{}, error) { - const ( - oldStakingDenom = "sxfi" - newStakingDenom = "xfi" - ) - var ( - denomsToRemove = []string{"xfi", "usdt", "btc"} - ) - - // Supply - { - moduleName := supply.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(supply.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - for _, denom := range denomsToRemove { - if err := opts.SetDenomOp(denom, true, "", "0"); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - } - if err := opts.SetDenomOp(oldStakingDenom, false, newStakingDenom, "0"); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // VMAuth - { - moduleName := vmauth.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(vmauth.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - for _, denom := range denomsToRemove { - if err := opts.SetAccountBalanceOp(denom, true, ""); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - } - if err := opts.SetAccountBalanceOp(oldStakingDenom, false, newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Staking - { - moduleName := staking.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(staking.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Distribution - { - moduleName := distribution.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(distribution.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetDecCoinOp(newStakingDenom, true, ""); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - if err := opts.SetDecCoinOp(oldStakingDenom, false, newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Mint - { - moduleName := mint.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(mint.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // Gov - { - moduleName := gov.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(gov.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetParamsOp(defaults.GovMinDepositAmount + newStakingDenom); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - // CCStorage - { - moduleName := ccstorage.ModuleName - optsObj, found := optsMap[moduleName] - if !found { - return nil, fmt.Errorf("module %s: options not found", moduleName) - } - opts, ok := optsObj.(ccstorage.SquashOptions) - if !ok { - return nil, fmt.Errorf("module %s: options type assert failed: %T", moduleName, optsObj) - } - - if err := opts.SetSupplyOperation(true); err != nil { - return nil, fmt.Errorf("module %s: %w", moduleName, err) - } - optsMap[moduleName] = opts - } - - return optsMap, nil -} - -// SXFIBalanceReportItem keeps initial, staked and reward balances per account. -type SXFIBalanceReportItem struct { - AccAddress sdk.AccAddress - AccBalance sdk.Coins - IssueCoins sdk.Coins - RewardCoins sdk.Coins - DelBondingShares sdk.Dec - DelLPShares sdk.Dec - DelBondingTokens sdk.Dec - DelLPTokens sdk.Dec - GenCoins sdk.Coins - StakerReport *SXFIStakerReportItem - IssueBondingDenom string - IssueLPDenom string - BondingDenom string - LPDenom string -} - -// SXFIStakerReportItem is a parsed Staker CSV-report. -type SXFIStakerReportItem struct { - TxHash string - AccAddress sdk.AccAddress - EthAddress string - BondingAmount sdk.Int - LPAmount sdk.Int -} - -// GetInitialBondingBalance returns initial amount for BondingDenom (gen balance + issues). -func (i SXFIBalanceReportItem) GetInitialBondingBalance() sdk.Int { - genAmt := i.GenCoins.AmountOf(i.BondingDenom) - issuedAmt := i.IssueCoins.AmountOf(i.IssueBondingDenom) - if i.StakerReport == nil { - issuedAmt = sdk.ZeroInt() - } - - return genAmt.Add(issuedAmt) -} - -// GetIssueBondingBalance returns initial amount for LPDenom (gen balance + issues). -func (i SXFIBalanceReportItem) GetInitialLPBalance() sdk.Int { - genAmt := i.GenCoins.AmountOf(i.LPDenom) - issuedAmt := i.IssueCoins.AmountOf(i.IssueLPDenom) - if i.StakerReport == nil { - issuedAmt = sdk.ZeroInt() - } - - return genAmt.Add(issuedAmt) -} - -// GetCurrentBondingBalance returns final amount for BondingDenom (current balance + rewards + delegations). -func (i SXFIBalanceReportItem) GetCurrentBondingBalance() sdk.Int { - accBalanceAmt := i.AccBalance.AmountOf(i.BondingDenom) - rewardAmt := i.RewardCoins.AmountOf(i.BondingDenom) - delAmt := i.DelBondingTokens.TruncateInt() - - return accBalanceAmt.Add(rewardAmt).Add(delAmt) -} - -// GetCurrentLPBalance returns final amount for LPDenom (current balance + rewards + delegations). -func (i SXFIBalanceReportItem) GetCurrentLPBalance() sdk.Int { - accBalanceAmt := i.AccBalance.AmountOf(i.LPDenom) - rewardAmt := i.RewardCoins.AmountOf(i.LPDenom) - delAmt := i.DelLPTokens.TruncateInt() - - return accBalanceAmt.Add(rewardAmt).Add(delAmt) -} - -func NewSXFIBalanceReportItem(accAddr sdk.AccAddress, accCoins sdk.Coins, issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string) *SXFIBalanceReportItem { - return &SXFIBalanceReportItem{ - AccAddress: accAddr, - AccBalance: accCoins, - IssueCoins: sdk.NewCoins(), - RewardCoins: sdk.NewCoins(), - DelBondingShares: sdk.ZeroDec(), - DelLPShares: sdk.ZeroDec(), - DelBondingTokens: sdk.ZeroDec(), - DelLPTokens: sdk.ZeroDec(), - GenCoins: sdk.NewCoins(), - StakerReport: nil, - IssueBondingDenom: issueBondingDenom, - IssueLPDenom: issueLPDenom, - BondingDenom: bondingDenom, - LPDenom: lpDenom, - } -} - -type SXFIBalanceReportResult struct { - ReportItem SXFIBalanceReportItem - BondingDiff sdk.Int - LPDiff sdk.Int -} - -type SXFIBalanceReportResults []SXFIBalanceReportResult - -func (results SXFIBalanceReportResults) SaveToCSV(path string) error { - f, err := os.Create(path) - if err != nil { - return fmt.Errorf("creating file: %w", err) - } - defer f.Close() - csvWriter := csv.NewWriter(f) - - // Header - err = csvWriter.Write([]string{ - "AccAddress", - "GenCoins", - "IssueCoins", - "WalletCoins", - "RewardCoins", - "DelBondingTokens", - "DelLPTokens", - "BondingDiff", - "LPDiff", - }) - if err != nil { - return fmt.Errorf("header write: %w", err) - } - - // Entries - for i, result := range results { - err := csvWriter.Write([]string{ - result.ReportItem.AccAddress.String(), - result.ReportItem.GenCoins.String(), - result.ReportItem.IssueCoins.String(), - result.ReportItem.AccBalance.String(), - result.ReportItem.RewardCoins.String(), - result.ReportItem.DelBondingTokens.String(), - result.ReportItem.DelLPTokens.String(), - result.BondingDiff.String(), - result.LPDiff.String(), - }) - if err != nil { - return fmt.Errorf("entry %d: write: %w", i+1, err) - } - } - - csvWriter.Flush() - - return nil -} - -func (results SXFIBalanceReportResults) String() string { - decimalDec := sdk.NewDecWithPrec(1, 18) - - str := strings.Builder{} - str.WriteString("Mainnet SXFI-XFI relation report:\n") - for _, result := range results { - diffBondingDec, diffLPDec := result.BondingDiff.ToDec().Mul(decimalDec), result.LPDiff.ToDec().Mul(decimalDec) - str.WriteString(fmt.Sprintf(" - %s\n", result.ReportItem.AccAddress)) - str.WriteString(fmt.Sprintf(" BondingDiff: %s (%s)\n", diffBondingDec, result.BondingDiff)) - str.WriteString(fmt.Sprintf(" LPDiff: %s (%s)\n", diffLPDec, result.LPDiff)) - str.WriteString(fmt.Sprintf(" GenBalance: %s\n", result.ReportItem.GenCoins)) - str.WriteString(fmt.Sprintf(" AccBalance: %s\n", result.ReportItem.AccBalance)) - str.WriteString(fmt.Sprintf(" Issues: %s\n", result.ReportItem.IssueCoins)) - str.WriteString(fmt.Sprintf(" Rewards: %s\n", result.ReportItem.RewardCoins)) - str.WriteString(fmt.Sprintf(" BDel: %s (%s)\n", result.ReportItem.DelBondingTokens, result.ReportItem.DelBondingShares)) - str.WriteString(fmt.Sprintf(" LPDel: %s (%s)\n", result.ReportItem.DelLPTokens, result.ReportItem.DelLPShares)) - } - - return str.String() -} - -// SXFIBalanceReport contains initial and final Testnet (v0.7) sxfi balance for accounts. -// Key - account address. -type SXFIBalanceReport map[string]*SXFIBalanceReportItem - -// AppendGenesisBalances modifies a SXFIBalanceReport with genesis account balances. -func (r SXFIBalanceReport) AppendGenesisBalances( - ctx sdk.Context, app *DnServiceApp, - issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string, -) error { - - genBalances := []struct { - AccAddress string - BondingBalance string - LPBalance string - }{ - { - AccAddress: "wallet1wwmenr38hhrem2v3ue3gwdhj03ynzcvlxgc92u", - BondingBalance: "3400000000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet1a6sd0y8l0ma0gnytacrnwlmnupm7ftnwxngalr", - BondingBalance: "2500000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet1whpkntyj549f7euftgpng24k2we8legght4rzg", - BondingBalance: "2500000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet1zwkqfm2sdgyx0g6h2dj9em4z4kjgy5lmtnmgjd", - BondingBalance: "2500000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet10a24shxzjtutj637rr8shwkwaxx8paplu4vc6f", - BondingBalance: "2500000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet19xshddf5ww7fhd53fumly2r7lqsszz63fxca9x", - BondingBalance: "2500000000000000000000", - LPBalance: "0", - }, - { - AccAddress: "wallet1l9mukqvh0etam66dvgw99w9awv3jjv6tyh2hpc", - BondingBalance: "50000000000000000000000", - LPBalance: "0", - }, - } - - for i, genBalance := range genBalances { - accAddress, err := sdk.AccAddressFromBech32(genBalance.AccAddress) - if err != nil { - return fmt.Errorf("genBalance (%d): AccAddress (%s): invalid: %w", i, genBalance.AccAddress, err) - } - bondingAmt, ok := sdk.NewIntFromString(genBalance.BondingBalance) - if !ok { - return fmt.Errorf("genBalance (%d): BondingBalance (%s): invalid sdk.Int", i, genBalance.BondingBalance) - } - lpAmt, ok := sdk.NewIntFromString(genBalance.LPBalance) - if !ok { - return fmt.Errorf("genBalance (%d): LPBalance (%s): invalid sdk.Int", i, genBalance.LPBalance) - } - acc := app.accountKeeper.GetAccount(ctx, accAddress) - if acc == nil { - return fmt.Errorf("genBalance (%d): account (%s): not found", i, accAddress) - } - - reportItem := NewSXFIBalanceReportItem(accAddress, acc.GetCoins(), issueBondingDenom, issueLPDenom, bondingDenom, lpDenom) - reportItem.GenCoins = sdk.NewCoins( - sdk.NewCoin(bondingDenom, bondingAmt), - sdk.NewCoin(lpDenom, lpAmt), - ) - r[accAddress.String()] = reportItem - } - - return nil -} - -// AppendStakerCSVReport modifies a SXFIBalanceReport with staker CSV report data. -func (r SXFIBalanceReport) AppendStakerCSVReport(filePath string) error { - const ( - csvEntryColumns = 5 - ) - - f, err := os.Open(filePath) - if err != nil { - return fmt.Errorf("CSV staker report open: %w", err) - } - defer f.Close() - - csvReader := csv.NewReader(f) - entryIdx := 0 - for { - entryIdx++ - csvEntry, err := csvReader.Read() - if err != nil { - if err == io.EOF { - break - } - return fmt.Errorf("entry (%d): read failed: %w", entryIdx, err) - } - if entryIdx == 1 { - // skip the header - continue - } - - // parse - if len(csvEntry) != csvEntryColumns { - return fmt.Errorf("entry (%d): invalid number of columns: %d / %d", entryIdx, len(csvEntry), csvEntryColumns) - } - stakerTxHash := csvEntry[0] - if stakerTxHash == "" { - return fmt.Errorf("entry (%d): TxHash: emtpy", entryIdx) - } - stakerBondingAmt := sdk.ZeroInt() - if amtRaw := csvEntry[1]; amtRaw != "" { - amt, ok := sdk.NewIntFromString(amtRaw) - if !ok { - return fmt.Errorf("entry (%d): BondingAmount (%s): invalid sdk.Int", entryIdx, amtRaw) - } - stakerBondingAmt = amt - } - stakerAccAddress, err := sdk.AccAddressFromBech32(csvEntry[2]) - if err != nil { - return fmt.Errorf("entry (%d): AccAddress (%s): invalid sdk.AccAddress: %w", entryIdx, csvEntry[2], err) - } - stakerEthAddress := csvEntry[3] - if !helpers.IsEthereumAddress(stakerEthAddress) { - return fmt.Errorf("entry (%d): EthAddress (%s): invalid", entryIdx, stakerEthAddress) - } - stakerLPAmt := sdk.ZeroInt() - if amtRaw := csvEntry[4]; amtRaw != "" { - amt, ok := sdk.NewIntFromString(amtRaw) - if !ok { - return fmt.Errorf("entry (%d): LPAmount (%s): invalid sdk.Int", entryIdx, amtRaw) - } - stakerLPAmt = amt - } - - stakerReport := &SXFIStakerReportItem{ - TxHash: stakerTxHash, - AccAddress: stakerAccAddress, - EthAddress: stakerEthAddress, - BondingAmount: stakerBondingAmt, - LPAmount: stakerLPAmt, - } - reportItem, found := r[stakerReport.AccAddress.String()] - if !found { - return fmt.Errorf("entry (%d): reportEntry for AccAddress %s: not found", entryIdx, stakerReport.AccAddress) - } - if reportItem.StakerReport != nil { - return fmt.Errorf("entry (%d): reportEntry for AccAddress %s: StakerReport already exists", entryIdx, stakerReport.AccAddress) - } - - reportItem.StakerReport = stakerReport - } - - return nil -} - -// Verify compares issues data with Staker report data. -func (r SXFIBalanceReport) Verify() error { - for accAddr, reportItem := range r { - if reportItem.StakerReport == nil { - continue - } - - issuedBondingAmt := reportItem.IssueCoins.AmountOf(reportItem.IssueBondingDenom) - stakerBondingAmt := reportItem.StakerReport.BondingAmount - if !issuedBondingAmt.Equal(stakerBondingAmt) { - return fmt.Errorf("account %s: issued / staker Bonding amount mismatch: %s / %s", accAddr, issuedBondingAmt, stakerBondingAmt) - } - } - - return nil -} - -func (r SXFIBalanceReport) GetResults() SXFIBalanceReportResults { - results := make(SXFIBalanceReportResults, 0, len(r)) - for _, reportItem := range r { - diffBonding := reportItem.GetCurrentBondingBalance().Sub(reportItem.GetInitialBondingBalance()) - diffLP := reportItem.GetCurrentLPBalance().Sub(reportItem.GetInitialLPBalance()) - - results = append(results, SXFIBalanceReportResult{ - ReportItem: *reportItem, - BondingDiff: diffBonding, - LPDiff: diffLP, - }) - } - - sort.Slice(results, func(i, j int) bool { - return results[i].BondingDiff.LT(results[j].BondingDiff) - }) - - return results -} - -// getMainnetSXFIBalanceReport returns a SXFIBalanceReport report. -func (app *DnServiceApp) getMainnetSXFIBalanceReport(ctx sdk.Context, - issueBondingDenom, issueLPDenom, bondingDenom, lpDenom string, - stakerCSVReportPath string, -) (SXFIBalanceReport, error) { - - cacheCtx, _ := ctx.CacheContext() - - // initialize report with genesis data - report := make(SXFIBalanceReport) - if err := report.AppendGenesisBalances(ctx, app, issueBondingDenom, issueLPDenom, bondingDenom, lpDenom); err != nil { - return nil, fmt.Errorf("append genesis balances: %w", err) - } - - // iterate all issues and combine duplicate payees - for _, issue := range app.ccKeeper.GetGenesisIssues(cacheCtx) { - accAddr := issue.Payee - - reportItem, found := report[accAddr.String()] - if !found { - acc := app.accountKeeper.GetAccount(cacheCtx, accAddr) - if acc == nil { - return nil, fmt.Errorf("issue %s: getAccount for %s: not found", issue.ID, accAddr) - } - - reportItem = NewSXFIBalanceReportItem(accAddr, acc.GetCoins(), issueBondingDenom, issueLPDenom, bondingDenom, lpDenom) - } - - reportItem.IssueCoins = reportItem.IssueCoins.Add(issue.Coin) - report[accAddr.String()] = reportItem - } - - // withdraw all rewards - // as all rewards were transferred to rewards bank before, we only query the bank coins - for _, reportItem := range report { - accAddr := reportItem.AccAddress - reportItem.RewardCoins = app.distrKeeper.GetDelegatorRewardsBankCoins(cacheCtx, accAddr) - } - - // unbond all delegations - // no actual undelegation is done, we just calculate delegator tokens based on shares and validator tokens - { - for _, reportItem := range report { - accAddr := reportItem.AccAddress - var iterationErr error - app.stakingKeeper.IterateDelegations( - cacheCtx, accAddr, - func(_ int64, del exported.DelegationI) (stop bool) { - val, found := app.stakingKeeper.GetValidator(cacheCtx, del.GetValidatorAddr()) - if !found { - iterationErr = fmt.Errorf("account %s: get delegation validator %s: not found", accAddr, del.GetValidatorAddr()) - return true - } - - reportItem.DelBondingShares = reportItem.DelBondingShares.Add(del.GetBondingShares()) - if !del.GetBondingShares().IsZero() { - reportItem.DelBondingTokens = reportItem.DelBondingTokens.Add(val.BondingTokensFromSharesTruncated(del.GetBondingShares())) - } - reportItem.DelLPShares = reportItem.DelLPShares.Add(del.GetLPShares()) - if !del.GetLPShares().IsZero() { - reportItem.DelLPTokens = reportItem.DelLPTokens.Add(val.LPTokensFromSharesTruncated(del.GetLPShares())) - } - - return false - }, - ) - if iterationErr != nil { - return nil, iterationErr - } - } - } - - // update report with Staker CSV-report - if stakerCSVReportPath != "" { - if err := report.AppendStakerCSVReport(stakerCSVReportPath); err != nil { - return nil, fmt.Errorf("append append StakerCSVReport: %w", err) - } - } - - return report, nil -} - -type SXFIBalanceReportStats struct { - TotalNegativeBondingDiffs sdk.Dec - TotalPositiveBondingDiffs sdk.Dec - AccMints map[string]sdk.DecCoin -} - -// processMainnetSXFIBalance builds getMainnetSXFIBalanceReport and mints and transfers negative diffs. -func (app *DnServiceApp) processMainnetSXFIBalance(ctx sdk.Context) error { - const ( - issueDenom = "sxfi" - bondingDenom = "xfi" - lpDenom = "lpt" - ) - decimalDec := sdk.NewDecWithPrec(1, 18) - - stakerReportPath := os.Getenv("DN_ZHP_STAKERREPORT_PATH") - reportOutputPrefix := os.Getenv("DN_ZHP_REPORTOUTPUT_PREFIX") - if stakerReportPath == "" { - return fmt.Errorf("envVar %q: not set", "DN_ZHP_STAKERREPORT_PATH") - } - if reportOutputPrefix == "" { - return fmt.Errorf("envVar %q: not set", "DN_ZHP_REPORTOUTPUT_PREFIX") - } - - // build report - report, err := app.getMainnetSXFIBalanceReport( - ctx, - issueDenom, lpDenom, bondingDenom, lpDenom, - stakerReportPath, - ) - if err != nil { - return fmt.Errorf("getMainnetSXFIBalanceReport: %w", err) - } - if err := report.Verify(); err != nil { - return fmt.Errorf("report verification: %w", err) - } - - // save results - results := report.GetResults() - if err := results.SaveToCSV(reportOutputPrefix + "data.csv"); err != nil { - return fmt.Errorf("saving report results to CSV: %w", err) - } - - // calculate the mint amount - positiveDiffs, negativeDiffs := sdk.ZeroInt(), sdk.ZeroInt() - stats := SXFIBalanceReportStats{ - TotalNegativeBondingDiffs: sdk.ZeroDec(), - TotalPositiveBondingDiffs: sdk.ZeroDec(), - AccMints: make(map[string]sdk.DecCoin, len(report)), - } - for _, result := range results { - if !result.BondingDiff.IsNegative() { - positiveDiffs = positiveDiffs.Add(result.BondingDiff) - continue - } - negativeDiffs = negativeDiffs.Add(result.BondingDiff) - } - negativeDiffs = negativeDiffs.MulRaw(-1) - bondingMintCoin := sdk.NewCoin(bondingDenom, negativeDiffs) - // - stats.TotalPositiveBondingDiffs = positiveDiffs.ToDec().Mul(decimalDec) - stats.TotalNegativeBondingDiffs = negativeDiffs.ToDec().Mul(decimalDec) - - // mint - if err := app.mintKeeper.MintCoins(ctx, sdk.NewCoins(bondingMintCoin)); err != nil { - return fmt.Errorf("minting bonding coins: %w", err) - } - if err := app.ccsKeeper.IncreaseCurrencySupply(ctx, bondingMintCoin); err != nil { - return fmt.Errorf("increasing ccStorage supply: %w", err) - } - - // distribute minted coins - for _, result := range results { - diff := result.BondingDiff - if !diff.IsNegative() { - continue - } - - coin := sdk.NewCoin(bondingDenom, diff.MulRaw(-1)) - if err := app.supplyKeeper.SendCoinsFromModuleToAccount(ctx, mint.ModuleName, result.ReportItem.AccAddress, sdk.NewCoins(coin)); err != nil { - return fmt.Errorf("sending minted coins to %s: %w", result.ReportItem.AccAddress, err) - } - // - stats.AccMints[result.ReportItem.AccAddress.String()] = sdk.NewDecCoinFromDec( - coin.Denom, - coin.Amount.ToDec().Mul(decimalDec), - ) - } - - // save stats - statsBz, err := json.Marshal(stats) - if err != nil { - return fmt.Errorf("stats: JSON marshal: %w", err) - } - f, err := os.Create(reportOutputPrefix + "stats.json") - if err != nil { - return fmt.Errorf("stats: creating file: %w", err) - } - defer f.Close() - if _, err := f.Write(statsBz); err != nil { - return fmt.Errorf("stats: write to file: %w", err) - } - - // check the invariants - if err := app.checkInvariants(ctx); err != nil { - return fmt.Errorf("post invariants check: %w", err) - } - - return nil -} diff --git a/go.mod b/go.mod index 04adb67c..1d9a705e 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/dfinance/dnode go 1.14 -replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85 +replace github.com/cosmos/cosmos-sdk => github.com/dfinance/cosmos-sdk v0.39.2-0.20210526161633-d89e846acf82 // Local development option //replace github.com/cosmos/cosmos-sdk => /Users/boris/go/src/github.com/dfinance/cosmos-sdk @@ -17,6 +17,7 @@ require ( github.com/OneOfOne/xxhash v1.2.7 github.com/atlassian/go-sentry-api v0.0.0-20200117001222-a9ccec16c98b github.com/cosmos/cosmos-sdk v0.0.1 + github.com/crazy-max/xgo v0.6.5 // indirect github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 github.com/dfinance/lcs v0.1.7-big diff --git a/go.sum b/go.sum index c7665fd1..aedbb5a1 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/crazy-max/xgo v0.6.5 h1:IL+OXddbWEKQMJhbf80uQgj2Yly7OviXl6cQkHsFSbQ= +github.com/crazy-max/xgo v0.6.5/go.mod h1:M82OOqVFATp75AnEFrBL+Xf7vdsNt2X36ebzNgOT8o4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -145,8 +147,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85 h1:E/IG4Fi01M2EglSmlGHtGaLsGlRglrhVO2H1h28f2Z0= -github.com/dfinance/cosmos-sdk v0.39.2-0.20201103114952-6e10e3e0ab85/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= +github.com/dfinance/cosmos-sdk v0.39.2-0.20210526161633-d89e846acf82 h1:ZvISL3KWHkK5td2Xlc035pLyl2jjLEbEhrY7kJeEJVw= +github.com/dfinance/cosmos-sdk v0.39.2-0.20210526161633-d89e846acf82/go.mod h1:2sfZJgnTxx4j5VycscAUaaI3P7ay5v0AfaO/UZXTFr0= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de h1:PZfrjeOs9epAU0n+FpX/JAr/e+5m5/GdfUsgtO8gCOY= github.com/dfinance/dvm-proto/go v0.0.0-20200819065410-6b70956c85de/go.mod h1:Vt1T0G56AYXbsduNKzSkq1RDTNa8PFraSqB9DaTCV0U= github.com/dfinance/glav v0.0.0-20200814081332-c4701f6c12a6 h1:fZIYncA5BRad0+YnP88cfBfo0ZPgxPSVeuh/jvoGrLc=