diff --git a/e2e/coinswap/cli_test.go b/e2e/coinswap/cli_test.go new file mode 100644 index 00000000..ec90ffec --- /dev/null +++ b/e2e/coinswap/cli_test.go @@ -0,0 +1,11 @@ +package coinswap + +// import ( +// "testing" + +// "github.com/stretchr/testify/suite" +// ) + +// func TestQueryTestSuite(t *testing.T) { +// suite.Run(t, new(QueryTestSuite)) +// } \ No newline at end of file diff --git a/e2e/coinswap/query.go b/e2e/coinswap/query.go new file mode 100644 index 00000000..8a9c77ed --- /dev/null +++ b/e2e/coinswap/query.go @@ -0,0 +1,254 @@ +package coinswap + +import ( + "context" + "fmt" + "time" + + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + coinswaptypes "mods.irisnet.org/modules/coinswap/types" + tokentypes "mods.irisnet.org/modules/token/types/v1" + "mods.irisnet.org/simapp" +) + +// QueryTestSuite is a suite of end-to-end tests for the nft module +type QueryTestSuite struct { + e2e.TestSuite +} + +// SetupSuite creates a new network for integration tests +func (s *QueryTestSuite) SetupSuite() { + depInjectOptions := simapp.DepinjectOptions{ + Config: e2e.AppConfig, + Providers: []interface{}{ + e2e.ProvideEVMKeeper(), + e2e.ProvideICS20Keeper(), + }, + } + sdk.SetCoinDenomRegex(func() string { + return `[a-zA-Z][a-zA-Z0-9/\-]{2,127}` + }) + + s.T().Log("setting up integration test suite") + s.Network = simapp.SetupNetwork(s.T(),depInjectOptions) +} + +// TestCoinswap tests all query command in the nft module +func (s *QueryTestSuite) TestCoinswap() { + val := s.Validators[0] + clientCtx := val.ClientCtx + // --------------------------------------------------------------------------- + + from := val.Address + symbol := "kitty" + name := "Kitty Token" + minUnit := "kitty" + scale := uint32(0) + initialSupply := uint64(100000000) + maxSupply := uint64(200000000) + mintable := true + baseURL := val.APIAddress + lptDenom := "lpt-1" + + // issue token + msgIssueToken := &tokentypes.MsgIssueToken{ + Symbol: symbol, + Name: name, + Scale: scale, + MinUnit: minUnit, + InitialSupply: initialSupply, + MaxSupply: maxSupply, + Mintable: mintable, + Owner: from.String(), + } + txResult := s.BlockSendMsgs(s.T(), msgIssueToken) + s.Require().Equal(0, txResult.Code, "send issue token msg failed") + + //_ = tokentestutil.IssueTokenExec(s.T(), s.Network, clientCtx, from.String(), args...) + + balances := simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("100000000", balances.AmountOf(symbol).String()) + s.Require().Equal("399986975", balances.AmountOf(sdk.DefaultBondDenom).String()) + + // test add liquidity (poor not exist) + status, err := clientCtx.Client.Status(context.Background()) + s.Require().NoError(err) + deadline := status.SyncInfo.LatestBlockTime.Add(time.Minute) + + msgAddLiquidity := &coinswaptypes.MsgAddLiquidity{ + MaxToken: sdk.NewCoin(symbol, sdk.NewInt(1000)), + ExactStandardAmt: sdk.NewInt(1000), + MinLiquidity: sdk.NewInt(1000), + Deadline: deadline.Unix(), + Sender: from.String(), + } + s.SendMsgs(s.T(), msgAddLiquidity) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("99999000", balances.AmountOf(symbol).String()) + s.Require().Equal("399980965", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("1000", balances.AmountOf(lptDenom).String()) + + queryPoolResponse := proto.Message(&coinswaptypes.QueryLiquidityPoolResponse{}) + url := fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err := testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + queryPool := queryPoolResponse.(*coinswaptypes.QueryLiquidityPoolResponse) + s.Require().Equal("1000", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("1000", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("1000", queryPool.Pool.Lpt.Amount.String()) + + // test add liquidity (poor exist) + status, err = clientCtx.Client.Status(context.Background()) + s.Require().NoError(err) + deadline = status.SyncInfo.LatestBlockTime.Add(time.Minute) + + msgAddLiquidity = &coinswaptypes.MsgAddLiquidity{ + MaxToken: sdk.NewCoin(symbol, sdk.NewInt(2001)), + ExactStandardAmt: sdk.NewInt(2000), + MinLiquidity: sdk.NewInt(2000), + Deadline: deadline.Unix(), + Sender: from.String(), + } + s.SendMsgs(s.T(), msgAddLiquidity) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("99996999", balances.AmountOf(symbol).String()) + s.Require().Equal("399978955", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("3000", balances.AmountOf(lptDenom).String()) + + url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + s.Require().Equal("3000", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("3001", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String()) + + // test sell order + msgSellOrder := &coinswaptypes.MsgSwapOrder{ + Input: coinswaptypes.Input{ + Address: from.String(), + Coin: sdk.NewCoin(symbol, sdk.NewInt(1000)), + }, + Output: coinswaptypes.Output{ + Address: from.String(), + Coin: sdk.NewInt64Coin(s.BondDenom, 748), + }, + Deadline: deadline.Unix(), + IsBuyOrder: false, + } + s.SendMsgs(s.T(), msgSellOrder) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("99995999", balances.AmountOf(symbol).String()) + s.Require().Equal("399979693", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("3000", balances.AmountOf(lptDenom).String()) + + url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + s.Require().Equal("2252", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("4001", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String()) + + // test buy order + msgBuyOrder := &coinswaptypes.MsgSwapOrder{ + Input: coinswaptypes.Input{ + Address: from.String(), + Coin: sdk.NewInt64Coin(s.BondDenom, 753), + }, + Output: coinswaptypes.Output{ + Address: from.String(), + Coin: sdk.NewCoin(symbol, sdk.NewInt(1000)), + }, + Deadline: deadline.Unix(), + IsBuyOrder: true, + } + s.SendMsgs(s.T(), msgBuyOrder) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("99996999", balances.AmountOf(symbol).String()) + s.Require().Equal("399978930", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("3000", balances.AmountOf(lptDenom).String()) + + url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + s.Require().Equal("3005", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("3001", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("3000", queryPool.Pool.Lpt.Amount.String()) + + // Test remove liquidity (remove part) + msgRemoveLiquidity := &coinswaptypes.MsgRemoveLiquidity{ + WithdrawLiquidity: sdk.NewCoin(lptDenom, sdk.NewInt(2000)), + MinToken: sdk.NewInt(2000), + MinStandardAmt: sdk.NewInt(2000), + Deadline: deadline.Unix(), + Sender: from.String(), + } + + // prepare txBuilder with msg + s.SendMsgs(s.T(), msgRemoveLiquidity) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("99998999", balances.AmountOf(symbol).String()) + s.Require().Equal("399980923", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("1000", balances.AmountOf(lptDenom).String()) + + url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + s.Require().Equal("1002", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("1001", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("1000", queryPool.Pool.Lpt.Amount.String()) + + // Test remove liquidity (remove all) + msgRemoveLiquidity = &coinswaptypes.MsgRemoveLiquidity{ + WithdrawLiquidity: sdk.NewCoin(lptDenom, sdk.NewInt(1000)), + MinToken: sdk.NewInt(1000), + MinStandardAmt: sdk.NewInt(1000), + Deadline: deadline.Unix(), + Sender: from.String(), + } + + // prepare txBuilder with msg + s.SendMsgs(s.T(), msgRemoveLiquidity) + + balances = simapp.QueryBalancesExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal("100000000", balances.AmountOf(symbol).String()) + s.Require().Equal("399981915", balances.AmountOf(sdk.DefaultBondDenom).String()) + s.Require().Equal("0", balances.AmountOf(lptDenom).String()) + + url = fmt.Sprintf("%s/irismod/coinswap/pools/%s", baseURL, lptDenom) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolResponse)) + + s.Require().Equal("0", queryPool.Pool.Standard.Amount.String()) + s.Require().Equal("0", queryPool.Pool.Token.Amount.String()) + s.Require().Equal("0", queryPool.Pool.Lpt.Amount.String()) + + queryPoolsResponse := proto.Message(&coinswaptypes.QueryLiquidityPoolsResponse{}) + url = fmt.Sprintf("%s/irismod/coinswap/pools", baseURL) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryPoolsResponse)) + + queryPools := queryPoolsResponse.(*coinswaptypes.QueryLiquidityPoolsResponse) + s.Require().Len(queryPools.Pools, 1) +} diff --git a/e2e/farm/cli_test.go b/e2e/farm/cli_test.go new file mode 100644 index 00000000..0687e53b --- /dev/null +++ b/e2e/farm/cli_test.go @@ -0,0 +1,15 @@ +package farm + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestTxTestSuite(t *testing.T) { + suite.Run(t, new(TxTestSuite)) +} + +func TestQueryTestSuite(t *testing.T) { + suite.Run(t, new(QueryTestSuite)) +} \ No newline at end of file diff --git a/e2e/farm/query.go b/e2e/farm/query.go new file mode 100644 index 00000000..1e3f9538 --- /dev/null +++ b/e2e/farm/query.go @@ -0,0 +1,206 @@ +package farm + +import ( + "context" + "fmt" + "time" + + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + coinswaptypes "mods.irisnet.org/modules/coinswap/types" + farmcli "mods.irisnet.org/modules/farm/client/cli" + farmtypes "mods.irisnet.org/modules/farm/types" + tokentypes "mods.irisnet.org/modules/token/types/v1" + "mods.irisnet.org/simapp" +) + +// QueryTestSuite is a suite of end-to-end tests for the farm module +type QueryTestSuite struct { + e2e.TestSuite +} + +// SetupSuite creates a new network for integration tests +func (s *QueryTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + depInjectOptions := simapp.DepinjectOptions{ + Config: e2e.AppConfig, + Providers: []interface{}{ + e2e.ProvideEVMKeeper(), + e2e.ProvideICS20Keeper(), + }, + } + + s.T().Log("setting up integration test suite") + s.Network = simapp.SetupNetwork(s.T(),depInjectOptions) + sdk.SetCoinDenomRegex(func() string { + return `[a-zA-Z][a-zA-Z0-9/\-]{2,127}` + }) +} + +// TestQueryCmd tests all query command in the farm module +func (s *QueryTestSuite) TestQueryCmd() { + val := s.Validators[0] + clientCtx := val.ClientCtx + baseURL := val.APIAddress + + s.setup() + + // --------------------------------------------------------------------------- + + creator := val.Address + description := "iris-atom farm pool" + startHeight := s.latestHeight() + 1 + rewardPerBlock := sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))) + lpTokenDenom := "lpt-1" + totalReward := sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(1000))) + editable := true + + globalFlags := []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + args := []string{ + fmt.Sprintf("--%s=%s", farmcli.FlagDescription, description), + fmt.Sprintf("--%s=%d", farmcli.FlagStartHeight, startHeight), + fmt.Sprintf("--%s=%s", farmcli.FlagRewardPerBlock, rewardPerBlock), + fmt.Sprintf("--%s=%s", farmcli.FlagLPTokenDenom, lpTokenDenom), + fmt.Sprintf("--%s=%s", farmcli.FlagTotalReward, totalReward), + fmt.Sprintf("--%s=%v", farmcli.FlagEditable, editable), + } + + args = append(args, globalFlags...) + txResult := CreateFarmPoolExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + args..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + + poolID := s.GetAttribute( + farmtypes.EventTypeCreatePool, + farmtypes.AttributeValuePoolId, + txResult.Events, + ) + expectedContents := farmtypes.FarmPoolEntry{ + Id: poolID, + Description: description, + Creator: creator.String(), + StartHeight: startHeight, + EndHeight: startHeight + 100, + Editable: editable, + Expired: false, + TotalLptLocked: sdk.NewCoin(lpTokenDenom, sdk.ZeroInt()), + TotalReward: totalReward, + RemainingReward: totalReward, + RewardPerBlock: rewardPerBlock, + } + + respType := proto.Message(&farmtypes.QueryFarmPoolsResponse{}) + queryPoolURL := fmt.Sprintf("%s/irismod/farm/pools", baseURL) + resp, err := testutil.GetRequest(queryPoolURL) + + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, respType)) + result := respType.(*farmtypes.QueryFarmPoolsResponse) + s.Require().EqualValues(expectedContents, *result.Pools[0]) + + _, err = s.WaitForHeight(startHeight) + s.Require().NoError(err) + s.WaitForNextBlock() + + lpToken := sdk.NewCoin(lpTokenDenom, sdk.NewInt(100)) + txResult = StakeExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + lpToken.String(), + globalFlags..., + ) + s.Require().Equal(uint32(0), txResult.Code, txResult.Log) + + expectFarmer := farmtypes.LockedInfo{ + PoolId: poolID, + Locked: lpToken, + PendingReward: sdk.Coins{}, + } + + queryFarmerRespType := proto.Message(&farmtypes.QueryFarmerResponse{}) + queryFarmInfoURL := fmt.Sprintf("%s/irismod/farm/farmers/%s", baseURL, creator.String()) + resp, err = testutil.GetRequest(queryFarmInfoURL) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, queryFarmerRespType)) + farmer := queryFarmerRespType.(*farmtypes.QueryFarmerResponse) + + if farmer.Height-txResult.Height > 0 { + expectFarmer.PendingReward = rewardPerBlock.MulInt( + sdk.NewInt(farmer.Height - txResult.Height), + ) + } + s.Require().EqualValues(expectFarmer, *farmer.List[0]) +} + +func (s *QueryTestSuite) latestHeight() int64 { + height, err := s.LatestHeight() + s.Require().NoError(err) + return height +} + +func (s *QueryTestSuite) setup() { + + val := s.Validators[0] + clientCtx := val.ClientCtx + + from := val.Address + symbol := "kitty" + name := "Kitty Token" + minUnit := "kitty" + scale := uint32(0) + initialSupply := uint64(100000000) + maxSupply := uint64(200000000) + mintable := true + + // issue token + msgIssueToken := &tokentypes.MsgIssueToken{ + Symbol: symbol, + Name: name, + Scale: scale, + MinUnit: minUnit, + InitialSupply: initialSupply, + MaxSupply: maxSupply, + Mintable: mintable, + Owner: from.String(), + } + res := s.BlockSendMsgs(s.T(), msgIssueToken) + s.Require().Equal(uint32(0), res.Code, res.Log) + + // add liquidity + status, err := clientCtx.Client.Status(context.Background()) + s.Require().NoError(err) + deadline := status.SyncInfo.LatestBlockTime.Add(time.Minute) + + msgAddLiquidity := &coinswaptypes.MsgAddLiquidity{ + MaxToken: sdk.NewCoin(symbol, sdk.NewInt(1000)), + ExactStandardAmt: sdk.NewInt(1000), + MinLiquidity: sdk.NewInt(1000), + Deadline: deadline.Unix(), + Sender: val.Address.String(), + } + res = s.BlockSendMsgs(s.T(), msgAddLiquidity) + s.Require().Equal(uint32(0), res.Code, res.Log) +} diff --git a/e2e/farm/test_helper.go b/e2e/farm/test_helper.go new file mode 100644 index 00000000..766c8077 --- /dev/null +++ b/e2e/farm/test_helper.go @@ -0,0 +1,144 @@ +package farm + +import ( + "fmt" + "testing" + + "github.com/cometbft/cometbft/libs/cli" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + farmcli "mods.irisnet.org/modules/farm/client/cli" + farmtypes "mods.irisnet.org/modules/farm/types" + "mods.irisnet.org/simapp" +) + +// CreateFarmPoolExec creates a redelegate message. +func CreateFarmPoolExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdCreateFarmPool(), args) +} + +// QueryFarmPoolsExec queries farm pools +func QueryFarmPoolsExec( + t *testing.T, + network simapp.Network, + clientCtx client.Context, + extraArgs ...string, +) *farmtypes.QueryFarmPoolsResponse { + args := []string{ + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &farmtypes.QueryFarmPoolsResponse{} + network.ExecQueryCmd(t, clientCtx, farmcli.GetCmdQueryFarmPools(), args, response) + return response +} + +// QueryFarmPoolExec queries farm pool +func QueryFarmPoolExec( + t *testing.T, + network simapp.Network, + clientCtx client.Context, + poolID string, + extraArgs ...string, +) *farmtypes.QueryFarmPoolResponse { + args := []string{ + poolID, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + response := &farmtypes.QueryFarmPoolResponse{} + network.ExecQueryCmd(t, clientCtx, farmcli.GetCmdQueryFarmPool(), args, response) + return response +} + +// AppendRewardExec creates a redelegate message. +func AppendRewardExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator, + poolID string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + poolID, + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdAdjustPool(), args) +} + +// StakeExec creates a redelegate message. +func StakeExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator, + poolID, + lpToken string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + poolID, + lpToken, + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdStake(), args) +} + +// UnstakeExec creates a redelegate message. +func UnstakeExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator, + poolID, + lpToken string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + poolID, + lpToken, + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdUnstake(), args) +} + +// HarvestExec creates a redelegate message. +func HarvestExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator, + poolID string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + poolID, + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdHarvest(), args) +} + +// DestroyExec creates a redelegate message. +func DestroyExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator, + poolID string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + poolID, + fmt.Sprintf("--%s=%s", flags.FlagFrom, creator), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, farmcli.GetCmdDestroyFarmPool(), args) +} + +// QueryFarmerExec creates a redelegate message. +func QueryFarmerExec(t *testing.T, network simapp.Network, clientCtx client.Context, + creator string, + extraArgs ...string) *farmtypes.QueryFarmerResponse { + args := []string{ + creator, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + response := &farmtypes.QueryFarmerResponse{} + network.ExecQueryCmd(t, clientCtx, farmcli.GetCmdQueryFarmer(), args, response) + return response +} diff --git a/e2e/farm/tx.go b/e2e/farm/tx.go new file mode 100644 index 00000000..a6a5954a --- /dev/null +++ b/e2e/farm/tx.go @@ -0,0 +1,229 @@ +package farm + +import ( + "context" + "fmt" + "time" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + coinswaptypes "mods.irisnet.org/modules/coinswap/types" + farmcli "mods.irisnet.org/modules/farm/client/cli" + farmtypes "mods.irisnet.org/modules/farm/types" + tokentypes "mods.irisnet.org/modules/token/types/v1" +) + +// TxTestSuite is a suite of end-to-end tests for the nft module +type TxTestSuite struct { + e2e.TestSuite +} + +// TestTxCmd tests all tx command in the nft module +func (s *TxTestSuite) TestTxCmd() { + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + + s.setup() + + // --------------------------------------------------------------------------- + + creator := val.Address + description := "iris-atom farm pool" + startHeight := s.latestHeight() + 2 + rewardPerBlock := sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))) + totalReward := sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(1000))) + editable := true + lptDenom := "lpt-1" + + globalFlags := []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + args := []string{ + fmt.Sprintf("--%s=%s", farmcli.FlagDescription, description), + fmt.Sprintf("--%s=%d", farmcli.FlagStartHeight, startHeight), + fmt.Sprintf("--%s=%s", farmcli.FlagRewardPerBlock, rewardPerBlock), + fmt.Sprintf("--%s=%s", farmcli.FlagLPTokenDenom, lptDenom), + fmt.Sprintf("--%s=%s", farmcli.FlagTotalReward, totalReward), + fmt.Sprintf("--%s=%v", farmcli.FlagEditable, editable), + } + + args = append(args, globalFlags...) + txResult := CreateFarmPoolExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + args..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + + poolID := s.Network.GetAttribute( + farmtypes.EventTypeCreatePool, + farmtypes.AttributeValuePoolId, + txResult.Events, + ) + expectedContents := &farmtypes.FarmPoolEntry{ + Id: poolID, + Creator: creator.String(), + Description: description, + StartHeight: startHeight, + EndHeight: startHeight + 100, + Editable: editable, + Expired: false, + TotalLptLocked: sdk.NewCoin(lptDenom, sdk.ZeroInt()), + TotalReward: totalReward, + RemainingReward: totalReward, + RewardPerBlock: rewardPerBlock, + } + + respType := QueryFarmPoolExec(s.T(), s.Network, val.ClientCtx, poolID) + s.Require().EqualValues(expectedContents, respType.Pool) + + reward := sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(1000))) + args = []string{ + fmt.Sprintf("--%s=%v", farmcli.FlagAdditionalReward, reward.String()), + } + args = append(args, globalFlags...) + txResult = AppendRewardExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + args..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + + lpToken := sdk.NewCoin(lptDenom, sdk.NewInt(100)) + txResult = StakeExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + lpToken.String(), + globalFlags..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + beginHeight := txResult.Height + + unstakeLPToken := sdk.NewCoin(lptDenom, sdk.NewInt(50)) + txResult = UnstakeExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + unstakeLPToken.String(), + globalFlags..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + endHeight := txResult.Height + + rewardGot := s.Network.GetAttribute( + farmtypes.EventTypeUnstake, + farmtypes.AttributeValueReward, + txResult.Events, + ) + expectedReward := rewardPerBlock.MulInt(sdk.NewInt(endHeight - beginHeight)) + s.Require().Equal(expectedReward.String(), rewardGot) + + txResult = HarvestExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + globalFlags..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) + endHeight1 := txResult.Height + + rewardGot = s.Network.GetAttribute( + farmtypes.EventTypeHarvest, + farmtypes.AttributeValueReward, + txResult.Events, + ) + expectedReward = rewardPerBlock.MulInt(sdk.NewInt(endHeight1 - endHeight)) + s.Require().Equal(expectedReward.String(), rewardGot) + + queryFarmerArgs := []string{ + fmt.Sprintf("--%s=%s", farmcli.FlagFarmPool, poolID), + } + + leftlpToken := lpToken.Sub(unstakeLPToken) + response := QueryFarmerExec( + s.T(), + s.Network, + val.ClientCtx, creator.String(), queryFarmerArgs...) + s.Require().EqualValues(leftlpToken, response.List[0].Locked) + + txResult = DestroyExec( + s.T(), + s.Network, + clientCtx, + creator.String(), + poolID, + globalFlags..., + ) + s.Require().EqualValues(txResult.Code, 0, txResult.Log) +} + +func (s *TxTestSuite) latestHeight() int64 { + height, err := s.Network.LatestHeight() + s.Require().NoError(err) + return height +} + +func (s *TxTestSuite) setup() { + + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + + from := val.Address + symbol := "kitty" + name := "Kitty Token" + minUnit := "kitty" + scale := uint32(0) + initialSupply := uint64(100000000) + maxSupply := uint64(200000000) + mintable := true + + // issue token + msgIssueToken := &tokentypes.MsgIssueToken{ + Symbol: symbol, + Name: name, + Scale: scale, + MinUnit: minUnit, + InitialSupply: initialSupply, + MaxSupply: maxSupply, + Mintable: mintable, + Owner: from.String(), + } + res := s.Network.BlockSendMsgs(s.T(), msgIssueToken) + s.Require().Equal(uint32(0), res.Code, res.Log) + + // add liquidity + status, err := clientCtx.Client.Status(context.Background()) + s.Require().NoError(err) + deadline := status.SyncInfo.LatestBlockTime.Add(time.Minute) + + msgAddLiquidity := &coinswaptypes.MsgAddLiquidity{ + MaxToken: sdk.NewCoin(symbol, sdk.NewInt(1000)), + ExactStandardAmt: sdk.NewInt(1000), + MinLiquidity: sdk.NewInt(1000), + Deadline: deadline.Unix(), + Sender: val.Address.String(), + } + res = s.Network.BlockSendMsgs(s.T(), msgAddLiquidity) + s.Require().Equal(uint32(0), res.Code, res.Log) +} \ No newline at end of file diff --git a/e2e/htlc/cli_test.go b/e2e/htlc/cli_test.go new file mode 100644 index 00000000..d84ce707 --- /dev/null +++ b/e2e/htlc/cli_test.go @@ -0,0 +1,15 @@ +package htlc + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestTxTestSuite(t *testing.T) { + suite.Run(t, new(TxTestSuite)) +} + +func TestQueryTestSuite(t *testing.T) { + suite.Run(t, new(QueryTestSuite)) +} \ No newline at end of file diff --git a/e2e/htlc/query.go b/e2e/htlc/query.go new file mode 100644 index 00000000..79aa182b --- /dev/null +++ b/e2e/htlc/query.go @@ -0,0 +1,59 @@ +package htlc + +import ( + "fmt" + + "github.com/cometbft/cometbft/crypto" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + htlccli "mods.irisnet.org/modules/htlc/client/cli" +) + +// QueryTestSuite is a suite of end-to-end tests for the htlc module +type QueryTestSuite struct { + e2e.TestSuite +} + +// TestQueryCmd tests all query command in the htlc module +func (s *QueryTestSuite) TestQueryCmd() { + val := s.Network.Validators[0] + + //------test GetCmdCreateHTLC()------------- + //baseURL := val.APIAddress + from := val.Address + to := sdk.AccAddress(crypto.AddressHash([]byte("dgsbl"))) + amount := "1000" + sdk.DefaultBondDenom + receiverOnOtherChain := "0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826" + hashLock := "e8d4133e1a82c74e2746e78c19385706ea7958a0ca441a08dacfa10c48ce2561" + timeLock := uint64(50) + timestamp := uint64(1580000000) + //stateOpen := "HTLC_STATE_OPEN" + + args := []string{ + fmt.Sprintf("--%s=%s", htlccli.FlagTo, to), + fmt.Sprintf("--%s=%s", htlccli.FlagAmount, amount), + fmt.Sprintf("--%s=%s", htlccli.FlagReceiverOnOtherChain, receiverOnOtherChain), + fmt.Sprintf("--%s=%s", htlccli.FlagHashLock, hashLock), + fmt.Sprintf("--%s=%d", htlccli.FlagTimeLock, timeLock), + fmt.Sprintf("--%s=%d", htlccli.FlagTimestamp, timestamp), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + _ = CreateHTLCExec( + s.T(), + s.Network, + val.ClientCtx, + from.String(), + args..., + ) +} diff --git a/e2e/htlc/test_helper.go b/e2e/htlc/test_helper.go new file mode 100644 index 00000000..9e7e1a73 --- /dev/null +++ b/e2e/htlc/test_helper.go @@ -0,0 +1,90 @@ +package htlc + +import ( + "fmt" + "testing" + + "github.com/cometbft/cometbft/libs/cli" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + htlccli "mods.irisnet.org/modules/htlc/client/cli" + htlctypes "mods.irisnet.org/modules/htlc/types" + "mods.irisnet.org/simapp" +) + +// CreateHTLCExec executes the creation of an HTLC with the provided parameters. +// +// Parameters: +// - t: testing.T instance for running test functions +// - network: simapp.Network instance for simulating the network +// - clientCtx: client.Context instance for client context +// - from: string representing the sender of the HTLC +// - extraArgs: variadic string arguments for additional parameters +// +// Returns a simapp.ResponseTx pointer. +func CreateHTLCExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, htlccli.GetCmdCreateHTLC(), args) +} + +// ClaimHTLCExec executes the claiming of an HTLC with the provided parameters. +// +// Parameters: +// - t: testing.T instance for running test functions +// - network: simapp.Network instance for simulating the network +// - clientCtx: client.Context instance for client context +// - from: string representing the sender of the HTLC +// - id: string representing the ID of the HTLC +// - secret: string representing the secret of the HTLC +// - extraArgs: variadic string arguments for additional parameters +// +// Returns a *simapp.ResponseTx pointer. +func ClaimHTLCExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + id string, + secret string, + extraArgs ...string) *simapp.ResponseTx { + args := []string{ + id, + secret, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, htlccli.GetCmdClaimHTLC(), args) +} + +// QueryHTLCExec executes a query for an HTLC based on the provided ID and additional arguments. +// +// Parameters: +// - t: testing.T instance for running test functions +// - network: simapp.Network instance for simulating the network +// - clientCtx: client.Context instance for client context +// - id: string representing the ID of the HTLC +// - extraArgs: variadic string arguments for additional parameters +// +// Returns an htlctypes.HTLC pointer. +func QueryHTLCExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + id string, + extraArgs ...string) *htlctypes.HTLC { + args := []string{ + id, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + response := &htlctypes.HTLC{} + network.ExecQueryCmd(t, clientCtx, htlccli.GetCmdQueryHTLC(), args, response) + return response +} diff --git a/e2e/htlc/tx.go b/e2e/htlc/tx.go new file mode 100644 index 00000000..faa2df99 --- /dev/null +++ b/e2e/htlc/tx.go @@ -0,0 +1,533 @@ +package htlc + +import ( + "crypto/rand" + "fmt" + "strconv" + "time" + + tmbytes "github.com/cometbft/cometbft/libs/bytes" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + htlccli "mods.irisnet.org/modules/htlc/client/cli" + htlctypes "mods.irisnet.org/modules/htlc/types" + "mods.irisnet.org/simapp" +) + +const ( + BNB_DENOM = "htltbnb" + DEPUTY_ADDR = "cosmos1kznrznww4pd6gx0zwrpthjk68fdmqypjpkj5hp" +) + +var ( + Deputy sdk.AccAddress + MinTimeLock uint64 = 50 + MaxTimeLock uint64 = 60 + ReceiverOnOtherChain = "ReceiverOnOtherChain" + SenderOnOtherChain = "SenderOnOtherChain" +) + +const DeputyArmor = `-----BEGIN TENDERMINT PRIVATE KEY----- +salt: C3586B75587D2824187D2CDA22B6AFB6 +type: secp256k1 +kdf: bcrypt + +1+15OrCKgjnwym1zO3cjo/SGe3PPqAYChQ5wMHjdUbTZM7mWsH3/ueL6swgjzI3b +DDzEQAPXBQflzNW6wbne9IfT651zCSm+j1MWaGk= +=wEHs +-----END TENDERMINT PRIVATE KEY-----` + +type TxTestSuite struct { + e2e.TestSuite +} + +func c(denom string, amount int64) sdk.Coin { + return sdk.NewInt64Coin(denom, amount) +} + +func cs(coins ...sdk.Coin) sdk.Coins { + return sdk.NewCoins(coins...) +} + +func ts(minOffset int) uint64 { + return uint64(time.Now().Add(time.Duration(minOffset) * time.Minute).Unix()) +} + +// SetupSuite creates a new network for integration tests +func (s *TxTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + depInjectOptions := simapp.DepinjectOptions{ + Config: e2e.AppConfig, + Providers: []interface{}{ + e2e.ProvideEVMKeeper(), + e2e.ProvideICS20Keeper(), + }, + } + + cfg,err := simapp.NewConfig(depInjectOptions) + s.Require().NoError(err) + + cfg.NumValidators = 4 + + Deputy, _ = sdk.AccAddressFromBech32(DEPUTY_ADDR) + cfg.GenesisState[htlctypes.ModuleName] = cfg.Codec.MustMarshalJSON(newHTLTGenesis(Deputy)) + s.Network = simapp.SetupNetworkWithConfig(s.T(), cfg) +} + +// TestTxCmd makes sure the cli command for this module works as expected +func (s *TxTestSuite) TestTxCmd() { + // --------------------------------------------------------------- + ctx := s.Network.Validators[0].ClientCtx + err := ctx.Keyring.ImportPrivKey("deputy", DeputyArmor, "1234567890") + s.Require().NoError(err) + + args := []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + _ = simapp.MsgSendExec( + s.T(), + s.Network, + ctx, + s.Network.Validators[0].Address, + Deputy, + cs(c(sdk.DefaultBondDenom, 50000000)), + args..., + ) + + // --------------------------------------------------------------- + + type htlcArgs struct { + sender sdk.AccAddress + receiver sdk.AccAddress + receiverOtherChain string + senderOtherChain string + amount sdk.Coins + secret tmbytes.HexBytes + timestamp uint64 + timeLock uint64 + transfer bool + direction htlctypes.SwapDirection + } + testCases := []struct { + name string + args htlcArgs + pass bool + }{{ + "valid htlc", + htlcArgs{ + sender: s.Network.Validators[0].Address, + receiver: s.Network.Validators[1].Address, + receiverOtherChain: ReceiverOnOtherChain, + senderOtherChain: SenderOnOtherChain, + amount: cs(c(sdk.DefaultBondDenom, 1000)), + secret: generateRandomSecret(), + timestamp: uint64(1580000000), + timeLock: uint64(50), + transfer: false, + direction: htlctypes.None, + }, + true, + }, { + "valid incoming htlt", + htlcArgs{ + sender: Deputy, + receiver: s.Network.Validators[0].Address, + receiverOtherChain: ReceiverOnOtherChain, + senderOtherChain: SenderOnOtherChain, + amount: cs(c(BNB_DENOM, 10000)), + secret: generateRandomSecret(), + timestamp: ts(0), + timeLock: MinTimeLock, + transfer: true, + direction: htlctypes.Incoming, + }, + true, + }, { + "valid outgoing htlt", + htlcArgs{ + sender: s.Network.Validators[0].Address, + receiver: Deputy, + receiverOtherChain: ReceiverOnOtherChain, + senderOtherChain: SenderOnOtherChain, + amount: cs(c(BNB_DENOM, 5000)), + secret: generateRandomSecret(), + timestamp: ts(0), + timeLock: MinTimeLock, + transfer: true, + direction: htlctypes.Outgoing, + }, + true, + }} + + // --------------------------------------------------------------- + // HTLC + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=%s", htlccli.FlagTo, testCases[0].args.receiver), + fmt.Sprintf("--%s=%s", htlccli.FlagAmount, testCases[0].args.amount), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagReceiverOnOtherChain, + testCases[0].args.receiverOtherChain, + ), + fmt.Sprintf("--%s=%s", htlccli.FlagSenderOnOtherChain, testCases[0].args.senderOtherChain), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagHashLock, + tmbytes.HexBytes(htlctypes.GetHashLock(testCases[0].args.secret, testCases[0].args.timestamp)). + String(), + ), + fmt.Sprintf("--%s=%d", htlccli.FlagTimeLock, testCases[0].args.timeLock), + fmt.Sprintf("--%s=%d", htlccli.FlagTimestamp, testCases[0].args.timestamp), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagTransfer, + strconv.FormatBool(testCases[0].args.transfer), + ), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult := CreateHTLCExec( + s.T(), + s.Network, + ctx, + testCases[0].args.sender.String(), + args..., + ) + + // --------------------------------------------------------------- + + expectedhtlc := htlctypes.HTLC{ + Id: htlctypes.GetID(testCases[0].args.sender, testCases[0].args.receiver, testCases[0].args.amount, htlctypes.GetHashLock(testCases[0].args.secret, testCases[0].args.timestamp)). + String(), + Sender: testCases[0].args.sender.String(), + To: testCases[0].args.receiver.String(), + ReceiverOnOtherChain: ReceiverOnOtherChain, + SenderOnOtherChain: SenderOnOtherChain, + Amount: testCases[0].args.amount, + Secret: "", + HashLock: tmbytes.HexBytes(htlctypes.GetHashLock(testCases[0].args.secret, testCases[0].args.timestamp)). + String(), + Timestamp: testCases[0].args.timestamp, + ExpirationHeight: uint64(txResult.Height) + testCases[0].args.timeLock, + State: htlctypes.Open, + ClosedBlock: 0, + Transfer: testCases[0].args.transfer, + Direction: testCases[0].args.direction, + } + respType := QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlc.Id, + ) + s.Require().Equal(expectedhtlc.String(), respType.String()) + + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = ClaimHTLCExec( + s.T(), + s.Network, + ctx, + testCases[0].args.sender.String(), + expectedhtlc.Id, + testCases[0].args.secret.String(), + args..., + ) + + respType = QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlc.Id, + ) + s.Require().Equal(htlctypes.Completed.String(), respType.State.String()) + + balance := simapp.QueryBalanceExec( + s.T(), + s.Network, + ctx, testCases[0].args.receiver.String(), + sdk.DefaultBondDenom, + ) + s.Require().Equal("400001000stake", balance.String()) + + // --------------------------------------------------------------- + // HTLT INCOMING + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=%s", htlccli.FlagTo, testCases[1].args.receiver), + fmt.Sprintf("--%s=%s", htlccli.FlagAmount, testCases[1].args.amount), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagReceiverOnOtherChain, + testCases[1].args.receiverOtherChain, + ), + fmt.Sprintf("--%s=%s", htlccli.FlagSenderOnOtherChain, testCases[1].args.senderOtherChain), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagHashLock, + tmbytes.HexBytes(htlctypes.GetHashLock(testCases[1].args.secret, testCases[1].args.timestamp)). + String(), + ), + fmt.Sprintf("--%s=%d", htlccli.FlagTimeLock, testCases[1].args.timeLock), + fmt.Sprintf("--%s=%d", htlccli.FlagTimestamp, testCases[1].args.timestamp), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagTransfer, + strconv.FormatBool(testCases[1].args.transfer), + ), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = CreateHTLCExec( + s.T(), + s.Network, + ctx, + testCases[1].args.sender.String(), + args..., + ) + + // --------------------------------------------------------------- + + expectedhtlt := htlctypes.HTLC{ + Id: htlctypes.GetID(testCases[1].args.sender, testCases[1].args.receiver, testCases[1].args.amount, htlctypes.GetHashLock(testCases[1].args.secret, testCases[1].args.timestamp)). + String(), + Sender: testCases[1].args.sender.String(), + To: testCases[1].args.receiver.String(), + ReceiverOnOtherChain: ReceiverOnOtherChain, + SenderOnOtherChain: SenderOnOtherChain, + Amount: testCases[1].args.amount, + Secret: "", + HashLock: tmbytes.HexBytes(htlctypes.GetHashLock(testCases[1].args.secret, testCases[1].args.timestamp)). + String(), + Timestamp: testCases[1].args.timestamp, + ExpirationHeight: uint64(txResult.Height) + testCases[1].args.timeLock, + State: htlctypes.Open, + ClosedBlock: 0, + Transfer: testCases[1].args.transfer, + Direction: testCases[1].args.direction, + } + respType = QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlt.Id, + ) + s.Require().Equal(expectedhtlt.String(), respType.String()) + + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = ClaimHTLCExec( + s.T(), + s.Network, + ctx, + testCases[1].args.sender.String(), + expectedhtlt.Id, + testCases[1].args.secret.String(), + args..., + ) + + respType = QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlc.Id, + ) + s.Require().Equal(htlctypes.Completed.String(), respType.State.String()) + + // --------------------------------------------------------------- + // HTLT OUTGOING + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=%s", htlccli.FlagTo, testCases[2].args.receiver), + fmt.Sprintf("--%s=%s", htlccli.FlagAmount, testCases[2].args.amount), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagReceiverOnOtherChain, + testCases[2].args.receiverOtherChain, + ), + fmt.Sprintf("--%s=%s", htlccli.FlagSenderOnOtherChain, testCases[2].args.senderOtherChain), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagHashLock, + tmbytes.HexBytes(htlctypes.GetHashLock(testCases[2].args.secret, testCases[2].args.timestamp)). + String(), + ), + fmt.Sprintf("--%s=%d", htlccli.FlagTimeLock, testCases[2].args.timeLock), + fmt.Sprintf("--%s=%d", htlccli.FlagTimestamp, testCases[2].args.timestamp), + fmt.Sprintf( + "--%s=%s", + htlccli.FlagTransfer, + strconv.FormatBool(testCases[2].args.transfer), + ), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = CreateHTLCExec( + s.T(), + s.Network, + ctx, + testCases[2].args.sender.String(), + args..., + ) + + // --------------------------------------------------------------- + + expectedhtlt = htlctypes.HTLC{ + Id: htlctypes.GetID(testCases[2].args.sender, testCases[2].args.receiver, testCases[2].args.amount, htlctypes.GetHashLock(testCases[2].args.secret, testCases[2].args.timestamp)). + String(), + Sender: testCases[2].args.sender.String(), + To: testCases[2].args.receiver.String(), + ReceiverOnOtherChain: ReceiverOnOtherChain, + SenderOnOtherChain: SenderOnOtherChain, + Amount: testCases[2].args.amount, + Secret: "", + HashLock: tmbytes.HexBytes(htlctypes.GetHashLock(testCases[2].args.secret, testCases[2].args.timestamp)). + String(), + Timestamp: testCases[2].args.timestamp, + ExpirationHeight: uint64(txResult.Height) + testCases[2].args.timeLock, + State: htlctypes.Open, + ClosedBlock: 0, + Transfer: testCases[2].args.transfer, + Direction: testCases[2].args.direction, + } + + respType = QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlc.Id, + ) + s.Require().Equal(htlctypes.Completed.String(), respType.State.String()) + + // --------------------------------------------------------------- + + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = ClaimHTLCExec( + s.T(), + s.Network, + ctx, + testCases[2].args.sender.String(), + expectedhtlt.Id, + testCases[2].args.secret.String(), + args..., + ) + + respType = QueryHTLCExec( + s.T(), + s.Network, + ctx, + expectedhtlc.Id, + ) + s.Require().Equal(htlctypes.Completed.String(), respType.State.String()) + + // --------------------------------------------------------------- +} + +func newHTLTGenesis(deputyAddress sdk.AccAddress) *htlctypes.GenesisState { + return &htlctypes.GenesisState{ + Params: htlctypes.Params{ + AssetParams: []htlctypes.AssetParam{ + { + Denom: "htltbnb", + SupplyLimit: htlctypes.SupplyLimit{ + Limit: sdk.NewInt(350000000000000), + TimeLimited: false, + TimeBasedLimit: sdk.ZeroInt(), + TimePeriod: time.Hour, + }, + Active: true, + DeputyAddress: deputyAddress.String(), + FixedFee: sdk.NewInt(1000), + MinSwapAmount: sdk.OneInt(), + MaxSwapAmount: sdk.NewInt(1000000000000), + MinBlockLock: MinTimeLock, + MaxBlockLock: MaxTimeLock, + }, + }, + }, + Htlcs: []htlctypes.HTLC{}, + Supplies: []htlctypes.AssetSupply{ + htlctypes.NewAssetSupply( + sdk.NewCoin("htltbnb", sdk.ZeroInt()), + sdk.NewCoin("htltbnb", sdk.ZeroInt()), + sdk.NewCoin("htltbnb", sdk.ZeroInt()), + sdk.NewCoin("htltbnb", sdk.ZeroInt()), + time.Duration(0), + ), + }, + PreviousBlockTime: htlctypes.DefaultPreviousBlockTime, + } +} + +func generateRandomSecret() tmbytes.HexBytes { + bytes := make([]byte, 32) + if _, err := rand.Read(bytes); err != nil { + panic(err.Error()) + } + return bytes +} diff --git a/e2e/mt/cli_test.go b/e2e/mt/cli_test.go new file mode 100644 index 00000000..a7c702c9 --- /dev/null +++ b/e2e/mt/cli_test.go @@ -0,0 +1,15 @@ +package mt + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestTxTestSuite(t *testing.T) { + suite.Run(t, new(TxTestSuite)) +} + +func TestQueryTestSuite(t *testing.T) { + suite.Run(t, new(QueryTestSuite)) +} \ No newline at end of file diff --git a/e2e/mt/query.go b/e2e/mt/query.go new file mode 100644 index 00000000..46d8f171 --- /dev/null +++ b/e2e/mt/query.go @@ -0,0 +1,145 @@ +package mt + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gogoproto/proto" + + "mods.irisnet.org/e2e" + mtcli "mods.irisnet.org/modules/mt/client/cli" + mttypes "mods.irisnet.org/modules/mt/types" +) + +// QueryTestSuite is a suite of end-to-end tests for the mt module +type QueryTestSuite struct { + e2e.TestSuite +} + +// TestQueryCmd tests all query command in the mt module +func (s *QueryTestSuite) TestQueryCmd() { + denomName := "name" + data := "data" + mintAmt := "10" + mintAmtUint := uint64(10) + + var ( + denomID string + mtID string + ) + + val := s.Validators[0] + from := val.Address + baseURL := val.APIAddress + + expectedCode := uint32(0) + clientCtx := val.ClientCtx + + // Issue + args := []string{ + fmt.Sprintf("--%s=%s", mtcli.FlagName, denomName), + fmt.Sprintf("--%s=%s", mtcli.FlagData, data), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + txResult := IssueDenomExec( + s.T(), + s.Network, + clientCtx, + from.String(), + args..., + ) + s.Require().Equal(expectedCode, txResult.Code) + denomID = s.GetAttribute( + mttypes.EventTypeIssueDenom, + mttypes.AttributeKeyDenomID, + txResult.Events, + ) + + // Mint + args = []string{ + fmt.Sprintf("--%s=%s", mtcli.FlagRecipient, from.String()), + fmt.Sprintf("--%s=%s", mtcli.FlagAmount, mintAmt), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(100))).String(), + ), + } + + txResult = MintMTExec(s.T(), + s.Network, + clientCtx, from.String(), denomID, args...) + s.Require().Equal(expectedCode, txResult.Code) + + mtID = s.GetAttribute( + mttypes.EventTypeMintMT, + mttypes.AttributeKeyMTID, + txResult.Events, + ) + + // Denom + respType := proto.Message(&mttypes.QueryDenomResponse{}) + url := fmt.Sprintf("%s/irismod/mt/denoms/%s", baseURL, denomID) + resp, err := testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + + denomItem := respType.(*mttypes.QueryDenomResponse) + s.Require().Equal(denomID, denomItem.Denom.Id) + s.Require().Equal([]byte(data), denomItem.Denom.Data) + s.Require().Equal(val.Address.String(), denomItem.Denom.Owner) + + // Denoms + respType = proto.Message(&mttypes.QueryDenomsResponse{}) + url = fmt.Sprintf("%s/irismod/mt/denoms", baseURL) + resp, err = testutil.GetRequest(url) + + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + + denomsItem := respType.(*mttypes.QueryDenomsResponse) + s.Require().Equal(1, len(denomsItem.Denoms)) + s.Require().Equal(denomID, denomsItem.Denoms[0].Id) + + // MTSupply + respType = proto.Message(&mttypes.QueryMTSupplyResponse{}) + url = fmt.Sprintf("%s/irismod/mt/mts/%s/%s/supply", baseURL, denomID, mtID) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + + mtSupplyItem := respType.(*mttypes.QueryMTSupplyResponse) + s.Require().Equal(mintAmtUint, mtSupplyItem.Amount) + + // MT + respType = proto.Message(&mttypes.QueryMTResponse{}) + url = fmt.Sprintf("%s/irismod/mt/mts/%s/%s", baseURL, denomID, mtID) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + + mtItem := respType.(*mttypes.QueryMTResponse) + s.Require().Equal(mtID, mtItem.Mt.Id) + + // MTs + respType = proto.Message(&mttypes.QueryMTsResponse{}) + url = fmt.Sprintf("%s/irismod/mt/mts/%s", baseURL, denomID) + resp, err = testutil.GetRequest(url) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + + mtsItem := respType.(*mttypes.QueryMTsResponse) + s.Require().Equal(1, len(mtsItem.Mts)) +} diff --git a/e2e/mt/test_helper.go b/e2e/mt/test_helper.go new file mode 100644 index 00000000..8092c924 --- /dev/null +++ b/e2e/mt/test_helper.go @@ -0,0 +1,341 @@ +package mt + +import ( + "fmt" + "testing" + + "github.com/cometbft/cometbft/libs/cli" + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + mtcli "mods.irisnet.org/modules/mt/client/cli" + mttypes "mods.irisnet.org/modules/mt/types" + "mods.irisnet.org/simapp" +) + +// IssueDenomExec executes the IssueDenom command with the specified parameters. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account issuing the denom. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func IssueDenomExec( + t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdIssueDenom(), args) +} + + +// BurnMTExec executes a burn token transaction. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account initiating the burn transaction. +// - denomID: The unique identifier of the denomination to burn. +// - mtID: The unique identifier of the multi-token to burn. +// - amount: The amount of tokens to burn. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func BurnMTExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + denomID string, + mtID string, + amount string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + denomID, + mtID, + amount, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdBurnMT(), args) +} + +// MintMTExec executes a mint token transaction. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account initiating the mint transaction. +// - denomID: The unique identifier of the denomination to mint. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func MintMTExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + denomID string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + denomID, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdMintMT(), args) +} + +// EditMTExec executes an edit MT transaction. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account initiating the edit transaction. +// - denomID: The unique identifier of the denomination to edit. +// - mtID: The unique identifier of the MT to edit. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func EditMTExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + denomID string, + mtID string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + denomID, + mtID, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdEditMT(), args) +} + +// TransferMTExec executes a transfer MT transaction. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account initiating the transfer transaction. +// - recipient: The address of the account receiving the transferred tokens. +// - denomID: The unique identifier of the denomination. +// - mtID: The unique identifier of the MT being transferred. +// - amount: The amount of tokens to transfer. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func TransferMTExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + recipient string, + denomID string, + mtID string, + amount string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + from, + recipient, + denomID, + mtID, + amount, + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdTransferMT(), args) +} + +// QueryDenomExec executes a query command to retrieve a specific denom from the network. +// +// Parameters: +// - t: The testing.T object for testing. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object for the client. +// - denomID: The ID of the denom to query. +// - extraArgs: Additional arguments to be passed to the command. +// +// Returns: +// - *mttypes.Denom: The response object containing the queried denom. +func QueryDenomExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + denomID string, + extraArgs ...string) *mttypes.Denom { + args := []string{ + denomID, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &mttypes.Denom{} + network.ExecQueryCmd(t, clientCtx, mtcli.GetCmdQueryDenom(), args, response) + return response +} + +// QueryDenomsExec executes a query command to retrieve all denoms from the network. +// +// Parameters: +// - t: The testing.T object for testing. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object for the client. +// - extraArgs: Additional arguments to be passed to the command. +// +// Returns: +// - *mttypes.QueryDenomsResponse: The response object containing the queried denoms. +func QueryDenomsExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + extraArgs ...string) *mttypes.QueryDenomsResponse { + args := []string{ + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &mttypes.QueryDenomsResponse{} + network.ExecQueryCmd(t, clientCtx, mtcli.GetCmdQueryDenoms(), args, response) + return response +} + +// QueryMTsExec executes a query command to retrieve all MTs from the network. +// +// Parameters: +// - t: The testing.T object for testing. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object for the client. +// - denomID: The ID of the denom to query. +// - resp: The response object to store the queried MTs. +// - extraArgs: Additional arguments to be passed to the command. +// +// Returns: None. +func QueryMTsExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + denomID string, + resp proto.Message, + extraArgs ...string, +) { + args := []string{ + denomID, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + network.ExecQueryCmd(t, clientCtx, mtcli.GetCmdQueryMTs(), args, resp) +} + +// QueryMTExec executes a query command to retrieve a specific MT from the network. +// +// Parameters: +// - t: The testing.T object for testing. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object for the client. +// - denomID: The ID of the denom containing the MT. +// - mtID: The ID of the MT to query. +// - extraArgs: Additional arguments to be passed to the command. +// +// Returns: +// - *mttypes.MT: The response object containing the queried MT. +func QueryMTExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + denomID string, + mtID string, + extraArgs ...string) *mttypes.MT { + args := []string{ + denomID, + mtID, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + response := &mttypes.MT{} + network.ExecQueryCmd(t, clientCtx, mtcli.GetCmdQueryMT(), args, response) + return response +} + +// QueryBlancesExec executes a query command to retrieve the balances of a specific account for a given denomination. +// +// Parameters: +// - t: The testing.T object for testing. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object for the client. +// - from: The address of the account to query balances for. +// - denomID: The ID of the denomination to query balances for. +// - extraArgs: Additional arguments to be passed to the command. +// +// Returns: +// - *mttypes.QueryBalancesResponse: The response object containing the queried balances. +func QueryBlancesExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + denomID string, + extraArgs ...string) *mttypes.QueryBalancesResponse { + args := []string{ + from, + denomID, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &mttypes.QueryBalancesResponse{} + network.ExecQueryCmd(t, clientCtx, mtcli.GetCmdQueryBalances(), args, response) + return response +} + +// TransferDenomExec executes a transfer denomination transaction. +// +// Parameters: +// - t: The testing.T object for logging and reporting. +// - network: The simapp.Network object representing the network. +// - clientCtx: The client.Context object representing the client context. +// - from: The address of the account initiating the transfer transaction. +// - recipient: The address of the account receiving the transferred tokens. +// - denomID: The unique identifier of the denomination. +// - extraArgs: Additional command line arguments. +// +// Returns: +// - *simapp.ResponseTx: The response transaction object. +func TransferDenomExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + recipient string, + denomID string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + from, + recipient, + denomID, + } + + args = append(args, extraArgs...) + return network.ExecTxCmdWithResult(t, clientCtx, mtcli.GetCmdTransferDenom(), args) +} diff --git a/e2e/mt/tx.go b/e2e/mt/tx.go new file mode 100644 index 00000000..49a96ef4 --- /dev/null +++ b/e2e/mt/tx.go @@ -0,0 +1,197 @@ +package mt + +import ( + "fmt" + + "github.com/cometbft/cometbft/crypto" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + mtcli "mods.irisnet.org/modules/mt/client/cli" + mttypes "mods.irisnet.org/modules/mt/types" +) + +// TxTestSuite is a suite of end-to-end tests for the mt module +type TxTestSuite struct { + e2e.TestSuite +} + +// TestMT tests all tx command in the mt module +func (s *TxTestSuite) TestMT() { + val := s.Validators[0] + val2 := s.Validators[1] + clientCtx := val.ClientCtx + + // --------------------------------------------------------------------------- + denomName := "name" + data := "data" + from := val.Address + mintAmt := "10" + transferAmt := "5" + burnAmt := "5" + + expectedCode := uint32(0) + + //------test GetCmdIssueDenom()------------- + args := []string{ + fmt.Sprintf("--%s=%s", mtcli.FlagName, denomName), + fmt.Sprintf("--%s=%s", mtcli.FlagData, data), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult := IssueDenomExec( + s.T(), + s.Network, + clientCtx, + from.String(), + args..., + ) + denomID := s.GetAttribute( + mttypes.EventTypeIssueDenom, + mttypes.AttributeKeyDenomID, + txResult.Events, + ) + + //------test GetCmdQueryDenom()------------- + queryDenomRespType := QueryDenomExec(s.T(), s.Network, clientCtx, denomID) + s.Require().Equal(denomName, queryDenomRespType.Name) + s.Require().Equal([]byte(data), queryDenomRespType.Data) + + //------test GetCmdQueryDenoms()------------- + queryDenomsRespType := QueryDenomsExec(s.T(), s.Network, clientCtx) + s.Require().Equal(1, len(queryDenomsRespType.Denoms)) + s.Require().Equal(denomID, queryDenomsRespType.Denoms[0].Id) + + //------test GetCmdMintMT()------------- + args = []string{ + fmt.Sprintf("--%s=%s", mtcli.FlagRecipient, from.String()), + fmt.Sprintf("--%s=%s", mtcli.FlagAmount, mintAmt), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(100))).String(), + ), + } + + txResult = MintMTExec(s.T(), + s.Network, + clientCtx, from.String(), denomID, args...) + s.Require().Equal(expectedCode, txResult.Code) + + mtID := s.GetAttribute( + mttypes.EventTypeMintMT, + mttypes.AttributeKeyMTID, + txResult.Events, + ) + //------test GetCmdQueryMT()------------- + queryMTResponse := QueryMTExec(s.T(), s.Network, clientCtx, denomID, mtID) + s.Require().Equal(mtID, queryMTResponse.Id) + + //-------test GetCmdQueryBalances()---------- + queryBalancesResponse := QueryBlancesExec( + s.T(), + s.Network, + clientCtx, + from.String(), + denomID, + ) + s.Require().Equal(1, len(queryBalancesResponse.Balance)) + s.Require().Equal(uint64(10), queryBalancesResponse.Balance[0].Amount) + + //------test GetCmdEditMT()------------- + newTokenDate := "newdata" + args = []string{ + fmt.Sprintf("--%s=%s", mtcli.FlagData, newTokenDate), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = EditMTExec(s.T(), + s.Network, + clientCtx, from.String(), denomID, mtID, args...) + s.Require().Equal(expectedCode, txResult.Code) + + queryMTResponse = QueryMTExec(s.T(), s.Network, clientCtx, denomID, mtID) + s.Require().Equal([]byte(newTokenDate), queryMTResponse.Data) + + //------test GetCmdTransferMT()------------- + recipient := sdk.AccAddress(crypto.AddressHash([]byte("dgsbl"))) + + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = TransferMTExec(s.T(), + s.Network, + clientCtx, from.String(), recipient.String(), denomID, mtID, transferAmt, args...) + s.Require().Equal(expectedCode, txResult.Code) + + queryMTResponse = QueryMTExec(s.T(), s.Network, clientCtx, denomID, mtID) + s.Require().Equal(mtID, queryMTResponse.Id) + s.Require().Equal([]byte(newTokenDate), queryMTResponse.Data) + + //------test GetCmdBurnMT()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = BurnMTExec(s.T(), + s.Network, + clientCtx, from.String(), denomID, mtID, burnAmt, args...) + s.Require().Equal(expectedCode, txResult.Code) + + queryMTResponse = QueryMTExec(s.T(), s.Network, clientCtx, denomID, mtID) + s.Require().Equal(mtID, queryMTResponse.Id) + s.Require().Equal([]byte(newTokenDate), queryMTResponse.Data) + s.Require().Equal(uint64(5), queryMTResponse.Supply) + + //------test GetCmdTransferDenom()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = TransferDenomExec(s.T(), + s.Network, + clientCtx, from.String(), val2.Address.String(), denomID, args...) + s.Require().Equal(expectedCode, txResult.Code) + + queryDenomResponse := QueryDenomExec(s.T(), s.Network, clientCtx, denomID) + s.Require().Equal(val2.Address.String(), queryDenomResponse.Owner) + s.Require().Equal(denomName, queryDenomResponse.Name) +} diff --git a/e2e/nft/query.go b/e2e/nft/query.go index e427ae17..1f1081ff 100644 --- a/e2e/nft/query.go +++ b/e2e/nft/query.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/testutil" @@ -13,41 +12,18 @@ import ( "mods.irisnet.org/e2e" nftcli "mods.irisnet.org/modules/nft/client/cli" nfttypes "mods.irisnet.org/modules/nft/types" - "mods.irisnet.org/simapp" ) // QueryTestSuite is a suite of end-to-end tests for the nft module type QueryTestSuite struct { - suite.Suite - - network simapp.Network -} - -// SetupSuite creates a new network for integration tests -func (s *QueryTestSuite) SetupSuite() { - depInjectOptions := simapp.DepinjectOptions{ - Config: e2e.AppConfig, - Providers: []interface{}{ - e2e.ProvideEVMKeeper(), - e2e.ProvideICS20Keeper(), - }, - } - - s.T().Log("setting up integration test suite") - s.network = simapp.SetupNetwork(s.T(),depInjectOptions) -} - -// TearDownSuite tears down the integration test suite -func (s *QueryTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() + e2e.TestSuite } // TestQueryCmd tests all query command in the nft module func (s *QueryTestSuite) TestQueryCmd() { // s.SetupSuite() - val := s.network.Validators[0] + val := s.Network.Validators[0] clientCtx := val.ClientCtx // --------------------------------------------------------------------------- @@ -84,14 +60,14 @@ func (s *QueryTestSuite) TestQueryCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } expectedCode := uint32(0) txResult := IssueDenomExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, args...) s.Require().Equal(expectedCode, txResult.Code) @@ -135,12 +111,12 @@ func (s *QueryTestSuite) TestQueryCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = MintNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, tokenID, args...) s.Require().Equal(expectedCode, txResult.Code) diff --git a/e2e/nft/tx.go b/e2e/nft/tx.go index 88ae69a3..7d97081d 100644 --- a/e2e/nft/tx.go +++ b/e2e/nft/tx.go @@ -6,45 +6,20 @@ import ( "github.com/cometbft/cometbft/crypto" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" "mods.irisnet.org/e2e" nftcli "mods.irisnet.org/modules/nft/client/cli" - "mods.irisnet.org/simapp" ) // TxTestSuite is a suite of end-to-end tests for the nft module type TxTestSuite struct { - suite.Suite - - network simapp.Network -} - -// SetupSuite creates a new network for integration tests -func (s *TxTestSuite) SetupSuite() { - depInjectOptions := simapp.DepinjectOptions{ - Config: e2e.AppConfig, - Providers: []interface{}{ - e2e.ProvideEVMKeeper(), - e2e.ProvideICS20Keeper(), - }, - } - - s.T().Log("setting up e2e test suite") - s.network = simapp.SetupNetwork(s.T(),depInjectOptions) -} - -// TearDownSuite tears down the integration test suite -func (s *TxTestSuite) TearDownSuite() { - s.T().Log("tearing down e2e nft test suite") - s.network.Cleanup() + e2e.TestSuite } - // TestTxCmd tests all tx command in the nft module func (s *TxTestSuite) TestTxCmd() { - val := s.network.Validators[0] - val2 := s.network.Validators[1] + val := s.Network.Validators[0] + val2 := s.Network.Validators[1] clientCtx := val.ClientCtx expectedCode := uint32(0) @@ -82,17 +57,17 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult := IssueDenomExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, args...) s.Require().Equal(expectedCode, txResult.Code) //------test GetCmdQueryDenom()------------- - queryDenomResponse := QueryDenomExec(s.T(), s.network, clientCtx, denomID) + queryDenomResponse := QueryDenomExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(denomName, queryDenomResponse.Name) s.Require().Equal(schema, queryDenomResponse.Schema) s.Require().Equal(symbol, queryDenomResponse.Symbol) @@ -104,7 +79,7 @@ func (s *TxTestSuite) TestTxCmd() { s.Require().Equal(updateRestricted, queryDenomResponse.UpdateRestricted) //------test GetCmdQueryDenoms()------------- - queryDenomsResponse := QueryDenomsExec(s.T(), s.network, clientCtx) + queryDenomsResponse := QueryDenomsExec(s.T(), s.Network, clientCtx) s.Require().Equal(1, len(queryDenomsResponse.Denoms)) s.Require().Equal(denomID, queryDenomsResponse.Denoms[0].Id) @@ -121,21 +96,21 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = MintNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, tokenID, args...) s.Require().Equal(expectedCode, txResult.Code) //------test GetCmdQuerySupply()------------- - querySupplyResponse := QuerySupplyExec(s.T(), s.network, clientCtx, denomID) + querySupplyResponse := QuerySupplyExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(uint64(1), querySupplyResponse.Amount) //------test GetCmdQueryNFT()------------- - queryNFTResponse := QueryNFTExec(s.T(), s.network, clientCtx, denomID, tokenID) + queryNFTResponse := QueryNFTExec(s.T(), s.Network, clientCtx, denomID, tokenID) s.Require().Equal(tokenID, queryNFTResponse.Id) s.Require().Equal(tokenName, queryNFTResponse.Name) s.Require().Equal(uri, queryNFTResponse.URI) @@ -146,7 +121,7 @@ func (s *TxTestSuite) TestTxCmd() { //------test GetCmdQueryOwner()------------- queryNFTsOfOwnerResponse := QueryOwnerExec( s.T(), - s.network, + s.Network, clientCtx, from.String(), ) @@ -155,7 +130,7 @@ func (s *TxTestSuite) TestTxCmd() { s.Require().Equal(tokenID, queryNFTsOfOwnerResponse.Owner.IDCollections[0].TokenIds[0]) //------test GetCmdQueryCollection()------------- - queryCollectionResponse := QueryCollectionExec(s.T(), s.network, clientCtx, denomID) + queryCollectionResponse := QueryCollectionExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(1, len(queryCollectionResponse.Collection.NFTs)) //------test GetCmdEditNFT()------------- @@ -174,16 +149,16 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = EditNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, tokenID, args...) s.Require().Equal(expectedCode, txResult.Code) - queryNFTResponse = QueryNFTExec(s.T(), s.network, clientCtx, denomID, tokenID) + queryNFTResponse = QueryNFTExec(s.T(), s.Network, clientCtx, denomID, tokenID) s.Require().Equal(newTokenName, queryNFTResponse.Name) s.Require().Equal(newTokenURI, queryNFTResponse.URI) s.Require().Equal(newTokenURIHash, queryNFTResponse.UriHash) @@ -203,16 +178,16 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = TransferNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), recipient.String(), denomID, tokenID, args...) s.Require().Equal(expectedCode, txResult.Code) - queryNFTResponse = QueryNFTExec(s.T(), s.network, clientCtx, denomID, tokenID) + queryNFTResponse = QueryNFTExec(s.T(), s.Network, clientCtx, denomID, tokenID) s.Require().Equal(tokenID, queryNFTResponse.Id) s.Require().Equal(tokenName, queryNFTResponse.Name) s.Require().Equal(uri, queryNFTResponse.URI) @@ -233,16 +208,16 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = MintNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, newTokenID, args...) s.Require().Equal(expectedCode, txResult.Code) - querySupplyResponse = QuerySupplyExec(s.T(), s.network, clientCtx, denomID) + querySupplyResponse = QuerySupplyExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(uint64(2), querySupplyResponse.Amount) args = []string{ @@ -251,15 +226,15 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = BurnNFTExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), denomID, newTokenID, args...) s.Require().Equal(expectedCode, txResult.Code) - querySupplyResponse = QuerySupplyExec(s.T(), s.network, clientCtx, denomID) + querySupplyResponse = QuerySupplyExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(uint64(1), querySupplyResponse.Amount) //------test GetCmdTransferDenom()------------- @@ -269,16 +244,16 @@ func (s *TxTestSuite) TestTxCmd() { fmt.Sprintf( "--%s=%s", flags.FlagFees, - sdk.NewCoins(sdk.NewCoin(s.network.BondDenom, sdk.NewInt(10))).String(), + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), ), } txResult = TransferDenomExec(s.T(), - s.network, + s.Network, clientCtx, from.String(), val2.Address.String(), denomID, args...) s.Require().Equal(expectedCode, txResult.Code) - queryDenomResponse = QueryDenomExec(s.T(), s.network, clientCtx, denomID) + queryDenomResponse = QueryDenomExec(s.T(), s.Network, clientCtx, denomID) s.Require().Equal(val2.Address.String(), queryDenomResponse.Creator) s.Require().Equal(denomName, queryDenomResponse.Name) s.Require().Equal(schema, queryDenomResponse.Schema) diff --git a/e2e/service/cli_test.go b/e2e/service/cli_test.go new file mode 100644 index 00000000..a8de824d --- /dev/null +++ b/e2e/service/cli_test.go @@ -0,0 +1,15 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestTxTestSuite(t *testing.T) { + suite.Run(t, new(TxTestSuite)) +} + +func TestQueryTestSuite(t *testing.T) { + suite.Run(t, new(QueryTestSuite)) +} \ No newline at end of file diff --git a/e2e/service/query.go b/e2e/service/query.go new file mode 100644 index 00000000..ba448f78 --- /dev/null +++ b/e2e/service/query.go @@ -0,0 +1,385 @@ +package service + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + servicecli "mods.irisnet.org/modules/service/client/cli" + "mods.irisnet.org/modules/service/types" + servicetypes "mods.irisnet.org/modules/service/types" + "mods.irisnet.org/simapp" +) + +// QueryTestSuite is a suite of end-to-end tests for the service module +type QueryTestSuite struct { + e2e.TestSuite +} + +// SetupSuite sets up test suite +func (s *QueryTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + depInjectOptions := simapp.DepinjectOptions{ + Config: e2e.AppConfig, + Providers: []interface{}{ + e2e.ProvideEVMKeeper(), + e2e.ProvideICS20Keeper(), + }, + } + + cfg,err := simapp.NewConfig(depInjectOptions) + s.Require().NoError(err) + + cfg.NumValidators = 1 + + var serviceGenesisState servicetypes.GenesisState + cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[servicetypes.ModuleName], &serviceGenesisState) + + serviceGenesisState.Params.ArbitrationTimeLimit = time.Duration(time.Second) + serviceGenesisState.Params.ComplaintRetrospect = time.Duration(time.Second) + cfg.GenesisState[servicetypes.ModuleName] = cfg.Codec.MustMarshalJSON(&serviceGenesisState) + + s.Network = simapp.SetupNetworkWithConfig(s.T(), cfg) +} + +// TestQueryCmd tests all query command in the service module +func (s *QueryTestSuite) TestQueryCmd() { + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + expectedCode := uint32(0) + // --------------------------------------------------------------------------- + + serviceName := "test-service" + serviceDesc := "test-description" + serviceAuthorDesc := "test-author-description" + serviceTags := "tags1,tags2" + serviceSchemas := `{"input":{"type":"object"},"output":{"type":"object"},"error":{"type":"object"}}` + serviceDenom := sdk.DefaultBondDenom + baseURL := val.APIAddress + + serviceDeposit := fmt.Sprintf("50000%s", serviceDenom) + servicePrices := fmt.Sprintf(`{"price": "50%s"}`, serviceDenom) + qos := uint64(3) + options := "{}" + + author := val.Address + provider := author + + consumerInfo, _, _ := val.ClientCtx.Keyring.NewMnemonic( + "NewValidator", + keyring.English, + sdk.FullFundraiserPath, + keyring.DefaultBIP39Passphrase, + hd.Secp256k1, + ) + + consumer, err := consumerInfo.GetAddress() + s.Require().NoError(err) + + reqServiceFee := fmt.Sprintf("50%s", serviceDenom) + reqInput := `{"header":{},"body":{}}` + respResult := `{"code":200,"message":""}` + respOutput := `{"header":{},"body":{}}` + timeout := qos + + expectedEarnedFees := fmt.Sprintf("48%s", serviceDenom) + + //------test GetCmdDefineService()------------- + args := []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagDescription, serviceDesc), + fmt.Sprintf("--%s=%s", servicecli.FlagTags, serviceTags), + fmt.Sprintf("--%s=%s", servicecli.FlagAuthorDescription, serviceAuthorDesc), + fmt.Sprintf("--%s=%s", servicecli.FlagSchemas, serviceSchemas), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult := DefineServiceExec( + s.T(), + s.Network, + clientCtx, + author.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryServiceDefinition()------------- + url := fmt.Sprintf("%s/irismod/service/definitions/%s", baseURL, serviceName) + resp, err := testutil.GetRequest(url) + respType := proto.Message(&servicetypes.QueryDefinitionResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceDefinitionResp := respType.(*servicetypes.QueryDefinitionResponse) + s.Require().Equal(serviceName, serviceDefinitionResp.ServiceDefinition.Name) + + //------test GetCmdBindService()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagServiceName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagDeposit, serviceDeposit), + fmt.Sprintf("--%s=%s", servicecli.FlagPricing, servicePrices), + fmt.Sprintf("--%s=%d", servicecli.FlagQoS, qos), + fmt.Sprintf("--%s=%s", servicecli.FlagOptions, options), + fmt.Sprintf("--%s=%s", servicecli.FlagProvider, provider), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = BindServiceExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryServiceBinding()------------- + url = fmt.Sprintf("%s/irismod/service/bindings/%s/%s", baseURL, serviceName, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryBindingResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceBindingResp := respType.(*servicetypes.QueryBindingResponse) + s.Require().Equal(serviceName, serviceBindingResp.ServiceBinding.ServiceName) + s.Require().Equal(provider.String(), serviceBindingResp.ServiceBinding.Provider) + + //------test GetCmdQueryServiceBindings()------------- + url = fmt.Sprintf("%s/irismod/service/bindings/%s", baseURL, serviceName) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryBindingsResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceBindings := respType.(*servicetypes.QueryBindingsResponse) + s.Require().Len(serviceBindings.ServiceBindings, 1) + + //------test GetCmdDisableServiceBinding()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = DisableServiceExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + url = fmt.Sprintf("%s/irismod/service/bindings/%s/%s", baseURL, serviceName, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryBindingResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceBindingResp = respType.(*servicetypes.QueryBindingResponse) + s.Require().False(serviceBindingResp.ServiceBinding.Available) + + //------test GetCmdRefundServiceDeposit()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = RefundDepositExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + url = fmt.Sprintf("%s/irismod/service/bindings/%s/%s", baseURL, serviceName, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryBindingResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceBindingResp = respType.(*servicetypes.QueryBindingResponse) + s.Require().True(serviceBindingResp.ServiceBinding.Deposit.IsZero()) + + //------test GetCmdEnableServiceBinding()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagDeposit, serviceDeposit), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = EnableServiceExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + url = fmt.Sprintf("%s/irismod/service/bindings/%s/%s", baseURL, serviceName, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryBindingResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + serviceBindingResp = respType.(*servicetypes.QueryBindingResponse) + s.Require().Equal(serviceDeposit, serviceBindingResp.ServiceBinding.Deposit.String()) + + //------send token to consumer------------------------ + amount := sdk.NewCoins( + sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50000000)), + ) + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = simapp.MsgSendExec(s.T(), s.Network, clientCtx, provider, consumer, amount, args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdCallService()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagServiceName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagProviders, provider), + fmt.Sprintf("--%s=%s", servicecli.FlagServiceFeeCap, reqServiceFee), + fmt.Sprintf("--%s=%s", servicecli.FlagData, reqInput), + fmt.Sprintf("--%s=%d", servicecli.FlagTimeout, timeout), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = CallServiceExec( + s.T(), + s.Network, + clientCtx, + consumer.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + requestContextId := s.Network.GetAttribute( + servicetypes.EventTypeCreateContext, + servicetypes.AttributeKeyRequestContextID, + txResult.Events, + ) + requestHeight := txResult.Height + + blockResult, err := val.RPCClient.BlockResults(context.Background(), &requestHeight) + s.Require().NoError(err) + var compactRequest servicetypes.CompactRequest + for _, event := range blockResult.EndBlockEvents { + if event.Type == servicetypes.EventTypeNewBatchRequest { + var found bool + var requests []servicetypes.CompactRequest + var requestsBz []byte + for _, attribute := range event.Attributes { + if string(attribute.Key) == types.AttributeKeyRequests { + requestsBz = []byte(attribute.Value) + } + if string(attribute.Key) == types.AttributeKeyRequestContextID && + string(attribute.GetValue()) == requestContextId { + found = true + } + } + s.Require().True(found) + if found { + err := json.Unmarshal(requestsBz, &requests) + s.Require().NoError(err) + } + s.Require().Len(requests, 1) + compactRequest = requests[0] + } + } + s.Require().Equal(requestContextId, compactRequest.RequestContextId) + + //------test GetCmdQueryServiceRequests()------------- + url = fmt.Sprintf("%s/irismod/service/requests/%s/%s", baseURL, serviceName, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryRequestsResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + requests := respType.(*servicetypes.QueryRequestsResponse).Requests + s.Require().Len(requests, 1) + s.Require().Equal(requestContextId, requests[0].RequestContextId) + + //------test GetCmdRespondService()------------- + request := requests[0] + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagRequestID, request.Id), + fmt.Sprintf("--%s=%s", servicecli.FlagResult, respResult), + fmt.Sprintf("--%s=%s", servicecli.FlagData, respOutput), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = RespondServiceExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryEarnedFees()------------- + url = fmt.Sprintf("%s/irismod/service/fees/%s", baseURL, provider.String()) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&servicetypes.QueryEarnedFeesResponse{}) + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, respType)) + earnedFees := respType.(*servicetypes.QueryEarnedFeesResponse).Fees + s.Require().Equal(expectedEarnedFees, earnedFees.String()) +} diff --git a/e2e/service/test_helper.go b/e2e/service/test_helper.go new file mode 100644 index 00000000..305a9482 --- /dev/null +++ b/e2e/service/test_helper.go @@ -0,0 +1,328 @@ +package service + +import ( + "fmt" + "testing" + + "github.com/cometbft/cometbft/libs/cli" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + servicecli "mods.irisnet.org/modules/service/client/cli" + servicetypes "mods.irisnet.org/modules/service/types" + "mods.irisnet.org/simapp" +) + +func DefineServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdDefineService(), args) +} + +func BindServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdBindService(), args) +} + +func UpdateBindingExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdUpdateServiceBinding(), args) +} + +func RefundDepositExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName, + provider, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + serviceName, + provider, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdRefundServiceDeposit(), args) +} + +func DisableServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName, + provider, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + serviceName, + provider, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdDisableServiceBinding(), args) +} + +func EnableServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName, + provider, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + serviceName, + provider, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdEnableServiceBinding(), args) +} + +func CallServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdCallService(), args) +} + +func RespondServiceExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdRespondService(), args) +} + +func SetWithdrawAddrExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + withdrawalAddress, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + withdrawalAddress, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdSetWithdrawAddr(), args) +} + +func WithdrawEarnedFeesExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + provider, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + provider, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, servicecli.GetCmdWithdrawEarnedFees(), args) +} + +func QueryServiceDefinitionExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName string, + extraArgs ...string, +) *servicetypes.ServiceDefinition { + args := []string{ + serviceName, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.ServiceDefinition{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceDefinition(), args, response) + return response +} + +func QueryServiceBindingExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName, + provider string, + extraArgs ...string, +) *servicetypes.ServiceBinding { + args := []string{ + serviceName, + provider, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.ServiceBinding{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceBinding(), args, response) + return response +} + +func QueryServiceBindingsExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName string, + extraArgs ...string, +) *servicetypes.QueryBindingsResponse { + args := []string{ + serviceName, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.QueryBindingsResponse{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceBindings(), args, response) + return response +} + +func QueryServiceRequestsExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + serviceName, + provider string, + extraArgs ...string) *servicetypes.QueryRequestsResponse { + args := []string{ + serviceName, + provider, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.QueryRequestsResponse{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceRequests(), args, response) + return response +} + +func QueryServiceRequestsByReqCtx(t *testing.T, + network simapp.Network, + clientCtx client.Context, + requestContextID, + batchCounter string, + extraArgs ...string, +) *servicetypes.QueryRequestsResponse { + args := []string{ + requestContextID, + batchCounter, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.QueryRequestsResponse{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceRequests(), args, response) + return response + +} + +func QueryEarnedFeesExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + extraArgs ...string, +) *servicetypes.QueryEarnedFeesResponse { + args := []string{ + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.QueryEarnedFeesResponse{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryEarnedFees(), args, response) + return response +} + +func QueryRequestContextExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + contextId string, + extraArgs ...string, +) *servicetypes.RequestContext { + args := []string{ + contextId, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.RequestContext{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryRequestContext(), args, response) + return response +} + +func QueryServiceRequestExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + requestId string, + extraArgs ...string, +) *servicetypes.Request { + args := []string{ + requestId, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.Request{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceRequest(), args, response) + return response +} + +func QueryServiceResponseExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + requestId string, + extraArgs ...string, +) *servicetypes.Response { + args := []string{ + requestId, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &servicetypes.Response{} + network.ExecQueryCmd(t, clientCtx, servicecli.GetCmdQueryServiceResponse(), args, response) + return response +} diff --git a/e2e/service/tx.go b/e2e/service/tx.go new file mode 100644 index 00000000..ba9670cc --- /dev/null +++ b/e2e/service/tx.go @@ -0,0 +1,475 @@ +package service + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/cometbft/cometbft/crypto" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "mods.irisnet.org/e2e" + servicecli "mods.irisnet.org/modules/service/client/cli" + "mods.irisnet.org/modules/service/types" + servicetypes "mods.irisnet.org/modules/service/types" + "mods.irisnet.org/simapp" +) + +// TxTestSuite is a suite of end-to-end tests for the service module +type TxTestSuite struct { + e2e.TestSuite +} + +// SetupSuite sets up test suite +func (s *TxTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + depInjectOptions := simapp.DepinjectOptions{ + Config: e2e.AppConfig, + Providers: []interface{}{ + e2e.ProvideEVMKeeper(), + e2e.ProvideICS20Keeper(), + }, + } + + cfg,err := simapp.NewConfig(depInjectOptions) + s.Require().NoError(err) + + cfg.NumValidators = 1 + + var serviceGenesisState servicetypes.GenesisState + cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[servicetypes.ModuleName], &serviceGenesisState) + + serviceGenesisState.Params.ArbitrationTimeLimit = time.Duration(time.Second) + serviceGenesisState.Params.ComplaintRetrospect = time.Duration(time.Second) + cfg.GenesisState[servicetypes.ModuleName] = cfg.Codec.MustMarshalJSON(&serviceGenesisState) + + s.Network = simapp.SetupNetworkWithConfig(s.T(), cfg) +} + +// TestQueryCmd tests all query command in the service module +func (s *TxTestSuite) TestQueryCmd() { + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + expectedCode := uint32(0) + // --------------------------------------------------------------------------- + + serviceName := "test-service" + serviceDesc := "test-description" + serviceAuthorDesc := "test-author-description" + serviceTags := "tags1,tags2" + serviceSchemas := `{"input":{"type":"object"},"output":{"type":"object"},"error":{"type":"object"}}` + serviceDenom := sdk.DefaultBondDenom + + serviceDeposit := fmt.Sprintf("50000%s", serviceDenom) + servicePrices := fmt.Sprintf(`{"price": "50%s"}`, serviceDenom) + qos := uint64(3) + options := "{}" + + author := val.Address + provider := author + + consumerInfo, _, _ := val.ClientCtx.Keyring.NewMnemonic( + "NewValidator", + keyring.English, + sdk.FullFundraiserPath, + keyring.DefaultBIP39Passphrase, + hd.Secp256k1, + ) + pubKey, err := consumerInfo.GetPubKey() + s.Require().NoError(err) + consumer := sdk.AccAddress(pubKey.Address()) + + reqServiceFee := fmt.Sprintf("50%s", serviceDenom) + reqInput := `{"header":{},"body":{}}` + respResult := `{"code":200,"message":""}` + respOutput := `{"header":{},"body":{}}` + timeout := qos + + expectedEarnedFees := fmt.Sprintf("48%s", serviceDenom) + expectedTaxFees := fmt.Sprintf("2%s", serviceDenom) + + withdrawalAddress := sdk.AccAddress(crypto.AddressHash([]byte("withdrawalAddress"))) + + //------test GetCmdDefineService()------------- + args := []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagDescription, serviceDesc), + fmt.Sprintf("--%s=%s", servicecli.FlagTags, serviceTags), + fmt.Sprintf("--%s=%s", servicecli.FlagAuthorDescription, serviceAuthorDesc), + fmt.Sprintf("--%s=%s", servicecli.FlagSchemas, serviceSchemas), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult := DefineServiceExec( + s.T(), + s.Network, + clientCtx, + author.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryServiceDefinition()------------- + serviceDefinition := QueryServiceDefinitionExec( + s.T(), + s.Network, + clientCtx, + serviceName, + ) + s.Require().Equal(serviceName, serviceDefinition.Name) + + //------test GetCmdBindService()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagServiceName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagDeposit, serviceDeposit), + fmt.Sprintf("--%s=%s", servicecli.FlagPricing, servicePrices), + fmt.Sprintf("--%s=%d", servicecli.FlagQoS, qos), + fmt.Sprintf("--%s=%s", servicecli.FlagOptions, options), + fmt.Sprintf("--%s=%s", servicecli.FlagProvider, provider), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = BindServiceExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryServiceBinding()------------- + serviceBinding := QueryServiceBindingExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + ) + s.Require().Equal(serviceName, serviceBinding.ServiceName) + s.Require().Equal(provider.String(), serviceBinding.Provider) + + //------test GetCmdQueryServiceBindings()------------- + serviceBindings := QueryServiceBindingsExec( + s.T(), + s.Network, + clientCtx, + serviceName, + ) + s.Require().Len(serviceBindings.ServiceBindings, 1) + + //------test GetCmdDisableServiceBinding()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = DisableServiceExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + serviceBinding = QueryServiceBindingExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + ) + s.Require().False(serviceBinding.Available) + + //------test GetCmdRefundServiceDeposit()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = RefundDepositExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + serviceBinding = QueryServiceBindingExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + ) + s.Require().True(serviceBinding.Deposit.IsZero()) + + //------test GetCmdEnableServiceBinding()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagDeposit, serviceDeposit), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = EnableServiceExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + serviceBinding = QueryServiceBindingExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + ) + s.Require().Equal(serviceDeposit, serviceBinding.Deposit.String()) + + //------send token to consumer------------------------ + amount := sdk.NewCoins( + sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50000000)), + ) + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = simapp.MsgSendExec(s.T(), s.Network, clientCtx, provider, consumer, amount, args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdCallService()------------- + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagServiceName, serviceName), + fmt.Sprintf("--%s=%s", servicecli.FlagProviders, provider), + fmt.Sprintf("--%s=%s", servicecli.FlagServiceFeeCap, reqServiceFee), + fmt.Sprintf("--%s=%s", servicecli.FlagData, reqInput), + fmt.Sprintf("--%s=%d", servicecli.FlagTimeout, timeout), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = CallServiceExec( + s.T(), + s.Network, + clientCtx, + consumer.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + requestContextId := s.Network.GetAttribute( + servicetypes.EventTypeCreateContext, + servicetypes.AttributeKeyRequestContextID, + txResult.Events, + ) + requestHeight := txResult.Height + + blockResult, err := val.RPCClient.BlockResults(context.Background(), &requestHeight) + s.Require().NoError(err) + var compactRequest servicetypes.CompactRequest + for _, event := range blockResult.EndBlockEvents { + if event.Type == servicetypes.EventTypeNewBatchRequest { + var found bool + var requests []servicetypes.CompactRequest + var requestsBz []byte + for _, attribute := range event.Attributes { + if string(attribute.Key) == types.AttributeKeyRequests { + requestsBz = []byte(attribute.GetValue()) + } + if string(attribute.Key) == types.AttributeKeyRequestContextID && + string(attribute.GetValue()) == requestContextId { + found = true + } + } + s.Require().True(found) + if found { + err := json.Unmarshal(requestsBz, &requests) + s.Require().NoError(err) + } + s.Require().Len(requests, 1) + compactRequest = requests[0] + } + } + s.Require().Equal(requestContextId, compactRequest.RequestContextId) + + //------test GetCmdQueryServiceRequests()------------- + queryRequestsResponse := QueryServiceRequestsExec( + s.T(), + s.Network, + clientCtx, + serviceName, + provider.String(), + ) + s.Require().Len(queryRequestsResponse.Requests, 1) + s.Require().Equal(requestContextId, queryRequestsResponse.Requests[0].RequestContextId) + + //------test GetCmdQueryServiceRequests()------------- + queryRequestsResponse = QueryServiceRequestsByReqCtx( + s.T(), + s.Network, + clientCtx, + queryRequestsResponse.Requests[0].RequestContextId, + fmt.Sprint(queryRequestsResponse.Requests[0].RequestContextBatchCounter), + ) + s.Require().Len(queryRequestsResponse.Requests, 1) + s.Require().Equal(requestContextId, queryRequestsResponse.Requests[0].RequestContextId) + + //------test GetCmdRespondService()------------- + request := queryRequestsResponse.Requests[0] + args = []string{ + fmt.Sprintf("--%s=%s", servicecli.FlagRequestID, request.Id), + fmt.Sprintf("--%s=%s", servicecli.FlagResult, respResult), + fmt.Sprintf("--%s=%s", servicecli.FlagData, respOutput), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = RespondServiceExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------test GetCmdQueryEarnedFees()------------- + queryEarnedFeesResponse := QueryEarnedFeesExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + ) + s.Require().Equal(expectedEarnedFees, queryEarnedFeesResponse.Fees.String()) + + //------GetCmdSetWithdrawAddr()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = SetWithdrawAddrExec( + s.T(), + s.Network, + clientCtx, + withdrawalAddress.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + //------GetCmdWithdrawEarnedFees()------------- + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = WithdrawEarnedFeesExec( + s.T(), + s.Network, + clientCtx, + provider.String(), + provider.String(), + args...) + s.Require().Equal(expectedCode, txResult.Code) + + withdrawalFees := simapp.QueryBalancesExec( + s.T(), + s.Network, + clientCtx, + withdrawalAddress.String(), + ) + s.Require().Equal(expectedEarnedFees, withdrawalFees.String()) + + //------check service tax------------- + taxFees := simapp.QueryBalancesExec( + s.T(), + s.Network, + clientCtx, + authtypes.NewModuleAddress(servicetypes.FeeCollectorName).String(), + ) + s.Require().Equal(expectedTaxFees, taxFees.String()) + + //------GetCmdQueryRequestContext()------------- + contextId := request.RequestContextId + contextResp := QueryRequestContextExec(s.T(), s.Network, clientCtx, contextId) + s.Require().False(contextResp.Empty()) + + //------GetCmdQueryServiceRequest()------------- + requestId := request.Id + requestResp := QueryServiceRequestExec(s.T(), s.Network, clientCtx, requestId) + s.Require().False(requestResp.Empty()) + s.Require().Equal(requestId, requestResp.Id) + + //------GetCmdQueryServiceResponse()------------- + responseResp := QueryServiceResponseExec(s.T(), s.Network, clientCtx, requestId) + s.Require().False(responseResp.Empty()) +} diff --git a/e2e/suite.go b/e2e/suite.go new file mode 100644 index 00000000..73f414e0 --- /dev/null +++ b/e2e/suite.go @@ -0,0 +1,33 @@ +package e2e + +import ( + "github.com/stretchr/testify/suite" + + "mods.irisnet.org/simapp" +) + +// TestSuite is a suite of end-to-end tests for the module +type TestSuite struct { + suite.Suite + simapp.Network +} + +// SetupSuite creates a new network for integration tests +func (s *TestSuite) SetupSuite() { + depInjectOptions := simapp.DepinjectOptions{ + Config: AppConfig, + Providers: []interface{}{ + ProvideEVMKeeper(), + ProvideICS20Keeper(), + }, + } + + s.T().Log("setting up e2e test suite") + s.Network = simapp.SetupNetwork(s.T(),depInjectOptions) +} + +// TearDownSuite tears down the integration test suite +func (s *TestSuite) TearDownSuite() { + s.T().Log("tearing down e2e nft test suite") + s.Network.Cleanup() +} \ No newline at end of file diff --git a/e2e/token/cli_test.go b/e2e/token/cli_test.go new file mode 100644 index 00000000..926808fd --- /dev/null +++ b/e2e/token/cli_test.go @@ -0,0 +1,15 @@ +package token + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestTxTestSuite(t *testing.T) { + suite.Run(t, new(TxTestSuite)) +} + +// func TestQueryTestSuite(t *testing.T) { +// suite.Run(t, new(QueryTestSuite)) +// } \ No newline at end of file diff --git a/e2e/token/query.go b/e2e/token/query.go new file mode 100644 index 00000000..6590f7b7 --- /dev/null +++ b/e2e/token/query.go @@ -0,0 +1,111 @@ +package token + +import ( + "encoding/json" + "fmt" + + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + tokencli "mods.irisnet.org/modules/token/client/cli" + tokentypes "mods.irisnet.org/modules/token/types" + v1 "mods.irisnet.org/modules/token/types/v1" +) + +// QueryTestSuite is a suite of end-to-end tests for the token module +type QueryTestSuite struct { + e2e.TestSuite +} + +// TestQueryCmd tests all query command in the token module +func (s *QueryTestSuite) TestQueryCmd() { + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + // --------------------------------------------------------------------------- + + from := val.Address + symbol := "kitty" + name := "Kitty Token" + minUnit := "kitty" + scale := 0 + initialSupply := int64(100000000) + maxSupply := int64(200000000) + mintable := true + baseURL := val.APIAddress + + //------test GetCmdIssueToken()------------- + args := []string{ + fmt.Sprintf("--%s=%s", tokencli.FlagSymbol, symbol), + fmt.Sprintf("--%s=%s", tokencli.FlagName, name), + fmt.Sprintf("--%s=%s", tokencli.FlagMinUnit, minUnit), + fmt.Sprintf("--%s=%d", tokencli.FlagScale, scale), + fmt.Sprintf("--%s=%d", tokencli.FlagInitialSupply, initialSupply), + fmt.Sprintf("--%s=%d", tokencli.FlagMaxSupply, maxSupply), + fmt.Sprintf("--%s=%t", tokencli.FlagMintable, mintable), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + txResult := IssueTokenExec(s.T(), s.Network, clientCtx, from.String(), args...) + + tokenSymbol := s.Network.GetAttribute( + tokentypes.EventTypeIssueToken, + tokentypes.AttributeKeySymbol, + txResult.Events, + ) + + //------test GetCmdQueryTokens()------------- + url := fmt.Sprintf("%s/irismod/token/v1/tokens", baseURL) + resp, err := testutil.GetRequest(url) + respType := proto.Message(&v1.QueryTokensResponse{}) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, respType)) + tokensResp := respType.(*v1.QueryTokensResponse) + s.Require().Equal(2, len(tokensResp.Tokens)) + + //------test GetCmdQueryToken()------------- + url = fmt.Sprintf("%s/irismod/token/v1/tokens/%s", baseURL, tokenSymbol) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&v1.QueryTokenResponse{}) + var token v1.TokenI + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, respType)) + tokenResp := respType.(*v1.QueryTokenResponse) + err = clientCtx.InterfaceRegistry.UnpackAny(tokenResp.Token, &token) + s.Require().NoError(err) + s.Require().Equal(name, token.GetName()) + s.Require().Equal(symbol, token.GetSymbol()) + s.Require().Equal(uint64(initialSupply), token.GetInitialSupply()) + + //------test GetCmdQueryFee()------------- + url = fmt.Sprintf("%s/irismod/token/v1/tokens/%s/fees", baseURL, tokenSymbol) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&v1.QueryFeesResponse{}) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, respType)) + feeResp := respType.(*v1.QueryFeesResponse) + expectedFeeResp := "{\"exist\":true,\"issue_fee\":{\"denom\":\"stake\",\"amount\":\"13015\"},\"mint_fee\":{\"denom\":\"stake\",\"amount\":\"1301\"}}" + result, _ := json.Marshal(feeResp) + s.Require().Equal(expectedFeeResp, string(result)) + + //------test GetCmdQueryParams()------------- + url = fmt.Sprintf("%s/irismod/token/v1/params", baseURL) + resp, err = testutil.GetRequest(url) + respType = proto.Message(&v1.QueryParamsResponse{}) + s.Require().NoError(err) + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(resp, respType)) + paramsResp := respType.(*v1.QueryParamsResponse) + s.Require().NoError(err) + expectedParams := "{\"token_tax_rate\":\"0.400000000000000000\",\"issue_token_base_fee\":{\"denom\":\"stake\",\"amount\":\"60000\"},\"mint_token_fee_ratio\":\"0.100000000000000000\",\"enable_erc20\":true}" + result, _ = json.Marshal(paramsResp.Params) + s.Require().Equal(expectedParams, string(result)) +} diff --git a/e2e/token/test_helper.go b/e2e/token/test_helper.go new file mode 100644 index 00000000..ffc33111 --- /dev/null +++ b/e2e/token/test_helper.go @@ -0,0 +1,200 @@ +package token + +import ( + "fmt" + "testing" + + "github.com/cometbft/cometbft/libs/cli" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + + tokencli "mods.irisnet.org/modules/token/client/cli" + v1 "mods.irisnet.org/modules/token/types/v1" + "mods.irisnet.org/simapp" +) + +func IssueTokenExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdIssueToken(), args) +} + +func EditTokenExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + symbol string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + symbol, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdEditToken(), args) +} + +func MintTokenExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + coinStr string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + coinStr, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdMintToken(), args) +} + +func BurnTokenExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + coinStr string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + coinStr, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdBurnToken(), args) +} + +func TransferTokenOwnerExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + symbol string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + symbol, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdTransferTokenOwner(), args) +} + +func SwapToERC20Exec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + coinStr string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + coinStr, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdSwapToErc20(), args) +} + +func SwapFromERC20Exec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + from string, + coinStr string, + extraArgs ...string, +) *simapp.ResponseTx { + args := []string{ + coinStr, + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + } + args = append(args, extraArgs...) + + return network.ExecTxCmdWithResult(t, clientCtx, tokencli.GetCmdSwapFromErc20(), args) +} + +func QueryTokenExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + denom string, + extraArgs ...string, +) v1.TokenI { + args := []string{ + denom, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + respType := proto.Message(&codectypes.Any{}) + network.ExecQueryCmd(t, clientCtx, tokencli.GetCmdQueryToken(), args, respType) + + var token v1.TokenI + err := clientCtx.InterfaceRegistry.UnpackAny(respType.(*codectypes.Any), &token) + require.NoError(t, err, "QueryTokenExec failed") + return token +} + +func QueryTokensExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + owner string, + extraArgs ...string, +) []v1.TokenI { + args := []string{ + owner, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + tokens := []v1.TokenI{} + buf, err := clitestutil.ExecTestCLICmd(clientCtx, tokencli.GetCmdQueryTokens(), args) + require.NoError(t, err, "QueryTokensExec failed") + require.NoError(t, clientCtx.LegacyAmino.UnmarshalJSON(buf.Bytes(), &tokens)) + return tokens +} + +func QueryFeeExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + symbol string, + extraArgs ...string, +) *v1.QueryFeesResponse { + args := []string{ + symbol, + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &v1.QueryFeesResponse{} + network.ExecQueryCmd(t, clientCtx, tokencli.GetCmdQueryFee(), args, response) + return response +} + +func QueryParamsExec(t *testing.T, + network simapp.Network, + clientCtx client.Context, + extraArgs ...string, +) *v1.Params { + args := []string{ + fmt.Sprintf("--%s=json", cli.OutputFlag), + } + args = append(args, extraArgs...) + + response := &v1.Params{} + network.ExecQueryCmd(t, clientCtx, tokencli.GetCmdQueryParams(), args, response) + return response +} diff --git a/e2e/token/tx.go b/e2e/token/tx.go new file mode 100644 index 00000000..dc3c19ff --- /dev/null +++ b/e2e/token/tx.go @@ -0,0 +1,275 @@ +package token + +import ( + "encoding/json" + "fmt" + + "github.com/cometbft/cometbft/crypto" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + + "mods.irisnet.org/e2e" + tokencli "mods.irisnet.org/modules/token/client/cli" + tokentypes "mods.irisnet.org/modules/token/types" + "mods.irisnet.org/simapp" +) + +// TxTestSuite is a suite of end-to-end tests for the nft module +type TxTestSuite struct { + e2e.TestSuite +} + +// TestTxCmd tests all tx command in the nft module +func (s *TxTestSuite) TestTxCmd() { + val := s.Network.Validators[0] + clientCtx := val.ClientCtx + // --------------------------------------------------------------------------- + + from := val.Address + symbol := "kitty" + name := "Kitty Token" + minUnit := "kitty" + scale := 0 + initialSupply := int64(100000000) + maxSupply := int64(200000000) + mintable := true + + //------test GetCmdIssueToken()------------- + args := []string{ + fmt.Sprintf("--%s=%s", tokencli.FlagSymbol, symbol), + fmt.Sprintf("--%s=%s", tokencli.FlagName, name), + fmt.Sprintf("--%s=%s", tokencli.FlagMinUnit, minUnit), + fmt.Sprintf("--%s=%d", tokencli.FlagScale, scale), + fmt.Sprintf("--%s=%d", tokencli.FlagInitialSupply, initialSupply), + fmt.Sprintf("--%s=%d", tokencli.FlagMaxSupply, maxSupply), + fmt.Sprintf("--%s=%t", tokencli.FlagMintable, mintable), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + expectedCode := uint32(0) + txResult := IssueTokenExec(s.T(), s.Network, clientCtx, from.String(), args...) + s.Require().Equal(expectedCode, txResult.Code) + + tokenSymbol := s.Network.GetAttribute( + tokentypes.EventTypeIssueToken, + tokentypes.AttributeKeySymbol, + txResult.Events, + ) + + //------test GetCmdQueryTokens()------------- + tokens := QueryTokensExec(s.T(), s.Network, clientCtx, from.String()) + s.Require().Equal(1, len(tokens)) + + //------test GetCmdQueryToken()------------- + token := QueryTokenExec(s.T(), s.Network, clientCtx, tokenSymbol) + s.Require().Equal(name, token.GetName()) + s.Require().Equal(symbol, token.GetSymbol()) + s.Require().Equal(uint64(initialSupply), token.GetInitialSupply()) + + //------test GetCmdQueryFee()------------- + queryFeeResponse := QueryFeeExec(s.T(), s.Network, clientCtx, symbol) + expectedFeeResp := "{\"exist\":true,\"issue_fee\":{\"denom\":\"stake\",\"amount\":\"13015\"},\"mint_fee\":{\"denom\":\"stake\",\"amount\":\"1301\"}}" + result, _ := json.Marshal(queryFeeResponse) + s.Require().Equal(expectedFeeResp, string(result)) + + //------test GetCmdQueryParams()------------- + queryParamsResponse := QueryParamsExec(s.T(), s.Network, clientCtx) + expectedParams := "{\"token_tax_rate\":\"0.400000000000000000\",\"issue_token_base_fee\":{\"denom\":\"stake\",\"amount\":\"60000\"},\"mint_token_fee_ratio\":\"0.100000000000000000\",\"enable_erc20\":true}" + result, _ = json.Marshal(queryParamsResponse) + s.Require().Equal(expectedParams, string(result)) + + //------test GetCmdMintToken()------------- + balance := simapp.QueryBalanceExec( + s.T(), + s.Network, + clientCtx, + from.String(), + symbol, + ) + initAmount := balance.Amount.Int64() + mintAmount := int64(50000000) + + args = []string{ + fmt.Sprintf("--%s=%s", tokencli.FlagTo, from.String()), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + coinMintedStr := fmt.Sprintf("%d%s", mintAmount, symbol) + + txResult = MintTokenExec( + s.T(), + s.Network, + clientCtx, + from.String(), + coinMintedStr, + args..., + ) + s.Require().Equal(expectedCode, txResult.Code) + + balance = simapp.QueryBalanceExec( + s.T(), + s.Network, + clientCtx, + from.String(), + symbol, + ) + exceptedAmount := initAmount + mintAmount + s.Require().Equal(exceptedAmount, balance.Amount.Int64()) + + //------test GetCmdBurnToken()------------- + + burnAmount := int64(2000000) + + args = []string{ + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + coinBurntStr := fmt.Sprintf("%d%s", burnAmount, symbol) + txResult = BurnTokenExec( + s.T(), + s.Network, + clientCtx, + from.String(), + coinBurntStr, + args...) + s.Require().Equal(expectedCode, txResult.Code) + + balance = simapp.QueryBalanceExec( + s.T(), + s.Network, + clientCtx, + from.String(), + symbol, + ) + exceptedAmount = exceptedAmount - burnAmount + s.Require().Equal(exceptedAmount, balance.Amount.Int64()) + + //------test GetCmdEditToken()------------- + newName := "Wd Token" + newMaxSupply := 200000000 + newMintable := false + + args = []string{ + fmt.Sprintf("--%s=%s", tokencli.FlagName, newName), + fmt.Sprintf("--%s=%d", tokencli.FlagMaxSupply, newMaxSupply), + fmt.Sprintf("--%s=%t", tokencli.FlagMintable, newMintable), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = EditTokenExec( + s.T(), + s.Network, + clientCtx, + from.String(), + symbol, + args...) + s.Require().Equal(expectedCode, txResult.Code) + + token2 := QueryTokenExec(s.T(), s.Network, clientCtx, tokenSymbol) + s.Require().Equal(newName, token2.GetName()) + s.Require().Equal(uint64(newMaxSupply), token2.GetMaxSupply()) + s.Require().Equal(newMintable, token2.GetMintable()) + + //------test GetCmdTransferTokenOwner()------------- + to := sdk.AccAddress(crypto.AddressHash([]byte("dgsbl"))) + + args = []string{ + fmt.Sprintf("--%s=%s", tokencli.FlagTo, to.String()), + + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf( + "--%s=%s", + flags.FlagFees, + sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + ), + } + + txResult = TransferTokenOwnerExec( + s.T(), + s.Network, + clientCtx, + from.String(), + symbol, + args...) + s.Require().Equal(expectedCode, txResult.Code) + + token3 := QueryTokenExec(s.T(), s.Network, clientCtx, tokenSymbol) + s.Require().Equal(to, token3.GetOwner()) + // --------------------------------------------------------------------------- + + //------test GetCmdSwapToErc20()------------- + // args = []string{ + // fmt.Sprintf("--%s=%s", tokencli.FlagTo, to.String()), + + // fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + // fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + // fmt.Sprintf( + // "--%s=%s", + // flags.FlagFees, + // sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + // ), + // } + + // txResult = SwapToERC20Exec( + // s.T(), + // s.Network, + // clientCtx, + // from.String(), + // sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(1))).String(), + // args...) + + // TODO assert + // s.Require().Equal(expectedCode, txResult.Code) + // --------------------------------------------------------------------------- + + //------test GetCmdSwapFromErc20()------------- + // args = []string{ + // fmt.Sprintf("--%s=%s", tokencli.FlagTo, to.String()), + + // fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + // fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + // fmt.Sprintf( + // "--%s=%s", + // flags.FlagFees, + // sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(10))).String(), + // ), + // } + + // txResult = SwapFromERC20Exec( + // s.T(), + // s.Network, + // clientCtx, + // from.String(), + // sdk.NewCoins(sdk.NewCoin(s.Network.BondDenom, sdk.NewInt(1))).String(), + // args...) + + // TODO assert + // s.Require().Equal(expectedCode, txResult.Code) + // --------------------------------------------------------------------------- +} diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000..5a4bbbf0 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,975 @@ +4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +cloud.google.com/go/accessapproval v1.7.4 h1:ZvLvJ952zK8pFHINjpMBY5k7LTAp/6pBf50RDMRgBUI= +cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= +cloud.google.com/go/accesscontextmanager v1.8.4 h1:Yo4g2XrBETBCqyWIibN3NHNPQKUfQqti0lI+70rubeE= +cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= +cloud.google.com/go/aiplatform v1.58.0 h1:xyCAfpI4yUMOQ4VtHN/bdmxPQ8xoEkTwFM1nbVmuQhs= +cloud.google.com/go/aiplatform v1.58.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/analytics v0.21.6 h1:fnV7B8lqyEYxCU0LKk+vUL7mTlqRAq4uFlIthIdr/iA= +cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/apigateway v1.6.4 h1:VVIxCtVerchHienSlaGzV6XJGtEM9828Erzyr3miUGs= +cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= +cloud.google.com/go/apigeeconnect v1.6.4 h1:jSoGITWKgAj/ssVogNE9SdsTqcXnryPzsulENSRlusI= +cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= +cloud.google.com/go/apigeeregistry v0.8.2 h1:DSaD1iiqvELag+lV4VnnqUUFd8GXELu01tKVdWZrviE= +cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= +cloud.google.com/go/appengine v1.8.4 h1:Qub3fqR7iA1daJWdzjp/Q0Jz0fUG0JbMc7Ui4E9IX/E= +cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= +cloud.google.com/go/area120 v0.8.4 h1:YnSO8m02pOIo6AEOgiOoUDVbw4pf+bg2KLHi4rky320= +cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= +cloud.google.com/go/artifactregistry v1.14.6 h1:/hQaadYytMdA5zBh+RciIrXZQBWK4vN7EUsrQHG+/t8= +cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= +cloud.google.com/go/asset v1.16.0 h1:VjwWNtEVsbpXfJqZbb2RLOBzSgAjN69vf2UJADHnkxk= +cloud.google.com/go/asset v1.16.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/assuredworkloads v1.11.4 h1:FsLSkmYYeNuzDm8L4YPfLWV+lQaUrJmH5OuD37t1k20= +cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= +cloud.google.com/go/automl v1.13.4 h1:i9tOKXX+1gE7+rHpWKjiuPfGBVIYoWvLNIGpWgPtF58= +cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= +cloud.google.com/go/baremetalsolution v1.2.3 h1:oQiFYYCe0vwp7J8ZmF6siVKEumWtiPFJMJcGuyDVRUk= +cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= +cloud.google.com/go/batch v1.7.0 h1:AxuSPoL2fWn/rUyvWeNCNd0V2WCr+iHRCU9QO1PUmpY= +cloud.google.com/go/batch v1.7.0/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/beyondcorp v1.0.3 h1:VXf9SnrnSmj2BF2cHkoTHvOUp8gjsz1KJFOMW7czdsY= +cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= +cloud.google.com/go/bigquery v1.57.1 h1:FiULdbbzUxWD0Y4ZGPSVCDLvqRSyCIO6zKV7E2nf5uA= +cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= +cloud.google.com/go/billing v1.18.0 h1:GvKy4xLy1zF1XPbwP5NJb2HjRxhnhxjjXxvyZ1S/IAo= +cloud.google.com/go/billing v1.18.0/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/binaryauthorization v1.8.0 h1:PHS89lcFayWIEe0/s2jTBiEOtqghCxzc7y7bRNlifBs= +cloud.google.com/go/binaryauthorization v1.8.0/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/certificatemanager v1.7.4 h1:5YMQ3Q+dqGpwUZ9X5sipsOQ1fLPsxod9HNq0+nrqc6I= +cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= +cloud.google.com/go/channel v1.17.3 h1:Rd4+fBrjiN6tZ4TR8R/38elkyEkz6oogGDr7jDyjmMY= +cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/cloudbuild v1.15.0 h1:9IHfEMWdCklJ1cwouoiQrnxmP0q3pH7JUt8Hqx4Qbck= +cloud.google.com/go/cloudbuild v1.15.0/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/clouddms v1.7.3 h1:xe/wJKz55VO1+L891a1EG9lVUgfHr9Ju/I3xh1nwF84= +cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= +cloud.google.com/go/cloudtasks v1.12.4 h1:5xXuFfAjg0Z5Wb81j2GAbB3e0bwroCeSF+5jBn/L650= +cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= +cloud.google.com/go/contactcenterinsights v1.12.1 h1:EiGBeejtDDtr3JXt9W7xlhXyZ+REB5k2tBgVPVtmNb0= +cloud.google.com/go/contactcenterinsights v1.12.1/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/container v1.29.0 h1:jIltU529R2zBFvP8rhiG1mgeTcnT27KhU0H/1d6SQRg= +cloud.google.com/go/container v1.29.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/containeranalysis v0.11.3 h1:5rhYLX+3a01drpREqBZVXR9YmWH45RnML++8NsCtuD8= +cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= +cloud.google.com/go/datacatalog v1.19.0 h1:rbYNmHwvAOOwnW2FPXYkaK3Mf1MmGqRzK0mMiIEyLdo= +cloud.google.com/go/datacatalog v1.19.0/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/dataflow v0.9.4 h1:7VmCNWcPJBS/srN2QnStTB6nu4Eb5TMcpkmtaPVhRt4= +cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= +cloud.google.com/go/dataform v0.9.1 h1:jV+EsDamGX6cE127+QAcCR/lergVeeZdEQ6DdrxW3sQ= +cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= +cloud.google.com/go/datafusion v1.7.4 h1:Q90alBEYlMi66zL5gMSGQHfbZLB55mOAg03DhwTTfsk= +cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= +cloud.google.com/go/datalabeling v0.8.4 h1:zrq4uMmunf2KFDl/7dS6iCDBBAxBnKVDyw6+ajz3yu0= +cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= +cloud.google.com/go/dataplex v1.13.0 h1:ACVOuxwe7gP0SqEso9SLyXbcZNk5l8hjcTX+XLntI5s= +cloud.google.com/go/dataplex v1.13.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataproc/v2 v2.3.0 h1:tTVP9tTxmc8fixxOd/8s6Q6Pz/+yzn7r7XdZHretQH0= +cloud.google.com/go/dataproc/v2 v2.3.0/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataqna v0.8.4 h1:NJnu1kAPamZDs/if3bJ3+Wb6tjADHKL83NUWsaIp2zg= +cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= +cloud.google.com/go/datastore v1.15.0 h1:0P9WcsQeTWjuD1H14JIY7XQscIPQ4Laje8ti96IC5vg= +cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= +cloud.google.com/go/datastream v1.10.3 h1:Z2sKPIB7bT2kMW5Uhxy44ZgdJzxzE5uKjavoW+EuHEE= +cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= +cloud.google.com/go/deploy v1.16.0 h1:5OVjzm8MPC5kP+Ywbs0mdE0O7AXvAUXksSyHAyMFyMg= +cloud.google.com/go/deploy v1.16.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/dialogflow v1.47.0 h1:tLCWad8HZhlyUNfDzDP5m+oH6h/1Uvw/ei7B9AnsWMk= +cloud.google.com/go/dialogflow v1.47.0/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dlp v1.11.1 h1:OFlXedmPP/5//X1hBEeq3D9kUVm9fb6ywYANlpv/EsQ= +cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= +cloud.google.com/go/documentai v1.23.7 h1:hlYieOXUwiJ7HpBR/vEPfr8nfSxveLVzbqbUkSK0c/4= +cloud.google.com/go/documentai v1.23.7/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/domains v0.9.4 h1:ua4GvsDztZ5F3xqjeLKVRDeOvJshf5QFgWGg1CKti3A= +cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= +cloud.google.com/go/edgecontainer v1.1.4 h1:Szy3Q/N6bqgQGyxqjI+6xJZbmvPvnFHp3UZr95DKcQ0= +cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= +cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.6.5 h1:S2if6wkjR4JCEAfDtIiYtD+sTz/oXjh2NUG4cgT1y/Q= +cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= +cloud.google.com/go/eventarc v1.13.3 h1:+pFmO4eu4dOVipSaFBLkmqrRYG94Xl/TQZFOeohkuqU= +cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= +cloud.google.com/go/filestore v1.8.0 h1:/+wUEGwk3x3Kxomi2cP5dsR8+SIXxo7M0THDjreFSYo= +cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= +cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= +cloud.google.com/go/functions v1.15.4 h1:ZjdiV3MyumRM6++1Ixu6N0VV9LAGlCX4AhW6Yjr1t+U= +cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= +cloud.google.com/go/gaming v1.6.0 h1:PKggmegChZulPW8yvtziF8P9UOuVFwbvylbEucTNups= +cloud.google.com/go/gkebackup v1.3.4 h1:KhnOrr9A1tXYIYeXKqCKbCI8TL2ZNGiD3dm+d7BDUBg= +cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= +cloud.google.com/go/gkeconnect v0.8.4 h1:1JLpZl31YhQDQeJ98tK6QiwTpgHFYRJwpntggpQQWis= +cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= +cloud.google.com/go/gkehub v0.14.4 h1:J5tYUtb3r0cl2mM7+YHvV32eL+uZQ7lONyUZnPikCEo= +cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= +cloud.google.com/go/gkemulticloud v1.0.3 h1:NmJsNX9uQ2CT78957xnjXZb26TDIMvv+d5W2vVUt0Pg= +cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/grafeas v0.2.0 h1:CYjC+xzdPvbV65gi6Dr4YowKcmLo045pm18L0DhdELM= +cloud.google.com/go/gsuiteaddons v1.6.4 h1:uuw2Xd37yHftViSI8J2hUcCS8S7SH3ZWH09sUDLW30Q= +cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= +cloud.google.com/go/iap v1.9.3 h1:M4vDbQ4TLXdaljXVZSwW7XtxpwXUUarY2lIs66m0aCM= +cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= +cloud.google.com/go/ids v1.4.4 h1:VuFqv2ctf/A7AyKlNxVvlHTzjrEvumWaZflUzBPz/M4= +cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= +cloud.google.com/go/iot v1.7.4 h1:m1WljtkZnvLTIRYW1YTOv5A6H1yKgLHR6nU7O8yf27w= +cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= +cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM= +cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= +cloud.google.com/go/language v1.12.2 h1:zg9uq2yS9PGIOdc0Kz/l+zMtOlxKWonZjjo5w5YPG2A= +cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= +cloud.google.com/go/lifesciences v0.9.4 h1:rZEI/UxcxVKEzyoRS/kdJ1VoolNItRWjNN0Uk9tfexg= +cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= +cloud.google.com/go/logging v1.9.0 h1:iEIOXFO9EmSiTjDmfpbRjOxECO7R8C7b8IXUGOj7xZw= +cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE= +cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= +cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= +cloud.google.com/go/managedidentities v1.6.4 h1:SF/u1IJduMqQQdJA4MDyivlIQ4SrV5qAawkr/ZEREkY= +cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= +cloud.google.com/go/maps v1.6.2 h1:WxxLo//b60nNFESefLgaBQevu8QGUmRV3+noOjCfIHs= +cloud.google.com/go/maps v1.6.2/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/mediatranslation v0.8.4 h1:VRCQfZB4s6jN0CSy7+cO3m4ewNwgVnaePanVCQh/9Z4= +cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= +cloud.google.com/go/memcache v1.10.4 h1:cdex/ayDd294XBj2cGeMe6Y+H1JvhN8y78B9UW7pxuQ= +cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= +cloud.google.com/go/metastore v1.13.3 h1:94l/Yxg9oBZjin2bzI79oK05feYefieDq0o5fjLSkC8= +cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= +cloud.google.com/go/monitoring v1.17.0 h1:blrdvF0MkPPivSO041ihul7rFMhXdVp8Uq7F59DKXTU= +cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= +cloud.google.com/go/networkconnectivity v1.14.3 h1:e9lUkCe2BexsqsUc2bjV8+gFBpQa54J+/F3qKVtW+wA= +cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= +cloud.google.com/go/networkmanagement v1.9.3 h1:HsQk4FNKJUX04k3OI6gUsoveiHMGvDRqlaFM2xGyvqU= +cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= +cloud.google.com/go/networksecurity v0.9.4 h1:947tNIPnj1bMGTIEBo3fc4QrrFKS5hh0bFVsHmFm4Vo= +cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= +cloud.google.com/go/notebooks v1.11.2 h1:eTOTfNL1yM6L/PCtquJwjWg7ZZGR0URFaFgbs8kllbM= +cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= +cloud.google.com/go/optimization v1.6.2 h1:iFsoexcp13cGT3k/Hv8PA5aK+FP7FnbhwDO9llnruas= +cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= +cloud.google.com/go/orchestration v1.8.4 h1:kgwZ2f6qMMYIVBtUGGoU8yjYWwMTHDanLwM/CQCFaoQ= +cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= +cloud.google.com/go/orgpolicy v1.11.4 h1:RWuXQDr9GDYhjmrredQJC7aY7cbyqP9ZuLbq5GJGves= +cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/osconfig v1.12.4 h1:OrRCIYEAbrbXdhm13/JINn9pQchvTTIzgmOCA7uJw8I= +cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= +cloud.google.com/go/oslogin v1.12.2 h1:NP/KgsD9+0r9hmHC5wKye0vJXVwdciv219DtYKYjgqE= +cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= +cloud.google.com/go/phishingprotection v0.8.4 h1:sPLUQkHq6b4AL0czSJZ0jd6vL55GSTHz2B3Md+TCZI0= +cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= +cloud.google.com/go/policytroubleshooter v1.10.2 h1:sq+ScLP83d7GJy9+wpwYJVnY+q6xNTXwOdRIuYjvHT4= +cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= +cloud.google.com/go/privatecatalog v0.9.4 h1:Vo10IpWKbNvc/z/QZPVXgCiwfjpWoZ/wbgful4Uh/4E= +cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= +cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= +cloud.google.com/go/recaptchaenterprise v1.3.1 h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQlyjGE9a4exk6iNQ= +cloud.google.com/go/recaptchaenterprise/v2 v2.9.0 h1:Zrd4LvT9PaW91X/Z13H0i5RKEv9suCLuk8zp+bfOpN4= +cloud.google.com/go/recaptchaenterprise/v2 v2.9.0/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recommendationengine v0.8.4 h1:JRiwe4hvu3auuh2hujiTc2qNgPPfVp+Q8KOpsXlEzKQ= +cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= +cloud.google.com/go/recommender v1.12.0 h1:tC+ljmCCbuZ/ybt43odTFlay91n/HLIhflvaOeb0Dh4= +cloud.google.com/go/recommender v1.12.0/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/redis v1.14.1 h1:J9cEHxG9YLmA9o4jTSvWt/RuVEn6MTrPlYSCRHujxDQ= +cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= +cloud.google.com/go/resourcemanager v1.9.4 h1:JwZ7Ggle54XQ/FVYSBrMLOQIKoIT/uer8mmNvNLK51k= +cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= +cloud.google.com/go/resourcesettings v1.6.4 h1:yTIL2CsZswmMfFyx2Ic77oLVzfBFoWBYgpkgiSPnC4Y= +cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= +cloud.google.com/go/retail v1.14.4 h1:geqdX1FNqqL2p0ADXjPpw8lq986iv5GrVcieTYafuJQ= +cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= +cloud.google.com/go/run v1.3.3 h1:qdfZteAm+vgzN1iXzILo3nJFQbzziudkJrvd9wCf3FQ= +cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= +cloud.google.com/go/scheduler v1.10.5 h1:eMEettHlFhG5pXsoHouIM5nRT+k+zU4+GUvRtnxhuVI= +cloud.google.com/go/scheduler v1.10.5/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/secretmanager v1.11.4 h1:krnX9qpG2kR2fJ+u+uNyNo+ACVhplIAS4Pu7u+4gd+k= +cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= +cloud.google.com/go/security v1.15.4 h1:sdnh4Islb1ljaNhpIXlIPgb3eYj70QWgPVDKOUYvzJc= +cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= +cloud.google.com/go/securitycenter v1.24.3 h1:crdn2Z2rFIy8WffmmhdlX3CwZJusqCiShtnrGFRwpeE= +cloud.google.com/go/securitycenter v1.24.3/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/servicedirectory v1.11.3 h1:5niCMfkw+jifmFtbBrtRedbXkJm3fubSR/KHbxSJZVM= +cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= +cloud.google.com/go/shell v1.7.4 h1:nurhlJcSVFZneoRZgkBEHumTYf/kFJptCK2eBUq/88M= +cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= +cloud.google.com/go/spanner v1.54.0 h1:ttU+lhARPF/iZE3OkCpmfsemCz9mLaqBhGPd3Qub2sQ= +cloud.google.com/go/spanner v1.54.0/go.mod h1:wZvSQVBgngF0Gq86fKup6KIYmN2be7uOKjtK97X+bQU= +cloud.google.com/go/speech v1.21.0 h1:qkxNao58oF8ghAHE1Eghen7XepawYEN5zuZXYWaUTA4= +cloud.google.com/go/speech v1.21.0/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= +cloud.google.com/go/storagetransfer v1.10.3 h1:YM1dnj5gLjfL6aDldO2s4GeU8JoAvH1xyIwXre63KmI= +cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= +cloud.google.com/go/talent v1.6.5 h1:LnRJhhYkODDBoTwf6BeYkiJHFw9k+1mAFNyArwZUZAs= +cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= +cloud.google.com/go/texttospeech v1.7.4 h1:ahrzTgr7uAbvebuhkBAAVU6kRwVD0HWsmDsvMhtad5Q= +cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= +cloud.google.com/go/tpu v1.6.4 h1:XIEH5c0WeYGaVy9H+UueiTaf3NI6XNdB4/v6TFQJxtE= +cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= +cloud.google.com/go/trace v1.10.4 h1:2qOAuAzNezwW3QN+t41BtkDJOG42HywL73q8x/f6fnM= +cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= +cloud.google.com/go/translate v1.9.3 h1:t5WXTqlrk8VVJu/i3WrYQACjzYJiff5szARHiyqqPzI= +cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/video v1.20.3 h1:Xrpbm2S9UFQ1pZEeJt9Vqm5t2T/z9y/M3rNXhFoo8Is= +cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= +cloud.google.com/go/videointelligence v1.11.4 h1:YS4j7lY0zxYyneTFXjBJUj2r4CFe/UoIi/PJG0Zt/Rg= +cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= +cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4= +cloud.google.com/go/vision/v2 v2.7.5 h1:T/ujUghvEaTb+YnFY/jiYwVAkMbIC8EieK0CJo6B4vg= +cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= +cloud.google.com/go/vmmigration v1.7.4 h1:qPNdab4aGgtaRX+51jCOtJxlJp6P26qua4o1xxUDjpc= +cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= +cloud.google.com/go/vmwareengine v1.0.3 h1:WY526PqM6QNmFHSqe2sRfK6gRpzWjmL98UFkql2+JDM= +cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= +cloud.google.com/go/vpcaccess v1.7.4 h1:zbs3V+9ux45KYq8lxxn/wgXole6SlBHHKKyZhNJoS+8= +cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= +cloud.google.com/go/webrisk v1.9.4 h1:iceR3k0BCRZgf2D/NiKviVMFfuNC9LmeNLtxUFRB/wI= +cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= +cloud.google.com/go/websecurityscanner v1.6.4 h1:5Gp7h5j7jywxLUp6NTpjNPkgZb3ngl0tUSw6ICWvtJQ= +cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= +cloud.google.com/go/workflows v1.12.3 h1:qocsqETmLAl34mSa01hKZjcqAvt699gaoFbooGGMvaM= +cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= +github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= +github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk= +github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= +github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= +github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= +github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 h1:qoVeMsc9/fh/yhxVaA0obYjVH/oI/ihrOoMwsLS9KSA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3 h1:E+m3SkZCN0Bf5q7YdTs5lSm2CYY3CK4spn5OmUIiQtk= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0 h1:Px2UA+2RvSSvv+RvJNuUB6n7rs5Wsel4dXLe90Um2n4= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= +github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= +github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= +github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= +github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= +github.com/alecthomas/kingpin/v2 v2.3.1 h1:ANLJcKmQm4nIaog7xdr/id6FM6zm5hHnfZrvtKPxqGg= +github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= +github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw= +github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= +github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= +github.com/aws/aws-lambda-go v1.13.3 h1:SuCy7H3NLyp+1Mrfp+m80jcbi9KYWAs9/BXwppwRDzY= +github.com/aws/aws-sdk-go-v2 v1.9.1 h1:ZbovGV/qo40nrOJ4q8G33AGICzaPI45FHQWJ9650pF4= +github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1 h1:NbvWIM1Mx6sNPTxowHgS2ewXCRp+NGTzUYb/96FZJbY= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 h1:EtEU7WRaWliitZh2nmuxEXrN0Cb8EgPUFGIoTMeqbzI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1 h1:w/fPGB0t5rWwA43mux4e9ozFSH5zF1moQemlA131PWc= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 h1:4AH9fFjUlVktQMznF+YN33aWNXaR4VgDXyP28qokJC0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1 h1:cKr6St+CtC3/dl/rEBJvlk7A/IN5D5F02GNkGzfbtVU= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 h1:37QubsarExl5ZuCBlnRP+7l1tNwZPBSTqpTBrPH98RU= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 h1:TJoIfnIFubCX0ACVeJ0w46HEH5MwjwYN4iFhuYIhfIY= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= +github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= +github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= +github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= +github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= +github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= +github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/bufbuild/buf v1.7.0 h1:uWRjhIXcrWkzIkA5TqXGyJbF51VW54QJsQZ3nwaes5Q= +github.com/bufbuild/buf v1.7.0/go.mod h1:Go40fMAF46PnPLC7jJgTQhAI95pmC0+VtxFKVC0qLq0= +github.com/bufbuild/connect-go v1.0.0 h1:htSflKUT8y1jxhoPhPYTZMrsY3ipUXjjrbcZR5O2cVo= +github.com/bufbuild/connect-go v1.0.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/casbin/casbin/v2 v2.37.0 h1:/poEwPSovi4bTOcP752/CsTQiRz2xycyVKFG7GUhbDw= +github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= +github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= +github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= +github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= +github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 h1:qbb/AE938DFhOajUYh9+OXELpSF9KZw2ZivtmW6eX1Q= +github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/containerd/containerd v1.6.8 h1:h4dOFDwzHmqFEP754PgfgTeVXFnLiRc6kiqC7tplDJs= +github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= +github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= +github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1.0.20220726092710-f848e4300a8a h1:2humuGPw3O5riJVFq/E2FRjF57UrO97W1qJcGVmK+6k= +github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1.0.20220726092710-f848e4300a8a/go.mod h1:c8IO23vgNxueCCJlSI9awQtcxsvc+buzaeThB85qfBU= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= +github.com/daixiang0/gci v0.8.1 h1:T4xpSC+hmsi4CSyuYfIJdMZAr9o7xZmHpQVygMghGZ4= +github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= +github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf h1:Yt+4K30SdjOkRoRRm3vYNQgR+/ZIy0RmeUDZo7Y8zeQ= +github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= +github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= +github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c h1:CndMRAH4JIwxbW8KYq6Q+cGWcGHz0FjGR3QqcInWcW0= +github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= +github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQWj4T+rfKHYCHxRHCtRxhKKjRidVw= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 h1:a9ENSRDFBUPkJ5lCgVZh26+ZbGyoVJG7yb5SSzF5H54= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= +github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= +github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo= +github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE= +github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git/v5 v5.5.2 h1:v8lgZa5k9ylUw+OR/roJHTxR4QItsNFI5nKtAXFuynw= +github.com/go-git/go-git/v5 v5.5.2/go.mod h1:BE5hUJ5yaV2YMxhmaP4l6RBQ08kMxKSPD4BlxtH7OjI= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0= +github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astequal v1.0.3 h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-zookeeper/zk v1.0.2 h1:4mx0EYENAdX/B/rbunjlt5+4RTA/a9SMHBRuSKdGxPM= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= +github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY= +github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9 h1:OF1IPgv+F4NmqmJ98KTjdN97Vs1JxDPB3vbmYzV2dpk= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/hashicorp/consul/api v1.15.3 h1:WYONYL2rxTXtlekAqblR2SCdJsizMDIj/uXb5wNy9zU= +github.com/hashicorp/consul/api v1.15.3/go.mod h1:/g/qgcoBcEXALCNZgRRisyTW0nY86++L0KbeAMXYCeY= +github.com/hashicorp/consul/sdk v0.3.0 h1:UOxjlb4xVNF93jak1mzzoBatyFju9nrkxpVwIp/QqxQ= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= +github.com/hashicorp/serf v0.9.8 h1:JGklO/2Drf1QGa312EieQN3zhxQ+aJg6pG+aC3MFaVo= +github.com/hashicorp/serf v0.9.8/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hudl/fargo v1.4.0 h1:ZDDILMbB37UlAVLlWcJ2Iz1XuahZZTDZfdCKeclfq2s= +github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/hydrogen18/memlistener v1.0.0 h1:JR7eDj8HD6eXrc5fWLbSUnfcQFL06PYvCc0DKQnWfaU= +github.com/hydrogen18/memlistener v1.0.0/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= +github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/informalsystems/tm-load-test v1.3.0 h1:FGjKy7vBw6mXNakt+wmNWKggQZRsKkEYpaFk/zR64VA= +github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6Bf4O0U4b1kRc+0qZlQJKw= +github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= +github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4= +github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f h1:BNuUg9k2EiJmlMwjoef3e8vZLHplbVw6DrjGFjLL+Yo= +github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= +github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= +github.com/kataras/golog v0.1.8 h1:isP8th4PJH2SrbkciKnylaND9xoTtfxv++NB+DF0l9g= +github.com/kataras/golog v0.1.8/go.mod h1:rGPAin4hYROfk1qT9wZP6VY2rsb4zzc37QpdPjdkqVw= +github.com/kataras/iris/v12 v12.2.0 h1:WzDY5nGuW/LgVaFS5BtTkW3crdSKJ/FEgWnxPnIVVLI= +github.com/kataras/iris/v12 v12.2.0/go.mod h1:BLzBpEunc41GbE68OUaQlqX4jzi791mx5HU04uPb90Y= +github.com/kataras/pio v0.0.11 h1:kqreJ5KOEXGMwHAWHDwIl+mjfNCPhAwZPa8gK7MKlyw= +github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI= +github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= +github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= +github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= +github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= +github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= +github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= +github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= +github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/labstack/echo/v4 v4.10.0 h1:5CiyngihEO4HXsz3vVsJn7f8xAlWwRr3aY6Ih280ZKA= +github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= +github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= +github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= +github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743 h1:143Bb8f8DuGWck/xpNUOckBVYfFbBTnLevfRZ1aVVqo= +github.com/lightstep/lightstep-tracer-go v0.18.1 h1:vi1F1IQ8N7hNWytK9DpJsUfQhGuNSc19z330K6vl4zk= +github.com/linxGnu/grocksdb v1.7.10 h1:dz7RY7GnFUA+GJO6jodyxgkUeGMEkPp3ikt9hAcNGEw= +github.com/linxGnu/grocksdb v1.7.10/go.mod h1:0hTf+iA+GOr0jDX4CgIYyJZxqOH9XlBh6KVj8+zmF34= +github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/lyft/protoc-gen-validate v0.0.13 h1:KNt/RhmQTOLr7Aj8PsJ7mTronaFyx80mRTT9qF261dA= +github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= +github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= +github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= +github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= +github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= +github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4= +github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76 h1:0xuRacu/Zr+jX+KyLLPPktbwXqyOvnOPUQmMLzX1jxU= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI= +github.com/nats-io/jwt/v2 v2.0.3 h1:i/O6cmIsjpcQyWDYNcq2JyZ3/VTF8SJ4JWluI5OhpvI= +github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY= +github.com/nats-io/nats-server/v2 v2.5.0 h1:wsnVaaXH9VRSg+A2MVg5Q727/CqxnmPLGFQ3YZYKTQg= +github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= +github.com/nats-io/nats.go v1.12.1 h1:+0ndxwUPz3CmQ2vjbXdkC1fo3FdiOQDim4gl3Mge8Qo= +github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM= +github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU= +github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU= +github.com/openzipkin/zipkin-go v0.2.5 h1:UwtQQx2pyPIgWYHRg+epgdx1/HnBQTgN3/oIYEJTQzU= +github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/performancecopilot/speed v3.0.0+incompatible h1:2WnRzIquHa5QxaJKShDkLM+sc0JPuwhXzK8OYOyt3Vg= +github.com/performancecopilot/speed/v4 v4.0.0 h1:VxEDCmdkfbQYDlcr/GC9YoN9PQ6p8ulk9xVsepYy9ZY= +github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI= +github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= +github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3 h1:hUmXhbljNFtrH5hzV9kiRoddZ5nfPTq3K0Sb2hYYiqE= +github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3/go.mod h1:q5NXNGzqj5uPnVuhGkZfmgHqNUhf15VLi6L9kW0VEc0= +github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4 h1:RHHRCZeaNyBXdYPMjZNH8/XHDBH38TZzw8izrW7dmBE= +github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4/go.mod h1:RdR1j20Aj5pB6+fw6Y9Ur7lMHpegTEjY1vc19hEZL40= +github.com/pointlander/peg v1.0.1 h1:mgA/GQE8TeS9MdkU6Xn6iEzBmQUQCNuWD7rHCK6Mjs0= +github.com/pointlander/peg v1.0.1/go.mod h1:5hsGDQR2oZI4QoWz0/Kdg3VSVEC31iJw/b7WjqCBGRI= +github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY= +github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= +github.com/quasilyte/go-ruleguard v0.3.18 h1:sd+abO1PEI9fkYennwzHn9kl3nqP6M5vE7FiOzZ+5CE= +github.com/quasilyte/go-ruleguard v0.3.18/go.mod h1:lOIzcYlgxrQ2sGJ735EHXmf/e9MJ516j16K/Ifcttvs= +github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f h1:6Gtn2i04RD0gVyYf2/IUMTIs+qYleBt4zxDqkLTcu4U= +github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= +github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= +github.com/sagikazarmark/crypt v0.8.0 h1:xtk0uUHVWVsRBdEUGYBym4CXbcllXky2M7Qlwsf8C0Y= +github.com/sagikazarmark/crypt v0.8.0/go.mod h1:TmKwZAo97S4Fy4sfMH/HX/cQP5D+ijra2NyLpNNmttY= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= +github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw= +github.com/sashamelentyev/usestdlibvars v1.20.0/go.mod h1:0GaP+ecfZMXShS0A94CJn6aEuPRILv8h/VuWI9n1ygg= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= +github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= +github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= +github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= +github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= +github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY= +github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= +github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e h1:mOtuXaRAbVZsxAHVdPR3IjfmN8T1h2iczJLynhLybf8= +github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 h1:m+8fKfQwCAy1QjzINvKe/pYtLjo2dl59x2w9YSEJxuY= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= +github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdewolff/minify/v2 v2.12.4 h1:kejsHQMM17n6/gwdw53qsi6lg0TGddZADVyQOz1KMdE= +github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= +github.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZycQ= +github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= +github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= +github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= +github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA= +github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= +github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= +github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y= +github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= +github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= +github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc= +github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vektra/mockery/v2 v2.14.0 h1:KZ1p5Hrn8tiY+LErRMr14HHle6khxo+JKOXLBW/yfqs= +github.com/vektra/mockery/v2 v2.14.0/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= +github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= +github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= +github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= +github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= +gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= +go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= +go.etcd.io/etcd/client/v2 v2.305.5 h1:DktRP60//JJpnPC0VBymAN/7V71GHMdjDCBt4ZPXDjI= +go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4= +go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI= +go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= +go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= +go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3 h1:syAz40OyelLZo42+3U68Phisvrx4qh+4wpdZw7eUUdY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3/go.mod h1:Dts42MGkzZne2yCru741+bFiTMWkIj/LLRizad7b9tw= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405 h1:o4S3HvTUEXgRsNSUQsALDVog0O9F/U1JJlHmmUN8Uas= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= +honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= +mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= +mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= diff --git a/simapp/network.go b/simapp/network.go index 64c96a17..9b8135ed 100644 --- a/simapp/network.go +++ b/simapp/network.go @@ -32,7 +32,9 @@ type ResponseTx struct { } func SetupNetwork(t *testing.T, depInjectOptions DepinjectOptions) Network { - cfg := NewConfig(depInjectOptions) + cfg,err := NewConfig(depInjectOptions) + require.NoError(t, err) + cfg.NumValidators = 4 network, err := network.New(t, t.TempDir(), cfg) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 26ea2388..3dcf147b 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "cosmossdk.io/depinject" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" @@ -30,6 +31,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" pruningtypes "github.com/cosmos/cosmos-sdk/store/pruning/types" @@ -165,15 +167,40 @@ func SetupWithGenesisStateFn( return app } -func NewConfig(depInjectOptions DepinjectOptions) network.Config { +func NewConfig(depInjectOptions DepinjectOptions) (network.Config, error) { + var ( + appBuilder *runtime.AppBuilder + txConfig client.TxConfig + legacyAmino *codec.LegacyAmino + cdc codec.Codec + interfaceRegistry codectypes.InterfaceRegistry + ) + + providers := append(depInjectOptions.Providers[:], log.NewNopLogger()) + if err := depinject.Inject( + depinject.Configs( + depInjectOptions.Config, + depinject.Supply( + providers..., + ), + ), + &appBuilder, + &txConfig, + &cdc, + &legacyAmino, + &interfaceRegistry, + ); err != nil { + return network.Config{}, err + } + cfg := network.DefaultConfig(func() network.TestFixture { return NewTestNetworkFixture(depInjectOptions) }) - encCfg := MakeTestEncodingConfig() // redundant - cfg.Codec = encCfg.Codec - cfg.TxConfig = encCfg.TxConfig - cfg.LegacyAmino = encCfg.Amino - cfg.InterfaceRegistry = encCfg.InterfaceRegistry + cfg.Codec = cdc + cfg.TxConfig = txConfig + cfg.LegacyAmino = legacyAmino + cfg.InterfaceRegistry = interfaceRegistry + cfg.GenesisState = appBuilder.DefaultGenesis() cfg.AppConstructor = func(val network.ValidatorI) servertypes.Application { return NewSimApp( val.GetCtx().Logger, @@ -186,8 +213,7 @@ func NewConfig(depInjectOptions DepinjectOptions) network.Config { bam.SetChainID(cfg.ChainID), ) } - cfg.GenesisState = NewDefaultGenesisState(cfg.Codec) - return cfg + return cfg, nil } // func SimAppConstructor(val network.ValidatorI) servertypes.Application {