diff --git a/.github/workflows/buf.yml b/.github/workflows/buf.yml index ea9c372e6..00e3c809b 100644 --- a/.github/workflows/buf.yml +++ b/.github/workflows/buf.yml @@ -27,3 +27,7 @@ jobs: run: | export PATH="$PATH:$(go env GOPATH)/bin" make tools proto-gen-check + - name: Test protobuf swagger changes + run: | + export PATH="$PATH:$(go env GOPATH)/bin" + make tools proto-swagger-check diff --git a/CHANGELOG.md b/CHANGELOG.md index d78169a66..36fa24b32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 0.2.3-alpha.6 +This release includes 6 features and 5 bugfixes. + +Features: +* [#346](https://github.com/bnb-chain/greenfield/pull/346) feat: Enable websocket client as a option in Greenfield sdk +* [#349](https://github.com/bnb-chain/greenfield/pull/349) feat: add UpdateChannelPermissions tx for crosschain module +* [#350](https://github.com/bnb-chain/greenfield/pull/350) feat: add create storage provider command +* [#357](https://github.com/bnb-chain/greenfield/pull/357) feat: add api to filter virtual group families qualification +* [#352](https://github.com/bnb-chain/greenfield/pull/352) feat: add query params for virtual group +* [#348](https://github.com/bnb-chain/greenfield/pull/348) feat: fix issues and add test cases for payment + +Bugfixes: +* [#351](https://github.com/bnb-chain/greenfield/pull/351) fix: update local virtual group event +* [#353](https://github.com/bnb-chain/greenfield/pull/353) fix: panic when delete unsealed object from lvg +* [#354](https://github.com/bnb-chain/greenfield/pull/354) fix: incorrect authority for keepers +* [#342](https://github.com/bnb-chain/greenfield/pull/342) fix: remove primary sp id from bucket info +* [#356](https://github.com/bnb-chain/greenfield/pull/356) fix: add validation of extra field when creating group + +Chores: +* [#359](https://github.com/bnb-chain/greenfield/pull/359) chore: add swagger check +* [#358](https://github.com/bnb-chain/greenfield/pull/358) chore: Refine event for sp exit and bucket migration + ## v0.2.3-alpha.5 This release adds 6 new features and 2 bugfixes. diff --git a/Makefile b/Makefile index 26d07f742..55c929621 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,11 @@ proto-gen: cd proto && buf generate && cp -r github.com/bnb-chain/greenfield/x/* ../x && cp -r github.com/bnb-chain/greenfield/types/* ../types && rm -rf github.com && go mod tidy proto-swagger-gen: - sh ./scripts/protoc-swagger-gen.sh + bash ./scripts/protoc-swagger-gen.sh + +proto-swagger-check: + bash ./scripts/protoc-swagger-gen.sh + git diff --exit-code proto-format: buf format -w diff --git a/app/app.go b/app/app.go index 412727fbf..13d7e146d 100644 --- a/app/app.go +++ b/app/app.go @@ -376,7 +376,7 @@ func New( appCodec, keys[crosschaintypes.StoreKey], authtypes.FeeCollectorName, - authtypes.NewModuleAddress(oracletypes.ModuleName).String(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.CrossChainKeeper, app.BankKeeper, app.StakingKeeper, @@ -468,7 +468,7 @@ func New( appCodec, keys[virtualgroupmoduletypes.StoreKey], tKeys[virtualgroupmoduletypes.TStoreKey], - authtypes.NewModuleAddress(virtualgroupmoduletypes.ModuleName).String(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.SpKeeper, app.AccountKeeper, app.BankKeeper, diff --git a/app/reconciliation.go b/app/reconciliation.go index cfc9334fd..f6f2d34a2 100644 --- a/app/reconciliation.go +++ b/app/reconciliation.go @@ -3,13 +3,15 @@ package app import ( "bytes" "encoding/binary" + "encoding/json" "fmt" "cosmossdk.io/math" - paymenttypes "github.com/bnb-chain/greenfield/x/payment/types" "github.com/cosmos/cosmos-sdk/store/iavl" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + paymenttypes "github.com/bnb-chain/greenfield/x/payment/types" ) const reconStoreKey = "reconciliation" @@ -124,6 +126,9 @@ func (app *App) reconPaymentChanges(ctx sdk.Context, paymentIavl *iavl.Store) bo ctx.Logger().Error("fail to unmarshal stream record", "err", err.Error()) } else { flowCurrent = flowCurrent.Add(sr.NetflowRate) + //TODO: impact performance, remove it later + j, _ := json.Marshal(sr) + ctx.Logger().Debug("stream_record_current", "stream record", j, "addr", parseAddressFromStreamRecordKey(kBz)) } } @@ -139,6 +144,9 @@ func (app *App) reconPaymentChanges(ctx sdk.Context, paymentIavl *iavl.Store) bo ctx.Logger().Error("fail to unmarshal stream record", "err", err.Error()) } else { flowPre = flowPre.Add(sr.NetflowRate) + //TODO: impact performance, remove it later + j, _ := json.Marshal(sr) + ctx.Logger().Debug("stream_record_previous", "stream record", j, "addr", parseAddressFromStreamRecordKey(kBz)) } } } @@ -196,3 +204,8 @@ func parseAmountFromValue(value []byte) math.Int { } return amount } + +func parseAddressFromStreamRecordKey(key []byte) string { + start := len(StreamRecordKeyPrefix) + return sdk.AccAddress(key[start:]).String() +} diff --git a/deployment/localup/localup.sh b/deployment/localup/localup.sh index 4c314d632..72fcbacaf 100644 --- a/deployment/localup/localup.sh +++ b/deployment/localup/localup.sh @@ -150,10 +150,10 @@ function generate_genesis() { sed -i -e "s/\"heartbeat_interval\": \"1000\"/\"heartbeat_interval\": \"100\"/g" ${workspace}/.local/validator${i}/config/genesis.json sed -i -e "s/\"attestation_inturn_interval\": \"120\"/\"attestation_inturn_interval\": \"10\"/g" ${workspace}/.local/validator${i}/config/genesis.json sed -i -e "s/\"discontinue_confirm_period\": \"604800\"/\"discontinue_confirm_period\": \"5\"/g" ${workspace}/.local/validator${i}/config/genesis.json - sed -i -e "s/\"discontinue_deletion_max\": \"10000\"/\"discontinue_deletion_max\": \"1\"/g" ${workspace}/.local/validator${i}/config/genesis.json - sed -i -e "s/\"voting_period\": \"30s\"/\"voting_period\": \"10s\"/g" ${workspace}/.local/validator${i}/config/genesis.json + sed -i -e "s/\"discontinue_deletion_max\": \"10000\"/\"discontinue_deletion_max\": \"2\"/g" ${workspace}/.local/validator${i}/config/genesis.json + sed -i -e "s/\"voting_period\": \"30s\"/\"voting_period\": \"5s\"/g" ${workspace}/.local/validator${i}/config/genesis.json #sed -i -e "s/\"community_tax\": \"0.020000000000000000\"/\"community_tax\": \"0\"/g" ${workspace}/.local/validator${i}/config/genesis.json - #sed -i -e "s/log_level = \"info\"/\log_level= \"debug\"/g" ${workspace}/.local/validator${i}/config/config.toml + sed -i -e "s/log_level = \"info\"/\log_level= \"debug\"/g" ${workspace}/.local/validator${i}/config/config.toml done # enable swagger API for validator0 diff --git a/e2e/client.toml b/e2e/client.toml index d03954e57..b7690fb0f 100644 --- a/e2e/client.toml +++ b/e2e/client.toml @@ -13,5 +13,5 @@ keyring-backend = "test" output = "text" # : to Tendermint RPC interface for this chain node = "tcp://127.0.0.1:26750" -# Transaction broadcasting mode (sync|async|block) -broadcast-mode = "block" +# Transaction broadcasting mode (sync|async) +broadcast-mode = "sync" diff --git a/e2e/core/basesuite.go b/e2e/core/basesuite.go index 86a57cccf..3214fb6be 100644 --- a/e2e/core/basesuite.go +++ b/e2e/core/basesuite.go @@ -14,6 +14,7 @@ import ( sdkmath "cosmossdk.io/math" "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" @@ -51,7 +52,7 @@ type BaseSuite struct { ValidatorBLS keys.KeyManager Relayer keys.KeyManager Challenger keys.KeyManager - StorageProviders []StorageProvider + StorageProviders map[uint32]*StorageProvider } func (s *BaseSuite) SetupSuite() { @@ -69,7 +70,7 @@ func (s *BaseSuite) SetupSuite() { s.Challenger, err = keys.NewMnemonicKeyManager(s.Config.ChallengerMnemonic) s.Require().NoError(err) - var spIDs []uint32 + s.StorageProviders = make(map[uint32]*StorageProvider, 7) for i, spMnemonics := range s.Config.SPMnemonics { sp := StorageProvider{} sp.OperatorKey, err = keys.NewMnemonicKeyManager(spMnemonics.OperatorMnemonic) @@ -91,46 +92,50 @@ func (s *BaseSuite) SetupSuite() { s.Require().NoError(err) sp.Info = resp.StorageProvider sp.GlobalVirtualGroupFamilies = make(map[uint32][]*virtualgroupmoduletypes.GlobalVirtualGroup) - s.StorageProviders = append(s.StorageProviders, sp) - - spIDs = append(spIDs, sp.Info.Id) + s.StorageProviders[sp.Info.Id] = &sp } - for i, sp := range s.StorageProviders { - var gvgFamilies []*virtualgroupmoduletypes.GlobalVirtualGroupFamily - resp1, err1 := s.Client.GlobalVirtualGroupFamilies(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamiliesRequest{StorageProviderId: sp.Info.Id}) - s.Require().NoError(err1) - if len(resp1.GlobalVirtualGroupFamilies) == 0 { + s.RefreshGVGFamilies() + for _, sp := range s.StorageProviders { + if len(sp.GlobalVirtualGroupFamilies) == 0 { // Create a GVG for each sp by default deposit := sdk.Coin{ Denom: s.Config.Denom, Amount: types.NewIntFromInt64WithDecimal(1, types.DecimalBNB), } - secondaryIds := append(spIDs[:i], spIDs[i+1:]...) + var secondaryIDs []uint32 + for _, ssp := range s.StorageProviders { + if ssp.Info.Id != sp.Info.Id { + secondaryIDs = append(secondaryIDs, ssp.Info.Id) + } + } msgCreateGVG := &virtualgroupmoduletypes.MsgCreateGlobalVirtualGroup{ StorageProvider: sp.OperatorKey.GetAddr().String(), - SecondarySpIds: secondaryIds, + SecondarySpIds: secondaryIDs, Deposit: deposit, } s.SendTxBlock(sp.OperatorKey, msgCreateGVG) - resp2, err2 := s.Client.GlobalVirtualGroupFamilies(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamiliesRequest{StorageProviderId: sp.Info.Id}) - s.Require().NoError(err2) - - gvgFamilies = resp2.GlobalVirtualGroupFamilies - } else { - gvgFamilies = resp1.GlobalVirtualGroupFamilies - } + } + s.RefreshGVGFamilies() +} - for _, family := range gvgFamilies { - gvgsResp, err3 := s.Client.GlobalVirtualGroupByFamilyID(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupByFamilyIDRequest{ - StorageProviderId: sp.Info.Id, - GlobalVirtualGroupFamilyId: family.Id, - }) - s.Require().NoError(err3) - sp.GlobalVirtualGroupFamilies[family.Id] = gvgsResp.GlobalVirtualGroups - s.StorageProviders[i] = sp +func (s *BaseSuite) RefreshGVGFamilies() { + resp1, err1 := s.Client.GlobalVirtualGroupFamilies(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamiliesRequest{Pagination: &query.PageRequest{Limit: math.MaxUint64}}) + s.Require().NoError(err1) + for _, gvgFamily := range resp1.GvgFamilies { + sp, ok := s.StorageProviders[gvgFamily.PrimarySpId] + if !ok { + continue } + + gvgsResp, err3 := s.Client.GlobalVirtualGroupByFamilyID(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupByFamilyIDRequest{ + StorageProviderId: sp.Info.Id, + GlobalVirtualGroupFamilyId: gvgFamily.Id, + }) + s.Require().NoError(err3) + sp.GlobalVirtualGroupFamilies[gvgFamily.Id] = gvgsResp.GlobalVirtualGroups + s.StorageProviders[gvgFamily.PrimarySpId] = sp } } @@ -150,7 +155,7 @@ func (s *BaseSuite) SendTxBlock(from keys.KeyManager, msg ...sdk.Msg) *sdk.TxRes }) s.Require().NoError(err) - s.T().Logf("block_height: %d, tx_hash: 0x%s", getTxRes.TxResponse.Height, response.TxResponse.TxHash) + s.T().Logf("block_height: %d, tx_hash: 0x%s, GasUsed: %v", getTxRes.TxResponse.Height, response.TxResponse.TxHash, response.TxResponse.GasUsed) return getTxRes.TxResponse } @@ -182,6 +187,11 @@ func (s *BaseSuite) SendTxBlockWithoutCheck(msg sdk.Msg, from keys.KeyManager) ( return s.Client.BroadcastTx(context.Background(), []sdk.Msg{msg}, txOpt) } +func (s *BaseSuite) SendTxBlockWithoutCheckWithTxOpt(msg sdk.Msg, from keys.KeyManager, txOpt *types.TxOption) (*tx.BroadcastTxResponse, error) { + s.Client.SetKeyManager(from) + return s.Client.BroadcastTx(context.Background(), []sdk.Msg{msg}, txOpt) +} + func (s *BaseSuite) SendTxBlockWithExpectErrorString(msg sdk.Msg, from keys.KeyManager, expectErrorString string) { mode := tx.BroadcastMode_BROADCAST_MODE_SYNC txOpt := &types.TxOption{ @@ -190,7 +200,7 @@ func (s *BaseSuite) SendTxBlockWithExpectErrorString(msg sdk.Msg, from keys.KeyM } s.Client.SetKeyManager(from) _, err := s.Client.BroadcastTx(context.Background(), []sdk.Msg{msg}, txOpt) - s.T().Logf("tx failed, err: %s, expect error string: %s", err, expectErrorString) + s.T().Logf("tx failed, err: %v, expect error string: %s", err, expectErrorString) s.Require().Error(err) s.Require().True(strings.Contains(err.Error(), expectErrorString)) } @@ -342,8 +352,8 @@ func (s *BaseSuite) LatestHeight() (int64, error) { func (sp *StorageProvider) GetFirstGlobalVirtualGroup() (*virtualgroupmoduletypes.GlobalVirtualGroup, bool) { for _, family := range sp.GlobalVirtualGroupFamilies { - if len(family) != 0 { - return family[0], true + for _, gvg := range family { + return gvg, true } } return nil, false @@ -547,16 +557,16 @@ func (s *BaseSuite) CreateObject(user keys.KeyManager, primarySP *StorageProvide secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) - if s.StorageProviders[i].Info.Id != primarySP.Info.Id { - ssp := s.StorageProviders[i] - secondarySps = append(secondarySps, &ssp) + if s.StorageProviders[spID].Info.Id != primarySP.Info.Id { + ssp := s.StorageProviders[spID] + secondarySps = append(secondarySps, ssp) } } aggBlsSig, err := BlsAggregateAndVerify(secondarySPBlsPubKeys, blsSignHash, secondarySigs) @@ -624,3 +634,33 @@ func (s *BaseSuite) CreateGlobalVirtualGroup(sp *StorageProvider, familyID uint3 func (s *BaseSuite) GetChainID() string { return s.Config.ChainId } + +func (s *BaseSuite) PickStorageProvider() *StorageProvider { + for _, sp := range s.StorageProviders { + return sp + } + return nil +} + +func (s *BaseSuite) PickDifferentStorageProvider(spId uint32) *StorageProvider { + for _, sp := range s.StorageProviders { + if sp.Info.Id != spId { + return sp + } + } + return nil +} + +func (s *BaseSuite) PickStorageProviderByBucketName(bucketName string) *StorageProvider { + queryHeadBucketResponse, err := s.Client.HeadBucket(context.Background(), &storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + }) + s.Require().NoError(err) + + family, err := s.Client.GlobalVirtualGroupFamily(context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, + }) + s.Require().NoError(err) + + return s.StorageProviders[family.GlobalVirtualGroupFamily.PrimarySpId] +} diff --git a/e2e/core/utils.go b/e2e/core/utils.go index 2042c8d44..33d1b898a 100644 --- a/e2e/core/utils.go +++ b/e2e/core/utils.go @@ -50,7 +50,7 @@ func RandInt64(min, max int64) int64 { return min + rand.Int63n(max-min) } -func BlsSignAndVerify(sp StorageProvider, signBz [32]byte) ([]byte, error) { +func BlsSignAndVerify(sp *StorageProvider, signBz [32]byte) ([]byte, error) { secondarySig, err := sp.BlsKey.Sign(signBz[:]) if err != nil { return nil, err diff --git a/e2e/tests/bridge_test.go b/e2e/tests/bridge_test.go index 4d0d457c3..4d6df2237 100644 --- a/e2e/tests/bridge_test.go +++ b/e2e/tests/bridge_test.go @@ -2,15 +2,26 @@ package tests import ( "context" + "reflect" + "strconv" "testing" + "time" sdkmath "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + crosschaintypes "github.com/cosmos/cosmos-sdk/x/crosschain/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" _ "github.com/ghodss/yaml" "github.com/stretchr/testify/suite" "github.com/bnb-chain/greenfield/e2e/core" + gnfdtypes "github.com/bnb-chain/greenfield/sdk/types" types2 "github.com/bnb-chain/greenfield/sdk/types" bridgetypes "github.com/bnb-chain/greenfield/x/bridge/types" ) @@ -68,6 +79,239 @@ func (s *BridgeTestSuite) TestTransferOut() { s.Require().Equal(moduleBalanceBefore.Balance.Amount.Add(transferAmount).Add(totalTransferOutRelayerFee).String(), moduleBalanceAfter.Balance.Amount.String()) } +func (s *BridgeTestSuite) TestGovChannel() { + var err error + validator := s.Validator.GetAddr() + + ctx := context.Background() + + msgUpdatePermissions := &crosschaintypes.MsgUpdateChannelPermissions{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ChannelPermissions: []*crosschaintypes.ChannelPermission{ + { + DestChainId: 714, + ChannelId: uint32(bridgetypes.TransferOutChannelID), + Permission: uint32(sdk.ChannelForbidden), + }, + }, + } + + msgProposal, err := govtypesv1.NewMsgSubmitProposal( + []sdk.Msg{msgUpdatePermissions}, + sdk.Coins{sdk.NewCoin(s.BaseSuite.Config.Denom, types2.NewIntFromInt64WithDecimal(100, types2.DecimalBNB))}, + validator.String(), + "test", "test", "test", + ) + s.Require().NoError(err) + + txRes := s.SendTxBlock(s.Validator, msgProposal) + s.Require().Equal(txRes.Code, uint32(0)) + + // 3. query proposal and get proposal ID + var proposalId uint64 + for _, event := range txRes.Logs[0].Events { + if event.Type == "submit_proposal" { + for _, attr := range event.Attributes { + if attr.Key == "proposal_id" { + proposalId, err = strconv.ParseUint(attr.Value, 10, 0) + s.Require().NoError(err) + break + } + } + break + } + } + s.Require().True(proposalId != 0) + + queryProposal := &govtypesv1.QueryProposalRequest{ProposalId: proposalId} + _, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + + // 4. submit MsgVote and wait the proposal exec + msgVote := govtypesv1.NewMsgVote(validator, proposalId, govtypesv1.OptionYes, "test") + txRes = s.SendTxBlock(s.Validator, msgVote) + s.Require().Equal(txRes.Code, uint32(0)) + + queryVoteParamsReq := govtypesv1.QueryParamsRequest{ParamsType: "voting"} + queryVoteParamsResp, err := s.Client.GovQueryClientV1.Params(ctx, &queryVoteParamsReq) + s.Require().NoError(err) + + // 5. wait a voting period and confirm that the proposal success. + s.T().Logf("voting period %s", *queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(*queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(1 * time.Second) + proposalRes, err := s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + s.Require().Equal(proposalRes.Proposal.Status, govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED) + + users := s.GenAndChargeAccounts(2, 1000000) + + from, to := users[0], users[1] + + // transfer out token + transferAmount := sdkmath.NewInt(10000) + msgTransferOut := &bridgetypes.MsgTransferOut{ + From: from.GetAddr().String(), + To: to.GetAddr().String(), + Amount: &types.Coin{Denom: types2.Denom, Amount: transferAmount}, + } + + s.Require().NoError(err) + + s.SendTxBlockWithExpectErrorString(msgTransferOut, from, "not allowed to write syn package") + + msgUpdatePermissions = &crosschaintypes.MsgUpdateChannelPermissions{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ChannelPermissions: []*crosschaintypes.ChannelPermission{ + { + DestChainId: 714, + ChannelId: uint32(bridgetypes.TransferOutChannelID), + Permission: uint32(sdk.ChannelAllow), + }, + }, + } + + msgProposal, err = govtypesv1.NewMsgSubmitProposal( + []sdk.Msg{msgUpdatePermissions}, + sdk.Coins{sdk.NewCoin(s.BaseSuite.Config.Denom, types2.NewIntFromInt64WithDecimal(100, types2.DecimalBNB))}, + validator.String(), + "test", "test", "test", + ) + s.Require().NoError(err) + + txRes = s.SendTxBlock(s.Validator, msgProposal) + s.Require().Equal(txRes.Code, uint32(0)) + + // 3. query proposal and get proposal ID + for _, event := range txRes.Logs[0].Events { + if event.Type == "submit_proposal" { + for _, attr := range event.Attributes { + if attr.Key == "proposal_id" { + proposalId, err = strconv.ParseUint(attr.Value, 10, 0) + s.Require().NoError(err) + break + } + } + break + } + } + s.Require().True(proposalId != 0) + + queryProposal = &govtypesv1.QueryProposalRequest{ProposalId: proposalId} + _, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + + // 4. submit MsgVote and wait the proposal exec + msgVote = govtypesv1.NewMsgVote(validator, proposalId, govtypesv1.OptionYes, "test") + txRes = s.SendTxBlock(s.Validator, msgVote) + s.Require().Equal(txRes.Code, uint32(0)) + + queryVoteParamsReq = govtypesv1.QueryParamsRequest{ParamsType: "voting"} + queryVoteParamsResp, err = s.Client.GovQueryClientV1.Params(ctx, &queryVoteParamsReq) + s.Require().NoError(err) + + // 5. wait a voting period and confirm that the proposal success. + s.T().Logf("voting period %s", *queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(*queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(1 * time.Second) + proposalRes, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + s.Require().Equal(proposalRes.Proposal.Status, govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED) +} + +func (s *BridgeTestSuite) TestUpdateBridgeParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.BridgeQueryClient.Params(context.Background(), &bridgetypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.BscTransferOutRelayerFee = sdkmath.NewInt(250000000000000) + msgUpdateParams := &bridgetypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update Bridge params", "Test update Bridge params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &gnfdtypes.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.BridgeQueryClient.Params(context.Background(), &bridgetypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} + func TestBridgeTestSuite(t *testing.T) { suite.Run(t, new(BridgeTestSuite)) } diff --git a/e2e/tests/challenge_test.go b/e2e/tests/challenge_test.go index b42a91619..795bf04b6 100644 --- a/e2e/tests/challenge_test.go +++ b/e2e/tests/challenge_test.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "math" + "reflect" "strconv" "strings" "testing" @@ -15,10 +16,15 @@ import ( "github.com/bits-and-blooms/bitset" ctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/suite" "github.com/bnb-chain/greenfield/e2e/core" + "github.com/bnb-chain/greenfield/sdk/types" storagetestutil "github.com/bnb-chain/greenfield/testutil/storage" challengetypes "github.com/bnb-chain/greenfield/x/challenge/types" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" @@ -39,11 +45,14 @@ func TestChallengeTestSuite(t *testing.T) { suite.Run(t, new(ChallengeTestSuite)) } -func (s *ChallengeTestSuite) createObject() (string, string, sdk.AccAddress) { +func (s *ChallengeTestSuite) createObject() (string, string, *core.StorageProvider) { var err error - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) + + s.T().Log(sp.Info.String()) + s.T().Log(gvg.String()) // CreateBucket user := s.GenAndChargeAccounts(1, 1000000)[0] bucketName := "ch" + storagetestutil.GenRandomBucketName() @@ -54,7 +63,6 @@ func (s *ChallengeTestSuite) createObject() (string, string, sdk.AccAddress) { msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) s.Require().NoError(err) s.SendTxBlock(user, msgCreateBucket) - // HeadBucket ctx := context.Background() queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ @@ -109,11 +117,11 @@ func (s *ChallengeTestSuite) createObject() (string, string, sdk.AccAddress) { secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, gvgID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[gvgID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[gvgID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -128,22 +136,23 @@ func (s *ChallengeTestSuite) createObject() (string, string, sdk.AccAddress) { s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName) s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) - return bucketName, objectName, sp.OperatorKey.GetAddr() + return bucketName, objectName, sp } func (s *ChallengeTestSuite) TestSubmit() { user := s.GenAndChargeAccounts(1, 1000000)[0] bucketName, objectName, primarySp := s.createObject() - msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp, bucketName, objectName, true, 1000) + msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp.OperatorKey.GetAddr(), bucketName, objectName, true, 1000) txRes := s.SendTxBlock(user, msgSubmit) event := filterChallengeEventFromTx(txRes) // secondary sps are faked with primary sp, redundancy check is meaningless here s.Require().GreaterOrEqual(event.ChallengeId, uint64(0)) s.Require().NotEqual(event.SegmentIndex, uint32(100)) - s.Require().Equal(event.SpOperatorAddress, primarySp.String()) + s.Require().Equal(event.SpOperatorAddress, primarySp.OperatorKey.GetAddr().String()) bucketName, objectName, _ = s.createObject() - msgSubmit = challengetypes.NewMsgSubmit(user.GetAddr(), s.StorageProviders[0].OperatorKey.GetAddr(), bucketName, objectName, false, 0) + + msgSubmit = challengetypes.NewMsgSubmit(user.GetAddr(), primarySp.OperatorKey.GetAddr(), bucketName, objectName, false, 0) txRes = s.SendTxBlock(user, msgSubmit) event = filterChallengeEventFromTx(txRes) s.Require().GreaterOrEqual(event.ChallengeId, uint64(0)) @@ -173,7 +182,7 @@ func (s *ChallengeTestSuite) TestNormalAttest() { user := s.GenAndChargeAccounts(1, 1000000)[0] bucketName, objectName, primarySp := s.createObject() - msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp, bucketName, objectName, true, 1000) + msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp.OperatorKey.GetAddr(), bucketName, objectName, true, 1000) txRes := s.SendTxBlock(user, msgSubmit) event := filterChallengeEventFromTx(txRes) @@ -183,7 +192,7 @@ func (s *ChallengeTestSuite) TestNormalAttest() { valBitset := s.calculateValidatorBitSet(height, s.ValidatorBLS.PubKey().String()) - msgAttest := challengetypes.NewMsgAttest(s.Challenger.GetAddr(), event.ChallengeId, event.ObjectId, primarySp.String(), + msgAttest := challengetypes.NewMsgAttest(s.Challenger.GetAddr(), event.ChallengeId, event.ObjectId, primarySp.OperatorKey.GetAddr().String(), challengetypes.CHALLENGE_SUCCEED, user.GetAddr().String(), valBitset.Bytes(), nil) toSign := msgAttest.GetBlsSignBytes(s.Config.ChainId) @@ -310,7 +319,7 @@ func (s *ChallengeTestSuite) TestFailedAttest_ChallengeExpired() { user := s.GenAndChargeAccounts(1, 1000000)[0] bucketName, objectName, primarySp := s.createObject() - msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp, bucketName, objectName, true, 1000) + msgSubmit := challengetypes.NewMsgSubmit(user.GetAddr(), primarySp.OperatorKey.GetAddr(), bucketName, objectName, true, 1000) txRes := s.SendTxBlock(user, msgSubmit) event := filterChallengeEventFromTx(txRes) @@ -334,7 +343,7 @@ func (s *ChallengeTestSuite) TestFailedAttest_ChallengeExpired() { height := statusRes.SyncInfo.LatestBlockHeight valBitset := s.calculateValidatorBitSet(height, s.ValidatorBLS.PubKey().String()) - msgAttest := challengetypes.NewMsgAttest(user.GetAddr(), event.ChallengeId, event.ObjectId, primarySp.String(), + msgAttest := challengetypes.NewMsgAttest(user.GetAddr(), event.ChallengeId, event.ObjectId, primarySp.OperatorKey.GetAddr().String(), challengetypes.CHALLENGE_SUCCEED, user.GetAddr().String(), valBitset.Bytes(), nil) toSign := msgAttest.GetBlsSignBytes(s.Config.ChainId) @@ -433,3 +442,96 @@ func filterChallengeEventFromTx(txRes *sdk.TxResponse) challengetypes.EventStart ExpiredHeight: uint64(expiredHeight), } } + +func (s *ChallengeTestSuite) TestUpdateChallengerParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.ChallengeQueryClient.Params(context.Background(), &challengetypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.HeartbeatInterval = 1800 + msgUpdateParams := &challengetypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update Challenger params", "Test update Challenger params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.ChallengeQueryClient.Params(context.Background(), &challengetypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} diff --git a/e2e/tests/eip712_test.go b/e2e/tests/eip712_test.go index 739d712c4..f561c3e27 100644 --- a/e2e/tests/eip712_test.go +++ b/e2e/tests/eip712_test.go @@ -29,7 +29,7 @@ func TestEip712TestSuite(t *testing.T) { func (s *Eip712TestSuite) TestMultiMessages() { var err error - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] diff --git a/e2e/tests/gashub_test.go b/e2e/tests/gashub_test.go index 0b9027dce..3ac8b9320 100644 --- a/e2e/tests/gashub_test.go +++ b/e2e/tests/gashub_test.go @@ -2,16 +2,20 @@ package tests import ( "context" + "reflect" "strconv" "testing" "time" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" gashubtypes "github.com/cosmos/cosmos-sdk/x/gashub/types" gov "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/stretchr/testify/suite" "github.com/bnb-chain/greenfield/e2e/core" @@ -96,6 +100,99 @@ func (s *GashubTestSuite) TestUpdateParams() { } } +func (s *GashubTestSuite) TestUpdateGasHubParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.GashubQueryClient.Params(context.Background(), &gashubtypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.MaxTxSize = 65535 + msgUpdateParams := &gashubtypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update GasHub params", "Test update GasHub params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.GashubQueryClient.Params(context.Background(), &gashubtypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} + func TestGashubTestSuite(t *testing.T) { suite.Run(t, new(GashubTestSuite)) } diff --git a/e2e/tests/gensp_test.go b/e2e/tests/gensp_test.go index 84737473c..0f257857e 100644 --- a/e2e/tests/gensp_test.go +++ b/e2e/tests/gensp_test.go @@ -22,7 +22,7 @@ func (s *GenStorageProviderTestSuite) SetupSuite() { func (s *GenStorageProviderTestSuite) TestGenStorageProvider() { ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() querySPReq := sptypes.QueryStorageProviderByOperatorAddressRequest{ OperatorAddress: sp.OperatorKey.GetAddr().String(), @@ -38,12 +38,12 @@ func (s *GenStorageProviderTestSuite) TestGenStorageProvider() { GcAddress: sp.GcKey.GetAddr().String(), BlsKey: sp.BlsKey.PubKey().Bytes(), Description: sptypes.Description{ - Moniker: "sp0", - Identity: "", - Details: "detail_sp0", - Website: "http://website", + Moniker: sp.Info.Description.Moniker, + Identity: sp.Info.Description.Identity, + Details: sp.Info.Description.Details, + Website: sp.Info.Description.Website, }, - Endpoint: "http://127.0.0.1:9033", + Endpoint: sp.Info.Endpoint, TotalDeposit: querySPResp.StorageProvider.TotalDeposit, } diff --git a/e2e/tests/payment_test.go b/e2e/tests/payment_test.go index a01607503..9d6e9fd61 100644 --- a/e2e/tests/payment_test.go +++ b/e2e/tests/payment_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "math" + "reflect" "sort" "strconv" "testing" @@ -17,6 +18,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/samber/lo" "github.com/stretchr/testify/suite" @@ -29,7 +31,7 @@ import ( paymenttypes "github.com/bnb-chain/greenfield/x/payment/types" sptypes "github.com/bnb-chain/greenfield/x/sp/types" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" - virtualgroupmoduletypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" + virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" ) type StreamRecords struct { @@ -41,15 +43,20 @@ type StreamRecords struct { type PaymentTestSuite struct { core.BaseSuite + defaultParams paymenttypes.Params } func (s *PaymentTestSuite) SetupSuite() { s.BaseSuite.SetupSuite() + s.defaultParams = s.queryParams() + } -func (s *PaymentTestSuite) SetupTest() {} +func (s *PaymentTestSuite) SetupTest() { + s.RefreshGVGFamilies() +} -func (s *PaymentTestSuite) TestPaymentAccount() { +func (s *PaymentTestSuite) TestCreatePaymentAccount() { user := s.GenAndChargeAccounts(1, 100)[0] ctx := context.Background() // create a new payment account @@ -88,269 +95,30 @@ func (s *PaymentTestSuite) TestPaymentAccount() { s.Require().Equal(false, paymentAccount.PaymentAccount.Refundable) } -func (s *PaymentTestSuite) updateParams(params paymenttypes.Params) { - var err error - validator := s.Validator.GetAddr() - - ctx := context.Background() - - ts := time.Now().Unix() - queryParamsRequest := &paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, queryParamsRequest) - s.Require().NoError(err) - - msgUpdateParams := &paymenttypes.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), - Params: params, - } - - msgProposal, err := govtypesv1.NewMsgSubmitProposal( - []sdk.Msg{msgUpdateParams}, - sdk.Coins{sdk.NewCoin(s.BaseSuite.Config.Denom, types.NewIntFromInt64WithDecimal(100, types.DecimalBNB))}, - validator.String(), - "test", "test", "test", - ) - s.Require().NoError(err) - - txRes := s.SendTxBlock(s.Validator, msgProposal) - s.Require().Equal(txRes.Code, uint32(0)) - - // 3. query proposal and get proposal ID - var proposalId uint64 - for _, event := range txRes.Logs[0].Events { - if event.Type == "submit_proposal" { - for _, attr := range event.Attributes { - if attr.Key == "proposal_id" { - proposalId, err = strconv.ParseUint(attr.Value, 10, 0) - s.Require().NoError(err) - break - } - } - break - } - } - s.Require().True(proposalId != 0) - - queryProposal := &govtypesv1.QueryProposalRequest{ProposalId: proposalId} - _, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) - s.Require().NoError(err) - - // 4. submit MsgVote and wait the proposal exec - msgVote := govtypesv1.NewMsgVote(validator, proposalId, govtypesv1.OptionYes, "test") - txRes = s.SendTxBlock(s.Validator, msgVote) - s.Require().Equal(txRes.Code, uint32(0)) - - queryVoteParamsReq := govtypesv1.QueryParamsRequest{ParamsType: "voting"} - queryVoteParamsResp, err := s.Client.GovQueryClientV1.Params(ctx, &queryVoteParamsReq) - s.Require().NoError(err) - - // 5. wait a voting period and confirm that the proposal success. - s.T().Logf("voting period %s", *queryVoteParamsResp.Params.VotingPeriod) - time.Sleep(*queryVoteParamsResp.Params.VotingPeriod) - time.Sleep(1 * time.Second) - proposalRes, err := s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) - s.Require().NoError(err) - s.Require().Equal(proposalRes.Proposal.Status, govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED) - - queryParamsByTimestampRequest := &paymenttypes.QueryParamsByTimestampRequest{Timestamp: ts} - queryParamsByTimestampResponse, err := s.Client.PaymentQueryClient.ParamsByTimestamp(ctx, queryParamsByTimestampRequest) - s.Require().NoError(err) - s.Require().Equal(queryParamsResponse.Params.VersionedParams.ReserveTime, - queryParamsByTimestampResponse.Params.VersionedParams.ReserveTime) - s.T().Logf("new params: %s", params.String()) -} - -func (s *PaymentTestSuite) createBucketAndObject() (keys.KeyManager, string, string, storagetypes.Uint, [][]byte) { - var err error - sp := s.StorageProviders[0] - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - - // CreateBucket - user := s.GenAndChargeAccounts(1, 1000000)[0] - bucketName := "ch" + storagetestutils.GenRandomBucketName() - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PRIVATE, sp.OperatorKey.GetAddr(), - nil, math.MaxUint, nil, 0) - msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId - msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) - s.Require().NoError(err) - s.SendTxBlock(user, msgCreateBucket) - - // CreateObject - objectName := storagetestutils.GenRandomObjectName() - // create test buffer - var buffer bytes.Buffer - line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,123` - // Create 1MiB content where each line contains 1024 characters. - for i := 0; i < 1024; i++ { - buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line)) - } - payloadSize := buffer.Len() - checksum := sdk.Keccak256(buffer.Bytes()) - expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum} - contextType := "text/event-stream" - msgCreateObject := storagetypes.NewMsgCreateObject(user.GetAddr(), bucketName, objectName, uint64(payloadSize), - storagetypes.VISIBILITY_TYPE_PRIVATE, expectChecksum, contextType, - storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil) - msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes()) - s.Require().NoError(err) - s.SendTxBlock(user, msgCreateObject) - - // HeadObject - queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ - BucketName: bucketName, - ObjectName: objectName, - } - queryHeadObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) - s.Require().NoError(err) - s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectName, objectName) - s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName) - - return user, bucketName, objectName, queryHeadObjectResponse.ObjectInfo.Id, expectChecksum -} - -func (s *PaymentTestSuite) createBucket() (keys.KeyManager, string) { - var err error - sp := s.StorageProviders[0] - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - - // CreateBucket - user := s.GenAndChargeAccounts(1, 1000000)[0] - bucketName := "ch" + storagetestutils.GenRandomBucketName() - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PRIVATE, sp.OperatorKey.GetAddr(), - nil, math.MaxUint, nil, 0) - msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId - msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) - s.Require().NoError(err) - s.SendTxBlock(user, msgCreateBucket) - - return user, bucketName -} - -func (s *PaymentTestSuite) createObject(user keys.KeyManager, bucketName string) (keys.KeyManager, string, string, storagetypes.Uint, [][]byte) { - var err error - sp := s.StorageProviders[0] - - // CreateObject - objectName := storagetestutils.GenRandomObjectName() - // create test buffer - var buffer bytes.Buffer - line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, - 1234567890,1234567890,1234567890,123` - // Create 1MiB content where each line contains 1024 characters. - for i := 0; i < 1024; i++ { - buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line)) - } - payloadSize := buffer.Len() - checksum := sdk.Keccak256(buffer.Bytes()) - expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum} - contextType := "text/event-stream" - msgCreateObject := storagetypes.NewMsgCreateObject(user.GetAddr(), bucketName, objectName, uint64(payloadSize), - storagetypes.VISIBILITY_TYPE_PRIVATE, expectChecksum, contextType, - storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil) - msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes()) - s.Require().NoError(err) - s.SendTxBlock(user, msgCreateObject) - - // HeadObject - queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ - BucketName: bucketName, - ObjectName: objectName, - } - queryHeadObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) - s.Require().NoError(err) - s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectName, objectName) - s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName) - - return user, bucketName, objectName, queryHeadObjectResponse.ObjectInfo.Id, expectChecksum -} - -func (s *PaymentTestSuite) sealObject(bucketName, objectName string, objectId storagetypes.Uint, checksums [][]byte) { - sp := s.StorageProviders[0] - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - s.T().Log("GVG info: ", gvg.String()) - - // SealObject - gvgId := gvg.Id - msgSealObject := storagetypes.NewMsgSealObject(sp.SealKey.GetAddr(), bucketName, objectName, gvg.Id, nil) - secondarySigs := make([][]byte, 0) - secondarySPBlsPubKeys := make([]bls.PublicKey, 0) - blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, objectId, storagetypes.GenerateHash(checksums[:])).GetBlsSignHash() - // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) - s.Require().NoError(err) - secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) - s.Require().NoError(err) - secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) - } - aggBlsSig, err := core.BlsAggregateAndVerify(secondarySPBlsPubKeys, blsSignHash, secondarySigs) - s.Require().NoError(err) - msgSealObject.SecondarySpBlsAggSignatures = aggBlsSig - s.T().Logf("msg %s", msgSealObject.String()) - s.SendTxBlock(sp.SealKey, msgSealObject) - - queryHeadObjectRequest2 := storagetypes.QueryHeadObjectRequest{ - BucketName: bucketName, - ObjectName: objectName, - } - queryHeadObjectResponse2, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest2) - s.Require().NoError(err) - s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.ObjectName, objectName) - s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.BucketName, bucketName) - s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) -} - // TestVersionedParams_SealAfterReserveTimeChange will cover the following case: // create an object, increase the reserve time, seal the object without error. func (s *PaymentTestSuite) TestVersionedParams_SealObjectAfterReserveTimeChange() { + defer s.revertParams() + ctx := context.Background() - queryParamsRequest := paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) // create bucket, create object - user, bucketName, objectName, objectId, checksums := s.createBucketAndObject() + user, bucketName, objectName, objectId, checksums := s.createBucketAndObject(sp) // update params - params := queryParamsResponse.GetParams() + params := s.queryParams() oldReserveTime := params.VersionedParams.ReserveTime oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate - s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", oldReserveTime, oldValidatorTaxRate) params.VersionedParams.ReserveTime = oldReserveTime * 2 params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) - s.updateParams(params) - queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params = queryParamsResponse.GetParams() - s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", params.VersionedParams.ReserveTime, params.VersionedParams.ValidatorTaxRate) // seal object - s.sealObject(bucketName, objectName, objectId, checksums) + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ BucketName: bucketName, @@ -367,21 +135,18 @@ func (s *PaymentTestSuite) TestVersionedParams_SealObjectAfterReserveTimeChange( // delete bucket msgDeleteBucket := storagetypes.NewMsgDeleteBucket(user.GetAddr(), bucketName) s.SendTxBlock(user, msgDeleteBucket) - - // revert params - params.VersionedParams.ReserveTime = oldReserveTime - params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate - s.updateParams(params) } // TestVersionedParams_DeleteAfterValidatorTaxRateChange will cover the following case: // create a bucket with non-zero read quota, change the validator tax rate, delete the bucket. // The rate of the validator tax address should be correct. func (s *PaymentTestSuite) TestVersionedParams_DeleteBucketAfterValidatorTaxRateChange() { + defer s.revertParams() + ctx := context.Background() - queryParamsRequest := paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) validatorTaxPoolRate := sdk.ZeroInt() queryStreamRequest := paymenttypes.QueryGetStreamRecordRequest{Account: paymenttypes.ValidatorTaxPoolAddress.String()} @@ -395,25 +160,22 @@ func (s *PaymentTestSuite) TestVersionedParams_DeleteBucketAfterValidatorTaxRate s.T().Logf("netflow, validatorTaxPoolRate: %s", validatorTaxPoolRate) // create bucket, create object - user, bucketName, objectName, objectId, checksums := s.createBucketAndObject() + user, bucketName, objectName, objectId, checksums := s.createBucketAndObject(sp) // seal object - s.sealObject(bucketName, objectName, objectId, checksums) + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) // update params - params := queryParamsResponse.GetParams() + params := s.queryParams() oldReserveTime := params.VersionedParams.ReserveTime + oldForceSettleTime := params.ForcedSettleTime oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", oldReserveTime, oldValidatorTaxRate) params.VersionedParams.ReserveTime = oldReserveTime / 2 + params.ForcedSettleTime = oldForceSettleTime / 2 params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) - s.updateParams(params) - queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params = queryParamsResponse.GetParams() - s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", params.VersionedParams.ReserveTime, params.VersionedParams.ValidatorTaxRate) // delete object msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName) @@ -426,26 +188,23 @@ func (s *PaymentTestSuite) TestVersionedParams_DeleteBucketAfterValidatorTaxRate queryStreamResponse, err = s.Client.PaymentQueryClient.StreamRecord(ctx, &queryStreamRequest) s.Require().NoError(err) s.Require().Equal(validatorTaxPoolRate, queryStreamResponse.StreamRecord.NetflowRate) - - // revert params - params.VersionedParams.ReserveTime = oldReserveTime - params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate - s.updateParams(params) } // TestVersionedParams_DeleteObjectAfterReserveTimeChange will cover the following case: // create an object, change the reserve time, the object can be force deleted even the object's own has no enough balance. func (s *PaymentTestSuite) TestVersionedParams_DeleteObjectAfterReserveTimeChange() { + defer s.revertParams() + ctx := context.Background() - queryParamsRequest := paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) // create bucket, create object - user, bucketName, objectName, objectId, checksums := s.createBucketAndObject() + user, bucketName, objectName, objectId, checksums := s.createBucketAndObject(sp) // seal object - s.sealObject(bucketName, objectName, objectId, checksums) + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) // for payment time.Sleep(2 * time.Second) @@ -472,19 +231,13 @@ func (s *PaymentTestSuite) TestVersionedParams_DeleteObjectAfterReserveTimeChang s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) // update params - params := queryParamsResponse.GetParams() + params := s.queryParams() oldReserveTime := params.VersionedParams.ReserveTime oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate - s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", oldReserveTime, oldValidatorTaxRate) params.VersionedParams.ReserveTime = oldReserveTime * 2 params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) - s.updateParams(params) - queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params = queryParamsResponse.GetParams() - s.T().Logf("params, ReserveTime: %d, ValidatorTaxRate: %s", params.VersionedParams.ReserveTime, params.VersionedParams.ValidatorTaxRate) queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ BucketName: bucketName, @@ -494,8 +247,6 @@ func (s *PaymentTestSuite) TestVersionedParams_DeleteObjectAfterReserveTimeChang s.Require().NoError(err) s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) - sp := s.StorageProviders[0] - // force delete bucket msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) @@ -516,26 +267,19 @@ func (s *PaymentTestSuite) TestVersionedParams_DeleteObjectAfterReserveTimeChang _, err = s.Client.HeadObject(ctx, &queryHeadObjectRequest) s.Require().ErrorContains(err, "No such object") - - // revert params - params.VersionedParams.ReserveTime = oldReserveTime - params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate - s.updateParams(params) } -func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { +func (s *PaymentTestSuite) TestDeposit_ActiveAccount() { ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] userAddr := user.GetAddr().String() var err error - params, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) - s.T().Logf("params %s, err: %v", params, err) - s.Require().NoError(err) - reserveTime := params.Params.VersionedParams.ReserveTime + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ SpAddr: sp.OperatorKey.GetAddr().String(), }) @@ -545,7 +289,93 @@ func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { bucketChargedReadQuota := uint64(1000) readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice totalUserRate := readPrice.MulInt(sdkmath.NewIntFromUint64(bucketChargedReadQuota)).TruncateInt() - taxRateParam := params.Params.VersionedParams.ValidatorTaxRate + taxRateParam := params.VersionedParams.ValidatorTaxRate + taxStreamRate := taxRateParam.MulInt(totalUserRate).TruncateInt() + expectedRate := totalUserRate.Add(taxStreamRate) + paymentAccountBNBNeeded := expectedRate.Mul(sdkmath.NewIntFromUint64(reserveTime)) + s.T().Log("paymentAccountBNBNeeded", paymentAccountBNBNeeded.String()) + + // create payment account and deposit + msgCreatePaymentAccount := &paymenttypes.MsgCreatePaymentAccount{ + Creator: userAddr, + } + _ = s.SendTxBlock(user, msgCreatePaymentAccount) + paymentAccountsReq := &paymenttypes.QueryGetPaymentAccountsByOwnerRequest{Owner: userAddr} + paymentAccounts, err := s.Client.PaymentQueryClient.GetPaymentAccountsByOwner(ctx, paymentAccountsReq) + s.Require().NoError(err) + s.T().Logf("paymentAccounts %s", core.YamlString(paymentAccounts)) + paymentAddr := paymentAccounts.PaymentAccounts[0] + s.Require().Lenf(paymentAccounts.PaymentAccounts, 1, "paymentAccounts %s", core.YamlString(paymentAccounts)) + + // deposit BNB needed + msgDeposit := &paymenttypes.MsgDeposit{ + Creator: user.GetAddr().String(), + To: paymentAddr, + Amount: paymentAccountBNBNeeded.MulRaw(2), // deposit more than needed + } + _ = s.SendTxBlock(user, msgDeposit) + + // create bucket + bucketName := storagetestutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + sdk.MustAccAddressFromHex(paymentAddr), math.MaxUint, nil, bucketChargedReadQuota) + msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId + msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateBucket) + + // check payment account stream record + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) + s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) + s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) + s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) + s.Require().Equal(paymentAccountStreamRecord.StaticBalance.String(), paymentAccountBNBNeeded.String()) + + time.Sleep(5 * time.Second) + + // deposit + msgDeposit = &paymenttypes.MsgDeposit{ + Creator: userAddr, + To: paymentAddr, + Amount: paymentAccountBNBNeeded, + } + _ = s.SendTxBlock(user, msgDeposit) + + // check payment account stream record + paymentAccountStreamRecordAfter := s.getStreamRecord(paymentAddr) + s.T().Logf("paymentAccountStreamRecordAfter %s", core.YamlString(paymentAccountStreamRecordAfter)) + s.Require().Equal(paymentAccountStreamRecordAfter.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) + + settledTime := paymentAccountStreamRecordAfter.CrudTimestamp - paymentAccountStreamRecord.CrudTimestamp + settledBalance := expectedRate.MulRaw(settledTime) + paymentBalanceChange := paymentAccountStreamRecordAfter.StaticBalance.Sub(paymentAccountStreamRecord.StaticBalance). + Add(paymentAccountStreamRecordAfter.BufferBalance.Sub(paymentAccountStreamRecord.BufferBalance)) + s.Require().Equal(settledBalance.Add(paymentBalanceChange).Int64(), paymentAccountBNBNeeded.Int64()) + s.Require().Equal(paymentAccountBNBNeeded.MulRaw(3), settledBalance.Add(paymentAccountStreamRecordAfter.StaticBalance.Add(paymentAccountStreamRecordAfter.BufferBalance))) +} + +func (s *PaymentTestSuite) TestDeposit_ResumeInOneBlock() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.GenAndChargeAccounts(1, 1000000)[0] + userAddr := user.GetAddr().String() + var err error + + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + bucketChargedReadQuota := uint64(1000) + readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + totalUserRate := readPrice.MulInt(sdkmath.NewIntFromUint64(bucketChargedReadQuota)).TruncateInt() + taxRateParam := params.VersionedParams.ValidatorTaxRate taxStreamRate := taxRateParam.MulInt(totalUserRate).TruncateInt() expectedRate := totalUserRate.Add(taxStreamRate) paymentAccountBNBNeeded := expectedRate.Mul(sdkmath.NewIntFromUint64(reserveTime)) @@ -581,7 +411,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { s.SendTxBlock(user, msgCreateBucket) // check payment account stream record - paymentAccountStreamRecord := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) @@ -604,7 +434,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { } } // check auto settle - paymentStreamRecordAfterAutoSettle := s.GetStreamRecord(paymentAddr) + paymentStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) s.T().Logf("paymentStreamRecordAfterAutoSettle %s", core.YamlString(paymentStreamRecordAfterAutoSettle)) s.Require().NotEqual(paymentStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) @@ -618,7 +448,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { _ = s.SendTxBlock(user, msgDeposit1) // check payment account stream record - paymentAccountStreamRecordAfterDeposit1 := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit1 := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit1 %s", core.YamlString(paymentAccountStreamRecordAfterDeposit1)) s.Require().NotEqual(paymentAccountStreamRecordAfterDeposit1.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) @@ -631,30 +461,22 @@ func (s *PaymentTestSuite) TestDepositAndResume_InOneBlock() { } s.SendTxBlock(user, msgDeposit2) // check payment account stream record - paymentAccountStreamRecordAfterDeposit2 := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit2 := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit2 %s", core.YamlString(paymentAccountStreamRecordAfterDeposit2)) s.Require().Equal(paymentAccountStreamRecordAfterDeposit2.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) s.Require().Equal(paymentAccountStreamRecordAfterDeposit2.StaticBalance.Add(paymentAccountStreamRecordAfterDeposit2.BufferBalance).String(), paymentAccountStreamRecordAfterDeposit1.StaticBalance.Add(depositAmount2).String()) } -func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { +func (s *PaymentTestSuite) TestDeposit_ResumeInBlocks() { + defer s.revertParams() + ctx := context.Background() // update params - queryParamsRequest := paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params := queryParamsResponse.GetParams() - oldMaxAutoResumeFlowCount := params.MaxAutoResumeFlowCount - s.T().Logf("params, MaxAutoResumeFlowCount: %d", oldMaxAutoResumeFlowCount) - + params := s.queryParams() params.MaxAutoResumeFlowCount = 1 // update to 1 s.updateParams(params) - queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params = queryParamsResponse.GetParams() - s.T().Logf("params: %s", params.String()) - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -706,7 +528,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { s.SendTxBlock(user, msgCreateBucket) // check payment account stream record - paymentAccountStreamRecord := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) @@ -729,7 +551,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { } } // check auto settle - paymentStreamRecordAfterAutoSettle := s.GetStreamRecord(paymentAddr) + paymentStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) s.T().Logf("paymentStreamRecordAfterAutoSettle %s", core.YamlString(paymentStreamRecordAfterAutoSettle)) s.Require().NotEqual(paymentStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) @@ -748,7 +570,7 @@ func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { s.SendTxWithTxOpt(msgDeposit, user, txOpt) // check payment account stream record - paymentAccountStreamRecordAfterDeposit := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit %s", core.YamlString(paymentAccountStreamRecordAfterDeposit)) s.Require().NotEqual(paymentAccountStreamRecordAfterDeposit.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) @@ -757,8 +579,18 @@ func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { latestBlock, err := s.TmClient.TmClient.Block(ctx, nil) s.Require().NoError(err) - paymentAccountStreamRecordAfterDeposit = s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit = s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit %s at %d", core.YamlString(paymentAccountStreamRecordAfterDeposit), latestBlock.Block.Height) + if paymentAccountStreamRecordAfterDeposit.Status == paymenttypes.STREAM_ACCOUNT_STATUS_FROZEN && + !paymentAccountStreamRecordAfterDeposit.NetflowRate.IsZero() { + s.T().Log("trying to deposit, which will error") + msgDeposit = &paymenttypes.MsgDeposit{ + Creator: user.GetAddr().String(), + To: paymentAddr, + Amount: paymentAccountBNBNeeded, + } + s.SendTxBlockWithExpectErrorString(msgDeposit, user, "resuming") + } if paymentAccountStreamRecordAfterDeposit.Status == paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE { break } @@ -768,34 +600,26 @@ func (s *PaymentTestSuite) TestDepositAndResume_InBlocks() { s.T().Fatalf("wait for resume time timeout") } } - - // revert params - params.MaxAutoResumeFlowCount = oldMaxAutoResumeFlowCount - s.updateParams(params) } func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] userAddr := user.GetAddr().String() var err error - queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamilyRequest{ - StorageProviderId: sp.Info.Id, - FamilyId: gvg.FamilyId, + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, }) s.Require().NoError(err) family := queryFamilyResponse.GlobalVirtualGroupFamily bucketChargedReadQuota := uint64(1000) - paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) - s.T().Logf("paymentParams %s, err: %v", paymentParams, err) - s.Require().NoError(err) - reserveTime := paymentParams.Params.VersionedParams.ReserveTime - forcedSettleTime := paymentParams.Params.ForcedSettleTime + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ SpAddr: sp.OperatorKey.GetAddr().String(), }) @@ -803,7 +627,7 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { s.Require().NoError(err) readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice totalUserRate := readPrice.MulInt(sdkmath.NewIntFromUint64(bucketChargedReadQuota)).TruncateInt() - taxRateParam := paymentParams.Params.VersionedParams.ValidatorTaxRate + taxRateParam := params.VersionedParams.ValidatorTaxRate taxStreamRate := taxRateParam.MulInt(totalUserRate).TruncateInt() expectedRate := totalUserRate.Add(taxStreamRate) paymentAccountBNBNeeded := expectedRate.Mul(sdkmath.NewIntFromUint64(reserveTime)) @@ -836,11 +660,13 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { s.Require().NoError(err) s.SendTxBlock(user, msgCreateBucket) // check payment account stream record - paymentAccountStreamRecord := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) s.Require().Equal(paymentAccountStreamRecord.StaticBalance.String(), sdkmath.ZeroInt().String()) + govStreamRecord := s.getStreamRecord(paymenttypes.GovernanceAddress.String()) + s.T().Logf("govStreamRecord %s", core.YamlString(govStreamRecord)) // increase bucket charged read quota is not allowed since the balance is not enough msgUpdateBucketInfo := &storagetypes.MsgUpdateBucketInfo{ @@ -849,25 +675,7 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { ChargedReadQuota: &common.UInt64Value{Value: bucketChargedReadQuota + 1}, Visibility: storagetypes.VISIBILITY_TYPE_PUBLIC_READ, } - _, err = s.SendTxBlockWithoutCheck(msgUpdateBucketInfo, user) - s.Require().ErrorContains(err, "balance not enough, lack of") - - // create bucket from user - msgCreateBucket.BucketName = storagetestutils.GenRandomBucketName() - msgCreateBucket.PaymentAddress = "" - msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId - msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) - s.Require().NoError(err) - s.SendTxBlock(user, msgCreateBucket) - - // check user stream record - userStreamRecord := s.GetStreamRecord(userAddr) - s.T().Logf("userStreamRecord %s", core.YamlString(userStreamRecord)) - s.Require().Equal(userStreamRecord.SettleTimestamp, userStreamRecord.CrudTimestamp+int64(reserveTime-forcedSettleTime)) - familyStreamRecord := s.GetStreamRecord(family.VirtualPaymentAddress) - s.T().Logf("familyStreamRecord %s", core.YamlString(familyStreamRecord)) - govStreamRecord := s.GetStreamRecord(paymenttypes.GovernanceAddress.String()) - s.T().Logf("govStreamRecord %s", core.YamlString(govStreamRecord)) + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "balance not enough, lack of") // wait until settle time retryCount := 0 @@ -875,8 +683,8 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { latestBlock, err := s.TmClient.TmClient.Block(ctx, nil) s.Require().NoError(err) currentTimestamp := latestBlock.Block.Time.Unix() - s.T().Logf("currentTimestamp %d, userStreamRecord.SettleTimestamp %d", currentTimestamp, userStreamRecord.SettleTimestamp) - if currentTimestamp > userStreamRecord.SettleTimestamp { + s.T().Logf("currentTimestamp %d, userStreamRecord.SettleTimestamp %d", currentTimestamp, paymentAccountStreamRecord.SettleTimestamp) + if currentTimestamp > paymentAccountStreamRecord.SettleTimestamp { break } time.Sleep(time.Second) @@ -886,26 +694,23 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { } } // check auto settle - userStreamRecordAfterAutoSettle := s.GetStreamRecord(userAddr) + userStreamRecordAfterAutoSettle := s.getStreamRecord(userAddr) s.T().Logf("userStreamRecordAfterAutoSettle %s", core.YamlString(userStreamRecordAfterAutoSettle)) - familyStreamRecordAfterAutoSettle := s.GetStreamRecord(family.VirtualPaymentAddress) + familyStreamRecordAfterAutoSettle := s.getStreamRecord(family.VirtualPaymentAddress) s.T().Logf("familyStreamRecordAfterAutoSettle %s", core.YamlString(familyStreamRecordAfterAutoSettle)) - paymentAccountStreamRecordAfterAutoSettle := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterAutoSettle %s", core.YamlString(paymentAccountStreamRecordAfterAutoSettle)) // payment account become frozen s.Require().NotEqual(paymentAccountStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) s.Require().Equal(familyStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) s.Require().Equal(userStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) - // user settle time become refreshed - s.Require().NotEqual(userStreamRecordAfterAutoSettle.SettleTimestamp, userStreamRecord.SettleTimestamp) - s.Require().Equal(userStreamRecordAfterAutoSettle.SettleTimestamp, userStreamRecordAfterAutoSettle.CrudTimestamp+int64(reserveTime-forcedSettleTime)) - // gov stream record balance increase - govStreamRecordAfterSettle := s.GetStreamRecord(paymenttypes.GovernanceAddress.String()) + + govStreamRecordAfterSettle := s.getStreamRecord(paymenttypes.GovernanceAddress.String()) s.T().Logf("govStreamRecordAfterSettle %s", core.YamlString(govStreamRecordAfterSettle)) s.Require().NotEqual(govStreamRecordAfterSettle.StaticBalance.String(), govStreamRecord.StaticBalance.String()) govStreamRecordStaticBalanceDelta := govStreamRecordAfterSettle.StaticBalance.Sub(govStreamRecord.StaticBalance) - expectedGovBalanceDelta := userStreamRecord.NetflowRate.Neg().MulRaw(userStreamRecordAfterAutoSettle.CrudTimestamp - userStreamRecord.CrudTimestamp) - s.Require().Equal(expectedGovBalanceDelta.String(), govStreamRecordStaticBalanceDelta.String()) + expectedGovBalanceDelta := paymentAccountStreamRecord.NetflowRate.Neg().MulRaw(paymentAccountStreamRecordAfterAutoSettle.CrudTimestamp - paymentAccountStreamRecord.CrudTimestamp) + s.Require().True(govStreamRecordStaticBalanceDelta.Int64() >= expectedGovBalanceDelta.Int64()) // deposit, balance not enough to resume depositAmount1 := sdk.NewInt(1) @@ -916,7 +721,7 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { } _ = s.SendTxBlock(user, msgDeposit1) // check payment account stream record - paymentAccountStreamRecordAfterDeposit1 := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit1 := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit1 %s", core.YamlString(paymentAccountStreamRecordAfterDeposit1)) s.Require().NotEqual(paymentAccountStreamRecordAfterDeposit1.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) s.Require().Equal(paymentAccountStreamRecordAfterDeposit1.StaticBalance.String(), paymentAccountStreamRecordAfterAutoSettle.StaticBalance.Add(depositAmount1).String()) @@ -930,30 +735,22 @@ func (s *PaymentTestSuite) TestAutoSettle_InOneBlock() { } s.SendTxBlock(user, msgDeposit2) // check payment account stream record - paymentAccountStreamRecordAfterDeposit2 := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecordAfterDeposit2 := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecordAfterDeposit2 %s", core.YamlString(paymentAccountStreamRecordAfterDeposit2)) s.Require().Equal(paymentAccountStreamRecordAfterDeposit2.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) s.Require().Equal(paymentAccountStreamRecordAfterDeposit2.StaticBalance.Add(paymentAccountStreamRecordAfterDeposit2.BufferBalance).String(), paymentAccountStreamRecordAfterDeposit1.StaticBalance.Add(depositAmount2).String()) } func (s *PaymentTestSuite) TestAutoSettle_InBlocks() { + defer s.revertParams() + ctx := context.Background() // update params - queryParamsRequest := paymenttypes.QueryParamsRequest{} - queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params := queryParamsResponse.GetParams() - oldMaxAutoSettleFlowCount := params.MaxAutoSettleFlowCount - s.T().Logf("params, MaxAutoSettleFlowCount: %d", oldMaxAutoSettleFlowCount) - + params := s.queryParams() params.MaxAutoSettleFlowCount = 2 // update to 2 s.updateParams(params) - queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, &queryParamsRequest) - s.Require().NoError(err) - params = queryParamsResponse.GetParams() - s.T().Logf("params: %s", params.String()) - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -1005,7 +802,7 @@ func (s *PaymentTestSuite) TestAutoSettle_InBlocks() { s.SendTxBlock(user, msgCreateBucket) // check payment account stream record - paymentAccountStreamRecord := s.GetStreamRecord(paymentAddr) + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) @@ -1029,7 +826,7 @@ func (s *PaymentTestSuite) TestAutoSettle_InBlocks() { } // check auto settle for { - paymentStreamRecordAfterAutoSettle := s.GetStreamRecord(paymentAddr) + paymentStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) s.T().Logf("paymentStreamRecordAfterAutoSettle %s", core.YamlString(paymentStreamRecordAfterAutoSettle)) if paymentStreamRecordAfterAutoSettle.NetflowRate.IsZero() { break @@ -1040,24 +837,103 @@ func (s *PaymentTestSuite) TestAutoSettle_InBlocks() { s.T().Fatalf("wait for settle time timeout") } } - paymentStreamRecordAfterAutoSettle := s.GetStreamRecord(paymentAddr) + paymentStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) s.T().Logf("paymentStreamRecordAfterAutoSettle %s", core.YamlString(paymentStreamRecordAfterAutoSettle)) s.Require().NotEqual(paymentStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) +} - // revert params - params.MaxAutoSettleFlowCount = oldMaxAutoSettleFlowCount - s.updateParams(params) +func (s *PaymentTestSuite) TestWithdraw() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.GenAndChargeAccounts(1, 1000000)[0] + userAddr := user.GetAddr().String() + var err error + + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + bucketChargedReadQuota := uint64(100000) + readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + totalUserRate := readPrice.MulInt(sdkmath.NewIntFromUint64(bucketChargedReadQuota)).TruncateInt() + taxRateParam := params.VersionedParams.ValidatorTaxRate + taxStreamRate := taxRateParam.MulInt(totalUserRate).TruncateInt() + expectedRate := totalUserRate.Add(taxStreamRate) + paymentAccountBNBNeeded := expectedRate.Mul(sdkmath.NewIntFromUint64(reserveTime)) + s.T().Log("paymentAccountBNBNeeded", paymentAccountBNBNeeded.String()) + + // create payment account and deposit + msgCreatePaymentAccount := &paymenttypes.MsgCreatePaymentAccount{ + Creator: userAddr, + } + _ = s.SendTxBlock(user, msgCreatePaymentAccount) + paymentAccountsReq := &paymenttypes.QueryGetPaymentAccountsByOwnerRequest{Owner: userAddr} + paymentAccounts, err := s.Client.PaymentQueryClient.GetPaymentAccountsByOwner(ctx, paymentAccountsReq) + s.Require().NoError(err) + s.T().Logf("paymentAccounts %s", core.YamlString(paymentAccounts)) + paymentAddr := paymentAccounts.PaymentAccounts[0] + s.Require().Lenf(paymentAccounts.PaymentAccounts, 1, "paymentAccounts %s", core.YamlString(paymentAccounts)) + + // deposit BNB needed + msgDeposit := &paymenttypes.MsgDeposit{ + Creator: user.GetAddr().String(), + To: paymentAddr, + Amount: paymentAccountBNBNeeded.MulRaw(2), // deposit more than needed + } + _ = s.SendTxBlock(user, msgDeposit) + + // create bucket + bucketName := storagetestutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + sdk.MustAccAddressFromHex(paymentAddr), math.MaxUint, nil, bucketChargedReadQuota) + msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId + msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateBucket) + + // check payment account stream record + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) + s.T().Logf("paymentAccountStreamRecord %s", core.YamlString(paymentAccountStreamRecord)) + s.Require().Equal(expectedRate.String(), paymentAccountStreamRecord.NetflowRate.Neg().String()) + s.Require().Equal(paymentAccountStreamRecord.BufferBalance.String(), paymentAccountBNBNeeded.String()) + s.Require().Equal(paymentAccountStreamRecord.StaticBalance.String(), paymentAccountBNBNeeded.String()) + + time.Sleep(5 * time.Second) + + dynamicBalanceResp, err := s.Client.DynamicBalance(ctx, &paymenttypes.QueryDynamicBalanceRequest{Account: user.GetAddr().String()}) + s.Require().NoError(err) + s.Require().True(dynamicBalanceResp.DynamicBalance.LT(paymentAccountBNBNeeded)) + + // withdraw more than static balance + withdrawMsg := paymenttypes.NewMsgWithdraw(userAddr, paymentAddr, paymentAccountBNBNeeded) + s.SendTxBlockWithExpectErrorString(withdrawMsg, user, "not enough") + + // withdraw less than static balance + amount := sdk.NewInt(1000) + withdrawMsg = paymenttypes.NewMsgWithdraw(userAddr, paymentAddr, amount) + s.SendTxBlock(user, withdrawMsg) + paymentAccountStreamRecordAfter := s.getStreamRecord(paymentAddr) + s.T().Logf("paymentAccountStreamRecordAfter %s", core.YamlString(paymentAccountStreamRecordAfter)) + + staticBalanceChange := paymentAccountStreamRecord.NetflowRate.MulRaw(paymentAccountStreamRecordAfter.CrudTimestamp - paymentAccountStreamRecord.CrudTimestamp).Neg() + s.Require().Equal(paymentAccountStreamRecord.StaticBalance.Sub(paymentAccountStreamRecordAfter.StaticBalance).Int64(), amount.Add(staticBalanceChange).Int64()) } -func (s *PaymentTestSuite) TestDeleteBucketWithReadQuota() { +func (s *PaymentTestSuite) TestStorageBill_DeleteBucket_WithReadQuota() { var err error ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) - queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamilyRequest{ - StorageProviderId: sp.Info.Id, - FamilyId: gvg.FamilyId, + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, }) s.Require().NoError(err) family := queryFamilyResponse.GlobalVirtualGroupFamily @@ -1081,7 +957,7 @@ func (s *PaymentTestSuite) TestDeleteBucketWithReadQuota() { s.Require().NoError(err) s.SendTxBlock(user, msgCreateBucket) - streamRecordsBeforeDelete := s.GetStreamRecords(streamAddresses) + streamRecordsBeforeDelete := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsBeforeDelete: %s", core.YamlString(streamRecordsBeforeDelete)) s.Require().NotEqual(streamRecordsBeforeDelete.User.NetflowRate.String(), "0") @@ -1090,20 +966,19 @@ func (s *PaymentTestSuite) TestDeleteBucketWithReadQuota() { s.SendTxBlock(user, msgDeleteBucket) // check the billing change - streamRecordsAfterDelete := s.GetStreamRecords(streamAddresses) + streamRecordsAfterDelete := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsBeforeDelete: %s", core.YamlString(streamRecordsAfterDelete)) s.Require().Equal(streamRecordsAfterDelete.User.NetflowRate.String(), "0") } -func (s *PaymentTestSuite) TestStorageSmoke() { +func (s *PaymentTestSuite) TestStorageBill_Smoke() { var err error ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) - queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamilyRequest{ - StorageProviderId: sp.Info.Id, - FamilyId: gvg.FamilyId, + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, }) s.Require().NoError(err) family := queryFamilyResponse.GlobalVirtualGroupFamily @@ -1115,12 +990,10 @@ func (s *PaymentTestSuite) TestStorageSmoke() { gvg.VirtualPaymentAddress, paymenttypes.ValidatorTaxPoolAddress.String(), } - streamRecordsBeforeCreateBucket := s.GetStreamRecords(streamAddresses) + streamRecordsBeforeCreateBucket := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsBeforeCreateBucket: %s", core.YamlString(streamRecordsBeforeCreateBucket)) - paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) - s.T().Logf("paymentParams %s, err: %v", paymentParams, err) - s.Require().NoError(err) + params := s.queryParams() // create bucket bucketName := storagetestutils.GenRandomBucketName() @@ -1142,7 +1015,7 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.Require().NoError(err) s.T().Logf("user bank account %s", userBankAccount) - streamRecordsAfterCreateBucket := s.GetStreamRecords(streamAddresses) + streamRecordsAfterCreateBucket := s.getStreamRecords(streamAddresses) userStreamRecord := streamRecordsAfterCreateBucket.User s.Require().Equal(userStreamRecord.StaticBalance, sdkmath.ZeroInt()) @@ -1163,7 +1036,7 @@ func (s *PaymentTestSuite) TestStorageSmoke() { readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(queryHeadBucketResponse.BucketInfo.ChargedReadQuota)).TruncateInt() s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) - userTaxRate := paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTaxRate := params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() userTotalRate := readChargeRate.Add(userTaxRate) s.Require().Equal(userStreamRecord.NetflowRate.Abs(), userTotalRate) expectedOutFlows := []paymenttypes.OutFlow{ @@ -1229,11 +1102,12 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.Require().NoError(err) primaryStorePrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice secondaryStorePrice := queryGetSecondarySpStorePriceByTime.SecondarySpStorePrice.StorePrice - chargeSize := s.GetChargeSize(queryHeadObjectResponse.ObjectInfo.PayloadSize) + chargeSize := s.getChargeSize(queryHeadObjectResponse.ObjectInfo.PayloadSize) expectedChargeRate := primaryStorePrice.Add(secondaryStorePrice.MulInt64(6)).MulInt(sdk.NewIntFromUint64(chargeSize)).TruncateInt() - expectedLockedBalance := expectedChargeRate.Mul(sdkmath.NewIntFromUint64(paymentParams.Params.VersionedParams.ReserveTime)) + expectedChargeRate = params.VersionedParams.ValidatorTaxRate.MulInt(expectedChargeRate).TruncateInt().Add(expectedChargeRate) + expectedLockedBalance := expectedChargeRate.Mul(sdkmath.NewIntFromUint64(params.VersionedParams.ReserveTime)) - streamRecordsAfterCreateObject := s.GetStreamRecords(streamAddresses) + streamRecordsAfterCreateObject := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsAfterCreateObject %s", core.YamlString(streamRecordsAfterCreateObject)) userStreamAccountAfterCreateObj := streamRecordsAfterCreateObject.User @@ -1246,11 +1120,11 @@ func (s *PaymentTestSuite) TestStorageSmoke() { secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(expectChecksum[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -1261,10 +1135,10 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.SendTxBlock(sp.SealKey, msgSealObject) // check bill after seal - streamRecordsAfterSeal := s.GetStreamRecords(streamAddresses) + streamRecordsAfterSeal := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsAfterSeal %s", core.YamlString(streamRecordsAfterSeal)) s.Require().Equal(sdkmath.ZeroInt(), streamRecordsAfterSeal.User.LockBalance) - s.CheckStreamRecordsBeforeAndAfter(streamRecordsAfterCreateObject, streamRecordsAfterSeal, readPrice, readChargeRate, primaryStorePrice, secondaryStorePrice, chargeSize, uint64(payloadSize)) + s.checkStreamRecordsBeforeAndAfter(streamRecordsAfterCreateObject, streamRecordsAfterSeal, readPrice, readChargeRate, primaryStorePrice, secondaryStorePrice, chargeSize, uint64(payloadSize)) // query dynamic balance time.Sleep(3 * time.Second) @@ -1276,7 +1150,7 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.T().Logf("queryDynamicBalanceResponse %s", core.YamlString(queryDynamicBalanceResponse)) // create empty object - streamRecordsBeforeCreateEmptyObject := s.GetStreamRecords(streamAddresses) + streamRecordsBeforeCreateEmptyObject := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsBeforeCreateEmptyObject %s", core.YamlString(streamRecordsBeforeCreateEmptyObject)) emptyObjectName := "sub_directory/" @@ -1290,10 +1164,10 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.Require().NoError(err) s.SendTxBlock(user, msgCreateEmptyObject) - streamRecordsAfterCreateEmptyObject := s.GetStreamRecords(streamAddresses) + streamRecordsAfterCreateEmptyObject := s.getStreamRecords(streamAddresses) s.T().Logf("streamRecordsAfterCreateEmptyObject %s", core.YamlString(streamRecordsAfterCreateEmptyObject)) - chargeSize = s.GetChargeSize(uint64(emptyPayloadSize)) - s.CheckStreamRecordsBeforeAndAfter(streamRecordsBeforeCreateEmptyObject, streamRecordsAfterCreateEmptyObject, readPrice, readChargeRate, primaryStorePrice, secondaryStorePrice, chargeSize, uint64(emptyPayloadSize)) + chargeSize = s.getChargeSize(uint64(emptyPayloadSize)) + s.checkStreamRecordsBeforeAndAfter(streamRecordsBeforeCreateEmptyObject, streamRecordsAfterCreateEmptyObject, readPrice, readChargeRate, primaryStorePrice, secondaryStorePrice, chargeSize, uint64(emptyPayloadSize)) // test query auto settle records queryAllAutoSettleRecordRequest := paymenttypes.QueryAllAutoSettleRecordRequest{} @@ -1308,95 +1182,199 @@ func (s *PaymentTestSuite) TestStorageSmoke() { s.T().Logf("deleteObjectSimRes %v", deleteObjectSimRes.Result) } -// TestForceDeletion_DeleteAfterPriceChange will cover the following case: -// create an object, sp increase the price a lot, the object can be force deleted even the object's own has no enough balance. -func (s *PaymentTestSuite) TestForceDeletion_AfterPriceChange() { +func (s *PaymentTestSuite) TestStorageBill_DeleteObjectBucket_WithoutPriceChange() { + var err error ctx := context.Background() - - // set storage price - sp := s.StorageProviders[0] - priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ - SpAddr: sp.OperatorKey.GetAddr().String(), - Timestamp: 0, + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, }) s.Require().NoError(err) - s.T().Log("price", priceRes.SpStoragePrice) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) // create bucket - user, bucketName := s.createBucket() + bucketName := s.createBucket(sp, user, 256) - // create & seal objects - _, _, objectName1, objectId1, checksums1 := s.createObject(user, bucketName) - s.sealObject(bucketName, objectName1, objectId1, checksums1) + //simulate delete bucket gas + msgDeleteBucket := storagetypes.NewMsgDeleteBucket(user.GetAddr(), bucketName) + simulateResponse := s.SimulateTx(msgDeleteBucket, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) - _, _, objectName2, objectId2, checksums2 := s.createObject(user, bucketName) - s.sealObject(bucketName, objectName2, objectId2, checksums2) + gas := gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))) + s.T().Log("total gas", "gas", gas) - // update new price - msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ - SpAddress: sp.OperatorKey.GetAddr().String(), - ReadPrice: priceRes.SpStoragePrice.ReadPrice, - FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, - StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), - } - s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + // create & seal objects + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) // for payment time.Sleep(2 * time.Second) - queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} - queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) - s.Require().NoError(err) - + //transfer gas msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( - sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + sdk.NewCoin(s.Config.Denom, sdkmath.NewInt(5*types.DecimalGwei)), )) + simulateResponse = s.SimulateTx(msgSend, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) - simulateResponse := s.SimulateTx(msgSend, user) - gasLimit := simulateResponse.GasInfo.GetGasUsed() - gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + //delete object gas + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName1) + simulateResponse = s.SimulateTx(msgDeleteObject, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + // transfer out user's balance + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) s.Require().NoError(err) msgSend.Amount = sdk.NewCoins( - sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gas)), ) s.SendTxBlock(user, msgSend) - queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + _, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) s.Require().NoError(err) - s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) - queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ - BucketName: bucketName, - ObjectName: objectName1, - } - queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.SendTxBlock(user, msgDeleteObject) + s.SendTxBlock(user, msgDeleteBucket) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestStorageBill_DeleteObjectBucket_WithPriceChange() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) s.Require().NoError(err) - s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] - // force delete bucket - msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") - txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) - deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) - for { - time.Sleep(200 * time.Millisecond) - statusRes, err := s.TmClient.TmClient.Status(context.Background()) - s.Require().NoError(err) - blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + // create bucket + bucketName := s.createBucket(sp, user, 256) - s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + //simulate delete bucket gas + msgDeleteBucket := storagetypes.NewMsgDeleteBucket(user.GetAddr(), bucketName) + simulateResponse := s.SimulateTx(msgDeleteBucket, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) - if blockTime > deleteAt { - break - } - } + gas := gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))) + s.T().Log("total gas", "gas", gas) - _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) - s.Require().ErrorContains(err, "No such bucket") + // create & seal objects + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) - // revert price - msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ - SpAddress: sp.OperatorKey.GetAddr().String(), + // for payment + time.Sleep(2 * time.Second) + + //transfer gas + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, sdkmath.NewInt(5*types.DecimalGwei)), + )) + simulateResponse = s.SimulateTx(msgSend, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + //delete object gas + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName1) + simulateResponse = s.SimulateTx(msgDeleteObject, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + // transfer out user's balance + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gas)), + ) + s.SendTxBlock(user, msgSend) + _, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + // sp price changes + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(1000), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + s.SendTxBlock(user, msgDeleteObject) + s.SendTxBlock(user, msgDeleteBucket) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), ReadPrice: priceRes.SpStoragePrice.ReadPrice, FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, StorePrice: priceRes.SpStoragePrice.StorePrice, @@ -1404,68 +1382,2326 @@ func (s *PaymentTestSuite) TestForceDeletion_AfterPriceChange() { s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) } -func (s *PaymentTestSuite) GetStreamRecord(addr string) (sr paymenttypes.StreamRecord) { +func (s *PaymentTestSuite) TestStorageBill_DeleteObjectBucket_WithPriceChangeReserveTimeChange() { + defer s.revertParams() + + var err error ctx := context.Background() - streamRecordResp, err := s.Client.StreamRecord(ctx, &paymenttypes.QueryGetStreamRecordRequest{ - Account: addr, + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, }) - if streamRecordResp != nil { - s.Require().NoError(err) - sr = streamRecordResp.StreamRecord - } else { - s.Require().ErrorContainsf(err, "not found", "account: %s", addr) - sr.StaticBalance = sdk.ZeroInt() - sr.BufferBalance = sdk.ZeroInt() - sr.LockBalance = sdk.ZeroInt() - sr.NetflowRate = sdk.ZeroInt() + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), } - return sr -} + streamRecordsBefore := s.getStreamRecords(streamAddresses) -func (s *PaymentTestSuite) GetStreamRecords(addrs []string) (streamRecords StreamRecords) { - streamRecords.User = s.GetStreamRecord(addrs[0]) - streamRecords.GVGFamily = s.GetStreamRecord(addrs[1]) - streamRecords.GVG = s.GetStreamRecord(addrs[2]) - streamRecords.Tax = s.GetStreamRecord(addrs[3]) - return + // create bucket + bucketName := s.createBucket(sp, user, 256) + + //simulate delete bucket gas + msgDeleteBucket := storagetypes.NewMsgDeleteBucket(user.GetAddr(), bucketName) + simulateResponse := s.SimulateTx(msgDeleteBucket, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas := gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))) + s.T().Log("total gas", "gas", gas) + + // create & seal objects + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + + // for payment + time.Sleep(2 * time.Second) + + //transfer gas + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, sdkmath.NewInt(5*types.DecimalGwei)), + )) + simulateResponse = s.SimulateTx(msgSend, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + //delete object gas + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName1) + simulateResponse = s.SimulateTx(msgDeleteObject, user) + gasLimit = simulateResponse.GasInfo.GetGasUsed() + gasPrice, err = sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + gas = gas.Add(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))) + s.T().Log("total gas", "gas", gas) + + // transfer out user's balance + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gas)), + ) + s.SendTxBlock(user, msgSend) + _, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + // sp price changes + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(1000), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // update params + params := s.queryParams() + oldReserveTime := params.VersionedParams.ReserveTime + oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate + + params.VersionedParams.ReserveTime = oldReserveTime * 2 + params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + s.SendTxBlock(user, msgDeleteObject) + s.SendTxBlock(user, msgDeleteBucket) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) } -func (s *PaymentTestSuite) CheckStreamRecordsBeforeAndAfter(streamRecordsBefore StreamRecords, streamRecordsAfter StreamRecords, readPrice sdk.Dec, - readChargeRate sdkmath.Int, primaryStorePrice sdk.Dec, secondaryStorePrice sdk.Dec, chargeSize uint64, payloadSize uint64) { - userRateDiff := streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate) - gvgFamilyRateDiff := streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate) - gvgRateDiff := streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate) - taxRateDiff := streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate) - s.Require().Equal(userRateDiff, gvgFamilyRateDiff.Add(gvgRateDiff).Add(taxRateDiff).Neg()) +func (s *PaymentTestSuite) TestStorageBill_DeleteObject_WithStoreLessThanReserveTime() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] - outFlowsResponse, err := s.Client.OutFlows(context.Background(), &paymenttypes.QueryOutFlowsRequest{Account: streamRecordsAfter.User.Account}) + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime + + // create bucket + bucketName := s.createBucket(sp, user, 256) + + // create & seal objects + _, _, objectName1, objectId1, checksums1, payloadSize := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + + headObjectRes, err := s.Client.HeadObject(ctx, &storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + }) s.Require().NoError(err) - userOutflowMap := lo.Reduce(outFlowsResponse.OutFlows, func(m map[string]sdkmath.Int, outflow paymenttypes.OutFlow, i int) map[string]sdkmath.Int { - m[outflow.ToAddress] = outflow.Rate - return m - }, make(map[string]sdkmath.Int)) - if payloadSize != 0 { - gvgFamilyRate := primaryStorePrice.MulInt(sdk.NewIntFromUint64(chargeSize)).TruncateInt().Add(readChargeRate) - s.Require().Equal(gvgFamilyRate, userOutflowMap[streamRecordsAfter.GVGFamily.Account]) + s.T().Log("headObjectRes", headObjectRes) - gvgRate := secondaryStorePrice.MulInt(sdk.NewIntFromUint64(chargeSize)).TruncateInt().MulRaw(6) - s.Require().Equal(gvgRate, userOutflowMap[streamRecordsAfter.GVG.Account]) + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, userRateRead := s.calculateReadRates(sp, bucketName) + _, _, _, userRateStore := s.calculateStorageRates(sp, bucketName, objectName1, payloadSize, 0) + + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName1) + s.SendTxBlock(user, msgDeleteObject) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + + settledTime := streamRecordsAfter.User.CrudTimestamp - streamRecordsBefore.User.CrudTimestamp + timeToPay := int64(reserveTime) + headObjectRes.ObjectInfo.CreateAt - streamRecordsAfter.User.CrudTimestamp + balanceDelta := userRateRead.Add(userRateStore).MulRaw(settledTime).Add(userRateStore.MulRaw(timeToPay)) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), userRateStore.Int64()) + userBalanceChange := streamRecordsAfter.User.BufferBalance.Add(streamRecordsAfter.User.StaticBalance). + Sub(streamRecordsBefore.User.BufferBalance.Add(streamRecordsBefore.User.StaticBalance)) + s.Require().Equal(userBalanceChange.Neg().Int64(), balanceDelta.Int64()) + + familyDelta := streamRecordsAfter.GVGFamily.StaticBalance.Sub(streamRecordsBefore.GVGFamily.StaticBalance) + gvgDelta := streamRecordsAfter.GVG.StaticBalance.Sub(streamRecordsBefore.GVG.StaticBalance) + taxPoolDelta := streamRecordsAfter.Tax.StaticBalance.Sub(streamRecordsBefore.Tax.StaticBalance) + s.T().Log("familyDelta", familyDelta, "gvgDelta", gvgDelta, "taxPoolDelta", taxPoolDelta) + s.Require().True(familyDelta.Add(gvgDelta).Add(taxPoolDelta).Int64() >= balanceDelta.Int64()) // could exist other buckets/objects on the gvg & family } -func (s *PaymentTestSuite) GetChargeSize(payloadSize uint64) uint64 { +func (s *PaymentTestSuite) TestStorageBill_DeleteObject_WithStoreMoreThanReserveTime() { + defer s.revertParams() + + var err error ctx := context.Background() - storageParams, err := s.Client.StorageQueryClient.Params(ctx, &storagetypes.QueryParamsRequest{}) + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) s.Require().NoError(err) - s.T().Logf("storageParams %s", storageParams) - minChargeSize := storageParams.Params.VersionedParams.MinChargeSize - if payloadSize < minChargeSize { - return minChargeSize - } else { - return payloadSize + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + params := s.queryParams() + params.VersionedParams.ReserveTime = 5 + params.ForcedSettleTime = 2 + s.updateParams(params) + + // create bucket + bucketName := s.createBucket(sp, user, 256) + + // create & seal objects + _, _, objectName1, objectId1, checksums1, payloadSize := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + + headObjectRes, err := s.Client.HeadObject(ctx, &storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + }) + s.Require().NoError(err) + s.T().Log("headObjectRes", headObjectRes) + + time.Sleep(5 * time.Second) + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + balanceBefore := queryBalanceResponse.Balance.Amount + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, userRateRead := s.calculateReadRates(sp, bucketName) + _, _, _, userRateStore := s.calculateStorageRates(sp, bucketName, objectName1, payloadSize, 0) + + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName1) + simulateResponse := s.SimulateTx(msgDeleteObject, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + gas := gasPrice.Amount.MulRaw(int64(gasLimit)) + + // delete object + s.SendTxBlock(user, msgDeleteObject) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + queryBalanceRequest = banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + balanceAfter := queryBalanceResponse.Balance.Amount + + settledTime := streamRecordsAfter.User.CrudTimestamp - streamRecordsBefore.User.CrudTimestamp + balanceDelta := userRateRead.Add(userRateStore).MulRaw(settledTime) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), userRateStore.Int64()) + userBalanceChange := streamRecordsBefore.User.BufferBalance.Add(streamRecordsBefore.User.StaticBalance). + Sub(streamRecordsAfter.User.BufferBalance.Add(streamRecordsAfter.User.StaticBalance)) + userBalanceChange = userBalanceChange.Add(balanceBefore.Sub(balanceAfter)).Sub(gas) + s.Require().Equal(userBalanceChange.Int64(), balanceDelta.Int64()) + + familyDelta := streamRecordsAfter.GVGFamily.StaticBalance.Sub(streamRecordsBefore.GVGFamily.StaticBalance) + gvgDelta := streamRecordsAfter.GVG.StaticBalance.Sub(streamRecordsBefore.GVG.StaticBalance) + taxPoolDelta := streamRecordsAfter.Tax.StaticBalance.Sub(streamRecordsBefore.Tax.StaticBalance) + s.T().Log("familyDelta", familyDelta, "gvgDelta", gvgDelta, "taxPoolDelta", taxPoolDelta) + s.Require().True(familyDelta.Add(gvgDelta).Add(taxPoolDelta).Int64() >= balanceDelta.Int64()) // could exist other buckets/objects on the gvg & family } -func TestPaymentTestSuite(t *testing.T) { - suite.Run(t, new(PaymentTestSuite)) +func (s *PaymentTestSuite) TestStorageBill_CreateBucket_WithZeroNoneZeroReadQuota() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + params := s.queryParams() + + // case: create bucket with zero read quota + bucketName := s.createBucket(sp, user, 0) + + // bucket created + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, streamRecordsBefore.User.NetflowRate) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate, streamRecordsBefore.GVGFamily.NetflowRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate, streamRecordsBefore.Tax.NetflowRate) + + // case: create bucket with none zero read quota + bucketName = s.createBucket(sp, user, 10240) + + // bucket created + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err := s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + // check price and rate calculation + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: queryHeadBucketResponse.BucketInfo.CreateAt, + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(queryHeadBucketResponse.BucketInfo.ChargedReadQuota)).TruncateInt() + s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTotalRate := readChargeRate.Add(taxRate) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + expectedOutFlows := []paymenttypes.OutFlow{ + {ToAddress: family.VirtualPaymentAddress, Rate: readChargeRate}, + {ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate}, + } + userOutFlowsResponse, err := s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: user.GetAddr().String()}) + s.Require().NoError(err) + sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool { + return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress + }) + sort.Slice(expectedOutFlows, func(i, j int) bool { + return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress + }) + s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) +} + +func (s *PaymentTestSuite) TestStorageBill_CreateObject_WithZeroNoneZeroPayload() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 0) + + // case: create object with zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, _, _, payloadSize := s.createObject(user, bucketName, true) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(sp, bucketName, objectName, payloadSize, 0) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + // case: create object with none zero payload size + streamRecordsBefore = s.getStreamRecords(streamAddresses) + _, _, objectName, _, _, payloadSize = s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestStorageBill_CreateObject_WithReserveTimeValidatorTaxRateChange() { + defer s.revertParams() + + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 0) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, _, _, payloadSize := s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // update params + + params := s.queryParams() + oldReserveTime := params.VersionedParams.ReserveTime + oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate + + params.VersionedParams.ReserveTime = oldReserveTime * 2 + params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + // create another object after parameter changes + streamRecordsBefore = s.getStreamRecords(streamAddresses) + _, _, objectName, _, _, payloadSize = s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFeeAfterParameterChange := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFeeAfterParameterChange) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + s.Require().True(lockFeeAfterParameterChange.GT(lockFee.MulRaw(2))) +} + +func (s *PaymentTestSuite) TestStorageBill_CancelCreateObject() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 0) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, _, _, payloadSize := s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // cancel create object + s.cancelCreateObject(user, bucketName, objectName) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, lockFee) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestStorageBill_SealObject_WithoutPriceChange() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 0) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // case: seal object without price change + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(sp, bucketName, objectName, payloadSize, 0) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) +} + +func (s *PaymentTestSuite) TestStorageBill_SealObject_WithPriceChange() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 102400) + + // case: seal object with read price change and storage price change + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user, bucketName, false) + + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(2), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(2), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + streamRecordsBefore := s.getStreamRecords(streamAddresses) + gvgFamilyRateReadBefore, taxRateReadBefore, userTotalRateReadBefore := s.calculateReadRates(sp, bucketName) + + // seal object + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + gvgFamilyRateReadAfter, taxRateReadAfter, userTotalRateReadAfter := s.calculateReadRatesCurrentTimestamp(sp, bucketName) + gvgFamilyRateStore, gvgRateStore, taxRateStore, userTotalRateStore := s.calculateStorageRatesCurrentTimestamp(sp, bucketName, objectName, payloadSize) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRateReadAfter.Sub(userTotalRateReadBefore).Add(userTotalRateStore).Neg()) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRateStore) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRateReadAfter.Sub(gvgFamilyRateReadBefore).Add(gvgFamilyRateStore)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRateReadAfter.Sub(taxRateReadBefore).Add(taxRateStore)) +} + +func (s *PaymentTestSuite) TestStorageBill_SealObject_WithPriceChangeValidatorTaxRateChange() { + defer s.revertParams() + + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + bucketName := s.createBucket(sp, user, 102400) + + // case: seal object with read price change and storage price change + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user, bucketName, false) + + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(2), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(2), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + streamRecordsBefore := s.getStreamRecords(streamAddresses) + gvgFamilyRateReadBefore, taxRateReadBefore, userTotalRateReadBefore := s.calculateReadRates(sp, bucketName) + + // seal object + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + gvgFamilyRateReadAfter, taxRateReadAfter, userTotalRateReadAfter := s.calculateReadRatesCurrentTimestamp(sp, bucketName) + gvgFamilyRateStore, gvgRateStore, taxRateStore, userTotalRateStore := s.calculateStorageRatesCurrentTimestamp(sp, bucketName, objectName, payloadSize) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRateReadAfter.Sub(userTotalRateReadBefore).Add(userTotalRateStore).Neg()) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRateStore) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRateReadAfter.Sub(gvgFamilyRateReadBefore).Add(gvgFamilyRateStore)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRateReadAfter.Sub(taxRateReadBefore).Add(taxRateStore)) + + // update params + params := s.queryParams() + oldReserveTime := params.VersionedParams.ReserveTime + oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate + + params.VersionedParams.ReserveTime = oldReserveTime * 2 + params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + _, _, objectName, objectId, checksums, payloadSize = s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + gvgFamilyRateReadAfter, taxRateReadAfter, userTotalRateReadAfter = s.calculateReadRatesCurrentTimestamp(sp, bucketName) + gvgFamilyRateStore, gvgRateStore, taxRateStore, userTotalRateStore = s.calculateStorageRatesCurrentTimestamp(sp, bucketName, objectName, payloadSize) + + gvgFamilyRateStore = gvgFamilyRateStore.MulRaw(2) + gvgRateStore = gvgRateStore.MulRaw(2) + taxRateStore = taxRateStore.MulRaw(2) + userTotalRateStore = userTotalRateStore.MulRaw(2) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRateReadAfter.Sub(userTotalRateReadBefore).Add(userTotalRateStore).Neg()) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRateStore) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRateReadAfter.Sub(gvgFamilyRateReadBefore).Add(gvgFamilyRateStore)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRateReadAfter.Sub(taxRateReadBefore).Add(taxRateStore)) +} + +func (s *PaymentTestSuite) TestStorageBill_FullLifecycle() { + defer s.revertParams() + + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + // query storage price + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // full lifecycle + bucketName1 := s.createBucket(sp, user, 0) + _, _, objectName1, _, _, _ := s.createObject(user, bucketName1, true) + _, _, objectName2, objectId2, checksums2, _ := s.createObject(user, bucketName1, false) + s.sealObject(sp, gvg, bucketName1, objectName2, objectId2, checksums2) + + bucketName2 := s.createBucket(sp, user, 1024) + _, _, objectName3, objectId3, checksums3, _ := s.createObject(user, bucketName2, false) + s.sealObject(sp, gvg, bucketName2, objectName3, objectId3, checksums3) + + // update params + params := s.queryParams() + params.VersionedParams.ReserveTime = params.VersionedParams.ReserveTime * 3 + params.ForcedSettleTime = params.ForcedSettleTime * 2 + s.updateParams(params) + + _, _, objectName4, objectId4, checksums4, _ := s.createObject(user, bucketName2, false) + s.sealObject(sp, gvg, bucketName2, objectName4, objectId4, checksums4) + + bucketName3 := s.createBucket(sp, user, 1024) + _, _, objectName5, objectId5, checksums5, _ := s.createObject(user, bucketName3, false) + s.sealObject(sp, gvg, bucketName3, objectName5, objectId5, checksums5) + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // update params + params = s.queryParams() + params.VersionedParams.ReserveTime = params.VersionedParams.ReserveTime / 2 + params.ForcedSettleTime = params.ForcedSettleTime / 3 + s.updateParams(params) + + _, _, objectName6, objectId6, checksums6, _ := s.createObject(user, bucketName3, false) + s.sealObject(sp, gvg, bucketName3, objectName6, objectId6, checksums6) + + bucketName4 := s.createBucket(sp, user, 1024) + _, _, objectName7, objectId7, checksums7, _ := s.createObject(user, bucketName4, false) + s.sealObject(sp, gvg, bucketName4, objectName7, objectId7, checksums7) + + // update params + params = s.queryParams() + params.VersionedParams.ValidatorTaxRate = params.VersionedParams.ValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + _, _, objectName8, objectId8, checksums8, _ := s.createObject(user, bucketName4, false) + s.sealObject(sp, gvg, bucketName4, objectName8, objectId8, checksums8) + + time.Sleep(3 * time.Second) + + _ = s.deleteObject(user, bucketName1, objectName1) + _ = s.deleteObject(user, bucketName1, objectName2) + + // update params + params = s.queryParams() + params.VersionedParams.ValidatorTaxRate = params.VersionedParams.ValidatorTaxRate.MulInt64(3) + s.updateParams(params) + + _ = s.deleteObject(user, bucketName2, objectName3) + _ = s.deleteObject(user, bucketName2, objectName4) + err = s.deleteBucket(user, bucketName1) + s.Require().Error(err) + err = s.deleteBucket(user, bucketName2) + s.Require().Error(err) + + _ = s.deleteObject(user, bucketName3, objectName5) + _ = s.deleteObject(user, bucketName3, objectName6) + _ = s.deleteObject(user, bucketName4, objectName7) + _ = s.deleteObject(user, bucketName4, objectName8) + err = s.deleteBucket(user, bucketName3) + s.Require().Error(err) + err = s.deleteBucket(user, bucketName4) + s.Require().Error(err) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().True(!streamRecordsAfter.User.StaticBalance.IsZero()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) +} + +func (s *PaymentTestSuite) TestVirtualGroup_Settle() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + bucketName := s.createBucket(sp, user, 1024) + _, _, objectName, objectId, checksums, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // sleep seconds + time.Sleep(3 * time.Second) + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // settle gvg family + msgSettle := virtualgrouptypes.MsgSettle{ + StorageProvider: sp.FundingKey.GetAddr().String(), + GlobalVirtualGroupFamilyId: family.Id, + } + s.SendTxBlock(sp.FundingKey, &msgSettle) + + // settle gvg + var secondarySp *core.StorageProvider + for _, sp := range s.StorageProviders { + for _, id := range gvg.SecondarySpIds { + if sp.Info.Id == id { + secondarySp = sp + break + } + } + } + msgSettle = virtualgrouptypes.MsgSettle{ + StorageProvider: secondarySp.FundingKey.GetAddr().String(), + GlobalVirtualGroupFamilyId: 0, + GlobalVirtualGroupIds: []uint32{gvg.Id}, + } + s.SendTxBlock(secondarySp.FundingKey, &msgSettle) + + // assertions - balance has been checked in other tests in virtual group + streamRecordsAfter := s.getStreamRecords(streamAddresses) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestVirtualGroup_SwapOut() { + ctx := context.Background() + user := s.GenAndChargeAccounts(1, 1000000)[0] + successorSp := s.PickStorageProvider() + + // create a new storage provider + sp := s.BaseSuite.CreateNewStorageProvider() + s.T().Logf("new SP Info: %s", sp.Info.String()) + + // create a new gvg group for this storage provider + var secondarySPIDs []uint32 + for _, ssp := range s.StorageProviders { + if ssp.Info.Id != successorSp.Info.Id { + secondarySPIDs = append(secondarySPIDs, ssp.Info.Id) + } + if len(secondarySPIDs) == 6 { + break + } + } + + gvgID, familyID := s.BaseSuite.CreateGlobalVirtualGroup(sp, 0, secondarySPIDs, 1) + + // create object + s.BaseSuite.CreateObject(user, sp, gvgID, storagetestutils.GenRandomBucketName(), storagetestutils.GenRandomObjectName()) + + // Create another gvg contains this new sp + anotherSP := s.PickDifferentStorageProvider(successorSp.Info.Id) + var anotherSecondarySPIDs []uint32 + for _, ssp := range s.StorageProviders { + if ssp.Info.Id != successorSp.Info.Id && ssp.Info.Id != anotherSP.Info.Id { + anotherSecondarySPIDs = append(anotherSecondarySPIDs, ssp.Info.Id) + } + if len(anotherSecondarySPIDs) == 5 { + break + } + } + anotherSecondarySPIDs = append(anotherSecondarySPIDs, sp.Info.Id) + + anotherGVGID, _ := s.BaseSuite.CreateGlobalVirtualGroup(anotherSP, 0, anotherSecondarySPIDs, 1) + + familyResp, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{FamilyId: familyID}) + s.Require().NoError(err) + gvgResp, err := s.Client.GlobalVirtualGroup(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupRequest{GlobalVirtualGroupId: anotherGVGID}) + s.Require().NoError(err) + + streamAddresses := []string{ + user.GetAddr().String(), + familyResp.GlobalVirtualGroupFamily.VirtualPaymentAddress, + gvgResp.GlobalVirtualGroup.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // sp exit + s.SendTxBlock(sp.OperatorKey, &virtualgrouptypes.MsgStorageProviderExit{ + StorageProvider: sp.OperatorKey.GetAddr().String(), + }) + + resp, err := s.Client.StorageProvider(context.Background(), &sptypes.QueryStorageProviderRequest{Id: sp.Info.Id}) + s.Require().NoError(err) + s.Require().Equal(resp.StorageProvider.Status, sptypes.STATUS_GRACEFUL_EXITING) + + // swap out, as secondary sp + msgSwapOut2 := virtualgrouptypes.NewMsgSwapOut(sp.OperatorKey.GetAddr(), 0, []uint32{anotherGVGID}, successorSp.Info.Id) + msgSwapOut2.SuccessorSpApproval = &common.Approval{ExpiredHeight: math.MaxUint} + msgSwapOut2.SuccessorSpApproval.Sig, err = successorSp.ApprovalKey.Sign(msgSwapOut2.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(sp.OperatorKey, msgSwapOut2) + + // complete swap out + msgCompleteSwapOut2 := virtualgrouptypes.NewMsgCompleteSwapOut(successorSp.OperatorKey.GetAddr(), 0, []uint32{anotherGVGID}) + s.Require().NoError(err) + s.SendTxBlock(successorSp.OperatorKey, msgCompleteSwapOut2) + + // swap out, as primary sp + msgSwapOut := virtualgrouptypes.NewMsgSwapOut(sp.OperatorKey.GetAddr(), familyID, nil, successorSp.Info.Id) + msgSwapOut.SuccessorSpApproval = &common.Approval{ExpiredHeight: math.MaxUint} + msgSwapOut.SuccessorSpApproval.Sig, err = successorSp.ApprovalKey.Sign(msgSwapOut.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(sp.OperatorKey, msgSwapOut) + + // complete swap out, as primary sp + msgCompleteSwapOut := virtualgrouptypes.NewMsgCompleteSwapOut(successorSp.OperatorKey.GetAddr(), familyID, nil) + s.Require().NoError(err) + s.SendTxBlock(successorSp.OperatorKey, msgCompleteSwapOut) + + // sp complete exit success + s.SendTxBlock( + sp.OperatorKey, + &virtualgrouptypes.MsgCompleteStorageProviderExit{StorageProvider: sp.OperatorKey.GetAddr().String()}, + ) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestDiscontinue_InOneBlock_WithoutPriceChange() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // create bucket + bucketName := s.createBucket(sp, user, 0) + + // create & seal objects + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + _ = s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + + // for payment + time.Sleep(2 * time.Second) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +func (s *PaymentTestSuite) TestDiscontinue_InOneBlock_WithPriceChange() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // query storage price + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // create bucket + bucketName := s.createBucket(sp, user, 1200987) + + // create & seal objects + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // for payment + time.Sleep(2 * time.Second) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) +} + +func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithoutPriceChange() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // create bucket + bucketName := s.createBucket(sp, user, 12780) + + // create & seal objects + for i := 0; i < 4; i++ { + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + _ = s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + time.Sleep(200 * time.Millisecond) + } + + // for payment + time.Sleep(2 * time.Second) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) +} + +// TestDiscontinue_InBlocks_WithPriceChange will cover the following case: +// create an object, sp increase the price a lot, the object can be force deleted even the object's own has no enough balance. +func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithPriceChange() { + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // query storage price + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // create bucket + bucketName := s.createBucket(sp, user, 0) + + // create objects + for i := 0; i < 2; i++ { + _, _, objectName1, _, _, _ := s.createObject(user, bucketName, false) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED) + time.Sleep(200 * time.Millisecond) + } + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // create & seal objects + for i := 0; i < 2; i++ { + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + time.Sleep(200 * time.Millisecond) + } + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + // for payment + time.Sleep(2 * time.Second) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + // update new price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) +} + +func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithPriceChangeReserveTimeChange() { + defer s.revertParams() + + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // query storage price + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // create bucket + bucketName := s.createBucket(sp, user, 10200) + + // create objects + for i := 0; i < 2; i++ { + _, _, objectName1, _, _, _ := s.createObject(user, bucketName, false) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED) + time.Sleep(200 * time.Millisecond) + } + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // create & seal objects + for i := 0; i < 2; i++ { + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + time.Sleep(200 * time.Millisecond) + } + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + // update params + params := s.queryParams() + oldReserveTime := params.VersionedParams.ReserveTime + oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate + + params.VersionedParams.ReserveTime = oldReserveTime * 2 + params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + // for payment + time.Sleep(2 * time.Second) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + // update new price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().True(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64() <= int64(0)) // there are other auto settling + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) +} + +func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithPriceChangeReserveTimeChange_FrozenAccount() { + defer s.revertParams() + + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 1000000)[0] + + // params + params := s.queryParams() + oldReserveTime := params.VersionedParams.ReserveTime + oldValidatorTaxRate := params.VersionedParams.ValidatorTaxRate + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + // query storage price + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + s.T().Log("price", priceRes.SpStoragePrice) + + // create bucket + bucketName := s.createBucket(sp, user, 0) + + // create objects + for i := 0; i < 2; i++ { + _, _, objectName1, _, _, _ := s.createObject(user, bucketName, false) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED) + time.Sleep(200 * time.Millisecond) + } + + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // update params + params.VersionedParams.ReserveTime = 8 + params.ForcedSettleTime = 5 + s.updateParams(params) + + // create & seal objects + for i := 0; i < 2; i++ { + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + time.Sleep(200 * time.Millisecond) + } + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + // wait account to be frozen + time.Sleep(8 * time.Second) + streamRecord := s.getStreamRecord(user.GetAddr().String()) + s.Require().True(streamRecord.Status == paymenttypes.STREAM_ACCOUNT_STATUS_FROZEN) + + // update params + params.VersionedParams.ReserveTime = oldReserveTime * 2 + params.VersionedParams.ValidatorTaxRate = oldValidatorTaxRate.MulInt64(2) + s.updateParams(params) + + // for payment + time.Sleep(2 * time.Second) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).DeleteAt + + // update new price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(10000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().True(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64() <= int64(0)) // there are other auto settling + + // revert price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) +} + +func TestPaymentTestSuite(t *testing.T) { + suite.Run(t, new(PaymentTestSuite)) +} + +func (s *PaymentTestSuite) getStreamRecord(addr string) (sr paymenttypes.StreamRecord) { + ctx := context.Background() + streamRecordResp, err := s.Client.StreamRecord(ctx, &paymenttypes.QueryGetStreamRecordRequest{ + Account: addr, + }) + if streamRecordResp != nil { + s.Require().NoError(err) + sr = streamRecordResp.StreamRecord + } else { + s.Require().ErrorContainsf(err, "not found", "account: %s", addr) + sr.StaticBalance = sdk.ZeroInt() + sr.BufferBalance = sdk.ZeroInt() + sr.LockBalance = sdk.ZeroInt() + sr.NetflowRate = sdk.ZeroInt() + } + return sr +} + +func (s *PaymentTestSuite) getStreamRecords(addrs []string) (streamRecords StreamRecords) { + streamRecords.User = s.getStreamRecord(addrs[0]) + streamRecords.GVGFamily = s.getStreamRecord(addrs[1]) + streamRecords.GVG = s.getStreamRecord(addrs[2]) + streamRecords.Tax = s.getStreamRecord(addrs[3]) + s.T().Logf("streamRecords: %s", core.YamlString(streamRecords)) + return +} + +func (s *PaymentTestSuite) checkStreamRecordsBeforeAndAfter(streamRecordsBefore StreamRecords, streamRecordsAfter StreamRecords, readPrice sdk.Dec, + readChargeRate sdkmath.Int, primaryStorePrice sdk.Dec, secondaryStorePrice sdk.Dec, chargeSize uint64, payloadSize uint64) { + userRateDiff := streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate) + gvgFamilyRateDiff := streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate) + gvgRateDiff := streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate) + taxRateDiff := streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate) + s.Require().Equal(userRateDiff, gvgFamilyRateDiff.Add(gvgRateDiff).Add(taxRateDiff).Neg()) + + outFlowsResponse, err := s.Client.OutFlows(context.Background(), &paymenttypes.QueryOutFlowsRequest{Account: streamRecordsAfter.User.Account}) + s.Require().NoError(err) + userOutflowMap := lo.Reduce(outFlowsResponse.OutFlows, func(m map[string]sdkmath.Int, outflow paymenttypes.OutFlow, i int) map[string]sdkmath.Int { + m[outflow.ToAddress] = outflow.Rate + return m + }, make(map[string]sdkmath.Int)) + if payloadSize != 0 { + gvgFamilyRate := primaryStorePrice.MulInt(sdk.NewIntFromUint64(chargeSize)).TruncateInt().Add(readChargeRate) + s.Require().Equal(gvgFamilyRate, userOutflowMap[streamRecordsAfter.GVGFamily.Account]) + + gvgRate := secondaryStorePrice.MulInt(sdk.NewIntFromUint64(chargeSize)).TruncateInt().MulRaw(6) + s.Require().Equal(gvgRate, userOutflowMap[streamRecordsAfter.GVG.Account]) + } +} + +func (s *PaymentTestSuite) getChargeSize(payloadSize uint64) uint64 { + ctx := context.Background() + storageParams, err := s.Client.StorageQueryClient.Params(ctx, &storagetypes.QueryParamsRequest{}) + s.Require().NoError(err) + s.T().Logf("storageParams %s", storageParams) + minChargeSize := storageParams.Params.VersionedParams.MinChargeSize + if payloadSize < minChargeSize { + return minChargeSize + } else { + return payloadSize + } +} + +func (s *PaymentTestSuite) calculateLockFee(sp *core.StorageProvider, bucketName, objectName string, payloadSize uint64) sdkmath.Int { + ctx := context.Background() + + params := s.queryParams() + + headBucketExtraResponse, err := s.Client.HeadBucketExtra(ctx, &storagetypes.QueryHeadBucketExtraRequest{BucketName: bucketName}) + s.Require().NoError(err) + + storageParams, err := s.Client.StorageQueryClient.Params(ctx, &storagetypes.QueryParamsRequest{}) + s.T().Logf("storageParams %s, err: %v", storageParams, err) + s.Require().NoError(err) + secondarySpCount := storageParams.Params.VersionedParams.RedundantDataChunkNum + storageParams.Params.VersionedParams.RedundantParityChunkNum + + chargeSize := s.getChargeSize(payloadSize) + _, primaryPrice, secondaryPrice := s.getPrices(sp, headBucketExtraResponse.ExtraInfo.PriceTime) + + gvgFamilyRate := primaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate := secondaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate = gvgRate.MulRaw(int64(secondarySpCount)) + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(gvgFamilyRate.Add(gvgRate)).TruncateInt() + return gvgFamilyRate.Add(gvgRate).Add(taxRate).MulRaw(int64(params.VersionedParams.ReserveTime)) +} + +func (s *PaymentTestSuite) getPrices(sp *core.StorageProvider, timestamp int64) (sdk.Dec, sdk.Dec, sdk.Dec) { + ctx := context.Background() + + spStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: timestamp, + }) + s.T().Logf("spStoragePriceByTimeResp %s, err: %v", spStoragePriceByTimeResp, err) + s.Require().NoError(err) + + secondaryStoragePriceByTimeResp, err := s.Client.QueryGetSecondarySpStorePriceByTime(ctx, &sptypes.QueryGetSecondarySpStorePriceByTimeRequest{ + Timestamp: timestamp, + }) + s.T().Logf("spStoragePriceByTimeResp %s, err: %v", spStoragePriceByTimeResp, err) + s.Require().NoError(err) + + return spStoragePriceByTimeResp.SpStoragePrice.ReadPrice, spStoragePriceByTimeResp.SpStoragePrice.StorePrice, + secondaryStoragePriceByTimeResp.SecondarySpStorePrice.StorePrice +} + +func (s *PaymentTestSuite) calculateReadRates(sp *core.StorageProvider, bucketName string) (sdkmath.Int, sdkmath.Int, sdkmath.Int) { + ctx := context.Background() + + params := s.queryParams() + + headBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + headBucketResponse, err := s.Client.HeadBucket(ctx, &headBucketRequest) + s.Require().NoError(err) + + readPrice, _, _ := s.getPrices(sp, headBucketResponse.BucketInfo.CreateAt) + + gvgFamilyRate := readPrice.MulInt64(int64(headBucketResponse.BucketInfo.ChargedReadQuota)).TruncateInt() + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(gvgFamilyRate).TruncateInt() + return gvgFamilyRate, taxRate, gvgFamilyRate.Add(taxRate) +} + +func (s *PaymentTestSuite) calculateReadRatesCurrentTimestamp(sp *core.StorageProvider, bucketName string) (sdkmath.Int, sdkmath.Int, sdkmath.Int) { + ctx := context.Background() + + params := s.queryParams() + + headBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + headBucketResponse, err := s.Client.HeadBucket(ctx, &headBucketRequest) + s.Require().NoError(err) + + readPrice, _, _ := s.getPrices(sp, time.Now().Unix()) + + gvgFamilyRate := readPrice.MulInt64(int64(headBucketResponse.BucketInfo.ChargedReadQuota)).TruncateInt() + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(gvgFamilyRate).TruncateInt() + return gvgFamilyRate, taxRate, gvgFamilyRate.Add(taxRate) +} + +func (s *PaymentTestSuite) calculateStorageRates(sp *core.StorageProvider, bucketName, objectName string, payloadSize uint64, priceTime int64) (sdkmath.Int, sdkmath.Int, sdkmath.Int, sdkmath.Int) { + params := s.queryParams() + + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + headObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + s.Require().NoError(err) + secondarySpCount := len(headObjectResponse.GlobalVirtualGroup.SecondarySpIds) + fmt.Println("secondarySpCount", secondarySpCount) + if priceTime == 0 { + headBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + headBucketResponse, err := s.Client.HeadBucket(context.Background(), &headBucketRequest) + s.Require().NoError(err) + priceTime = headBucketResponse.BucketInfo.CreateAt + } + + chargeSize := s.getChargeSize(payloadSize) + _, primaryPrice, secondaryPrice := s.getPrices(sp, priceTime) + s.T().Logf("===secondaryPrice: %v,primaryPrice: %v===", secondaryPrice, primaryPrice) + gvgFamilyRate := primaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate := secondaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate = gvgRate.MulRaw(int64(secondarySpCount)) + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(gvgFamilyRate.Add(gvgRate)).TruncateInt() + return gvgFamilyRate, gvgRate, taxRate, gvgFamilyRate.Add(gvgRate).Add(taxRate) +} + +func (s *PaymentTestSuite) calculateStorageRatesCurrentTimestamp(sp *core.StorageProvider, bucketName, objectName string, payloadSize uint64) (sdkmath.Int, sdkmath.Int, sdkmath.Int, sdkmath.Int) { + params := s.queryParams() + + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + headObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + s.Require().NoError(err) + secondarySpCount := len(headObjectResponse.GlobalVirtualGroup.SecondarySpIds) + fmt.Println("secondarySpCount", secondarySpCount) + + chargeSize := s.getChargeSize(payloadSize) + _, primaryPrice, secondaryPrice := s.getPrices(sp, time.Now().Unix()) + + gvgFamilyRate := primaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate := secondaryPrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + gvgRate = gvgRate.MulRaw(int64(secondarySpCount)) + taxRate := params.VersionedParams.ValidatorTaxRate.MulInt(gvgFamilyRate.Add(gvgRate)).TruncateInt() + return gvgFamilyRate, gvgRate, taxRate, gvgFamilyRate.Add(gvgRate).Add(taxRate) +} + +func (s *PaymentTestSuite) updateParams(params paymenttypes.Params) { + var err error + validator := s.Validator.GetAddr() + + ctx := context.Background() + + ts := time.Now().Unix() + queryParamsRequest := &paymenttypes.QueryParamsRequest{} + queryParamsResponse, err := s.Client.PaymentQueryClient.Params(ctx, queryParamsRequest) + s.Require().NoError(err) + s.T().Log("params before", core.YamlString(queryParamsResponse.Params)) + + msgUpdateParams := &paymenttypes.MsgUpdateParams{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Params: params, + } + + msgProposal, err := govtypesv1.NewMsgSubmitProposal( + []sdk.Msg{msgUpdateParams}, + sdk.Coins{sdk.NewCoin(s.BaseSuite.Config.Denom, types.NewIntFromInt64WithDecimal(100, types.DecimalBNB))}, + validator.String(), + "test", "test", "test", + ) + s.Require().NoError(err) + + txRes := s.SendTxBlock(s.Validator, msgProposal) + s.Require().Equal(txRes.Code, uint32(0)) + + // 3. query proposal and get proposal ID + var proposalId uint64 + for _, event := range txRes.Logs[0].Events { + if event.Type == "submit_proposal" { + for _, attr := range event.Attributes { + if attr.Key == "proposal_id" { + proposalId, err = strconv.ParseUint(attr.Value, 10, 0) + s.Require().NoError(err) + break + } + } + break + } + } + s.Require().True(proposalId != 0) + + queryProposal := &govtypesv1.QueryProposalRequest{ProposalId: proposalId} + _, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + + // 4. submit MsgVote and wait the proposal exec + msgVote := govtypesv1.NewMsgVote(validator, proposalId, govtypesv1.OptionYes, "test") + txRes = s.SendTxBlock(s.Validator, msgVote) + s.Require().Equal(txRes.Code, uint32(0)) + + queryVoteParamsReq := govtypesv1.QueryParamsRequest{ParamsType: "voting"} + queryVoteParamsResp, err := s.Client.GovQueryClientV1.Params(ctx, &queryVoteParamsReq) + s.Require().NoError(err) + + // 5. wait a voting period and confirm that the proposal success. + s.T().Logf("voting period %s", *queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(*queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(1 * time.Second) + proposalRes, err := s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + s.Require().Equal(proposalRes.Proposal.Status, govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED) + + queryParamsByTimestampRequest := &paymenttypes.QueryParamsByTimestampRequest{Timestamp: ts} + queryParamsByTimestampResponse, err := s.Client.PaymentQueryClient.ParamsByTimestamp(ctx, queryParamsByTimestampRequest) + s.Require().NoError(err) + s.T().Log("params by timestamp", core.YamlString(queryParamsResponse.Params)) + s.Require().Equal(queryParamsResponse.Params.VersionedParams.ReserveTime, + queryParamsByTimestampResponse.Params.VersionedParams.ReserveTime) + + queryParamsRequest = &paymenttypes.QueryParamsRequest{} + queryParamsResponse, err = s.Client.PaymentQueryClient.Params(ctx, queryParamsRequest) + s.Require().NoError(err) + s.T().Log("params after", core.YamlString(queryParamsResponse.Params)) +} + +func (s *PaymentTestSuite) createBucketAndObject(sp *core.StorageProvider) (keys.KeyManager, string, string, storagetypes.Uint, [][]byte) { + var err error + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + + // CreateBucket + user := s.GenAndChargeAccounts(1, 1000000)[0] + bucketName := "ch" + storagetestutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PRIVATE, sp.OperatorKey.GetAddr(), + nil, math.MaxUint, nil, 0) + msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId + msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateBucket) + + // CreateObject + objectName := storagetestutils.GenRandomObjectName() + // create test buffer + var buffer bytes.Buffer + line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,123` + // Create 1MiB content where each line contains 1024 characters. + for i := 0; i < 1024; i++ { + buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line)) + } + payloadSize := buffer.Len() + checksum := sdk.Keccak256(buffer.Bytes()) + expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum} + contextType := "text/event-stream" + msgCreateObject := storagetypes.NewMsgCreateObject(user.GetAddr(), bucketName, objectName, uint64(payloadSize), + storagetypes.VISIBILITY_TYPE_PRIVATE, expectChecksum, contextType, + storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil) + msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateObject) + + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + queryHeadObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectName, objectName) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName) + + return user, bucketName, objectName, queryHeadObjectResponse.ObjectInfo.Id, expectChecksum +} + +func (s *PaymentTestSuite) createBucket(sp *core.StorageProvider, user keys.KeyManager, readQuota uint64) string { + var err error + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + + // CreateBucket + bucketName := "ch" + storagetestutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PRIVATE, sp.OperatorKey.GetAddr(), + nil, math.MaxUint, nil, readQuota) + msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId + msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateBucket) + + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err = s.Client.HeadBucket(context.Background(), &queryHeadBucketRequest) + s.Require().NoError(err) + + return bucketName +} + +func (s *PaymentTestSuite) createObject(user keys.KeyManager, bucketName string, empty bool) (keys.KeyManager, string, string, storagetypes.Uint, [][]byte, uint64) { + var err error + sp := s.BaseSuite.PickStorageProviderByBucketName(bucketName) + + // CreateObject + objectName := storagetestutils.GenRandomObjectName() + // create test buffer + var buffer bytes.Buffer + line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,123` + // Create 1MiB content where each line contains 1024 characters. + if !empty { + for i := 0; i < 1024; i++ { + buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line)) + } + } + payloadSize := uint64(buffer.Len()) + checksum := sdk.Keccak256(buffer.Bytes()) + expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum} + contextType := "text/event-stream" + msgCreateObject := storagetypes.NewMsgCreateObject(user.GetAddr(), bucketName, objectName, payloadSize, + storagetypes.VISIBILITY_TYPE_PRIVATE, expectChecksum, contextType, + storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil) + msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateObject) + + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + headObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(headObjectResponse.ObjectInfo.ObjectName, objectName) + s.Require().Equal(headObjectResponse.ObjectInfo.BucketName, bucketName) + + return user, bucketName, objectName, headObjectResponse.ObjectInfo.Id, expectChecksum, payloadSize +} + +func (s *PaymentTestSuite) cancelCreateObject(user keys.KeyManager, bucketName, objectName string) { + msgCancelCreateObject := storagetypes.NewMsgCancelCreateObject(user.GetAddr(), bucketName, objectName) + s.SendTxBlock(user, msgCancelCreateObject) + + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + _, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + s.Require().Error(err) +} + +func (s *PaymentTestSuite) sealObject(sp *core.StorageProvider, gvg *virtualgrouptypes.GlobalVirtualGroup, bucketName, objectName string, objectId storagetypes.Uint, checksums [][]byte) *virtualgrouptypes.GlobalVirtualGroup { + // SealObject + gvgId := gvg.Id + msgSealObject := storagetypes.NewMsgSealObject(sp.SealKey.GetAddr(), bucketName, objectName, gvg.Id, nil) + secondarySigs := make([][]byte, 0) + secondarySPBlsPubKeys := make([]bls.PublicKey, 0) + blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, objectId, storagetypes.GenerateHash(checksums[:])).GetBlsSignHash() + // every secondary sp signs the checksums + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) + s.Require().NoError(err) + secondarySigs = append(secondarySigs, sig) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) + s.Require().NoError(err) + secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) + } + aggBlsSig, err := core.BlsAggregateAndVerify(secondarySPBlsPubKeys, blsSignHash, secondarySigs) + s.Require().NoError(err) + msgSealObject.SecondarySpBlsAggSignatures = aggBlsSig + s.T().Logf("msg %s", msgSealObject.String()) + s.SendTxBlock(sp.SealKey, msgSealObject) + + queryHeadObjectRequest2 := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + queryHeadObjectResponse2, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest2) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.ObjectName, objectName) + s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.BucketName, bucketName) + s.Require().Equal(queryHeadObjectResponse2.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + + return gvg +} + +func (s *PaymentTestSuite) deleteObject(user keys.KeyManager, bucketName, objectName string) error { + msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName) + s.SendTxBlock(user, msgDeleteObject) + + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + _, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + return err +} + +func (s *PaymentTestSuite) deleteBucket(user keys.KeyManager, bucketName string) error { + msgDeleteObject := storagetypes.NewMsgDeleteBucket(user.GetAddr(), bucketName) + s.SendTxBlock(user, msgDeleteObject) + + // HeadObject + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err := s.Client.HeadBucket(context.Background(), &queryHeadBucketRequest) + return err +} + +func (s *PaymentTestSuite) TestUpdatePaymentParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.PaymentQueryClient.Params(context.Background(), &paymenttypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.PaymentAccountCountLimit = 300 + msgUpdateParams := &paymenttypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update Payment params", "Test update Payment params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.PaymentQueryClient.Params(context.Background(), &paymenttypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} + +func (s *PaymentTestSuite) revertParams() { + s.updateParams(s.defaultParams) +} + +func (s *PaymentTestSuite) queryParams() paymenttypes.Params { + queryParamsRequest := paymenttypes.QueryParamsRequest{} + queryParamsResponse, err := s.Client.PaymentQueryClient.Params(context.Background(), &queryParamsRequest) + s.Require().NoError(err) + s.T().Log("params", core.YamlString(queryParamsResponse.Params)) + return queryParamsResponse.Params } diff --git a/e2e/tests/permission_test.go b/e2e/tests/permission_test.go index 03470f410..b4cd6c34a 100644 --- a/e2e/tests/permission_test.go +++ b/e2e/tests/permission_test.go @@ -23,7 +23,7 @@ func (s *StorageTestSuite) TestDeleteBucketPermission() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -45,7 +45,7 @@ func (s *StorageTestSuite) TestDeleteBucketPermission() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -101,7 +101,7 @@ func (s *StorageTestSuite) TestDeletePolicy() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -123,7 +123,7 @@ func (s *StorageTestSuite) TestDeletePolicy() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -204,7 +204,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthers() { var err error user := s.GenAndChargeAccounts(3, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -226,7 +226,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthers() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -383,7 +383,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthersExpiration() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -405,7 +405,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthersExpiration() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -504,7 +504,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthersLimitSize() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -526,7 +526,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthersLimitSize() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -631,7 +631,7 @@ func (s *StorageTestSuite) TestGrantsPermissionToGroup() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket @@ -653,7 +653,7 @@ func (s *StorageTestSuite) TestGrantsPermissionToGroup() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user[0].GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user[0].GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -724,7 +724,7 @@ func (s *StorageTestSuite) TestVisibilityPermission() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) // CreateBucket bucket0:public bucket1:private bucket2:default @@ -871,7 +871,7 @@ func (s *StorageTestSuite) TestEmptyPermission() { var err error user := s.GenAndChargeAccounts(2, 1000000) - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) ctx := context.Background() @@ -1209,7 +1209,7 @@ func (s *StorageTestSuite) TestGroupMembersAndPolicyGC() { user := s.GenAndChargeAccounts(4, 1000000) owner := user[0] - _ = s.StorageProviders[0] + _ = s.BaseSuite.PickStorageProvider() // Create Group testGroupName := "testGroup" @@ -1274,13 +1274,13 @@ func (s *StorageTestSuite) TestExceedEachBlockLimitGC() { ctx := context.Background() owner := s.GenAndChargeAccounts(1, 10000)[0] user := s.GenAndChargeAccounts(1, 10000)[0] - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) s.Client.SetKeyManager(owner) - nonce, _ := s.Client.GetNonce() + nonce, _ := s.Client.GetNonce(ctx) bucketNames := make([]string, 0) // Create 250 Buckets diff --git a/e2e/tests/sp_test.go b/e2e/tests/sp_test.go index 839b2e482..9b447466d 100644 --- a/e2e/tests/sp_test.go +++ b/e2e/tests/sp_test.go @@ -3,11 +3,19 @@ package tests import ( "context" "encoding/hex" + "math/big" + "reflect" "sort" + "strconv" "testing" + "time" "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/stretchr/testify/suite" "github.com/bnb-chain/greenfield/e2e/core" @@ -64,7 +72,7 @@ func (s *StorageProviderTestSuite) TestCreateStorageProvider() { func (s *StorageProviderTestSuite) TestEditStorageProvider() { ctx := context.Background() - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() blsProof, _ := sp.BlsKey.Sign(tmhash.Sum(sp.BlsKey.PubKey().Bytes())) // 1. query previous storage provider @@ -133,7 +141,7 @@ func (s *StorageProviderTestSuite) TestEditStorageProvider() { } func (s *StorageProviderTestSuite) TestDeposit() { - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() deposit := sdk.Coin{ Denom: s.Config.Denom, @@ -149,7 +157,7 @@ func (s *StorageProviderTestSuite) TestDeposit() { func (s *StorageProviderTestSuite) TestSpStoragePrice() { ctx := context.Background() s.CheckSecondarySpPrice() - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() spAddr := sp.OperatorKey.GetAddr().String() spStoragePrice, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ SpAddr: spAddr, @@ -229,3 +237,96 @@ func (s *StorageProviderTestSuite) CheckSecondarySpPrice() { func TestStorageProviderTestSuite(t *testing.T) { suite.Run(t, new(StorageProviderTestSuite)) } + +func (s *StorageProviderTestSuite) TestUpdateStorageProviderParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.SpQueryClient.Params(context.Background(), &sptypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.SecondarySpStorePriceRatio = sdk.NewDecFromBigIntWithPrec(big.NewInt(1), 18) + msgUpdateParams := &sptypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update StorageProvider params", "Test update StorageProvider params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.SpQueryClient.Params(context.Background(), &sptypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} diff --git a/e2e/tests/storage_bill_test.go b/e2e/tests/storage_bill_test.go new file mode 100644 index 000000000..4f063ebb3 --- /dev/null +++ b/e2e/tests/storage_bill_test.go @@ -0,0 +1,813 @@ +package tests + +import ( + "context" + "math" + "sort" + "time" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/prysmaticlabs/prysm/crypto/bls" + + "github.com/bnb-chain/greenfield/e2e/core" + "github.com/bnb-chain/greenfield/sdk/keys" + "github.com/bnb-chain/greenfield/sdk/types" + storagetestutils "github.com/bnb-chain/greenfield/testutil/storage" + paymenttypes "github.com/bnb-chain/greenfield/x/payment/types" + sptypes "github.com/bnb-chain/greenfield/x/sp/types" + storagetypes "github.com/bnb-chain/greenfield/x/storage/types" + virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" +) + +// TestStorageBill_CopyObject_WithoutPriceChange +func (s *PaymentTestSuite) TestStorageBill_CopyObject_WithoutPriceChange() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user0 := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user0.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + bucketName := s.createBucket(sp, user0, 0) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user0, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // case: seal object without price change + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(sp, bucketName, objectName, payloadSize, 0) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + distBucketName := bucketName + distObjectName := storagetestutils.GenRandomObjectName() + + objectIfo, err := s.copyObject(user0, sp, bucketName, objectName, distBucketName, distObjectName) + s.Require().NoError(err) + s.sealObject(sp, gvg, distBucketName, distObjectName, objectIfo.Id, objectIfo.Checksums) + // assertions + streamRecordsAfterCopy := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfterCopy.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfterCopy.User.LockBalance, sdkmath.ZeroInt()) + //gvgFamilyRate1, gvgRate1, taxRate1, userTotalRate1 := s.calculateStorageRates(sp,distBucketName, distObjectName, payloadSize) + s.Require().Equal(streamRecordsAfterCopy.User.NetflowRate.Sub(streamRecordsAfter.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfterCopy.GVGFamily.NetflowRate.Sub(streamRecordsAfter.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfterCopy.GVG.NetflowRate.Sub(streamRecordsAfter.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfterCopy.Tax.NetflowRate.Sub(streamRecordsAfter.Tax.NetflowRate), taxRate) +} + +// TestStorageBill_CopyObject_WithoutPriceChange +func (s *PaymentTestSuite) TestStorageBill_CopyObject_WithPriceChange() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user0 := s.GenAndChargeAccounts(1, 1000000)[0] + + streamAddresses := []string{ + user0.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + bucketName := s.createBucket(sp, user0, 0) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user0, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(sp, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // case: seal object without price change + s.sealObject(sp, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(sp, bucketName, objectName, payloadSize, 0) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + priceRes, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: 0, + }) + s.Require().NoError(err) + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: priceRes.SpStoragePrice.ReadPrice, + FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, + StorePrice: priceRes.SpStoragePrice.StorePrice.MulInt64(1000), + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + distBucketName := s.createBucket(sp, user0, 0) + distObjectName := storagetestutils.GenRandomObjectName() + objectIfo, err := s.copyObject(user0, sp, bucketName, objectName, distBucketName, distObjectName) + s.Require().NoError(err) + s.sealObject(sp, gvg, distBucketName, distObjectName, objectIfo.Id, objectIfo.Checksums) + // assertions + streamRecordsAfterCopy := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfterCopy.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfterCopy.User.LockBalance, sdkmath.ZeroInt()) + gvgFamilyRate1, gvgRate1, taxRate1, userTotalRate1 := s.calculateStorageRates(sp, distBucketName, distObjectName, payloadSize, 0) + s.Require().Equal(streamRecordsAfterCopy.GVGFamily.NetflowRate.Sub(streamRecordsAfter.GVGFamily.NetflowRate), gvgFamilyRate1) + s.Require().Equal(streamRecordsAfterCopy.GVG.NetflowRate.Sub(streamRecordsAfter.GVG.NetflowRate), gvgRate1) + s.Require().Equal(streamRecordsAfterCopy.Tax.NetflowRate.Sub(streamRecordsAfter.Tax.NetflowRate), taxRate1) + s.Require().Equal(streamRecordsAfterCopy.User.NetflowRate.Sub(streamRecordsAfter.User.NetflowRate).BigInt().String(), userTotalRate1.Neg().BigInt().String()) + +} + +// TestStorageBill_UpdateBucketQuota +func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + // recover price + defer s.SetSPPrice(sp, "12.34", "0") + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 10)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + // case: create bucket with zero read quota + bucketName := s.createBucket(sp, user, 0) + + // bucket created + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, streamRecordsBefore.User.NetflowRate) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate, streamRecordsBefore.GVGFamily.NetflowRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate, streamRecordsBefore.Tax.NetflowRate) + + readQuota := uint64(1024 * 1024 * 100) + // case: update bucket read quota + bucketInfo, err := s.updateBucket(user, bucketName, "", readQuota) + s.Require().NoError(err) + + // check price and rate calculation + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() + s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) + taxRate := paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTotalRate := readChargeRate.Add(taxRate) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + expectedOutFlows := []paymenttypes.OutFlow{ + {ToAddress: family.VirtualPaymentAddress, Rate: readChargeRate}, + {ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate}, + } + userOutFlowsResponse, err := s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: user.GetAddr().String()}) + s.Require().NoError(err) + sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool { + return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress + }) + sort.Slice(expectedOutFlows, func(i, j int) bool { + return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress + }) + s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: queryGetSpStoragePriceByTimeResp.SpStoragePrice.FreeReadQuota, + StorePrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // case: update bucket read quota + bucketInfo, err = s.updateBucket(user, bucketName, "", readQuota*2) + s.Require().NoError(err) + + // check price and rate calculation + queryGetSpStoragePriceByTimeResp, err = s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice = queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + readChargeRate = readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() + s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) + taxRate = paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTotalRate = readChargeRate.Add(taxRate) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + expectedOutFlows = []paymenttypes.OutFlow{ + {ToAddress: family.VirtualPaymentAddress, Rate: readChargeRate}, + {ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate}, + } + userOutFlowsResponse, err = s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: user.GetAddr().String()}) + s.Require().NoError(err) + sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool { + return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress + }) + sort.Slice(expectedOutFlows, func(i, j int) bool { + return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress + }) + s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) + // set big read price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), + FreeReadQuota: queryGetSpStoragePriceByTimeResp.SpStoragePrice.FreeReadQuota, + StorePrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + chargedReadQuota := readQuota * 1024 * 1024 + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &chargedReadQuota, user.GetAddr(), storagetypes.VISIBILITY_TYPE_PRIVATE) + + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "apply user flows list failed") + +} + +// TestStorageBill_UpdatePaymentAddress +func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { + var err error + ctx := context.Background() + sp := s.PickStorageProvider() + defer s.SetSPPrice(sp, "12.34", "0") + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 100)[0] + + paymentAccountAddr := s.CreatePaymentAccount(user, 1, 17) + paymentAcc := sdk.MustAccAddressFromHex(paymentAccountAddr) + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + // case: create bucket with zero read quota + bucketName := s.createBucket(sp, user, 0) + + // bucket created + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate, streamRecordsBefore.User.NetflowRate) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate, streamRecordsBefore.GVGFamily.NetflowRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate, streamRecordsBefore.Tax.NetflowRate) + + readQuota := uint64(1024 * 100) + // case: update bucket read quota + bucketInfo, err := s.updateBucket(user, bucketName, "", readQuota) + s.Require().NoError(err) + + // check price and rate calculation + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() + s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) + taxRate := paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTotalRate := readChargeRate.Add(taxRate) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + expectedOutFlows := []paymenttypes.OutFlow{ + {ToAddress: family.VirtualPaymentAddress, Rate: readChargeRate}, + {ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate}, + } + userOutFlowsResponse, err := s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: user.GetAddr().String()}) + s.Require().NoError(err) + sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool { + return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress + }) + sort.Slice(expectedOutFlows, func(i, j int) bool { + return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress + }) + s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) + // update new price + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: queryGetSpStoragePriceByTimeResp.SpStoragePrice.FreeReadQuota, + StorePrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + // case: update bucket paymentAccountAddr + bucketInfo, err = s.updateBucket(user, bucketName, paymentAccountAddr, readQuota) + s.Require().NoError(err) + + // check price and rate calculation + queryGetSpStoragePriceByTimeResp, err = s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice = queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice + readChargeRate = readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() + s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) + taxRate = paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() + userTotalRate = readChargeRate.Add(taxRate) + + // assertions + streamAddresses[0] = paymentAccountAddr + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + expectedOutFlows = []paymenttypes.OutFlow{ + {ToAddress: family.VirtualPaymentAddress, Rate: readChargeRate}, + {ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate}, + } + userOutFlowsResponse, err = s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: paymentAccountAddr}) + s.Require().NoError(err) + sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool { + return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress + }) + sort.Slice(expectedOutFlows, func(i, j int) bool { + return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress + }) + s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) + + // set big read price + msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), + FreeReadQuota: queryGetSpStoragePriceByTimeResp.SpStoragePrice.FreeReadQuota, + StorePrice: queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + + chargedReadQuota := readQuota * 1024 * 1024 * 1024 * 1024 + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &chargedReadQuota, paymentAcc, storagetypes.VISIBILITY_TYPE_PRIVATE) + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "apply user flows list failed") + // new payment account balance not enough + paymentAccountAddr = s.CreatePaymentAccount(user, 1, 13) + paymentAcc = sdk.MustAccAddressFromHex(paymentAccountAddr) + msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &readQuota, paymentAcc, storagetypes.VISIBILITY_TYPE_PRIVATE) + + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "apply user flows list failed") + +} + +func (s *PaymentTestSuite) TestStorageBill_MigrationBucket() { + var err error + ctx := context.Background() + primarySP := s.PickStorageProvider() + s.SetSPPrice(primarySP, "1", "1.15") + + gvg, found := primarySP.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user0 := s.GenAndChargeAccounts(1, 10)[0] + + streamAddresses := []string{ + user0.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + streamAddresses0 := streamAddresses + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + bucketName := s.createBucket(primarySP, user0, 0) + bucketInfo, err := s.Client.HeadBucket(context.Background(), &storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + }) + s.Require().NoError(err) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user0, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(primarySP, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // case: seal object without price change + s.sealObject(primarySP, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(primarySP, bucketName, objectName, payloadSize, 0) + s.T().Logf("gvgFamilyRate: %v, gvgRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, gvgRate, taxRate, userTotalRate) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + taxRate0 := taxRate + dstPrimarySP := s.CreateNewStorageProvider() + + s.SetSPPrice(dstPrimarySP, "2", "1.45") + _, secondarySPIDs := s.GetSecondarySP(dstPrimarySP, primarySP) + gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(dstPrimarySP, 0, secondarySPIDs, 1) + gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{ + GlobalVirtualGroupId: gvgID, + }) + s.Require().NoError(err) + dstGVG := gvgResp.GlobalVirtualGroup + s.Require().True(found) + + queryFamilyResponse, err = s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: dstGVG.FamilyId, + }) + s.Require().NoError(err) + family = queryFamilyResponse.GlobalVirtualGroupFamily + streamAddresses = []string{ + user0.GetAddr().String(), + family.VirtualPaymentAddress, + dstGVG.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + fundAddress := primarySP.FundingKey.GetAddr() + streamRecordsBefore = s.getStreamRecords(streamAddresses) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: fundAddress.String()} + fundBalanceBefore, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + + // MigrationBucket + msgMigrationBucket, msgCompleteMigrationBucket := s.NewMigrateBucket(primarySP, dstPrimarySP, user0, bucketName, gvg.FamilyId, dstGVG.FamilyId, bucketInfo.BucketInfo.Id) + s.SendTxBlock(user0, msgMigrationBucket) + s.Require().NoError(err) + + // complete MigrationBucket + s.SendTxBlock(dstPrimarySP.OperatorKey, msgCompleteMigrationBucket) + streamRecordsAfter = s.getStreamRecords(streamAddresses) + fundBalanceAfter, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + s.T().Logf("fundBalanceBefore: %v, fundBalanceAfter: %v, diff: %v", fundBalanceBefore, fundBalanceAfter, fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount)) + s.Require().True(fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount).GT(sdkmath.NewInt(0)), "migrate sp fund address need settle") + gvgFamilyRate, gvgRate, taxRate, userTotalRate = s.calculateStorageRates(dstPrimarySP, bucketName, objectName, payloadSize, time.Now().Unix()) + s.T().Logf("gvgFamilyRate: %v, gvgRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, gvgRate, taxRate, userTotalRate) + s.T().Logf("NetflowRate: %v, userTotalRate: %v, actual taxRate diff: %v, expect taxRate diff: %v", streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Neg(), streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0)) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + // tax rate diff + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0)) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Abs()) + + s.SetSPPrice(primarySP, "12.3", "100") + + queryBalanceRequest.Address = dstPrimarySP.FundingKey.GetAddr().String() + fundBalanceBefore, err = s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + streamRecordsBefore = s.getStreamRecords(streamAddresses0) + // send msgMigrationBucket + msgMigrationBucket, msgCompleteMigrationBucket = s.NewMigrateBucket(dstPrimarySP, primarySP, user0, bucketName, dstGVG.FamilyId, gvg.FamilyId, bucketInfo.BucketInfo.Id) + + s.SendTxBlock(user0, msgMigrationBucket) + s.Require().NoError(err) + s.reduceBNBBalance(user0, s.Validator, sdkmath.NewIntWithDecimal(1, 1)) + + s.SendTxBlockWithExpectErrorString(msgCompleteMigrationBucket, primarySP.OperatorKey, "apply stream record changes for user failed") + + s.SetSPPrice(primarySP, "12.3", "13") + readPrice, primaryPrice, secondaryPrice := s.getPrices(primarySP, time.Now().Unix()) + s.T().Logf("readPrice: %v, primaryPrice: %v,secondaryPrice: %v", readPrice, primaryPrice, secondaryPrice) + + s.transferBNB(s.Validator, user0, sdkmath.NewIntWithDecimal(10000, 18)) + + s.SendTxBlock(primarySP.OperatorKey, msgCompleteMigrationBucket) + streamRecordsAfter = s.getStreamRecords(streamAddresses0) + fundBalanceAfter, err = s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + s.T().Logf("fundBalanceBefore: %v, fundBalanceAfter: %v, diff: %v", fundBalanceBefore, fundBalanceAfter, fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount)) + s.Require().True(fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount).GT(sdkmath.NewInt(0)), "migrate sp fund address need settle") + taxRate1 := taxRate + gvgFamilyRate, gvgRate, taxRate, userTotalRate = s.calculateStorageRates(primarySP, bucketName, objectName, payloadSize, time.Now().Unix()) + s.T().Logf("gvgFamilyRate: %v, gvgRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, gvgRate, taxRate, userTotalRate) + s.T().Logf("NetflowRate: %v, userTotalRate: %v, actual taxRate diff: %v, expect taxRate diff: %v", streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Neg(), streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0)) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + // tax rate diff + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate1)) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Abs()) +} + +func (s *PaymentTestSuite) GetSecondarySP(sps ...*core.StorageProvider) ([]*core.StorageProvider, []uint32) { + var secondarySPs []*core.StorageProvider + var secondarySPIDs []uint32 + + for _, ssp := range s.StorageProviders { + isSecondSP := true + for _, sp := range sps { + if ssp.Info.Id == sp.Info.Id { + isSecondSP = false + break + } + } + if isSecondSP { + secondarySPIDs = append(secondarySPIDs, ssp.Info.Id) + secondarySPs = append(secondarySPs, ssp) + } + if len(secondarySPIDs) == 6 { + break + } + } + return secondarySPs, secondarySPIDs +} +func (s *PaymentTestSuite) NewMigrateBucket(srcSP, dstSP *core.StorageProvider, user keys.KeyManager, bucketName string, srcID, dstID uint32, bucketID sdkmath.Uint) (*storagetypes.MsgMigrateBucket, *storagetypes.MsgCompleteMigrateBucket) { + + secondarySPs, _ := s.GetSecondarySP(srcSP, dstSP) + var gvgMappings []*storagetypes.GVGMapping + gvgMappings = append(gvgMappings, &storagetypes.GVGMapping{SrcGlobalVirtualGroupId: srcID, DstGlobalVirtualGroupId: dstID}) + for _, gvgMapping := range gvgMappings { + migrationBucketSignHash := storagetypes.NewSecondarySpMigrationBucketSignDoc(s.GetChainID(), bucketID, dstSP.Info.Id, gvgMapping.SrcGlobalVirtualGroupId, gvgMapping.DstGlobalVirtualGroupId).GetBlsSignHash() + secondarySigs := make([][]byte, 0) + secondarySPBlsPubKeys := make([]bls.PublicKey, 0) + for _, ssp := range secondarySPs { + sig, err := core.BlsSignAndVerify(ssp, migrationBucketSignHash) + s.Require().NoError(err) + secondarySigs = append(secondarySigs, sig) + pk, err := bls.PublicKeyFromBytes(ssp.BlsKey.PubKey().Bytes()) + s.Require().NoError(err) + secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) + } + aggBlsSig, err := core.BlsAggregateAndVerify(secondarySPBlsPubKeys, migrationBucketSignHash, secondarySigs) + s.Require().NoError(err) + gvgMapping.SecondarySpBlsSignature = aggBlsSig + } + + msgMigrationBucket := storagetypes.NewMsgMigrateBucket(user.GetAddr(), bucketName, dstSP.Info.Id) + msgMigrationBucket.DstPrimarySpApproval.ExpiredHeight = math.MaxInt + msgMigrationBucket.DstPrimarySpApproval.Sig, _ = dstSP.ApprovalKey.Sign(msgMigrationBucket.GetApprovalBytes()) + + msgCompleteMigrationBucket := storagetypes.NewMsgCompleteMigrateBucket(dstSP.OperatorKey.GetAddr(), bucketName, dstID, gvgMappings) + + return msgMigrationBucket, msgCompleteMigrationBucket + +} +func (s *PaymentTestSuite) SetSPPrice(sp *core.StorageProvider, readPrice, storePrice string) { + ctx := context.Background() + + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.Require().NoError(err) + ReadPrice, err := sdk.NewDecFromStr(readPrice) + s.Require().NoError(err) + StorePrice := queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice + if storePrice != "0" { + StorePrice, err = sdk.NewDecFromStr(storePrice) + s.Require().NoError(err) + } + + msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ + SpAddress: sp.OperatorKey.GetAddr().String(), + ReadPrice: ReadPrice, + FreeReadQuota: queryGetSpStoragePriceByTimeResp.SpStoragePrice.FreeReadQuota, + StorePrice: StorePrice, + } + s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) + queryGetSpStoragePriceByTimeResp, err = s.Client.QueryGetSpStoragePriceByTime(ctx, &sptypes.QueryGetSpStoragePriceByTimeRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + Timestamp: time.Now().Unix(), + }) + s.Require().NoError(err) + s.T().Logf("queryGetSpStoragePriceByTimeResp read price: %s, store price: %v", + queryGetSpStoragePriceByTimeResp.SpStoragePrice.ReadPrice, queryGetSpStoragePriceByTimeResp.SpStoragePrice.StorePrice) + +} + +// CreatePaymentAccount create new payment account and return latest payment account +func (s *PaymentTestSuite) CreatePaymentAccount(user keys.KeyManager, amount, decimal int64) string { + ctx := context.Background() + // create a new payment account + msgCreatePaymentAccount := &paymenttypes.MsgCreatePaymentAccount{ + Creator: user.GetAddr().String(), + } + _ = s.SendTxBlock(user, msgCreatePaymentAccount) + // query user's payment accounts + queryGetPaymentAccountsByOwnerRequest := paymenttypes.QueryGetPaymentAccountsByOwnerRequest{ + Owner: user.GetAddr().String(), + } + paymentAccounts, err := s.Client.GetPaymentAccountsByOwner(ctx, &queryGetPaymentAccountsByOwnerRequest) + s.Require().NoError(err) + s.T().Log(paymentAccounts) + paymentAccountAddr := paymentAccounts.PaymentAccounts[len(paymentAccounts.PaymentAccounts)-1] + // charge payment account + paymentAcc := sdk.MustAccAddressFromHex(paymentAccountAddr) + msgSend := banktypes.NewMsgSend(user.GetAddr(), paymentAcc, []sdk.Coin{{Denom: "BNB", Amount: types.NewIntFromInt64WithDecimal(amount, decimal)}}) + s.SendTxBlock(user, msgSend) + + return paymentAccountAddr +} + +func (s *PaymentTestSuite) copyObject(user keys.KeyManager, sp *core.StorageProvider, bucketName, objectName, dstBucketName, dstObjectName string) (*storagetypes.ObjectInfo, error) { + msgCopyObject := storagetypes.NewMsgCopyObject(user.GetAddr(), bucketName, dstBucketName, objectName, dstObjectName, math.MaxUint, nil) + msgCopyObject.DstPrimarySpApproval.Sig, _ = sp.ApprovalKey.Sign(msgCopyObject.GetApprovalBytes()) + + s.SendTxBlock(user, msgCopyObject) + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: dstBucketName, + ObjectName: dstObjectName, + } + headObjectResponse, err := s.Client.HeadObject(context.Background(), &queryHeadObjectRequest) + return headObjectResponse.ObjectInfo, err + +} + +func (s *PaymentTestSuite) updateBucket(user keys.KeyManager, bucketName string, paymentAddress string, chargedReadQuota uint64) (*storagetypes.BucketInfo, error) { + + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &chargedReadQuota, user.GetAddr(), storagetypes.VISIBILITY_TYPE_PRIVATE) + if paymentAddress != "" { + msgUpdateBucketInfo.PaymentAddress = paymentAddress + } + s.SendTxBlock(user, msgUpdateBucketInfo) + + queryHeadObjectRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + headObjectResponse, err := s.Client.HeadBucket(context.Background(), &queryHeadObjectRequest) + return headObjectResponse.BucketInfo, err + +} + +func (s *PaymentTestSuite) reduceBNBBalance(user, to keys.KeyManager, leftBalance sdkmath.Int) { + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), to.GetAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + sendBNBAmount := queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit)))).Sub(leftBalance) + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, sendBNBAmount), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + s.T().Logf("balance: %v", queryBalanceResponse.Balance.Amount) +} + +func (s *PaymentTestSuite) transferBNB(user, to keys.KeyManager, amount sdkmath.Int) { + + msgSend := banktypes.NewMsgSend(user.GetAddr(), to.GetAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, amount), + )) + s.SendTxBlock(user, msgSend) + +} diff --git a/e2e/tests/storage_test.go b/e2e/tests/storage_test.go index 517509a43..5b04412ba 100644 --- a/e2e/tests/storage_test.go +++ b/e2e/tests/storage_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "math" + "reflect" "strconv" "strings" "testing" @@ -13,9 +14,11 @@ import ( sdkmath "cosmossdk.io/math" ctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -56,7 +59,7 @@ var ( func (s *StorageTestSuite) TestCreateBucket() { var err error - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.User @@ -79,7 +82,7 @@ func (s *StorageTestSuite) TestCreateBucket() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -104,7 +107,7 @@ func (s *StorageTestSuite) TestCreateBucket() { func (s *StorageTestSuite) TestCreateObject() { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -126,7 +129,7 @@ func (s *StorageTestSuite) TestCreateObject() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -173,11 +176,11 @@ func (s *StorageTestSuite) TestCreateObject() { secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -292,7 +295,7 @@ func (s *StorageTestSuite) TestCreateGroup() { func (s *StorageTestSuite) TestDeleteBucket() { var err error user := s.GenAndChargeAccounts(1, 1000000)[0] - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) s.T().Logf("Global virtual group: %s", gvg.String()) @@ -354,11 +357,11 @@ func (s *StorageTestSuite) TestDeleteBucket() { secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -384,7 +387,7 @@ func (s *StorageTestSuite) TestDeleteBucket() { func (s *StorageTestSuite) TestMirrorBucket() { var err error - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.User @@ -407,7 +410,7 @@ func (s *StorageTestSuite) TestMirrorBucket() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -434,7 +437,7 @@ func (s *StorageTestSuite) TestMirrorBucket() { func (s *StorageTestSuite) TestMirrorObject() { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -456,7 +459,7 @@ func (s *StorageTestSuite) TestMirrorObject() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -502,11 +505,11 @@ func (s *StorageTestSuite) TestMirrorObject() { secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvg.Id, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -556,11 +559,11 @@ func (s *StorageTestSuite) TestMirrorObject() { secondarySPBlsPubKeys = make([]bls.PublicKey, 0) blsSignHash = storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -763,7 +766,7 @@ func (s *StorageTestSuite) TestDiscontinueBucket_Normal() { deleteAt1 := filterDiscontinueBucketEventFromTx(txRes1).DeleteAt time.Sleep(3 * time.Second) - msgDiscontinueBucket2 := storagetypes.NewMsgDiscontinueBucket(sp1.GcKey.GetAddr(), bucketName2, "test") + msgDiscontinueBucket2 := storagetypes.NewMsgDiscontinueBucket(sp2.GcKey.GetAddr(), bucketName2, "test") txRes2 := s.SendTxBlock(sp2.GcKey, msgDiscontinueBucket2) deleteAt2 := filterDiscontinueBucketEventFromTx(txRes2).DeleteAt @@ -903,14 +906,14 @@ func (s *StorageTestSuite) TestDiscontinueBucket_UserDeleted() { } // createObject with default VISIBILITY_TYPE_PRIVATE -func (s *StorageTestSuite) createObject() (core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { +func (s *StorageTestSuite) createObject() (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { return s.createObjectWithVisibility(storagetypes.VISIBILITY_TYPE_PRIVATE) } -func (s *StorageTestSuite) createObjectWithVisibility(v storagetypes.VisibilityType) (core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { +func (s *StorageTestSuite) createObjectWithVisibility(v storagetypes.VisibilityType) (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -932,7 +935,7 @@ func (s *StorageTestSuite) createObjectWithVisibility(v storagetypes.VisibilityT s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, v) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -990,11 +993,11 @@ func (s *StorageTestSuite) createObjectWithVisibility(v storagetypes.VisibilityT secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) } @@ -1137,7 +1140,7 @@ func filterDeleteBucketEventFromTx(txRes *sdk.TxResponse) storagetypes.EventDele func (s *StorageTestSuite) TestCancelCreateObject() { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -1159,7 +1162,7 @@ func (s *StorageTestSuite) TestCancelCreateObject() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -1208,7 +1211,7 @@ func (s *StorageTestSuite) TestCancelCreateObject() { func (s *StorageTestSuite) TestCreateObjectWithCommonPrefix() { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -1230,7 +1233,7 @@ func (s *StorageTestSuite) TestCreateObjectWithCommonPrefix() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -1421,7 +1424,7 @@ func (s *StorageTestSuite) TestCreateAndUpdateGroupExtraField() { func (s *StorageTestSuite) TestRejectSealObject() { var err error // CreateBucket - sp := s.StorageProviders[0] + sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] @@ -1443,7 +1446,7 @@ func (s *StorageTestSuite) TestRejectSealObject() { s.Require().NoError(err) s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String()) - s.Require().Equal(queryHeadBucketResponse.BucketInfo.PrimarySpId, sp.Info.Id) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId) s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String()) s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PRIVATE) s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) @@ -1499,13 +1502,13 @@ func (s *StorageTestSuite) TestRejectSealObject() { func (s *StorageTestSuite) TestMigrationBucket() { // construct bucket and object - primarySP := s.StorageProviders[0] + primarySP := s.BaseSuite.PickStorageProvider() gvg, found := primarySP.GetFirstGlobalVirtualGroup() s.Require().True(found) user := s.GenAndChargeAccounts(1, 1000000)[0] bucketName := storageutils.GenRandomBucketName() objectName := storageutils.GenRandomObjectName() - _, _, _, bucketInfo := s.BaseSuite.CreateObject(user, &primarySP, gvg.Id, bucketName, objectName) + _, _, _, bucketInfo := s.BaseSuite.CreateObject(user, primarySP, gvg.Id, bucketName, objectName) var err error dstPrimarySP := s.CreateNewStorageProvider() @@ -1524,7 +1527,7 @@ func (s *StorageTestSuite) TestMigrationBucket() { // complete migration bucket var secondarySPIDs []uint32 - var secondarySPs []core.StorageProvider + var secondarySPs []*core.StorageProvider for _, ssp := range s.StorageProviders { if ssp.Info.Id != primarySP.Info.Id { @@ -1576,5 +1579,97 @@ func (s *StorageTestSuite) TestMigrationBucket() { // complete again msgCompleteMigrationBucket = storagetypes.NewMsgCompleteMigrateBucket(dstPrimarySP.OperatorKey.GetAddr(), bucketName, dstGVG.FamilyId, gvgMappings) s.SendTxBlock(dstPrimarySP.OperatorKey, msgCompleteMigrationBucket) +} + +func (s *StorageTestSuite) TestUpdateStorageParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.StorageQueryClient.Params(context.Background(), &storagetypes.QueryParamsRequest{}) + s.Require().NoError(err) + + updatedParams := queryParamsResp.Params + updatedParams.MaxBucketsPerAccount = 10000 + msgUpdateParams := &storagetypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update storage params", "Test update storage params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.StorageQueryClient.Params(context.Background(), &storagetypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } } diff --git a/e2e/tests/virtualgroup_test.go b/e2e/tests/virtualgroup_test.go index f6caef2c8..91afee122 100644 --- a/e2e/tests/virtualgroup_test.go +++ b/e2e/tests/virtualgroup_test.go @@ -5,12 +5,18 @@ import ( "context" "fmt" "math" + "reflect" + "strconv" "testing" "time" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" types2 "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/suite" @@ -54,25 +60,29 @@ func (s *VirtualGroupTestSuite) queryGlobalVirtualGroupByFamily(spID, familyID u GlobalVirtualGroupFamilyId: familyID, }) s.Require().NoError(err) - return resp.GlobalVirtualGroups -} - -func (s *VirtualGroupTestSuite) queryGlobalVirtualGroupFamilies(spID uint32) []*virtualgroupmoduletypes.GlobalVirtualGroupFamily { - resp, err := s.Client.GlobalVirtualGroupFamilies( - context.Background(), - &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamiliesRequest{StorageProviderId: spID}) + _, err = s.Client.VirtualGroupQueryClient.Params(context.Background(), &virtualgroupmoduletypes.QueryParamsRequest{}) s.Require().NoError(err) - return resp.GlobalVirtualGroupFamilies + return resp.GlobalVirtualGroups } func (s *VirtualGroupTestSuite) TestBasic() { - primarySP := s.StorageProviders[0] + primarySP := s.BaseSuite.PickStorageProvider() - gvgFamilies := s.queryGlobalVirtualGroupFamilies(primarySP.Info.Id) - s.Require().Greater(len(gvgFamilies), 0) + s.BaseSuite.RefreshGVGFamilies() + s.Require().Greater(len(primarySP.GlobalVirtualGroupFamilies), 0) - family := gvgFamilies[0] - s.T().Log(family.String()) + var gvgs []*virtualgroupmoduletypes.GlobalVirtualGroup + var gvg *virtualgroupmoduletypes.GlobalVirtualGroup + for _, g := range primarySP.GlobalVirtualGroupFamilies { + gvgs = g + } + s.Require().Greater(len(gvgs), 0) + + for _, g := range gvgs { + gvg = g + } + + srcGVGs := s.queryGlobalVirtualGroupByFamily(primarySP.Info.Id, gvg.FamilyId) var secondarySPIDs []uint32 for _, ssp := range s.StorageProviders { @@ -80,14 +90,14 @@ func (s *VirtualGroupTestSuite) TestBasic() { secondarySPIDs = append(secondarySPIDs, ssp.Info.Id) } } - s.BaseSuite.CreateGlobalVirtualGroup(&primarySP, family.Id, secondarySPIDs, 1) + s.BaseSuite.CreateGlobalVirtualGroup(primarySP, gvg.FamilyId, secondarySPIDs, 1) - gvgs := s.queryGlobalVirtualGroupByFamily(primarySP.Info.Id, family.Id) - s.Require().Equal(len(gvgs), len(family.GlobalVirtualGroupIds)+1) + gvgs = s.queryGlobalVirtualGroupByFamily(primarySP.Info.Id, gvg.FamilyId) + s.Require().Equal(len(gvgs), len(srcGVGs)+1) oldGVGIDs := make(map[uint32]bool) - for _, id := range family.GlobalVirtualGroupIds { - oldGVGIDs[id] = true + for _, gvg := range srcGVGs { + oldGVGIDs[gvg.Id] = true } var newGVG *virtualgroupmoduletypes.GlobalVirtualGroup @@ -136,7 +146,7 @@ func (s *VirtualGroupTestSuite) TestBasic() { } s.SendTxBlock(primarySP.OperatorKey, &msgDeleteGVG) - newGVGs := s.queryGlobalVirtualGroupByFamily(primarySP.Info.Id, family.Id) + newGVGs := s.queryGlobalVirtualGroupByFamily(primarySP.Info.Id, newGVG.FamilyId) for _, gvg := range newGVGs { if gvg.Id == newGVG.Id { @@ -156,8 +166,7 @@ func (s *VirtualGroupTestSuite) TestSettle() { queryFamilyResp, err := s.Client.GlobalVirtualGroupFamily( context.Background(), &virtualgroupmoduletypes.QueryGlobalVirtualGroupFamilyRequest{ - StorageProviderId: primarySp.Info.Id, - FamilyId: gvgFamilyId, + FamilyId: gvgFamilyId, }) s.Require().NoError(err) gvgFamily := queryFamilyResp.GlobalVirtualGroupFamily @@ -178,7 +187,7 @@ func (s *VirtualGroupTestSuite) TestSettle() { for _, secondarySp := range secondarySps { if _, ok := secondarySpIds[secondarySp.Info.Id]; ok { secondarySpAddrs = append(secondarySpAddrs, secondarySp.FundingKey.GetAddr().String()) - lastSecondarySp = &secondarySp + lastSecondarySp = secondarySp } } @@ -250,10 +259,10 @@ func (s *VirtualGroupTestSuite) TestSettle() { } } -func (s *VirtualGroupTestSuite) createObject() (string, string, core.StorageProvider, []core.StorageProvider, uint32, uint32) { +func (s *VirtualGroupTestSuite) createObject() (string, string, *core.StorageProvider, []*core.StorageProvider, uint32, uint32) { var err error - sp := s.StorageProviders[0] - secondarySps := make([]core.StorageProvider, 0) + sp := s.BaseSuite.PickStorageProvider() + secondarySps := make([]*core.StorageProvider, 0) gvg, found := sp.GetFirstGlobalVirtualGroup() s.Require().True(found) @@ -322,15 +331,15 @@ func (s *VirtualGroupTestSuite) createObject() (string, string, core.StorageProv secondarySPBlsPubKeys := make([]bls.PublicKey, 0) blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash() // every secondary sp signs the checksums - for i := 1; i < len(s.StorageProviders); i++ { - sig, err := core.BlsSignAndVerify(s.StorageProviders[i], blsSignHash) + for _, spID := range gvg.SecondarySpIds { + sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash) s.Require().NoError(err) secondarySigs = append(secondarySigs, sig) - pk, err := bls.PublicKeyFromBytes(s.StorageProviders[i].BlsKey.PubKey().Bytes()) + pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes()) s.Require().NoError(err) secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk) - if s.StorageProviders[i].Info.Id != sp.Info.Id { - secondarySps = append(secondarySps, s.StorageProviders[i]) + if s.StorageProviders[spID].Info.Id != sp.Info.Id { + secondarySps = append(secondarySps, s.StorageProviders[spID]) } } aggBlsSig, err := core.BlsAggregateAndVerify(secondarySPBlsPubKeys, blsSignHash, secondarySigs) @@ -353,7 +362,7 @@ func (s *VirtualGroupTestSuite) TestSPExit() { sp := s.BaseSuite.CreateNewStorageProvider() s.T().Logf("new SP Info: %s", sp.Info.String()) - successorSp := s.StorageProviders[0] + successorSp := s.BaseSuite.PickStorageProvider() // 2, create a new gvg group for this storage provider var secondarySPIDs []uint32 @@ -372,7 +381,13 @@ func (s *VirtualGroupTestSuite) TestSPExit() { s.BaseSuite.CreateObject(user, sp, gvgID, storagetestutil.GenRandomBucketName(), storagetestutil.GenRandomObjectName()) // 4. Create another gvg contains this new sp - anotherSP := s.StorageProviders[1] + var anotherSP *core.StorageProvider + for _, tsp := range s.StorageProviders { + if tsp.Info.Id != sp.Info.Id && tsp.Info.Id != successorSp.Info.Id { + anotherSP = tsp + break + } + } var anotherSecondarySPIDs []uint32 for _, ssp := range s.StorageProviders { if ssp.Info.Id != successorSp.Info.Id && ssp.Info.Id != anotherSP.Info.Id { @@ -384,9 +399,7 @@ func (s *VirtualGroupTestSuite) TestSPExit() { } anotherSecondarySPIDs = append(anotherSecondarySPIDs, sp.Info.Id) - anotherSPsFamilies := s.queryGlobalVirtualGroupFamilies(anotherSP.Info.Id) - s.Require().Greater(len(anotherSPsFamilies), 0) - anotherGVGID, _ := s.BaseSuite.CreateGlobalVirtualGroup(&anotherSP, anotherSPsFamilies[0].Id, anotherSecondarySPIDs, 1) + anotherGVGID, _ := s.BaseSuite.CreateGlobalVirtualGroup(anotherSP, 0, anotherSecondarySPIDs, 1) // 5. sp exit s.SendTxBlock(sp.OperatorKey, &virtualgroupmoduletypes.MsgStorageProviderExit{ @@ -496,7 +509,7 @@ func (s *VirtualGroupTestSuite) TestSPExit_CreateAndDeleteBucket() { sp := s.BaseSuite.CreateNewStorageProvider() s.T().Logf("new SP Info: %s", sp.Info.String()) - successorSp := s.StorageProviders[0] + successorSp := s.BaseSuite.PickStorageProvider() // 2, create a new gvg group for this storage provider var secondarySPIDs []uint32 @@ -544,3 +557,96 @@ func (s *VirtualGroupTestSuite) TestSPExit_CreateAndDeleteBucket() { ) } + +func (s *VirtualGroupTestSuite) TestUpdateVirtualGroupParams() { + // 1. create proposal + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + queryParamsResp, err := s.Client.VirtualGroupQueryClient.Params(context.Background(), &virtualgroupmoduletypes.QueryParamsRequest{}) + s.Require().NoError(err) + updatedParams := queryParamsResp.Params + updatedParams.MaxLocalVirtualGroupNumPerBucket = 1000 + + msgUpdateParams := &virtualgroupmoduletypes.MsgUpdateParams{ + Authority: govAddr, + Params: updatedParams, + } + + proposal, err := v1.NewMsgSubmitProposal([]sdk.Msg{msgUpdateParams}, sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + s.Validator.GetAddr().String(), "", "update virtual group params", "Test update virtual group params") + s.Require().NoError(err) + txBroadCastResp, err := s.SendTxBlockWithoutCheck(proposal, s.Validator) + s.Require().NoError(err) + s.T().Log("create proposal tx hash: ", txBroadCastResp.TxResponse.TxHash) + + // get proposal id + proposalID := 0 + txResp, err := s.WaitForTx(txBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + if txResp.Code == 0 && txResp.Height > 0 { + for _, event := range txResp.Events { + if event.Type == "submit_proposal" { + proposalID, err = strconv.Atoi(event.GetAttributes()[0].Value) + s.Require().NoError(err) + } + } + } + + // 2. vote + if proposalID == 0 { + s.T().Errorf("proposalID is 0") + return + } + s.T().Log("proposalID: ", proposalID) + mode := tx.BroadcastMode_BROADCAST_MODE_SYNC + txOpt := &types.TxOption{ + Mode: &mode, + Memo: "", + FeeAmount: sdk.NewCoins(sdk.NewCoin("BNB", sdk.NewInt(1000000000000000000))), + } + voteBroadCastResp, err := s.SendTxBlockWithoutCheckWithTxOpt(v1.NewMsgVote(s.Validator.GetAddr(), uint64(proposalID), v1.OptionYes, ""), + s.Validator, txOpt) + s.Require().NoError(err) + voteResp, err := s.WaitForTx(voteBroadCastResp.TxResponse.TxHash) + s.Require().NoError(err) + s.T().Log("vote tx hash: ", voteResp.TxHash) + if voteResp.Code > 0 { + s.T().Errorf("voteTxResp.Code > 0") + return + } + + // 3. query proposal until it is end voting period +CheckProposalStatus: + for { + queryProposalResp, err := s.Client.Proposal(context.Background(), &v1.QueryProposalRequest{ProposalId: uint64(proposalID)}) + s.Require().NoError(err) + if queryProposalResp.Proposal.Status != v1.StatusVotingPeriod { + switch queryProposalResp.Proposal.Status { + case v1.StatusDepositPeriod: + s.T().Errorf("proposal deposit period") + return + case v1.StatusRejected: + s.T().Errorf("proposal rejected") + return + case v1.StatusPassed: + s.T().Logf("proposal passed") + break CheckProposalStatus + case v1.StatusFailed: + s.T().Errorf("proposal failed, reason %s", queryProposalResp.Proposal.FailedReason) + return + } + } + time.Sleep(1 * time.Second) + } + + // 4. check params updated + err = s.WaitForNextBlock() + s.Require().NoError(err) + + updatedQueryParamsResp, err := s.Client.VirtualGroupQueryClient.Params(context.Background(), &virtualgroupmoduletypes.QueryParamsRequest{}) + s.Require().NoError(err) + if reflect.DeepEqual(updatedQueryParamsResp.Params, updatedParams) { + s.T().Logf("update params success") + } else { + s.T().Errorf("update params failed") + } +} diff --git a/go.mod b/go.mod index 1642ecbbb..c74e06b2a 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,6 @@ require ( cosmossdk.io/core v0.6.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/log v1.1.0 // indirect - cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -55,13 +54,11 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.0 // indirect - github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -176,10 +173,10 @@ replace ( cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9 cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.23.0 - github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.1 + github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.2 github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3 + github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.4 github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1-alpha.1 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/go.sum b/go.sum index 8c67e84f0..7a0a07453 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,6 @@ cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= -cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= -cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -161,12 +159,12 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsy github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.1 h1:DU/lvMpzyS5PzLaAcBu1xaQ2/ezuxcJFdi0ej3ZeAsc= -github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.1/go.mod h1:EBmwmUdaNbGPyGjf1cMuoN3pAeM2tQu7Lfg95813EAw= +github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.2 h1:ys9kmgtRx04wcCextE6CrVmbL1bJDklWr+hWgm1y2k4= +github.com/bnb-chain/greenfield-cometbft v0.0.2-alpha.2/go.mod h1:EBmwmUdaNbGPyGjf1cMuoN3pAeM2tQu7Lfg95813EAw= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 h1:XcWulGacHVRiSCx90Q8Y//ajOrLNBQWR/KDB89dy3cU= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1/go.mod h1:ey1CiK4bYo1RBNJLRiVbYr5CMdSxci9S/AZRINLtppI= -github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3 h1:b7guOnZt6gFS3HjYITV3x/+vU0NVL+QQCDPDHr22ygg= -github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3/go.mod h1:xgxstYzesnI8FPGm3wcb9ddwnYNXBIbA3ZJBum+8BuU= +github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.4 h1:Q5EzT1r3jKv0BZgVJkYFVvqn+7Ghj6RU7mUM0VkUZ4U= +github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.4/go.mod h1:EghjYxFg4NRNMfTJ6g9rVhjImhXQm+tuboknHqeGmJA= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9 h1:6fLpmmI0EZvDTfPvI0zy5dBaaTUboHnEkoC5/p/w8TQ= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230425074444-eb5869b05fe9/go.mod h1:rbc4o84RSEvhf09o2+4Qiazsv0snRJLiEZdk17HeIDw= github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230425074444-eb5869b05fe9 h1:1ZdK+iR1Up02bOa2YTZCml7PBpP//kcdamOcK6aWO/s= @@ -238,8 +236,6 @@ github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOG github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= -github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -268,8 +264,6 @@ github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoK github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/ledger-cosmos-go v0.13.0 h1:ex0CvCxToSR7j5WjrghPu2Bu9sSXKikjnVvUryNnx4s= github.com/cosmos/ledger-cosmos-go v0.13.0/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= -github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= diff --git a/proto/greenfield/storage/common.proto b/proto/greenfield/storage/common.proto index ec69cb7aa..1cb6da4b8 100644 --- a/proto/greenfield/storage/common.proto +++ b/proto/greenfield/storage/common.proto @@ -102,10 +102,10 @@ message LocalVirtualGroup { // id is the identifier of the local virtual group. uint32 id = 1; // global_virtual_group_id is the identifier of the global virtual group. - uint32 global_virtual_group_id = 3; + uint32 global_virtual_group_id = 2; // stored_size is the size of the stored data in the local virtual group. - uint64 stored_size = 4; + uint64 stored_size = 3; // total_charge_size is the total charged size of the objects in the LVG. // Notice that the minimum unit of charge is 128K - uint64 total_charge_size = 5; + uint64 total_charge_size = 4; } diff --git a/proto/greenfield/storage/events.proto b/proto/greenfield/storage/events.proto index d14c1c38c..527da5f34 100644 --- a/proto/greenfield/storage/events.proto +++ b/proto/greenfield/storage/events.proto @@ -52,8 +52,8 @@ message EventDeleteBucket { (gogoproto.customtype) = "Uint", (gogoproto.nullable) = false ]; - // primary_sp_id is the unique id of primary sp. - uint32 primary_sp_id = 5; + // global_virtual_group_family_id defines the unique id of gvg family + uint32 global_virtual_group_family_id = 5; } // EventUpdateBucketInfo is emitted on MsgUpdateBucketInfo @@ -68,16 +68,14 @@ message EventUpdateBucketInfo { (gogoproto.customtype) = "Uint", (gogoproto.nullable) = false ]; - // charged_read_quota_before define the read quota before updated - uint64 charged_read_quota_before = 4; // charged_read_quota_after define the read quota after updated - uint64 charged_read_quota_after = 5; - // payment_address_before define the payment address before updated - string payment_address_before = 6; - // payment_address_after define the payment address after updated - string payment_address_after = 7; + uint64 charged_read_quota = 4; + // payment_address define the payment address after updated + string payment_address = 5; // visibility defines the highest permission of object. - VisibilityType visibility = 8; + VisibilityType visibility = 6; + // global_virtual_group_family_id defines the gvg family id after migrated. + uint32 global_virtual_group_family_id = 7; } // EventDiscontinueBucket is emitted on MsgDiscontinueBucket @@ -510,6 +508,6 @@ message EventCompleteMigrationBucket { ]; // The family id that the bucket to be migrated to uint32 global_virtual_group_family_id = 4; - // The src and dst gvg mapping - repeated GVGMapping gvg_mappings = 5; + // The src_primary_sp_id defines the primary sp id of the bucket before migrate. + uint32 src_primary_sp_id = 5; } diff --git a/proto/greenfield/storage/query.proto b/proto/greenfield/storage/query.proto index ad2bb14eb..411f7f931 100644 --- a/proto/greenfield/storage/query.proto +++ b/proto/greenfield/storage/query.proto @@ -118,6 +118,16 @@ service Query { option (google.api.http).get = "/greenfield/storage/lock_fee"; } + // Queries a bucket extra info (with gvg bindings and price time) with specify name. + rpc HeadBucketExtra(QueryHeadBucketExtraRequest) returns (QueryHeadBucketExtraResponse) { + option (google.api.http).get = "/greenfield/storage/head_bucket_extra/{bucket_name}"; + } + + // Queries whether read and storage prices changed for the bucket. + rpc QueryIsPriceChanged(QueryIsPriceChangedRequest) returns (QueryIsPriceChangedResponse) { + option (google.api.http).get = "/greenfield/storage/is_price_changed/{bucket_name}"; + } + // this line is used by starport scaffolding # 2 } @@ -291,4 +301,59 @@ message QueryLockFeeResponse { ]; } +message QueryHeadBucketExtraRequest { + string bucket_name = 1; +} + +message QueryHeadBucketExtraResponse { + InternalBucketInfo extra_info = 1; +} + +message QueryIsPriceChangedRequest { + string bucket_name = 1; +} + +message QueryIsPriceChangedResponse { + bool changed = 1; + string current_read_price = 2 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string current_primary_store_price = 3 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string current_secondary_store_price = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string current_validator_tax_rate = 5 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string new_read_price = 6 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string new_primary_store_price = 7 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string new_secondary_store_price = 8 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string new_validator_tax_rate = 9 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} // this line is used by starport scaffolding # 3 diff --git a/proto/greenfield/storage/types.proto b/proto/greenfield/storage/types.proto index 0b28518f9..a166e9a19 100644 --- a/proto/greenfield/storage/types.proto +++ b/proto/greenfield/storage/types.proto @@ -30,17 +30,14 @@ message BucketInfo { int64 create_at = 6; // payment_address is the address of the payment account string payment_address = 7 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // primary_sp_id is the unique id of the primary sp. Objects belongs to this bucket will never - // leave this SP, unless you explicitly shift them to another SP. - uint32 primary_sp_id = 8; // global_virtual_group_family_id defines the unique id of gvg family - uint32 global_virtual_group_family_id = 9; + uint32 global_virtual_group_family_id = 8; // charged_read_quota defines the traffic quota for read in bytes per month. // The available read data for each user is the sum of the free read data provided by SP and // the ChargeReadQuota specified here. - uint64 charged_read_quota = 10; + uint64 charged_read_quota = 9; // bucket_status define the status of the bucket. - BucketStatus bucket_status = 11; + BucketStatus bucket_status = 10; } message InternalBucketInfo { diff --git a/proto/greenfield/virtualgroup/events.proto b/proto/greenfield/virtualgroup/events.proto index 6fe9aed0f..47e25debe 100644 --- a/proto/greenfield/virtualgroup/events.proto +++ b/proto/greenfield/virtualgroup/events.proto @@ -9,19 +9,14 @@ option go_package = "github.com/bnb-chain/greenfield/x/virtualgroup/types"; message EventCreateGlobalVirtualGroup { // The unique id of global virtual group, which is generated by blockchain uint32 id = 1; - // The id of the global virtual group family where the gvg belongs uint32 family_id = 2; - // The id of the primary sp who create this global virtual group uint32 primary_sp_id = 3; - // The ids of the secondary sps which belongs to this global virtual group repeated uint32 secondary_sp_ids = 4; - // The store size of all the objects stores in this global virtual group uint64 stored_size = 5; - // The virtual payment address of this global virtual group, which is auto generated by blockchain // And, all users' payment flows will flow to this account string virtual_payment_address = 6 [(cosmos_proto.scalar) = "cosmos.AddressString"]; @@ -33,20 +28,6 @@ message EventCreateGlobalVirtualGroup { ]; } -message EventCreateGlobalVirtualGroupFamily { - // The id of global virtual group family, which is auto generated by blockchain - uint32 id = 1; - - // The virtual payment address of this global virtual group family, which is auto generated by blockcahin - // all users' read quota payment flows will flow to this account. - string virtual_payment_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; -} - -message EventDeleteGlobalVirtualGroup { - // The id of global virtual group, which has been deleted - uint32 id = 1; -} - message EventUpdateGlobalVirtualGroup { // The id of global virtual group, which has been updated uint32 id = 1; @@ -58,6 +39,45 @@ message EventUpdateGlobalVirtualGroup { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; + // Primary SP ID represents the unique id of the primary storage provider in the group. + uint32 primary_sp_id = 4; + // Secondary SP IDs represents the list of unique identifiers of the secondary storage providers in the group. + repeated uint32 secondary_sp_ids = 5; +} + +message EventDeleteGlobalVirtualGroup { + // The id of global virtual group, which has been deleted + uint32 id = 1; + // The id of the primary sp who create this global virtual group family + uint32 primary_sp_id = 2; +} + +message EventCreateGlobalVirtualGroupFamily { + // The id of global virtual group family, which is auto generated by blockchain + uint32 id = 1; + // The id of the primary sp who create this global virtual group family + uint32 primary_sp_id = 2; + // The virtual payment address of this global virtual group family, which is auto generated by blockcahin + // all users' read quota payment flows will flow to this account. + string virtual_payment_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // global_virtual_group_ids are the ids of gvgs in this family + repeated uint32 global_virtual_group_ids = 4; +} + +message EventUpdateGlobalVirtualGroupFamily { + // The id of global virtual group family, which is auto generated by blockchain + uint32 id = 1; + // The id of the primary sp who create this global virtual group family + uint32 primary_sp_id = 2; + // global_virtual_group_ids are the ids of gvgs in this family + repeated uint32 global_virtual_group_ids = 3; +} + +message EventDeleteGlobalVirtualGroupFamily { + // The id of global virtual group family, which is auto generated by blockchain + uint32 id = 1; + // The id of the primary sp who create this global virtual group family + uint32 primary_sp_id = 2; } message EventCreateLocalVirtualGroup { @@ -79,10 +99,27 @@ message EventCreateLocalVirtualGroup { message EventUpdateLocalVirtualGroup { // The id of the local virtual group uint32 id = 1; - // The id of the global virtual group - uint32 global_virtual_group_id = 2; + // The id of the bucket + string bucket_id = 2 [ + (cosmos_proto.scalar) = "cosmos.Uint", + (gogoproto.customtype) = "Uint", + (gogoproto.nullable) = false + ]; + // The global_virtual_group_id is gvgid of lvg after migrate + uint32 global_virtual_group_id = 3; // The stored size of all the objects stores in this lvg - uint64 stored_size = 3; + uint64 stored_size = 4; +} + +message EventDeleteLocalVirtualGroup { + // The id of the local virtual group + uint32 id = 1; + // The id of the bucket + string bucket_id = 2 [ + (cosmos_proto.scalar) = "cosmos.Uint", + (gogoproto.customtype) = "Uint", + (gogoproto.nullable) = false + ]; } message EventSwapOut { diff --git a/proto/greenfield/virtualgroup/query.proto b/proto/greenfield/virtualgroup/query.proto index 9f3f14b97..649326401 100644 --- a/proto/greenfield/virtualgroup/query.proto +++ b/proto/greenfield/virtualgroup/query.proto @@ -29,17 +29,22 @@ service Query { option (google.api.http).get = "/greenfield/virtualgroup/global_virtual_group_by_family_id"; } - // Queries a list of global virtual group families by storage provider id. - rpc GlobalVirtualGroupFamilies(QueryGlobalVirtualGroupFamiliesRequest) returns (QueryGlobalVirtualGroupFamiliesResponse) { - option (google.api.http).get = "/greenfield/virtualgroup/global_virtual_group_families"; - } - // Queries a global virtual group family by its id. rpc GlobalVirtualGroupFamily(QueryGlobalVirtualGroupFamilyRequest) returns (QueryGlobalVirtualGroupFamilyResponse) { option (google.api.http).get = "/greenfield/virtualgroup/global_virtual_group_family"; } // this line is used by starport scaffolding # 2 + + // Queries a list of GlobalVirtualGroupFamilies items. + rpc GlobalVirtualGroupFamilies(QueryGlobalVirtualGroupFamiliesRequest) returns (QueryGlobalVirtualGroupFamiliesResponse) { + option (google.api.http).get = "/greenfield/virtualgroup/global_virtual_group_families"; + } + + // AvailableGlobalVirtualGroupFamilies filters a list of GlobalVirtualGroupFamilies ID which are qualified to create bucket on + rpc AvailableGlobalVirtualGroupFamilies(AvailableGlobalVirtualGroupFamiliesRequest) returns (AvailableGlobalVirtualGroupFamiliesResponse) { + option (google.api.http).get = "/greenfield/virtualgroup/available_global_virtual_group_families"; + } } // QueryParamsRequest is request type for the Query/Params RPC method. @@ -68,22 +73,28 @@ message QueryGlobalVirtualGroupByFamilyIDResponse { repeated GlobalVirtualGroup global_virtual_groups = 1; } +message QueryGlobalVirtualGroupFamilyRequest { + uint32 family_id = 1; +} + +message QueryGlobalVirtualGroupFamilyResponse { + GlobalVirtualGroupFamily global_virtual_group_family = 1; +} + +// this line is used by starport scaffolding # 3 message QueryGlobalVirtualGroupFamiliesRequest { - uint32 storage_provider_id = 1; - cosmos.base.query.v1beta1.PageRequest pagination = 2; + cosmos.base.query.v1beta1.PageRequest pagination = 1; } message QueryGlobalVirtualGroupFamiliesResponse { - repeated GlobalVirtualGroupFamily global_virtual_group_families = 1; + repeated GlobalVirtualGroupFamily gvg_families = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } -message QueryGlobalVirtualGroupFamilyRequest { - uint32 storage_provider_id = 1; - uint32 family_id = 2; +message AvailableGlobalVirtualGroupFamiliesRequest { + repeated uint32 global_virtual_group_family_ids = 1; } -message QueryGlobalVirtualGroupFamilyResponse { - GlobalVirtualGroupFamily global_virtual_group_family = 1; +message AvailableGlobalVirtualGroupFamiliesResponse { + repeated uint32 global_virtual_group_family_ids = 1; } -// this line is used by starport scaffolding # 3 diff --git a/proto/greenfield/virtualgroup/types.proto b/proto/greenfield/virtualgroup/types.proto index 393097b08..2a1e40865 100644 --- a/proto/greenfield/virtualgroup/types.proto +++ b/proto/greenfield/virtualgroup/types.proto @@ -35,10 +35,12 @@ message GlobalVirtualGroup { message GlobalVirtualGroupFamily { // id is the identifier of the global virtual group family. uint32 id = 1; + // primary_sp_id + uint32 primary_sp_id = 2; // global_virtual_group_ids is a list of identifiers of the global virtual groups associated with the family. - repeated uint32 global_virtual_group_ids = 2; + repeated uint32 global_virtual_group_ids = 3; // virtual_payment_address is the payment address associated with the global virtual group family. - string virtual_payment_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string virtual_payment_address = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; } message GlobalVirtualGroupsBindingOnBucket { @@ -57,6 +59,8 @@ message GlobalVirtualGroupsBindingOnBucket { message GVGStatisticsWithinSP { // storage_provider_id defines the id of the sp which the statistics associated to uint32 storage_provider_id = 1; + // primary_sp_family_count defines the number of the family which this sp serves as primary sp + uint32 primary_count = 2; // secondary_count defines the number of global virtual groups (GVGs) in // which this storage provider serves as a secondary storage provider. uint32 secondary_count = 3; diff --git a/scripts/protoc-swagger-gen.sh b/scripts/protoc-swagger-gen.sh index c4e9ebfd7..67b361d70 100755 --- a/scripts/protoc-swagger-gen.sh +++ b/scripts/protoc-swagger-gen.sh @@ -1,4 +1,11 @@ -#!/usr/bin/env bash +#!/bin/bash + + +which swagger-combine || npm install -g swagger-combine +which protoc-gen-swagger || go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger + +swagger-combine -v +buf --version set -eo pipefail @@ -22,4 +29,4 @@ cd .. swagger-combine ./swagger/config.json -o ./swagger/static/swagger.yaml -f yaml --continueOnConflictingPaths true --includeDefinitions true # clean swagger files -rm -rf ./tmp-swagger-gen \ No newline at end of file +rm -rf ./tmp-swagger-gen diff --git a/sdk/client/gnfd_client.go b/sdk/client/gnfd_client.go index ea3ce9aa0..39a6c1c51 100644 --- a/sdk/client/gnfd_client.go +++ b/sdk/client/gnfd_client.go @@ -3,9 +3,10 @@ package client import ( _ "encoding/json" "net/http" - "strings" + "github.com/cometbft/cometbft/rpc/client" rpchttp "github.com/cometbft/cometbft/rpc/client/http" + bftws "github.com/cometbft/cometbft/rpc/client/http/v2" sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" @@ -35,7 +36,6 @@ import ( sptypes "github.com/bnb-chain/greenfield/x/sp/types" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" virtualgroupmoduletypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" - bfthttp "github.com/cometbft/cometbft/rpc/client/http" ) // AuthQueryClient is a type to define the auth types Query Client @@ -140,8 +140,10 @@ type GreenfieldClient struct { TxClient // TmService holds the tendermint service client TmClient - // tendermintClient directly interact with tendermint Node - tendermintClient *bfthttp.HTTP + // tendermintClient directly interact with tendermint Node via rpc + tendermintClient client.Client + // useWebSocket + useWebSocket bool // keyManager is the manager used for generating and managing keys. keyManager keys.KeyManager // chainId is the id of the chain. @@ -186,16 +188,24 @@ func newGreenfieldClient(rpcAddr, chainId string, rpcClient *rpchttp.HTTP, opts setClientsConn(client, client.grpcConn) return client, nil } - if len(strings.TrimSpace(rpcAddr)) == 0 { - return nil, types.RpcAddressNotProvidedError + if client.useWebSocket { + wsClient, err := bftws.New(rpcAddr, "/websocket") + if err != nil { + return nil, err + } + err = wsClient.Start() + if err != nil { + return nil, err + } + // override the tendermintClient with wsClient and use it in the cosmos context + client.tendermintClient = wsClient } - txConfig := authtx.NewTxConfig(cdc, []signing.SignMode{signing.SignMode_SIGN_MODE_EIP_712}) clientCtx := sdkclient.Context{}. WithCodec(cdc). WithInterfaceRegistry(cdc.InterfaceRegistry()). WithTxConfig(txConfig). - WithClient(rpcClient) + WithClient(client.tendermintClient) setClientsConn(client, clientCtx) return client, nil diff --git a/sdk/client/gnfd_client_option.go b/sdk/client/gnfd_client_option.go index fb01cdf36..8ec51e17d 100644 --- a/sdk/client/gnfd_client_option.go +++ b/sdk/client/gnfd_client_option.go @@ -33,6 +33,13 @@ func WithGrpcConnectionAndDialOption(grpcAddr string, opts ...grpc.DialOption) G }) } +// WithWebSocketClient returns a GreenfieldClientOption which specify that connection is a websocket connection +func WithWebSocketClient() GreenfieldClientOption { + return GreenfieldClientOptionFunc(func(client *GreenfieldClient) { + client.useWebSocket = true + }) +} + // grpcConn is used to establish a connection with a given address and dial options. func grpcConn(addr string, opts ...grpc.DialOption) *grpc.ClientConn { conn, err := grpc.Dial( diff --git a/sdk/client/gnfd_tm.go b/sdk/client/gnfd_tm.go index 39e3f97fa..a3558e039 100644 --- a/sdk/client/gnfd_tm.go +++ b/sdk/client/gnfd_tm.go @@ -5,6 +5,7 @@ import ( "encoding/hex" ctypes "github.com/cometbft/cometbft/rpc/core/types" + "github.com/cometbft/cometbft/votepool" ) // GetBlock by height, gets the latest block if height is nil @@ -40,3 +41,20 @@ func (c *GreenfieldClient) GetHeader(ctx context.Context, height *int64) (*ctype func (c *GreenfieldClient) GetUnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) { return c.tendermintClient.UnconfirmedTxs(ctx, limit) } + +func (c *GreenfieldClient) GetCommit(ctx context.Context, height int64) (*ctypes.ResultCommit, error) { + return c.tendermintClient.Commit(ctx, &height) +} + +func (c *GreenfieldClient) GetStatus(ctx context.Context) (*ctypes.ResultStatus, error) { + return c.tendermintClient.Status(ctx) +} + +func (c *GreenfieldClient) BroadcastVote(ctx context.Context, vote votepool.Vote) error { + _, err := c.tendermintClient.BroadcastVote(ctx, vote) + return err +} + +func (c *GreenfieldClient) QueryVote(ctx context.Context, eventType int, eventHash []byte) (*ctypes.ResultQueryVote, error) { + return c.tendermintClient.QueryVote(ctx, eventType, eventHash) +} diff --git a/sdk/client/gnfd_tm_test.go b/sdk/client/gnfd_tm_test.go index 73cddc589..861f112ec 100644 --- a/sdk/client/gnfd_tm_test.go +++ b/sdk/client/gnfd_tm_test.go @@ -5,17 +5,18 @@ import ( "testing" "time" - "github.com/bnb-chain/greenfield/sdk/client/test" - "github.com/bnb-chain/greenfield/sdk/keys" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/assert" + + "github.com/bnb-chain/greenfield/sdk/client/test" + "github.com/bnb-chain/greenfield/sdk/keys" ) func TestTmClient(t *testing.T) { km, err := keys.NewPrivateKeyManager(test.TEST_PRIVATE_KEY) assert.NoError(t, err) - gnfdCli, err := NewGreenfieldClient(test.TEST_RPC_ADDR, test.TEST_CHAIN_ID, WithKeyManager(km)) + gnfdCli, err := NewGreenfieldClient(test.TEST_RPC_ADDR, test.TEST_CHAIN_ID, WithKeyManager(km), WithWebSocketClient()) assert.NoError(t, err) to, err := sdk.AccAddressFromHexUnsafe(test.TEST_ADDR) assert.NoError(t, err) diff --git a/sdk/client/test/bank/client_query_test.go b/sdk/client/test/bank/client_query_test.go index c49f96df9..370eead8e 100644 --- a/sdk/client/test/bank/client_query_test.go +++ b/sdk/client/test/bank/client_query_test.go @@ -30,7 +30,7 @@ func TestBankAllBalances(t *testing.T) { km, err := keys.NewPrivateKeyManager("e3ac46e277677f0f103774019d03bd89c7b4b5ecc554b2650bd5d5127992c20c") assert.NoError(t, err) t.Log(km) - client, err := gnfdclient.NewGreenfieldClient(test.TEST_RPC_ADDR, test.TEST_CHAIN_ID) + client, err := gnfdclient.NewGreenfieldClient(test.TEST_RPC_ADDR, test.TEST_CHAIN_ID, gnfdclient.WithWebSocketClient()) assert.NoError(t, err) query := banktypes.QueryAllBalancesRequest{ diff --git a/sdk/client/test/config.go b/sdk/client/test/config.go index 86b6cceec..5d0169089 100644 --- a/sdk/client/test/config.go +++ b/sdk/client/test/config.go @@ -1,7 +1,7 @@ package test const ( - TEST_PRIVATE_KEY = "a6d9af079ae116f6ba2ff5cc269bb11e028223229473418ced422e6976bb8cc9" + TEST_PRIVATE_KEY = "a6d9af079ae116f6ba2ff5cc269bb11e028223229473418ced422e6976bb8cc9" // address: 0xF03Af05bE1a3ADF6Df23E7ee9A151718284FAE1a TEST_PUBKEY = "0398e12884f09328bf64a41d658c0d9949d1588f6ba96bbf75167d7e009f250fd5" TEST_ADDR = "0x76d244CE05c3De4BbC6fDd7F56379B145709ade9" TEST_ADDR2 = "0x5dEfC28ce1Ed331D56aB6F607f78708880e11Bea" diff --git a/sdk/client/tx.go b/sdk/client/tx.go index 712cd1700..a6e338a4b 100644 --- a/sdk/client/tx.go +++ b/sdk/client/tx.go @@ -2,8 +2,11 @@ package client import ( "context" + "fmt" + ctypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" + sdkclient "github.com/cosmos/cosmos-sdk/client" clitx "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" @@ -18,12 +21,12 @@ import ( ) type TransactionClient interface { - BroadcastTx(msgs []sdk.Msg, txOpt *types.TxOption, opts ...grpc.CallOption) (*tx.BroadcastTxResponse, error) - SimulateTx(msgs []sdk.Msg, txOpt *types.TxOption, opts ...grpc.CallOption) (*tx.SimulateResponse, error) - SignTx(msgs []sdk.Msg, txOpt *types.TxOption) ([]byte, error) - GetNonce() (uint64, error) - GetNonceByAddr(addr sdk.AccAddress) (uint64, error) - GetAccountByAddr(addr sdk.AccAddress) (authtypes.AccountI, error) + BroadcastTx(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption, opts ...grpc.CallOption) (*tx.BroadcastTxResponse, error) + SimulateTx(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption, opts ...grpc.CallOption) (*tx.SimulateResponse, error) + SignTx(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption) ([]byte, error) + GetNonce(ctx context.Context) (uint64, error) + GetNonceByAddr(ctx context.Context, addr sdk.AccAddress) (uint64, error) + GetAccountByAddr(ctx context.Context, addr sdk.AccAddress) (authtypes.AccountI, error) } // BroadcastTx signs and broadcasts a tx with simulated gas(if not provided in txOpt) @@ -46,7 +49,29 @@ func (c *GreenfieldClient) BroadcastTx(ctx context.Context, msgs []sdk.Msg, txOp if txOpt != nil && txOpt.Mode != nil { mode = *txOpt.Mode } - txRes, err := c.TxClient.BroadcastTx( + + // use the tendermint websocket client + if c.useWebSocket { + var txRes *ctypes.ResultBroadcastTx + switch mode { + case tx.BroadcastMode_BROADCAST_MODE_SYNC: + txRes, err = c.tendermintClient.BroadcastTxSync(ctx, txSignedBytes) + case tx.BroadcastMode_BROADCAST_MODE_ASYNC: + txRes, err = c.tendermintClient.BroadcastTxAsync(ctx, txSignedBytes) + default: + return nil, fmt.Errorf("mode %s is not support broadcast mode when use websocket", mode.String()) + } + if errRes := sdkclient.CheckTendermintError(err, txSignedBytes); errRes != nil { + return &tx.BroadcastTxResponse{TxResponse: errRes}, nil + } + if err != nil { + return nil, err + } + return &tx.BroadcastTxResponse{TxResponse: sdk.NewResponseFormatBroadcastTx(txRes)}, nil + } + + // use cosmos sdk tx Client + return c.TxClient.BroadcastTx( ctx, &tx.BroadcastTxRequest{ Mode: mode, @@ -54,17 +79,13 @@ func (c *GreenfieldClient) BroadcastTx(ctx context.Context, msgs []sdk.Msg, txOp }, opts..., ) - if err != nil { - return nil, err - } - return txRes, nil } // SimulateTx simulates a tx and gets Gas info func (c *GreenfieldClient) SimulateTx(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption, opts ...grpc.CallOption) (*tx.SimulateResponse, error) { txConfig := authtx.NewTxConfig(c.codec, []signing.SignMode{signing.SignMode_SIGN_MODE_EIP_712}) txBuilder := txConfig.NewTxBuilder() - err := c.constructTx(msgs, txOpt, txBuilder) + err := c.constructTx(ctx, msgs, txOpt, txBuilder) if err != nil { return nil, err } @@ -117,7 +138,7 @@ func (c *GreenfieldClient) signTx(ctx context.Context, txConfig client.TxConfig, } } - account, err := c.GetAccountByAddr(km.GetAddr()) + account, err := c.GetAccountByAddr(ctx, km.GetAddr()) if err != nil { return nil, err } @@ -154,7 +175,7 @@ func (c *GreenfieldClient) signTx(ctx context.Context, txConfig client.TxConfig, } // setSingerInfo gathers the signer info by doing "empty signature" hack, and inject it into txBuilder -func (c *GreenfieldClient) setSingerInfo(txBuilder client.TxBuilder, txOpt *types.TxOption) error { +func (c *GreenfieldClient) setSingerInfo(ctx context.Context, txBuilder client.TxBuilder, txOpt *types.TxOption) error { var km keys.KeyManager var err error @@ -166,7 +187,7 @@ func (c *GreenfieldClient) setSingerInfo(txBuilder client.TxBuilder, txOpt *type return err } } - account, err := c.GetAccountByAddr(km.GetAddr()) + account, err := c.GetAccountByAddr(ctx, km.GetAddr()) if err != nil { return err } @@ -187,7 +208,7 @@ func (c *GreenfieldClient) setSingerInfo(txBuilder client.TxBuilder, txOpt *type return nil } -func (c *GreenfieldClient) constructTx(msgs []sdk.Msg, txOpt *types.TxOption, txBuilder client.TxBuilder) error { +func (c *GreenfieldClient) constructTx(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption, txBuilder client.TxBuilder) error { for _, m := range msgs { if err := m.ValidateBasic(); err != nil { return err @@ -212,12 +233,12 @@ func (c *GreenfieldClient) constructTx(msgs []sdk.Msg, txOpt *types.TxOption, tx } } // inject signer info into txBuilder, it is needed for simulating and signing - return c.setSingerInfo(txBuilder, txOpt) + return c.setSingerInfo(ctx, txBuilder, txOpt) } func (c *GreenfieldClient) constructTxWithGasInfo(ctx context.Context, msgs []sdk.Msg, txOpt *types.TxOption, txConfig client.TxConfig, txBuilder client.TxBuilder) error { // construct a tx with txOpt excluding GasLimit and - if err := c.constructTx(msgs, txOpt, txBuilder); err != nil { + if err := c.constructTx(ctx, msgs, txOpt, txBuilder); err != nil { return err } txBytes, err := txConfig.TxEncoder()(txBuilder.GetTx()) @@ -258,28 +279,28 @@ func (c *GreenfieldClient) constructTxWithGasInfo(ctx context.Context, msgs []sd return nil } -func (c *GreenfieldClient) GetNonce() (uint64, error) { +func (c *GreenfieldClient) GetNonce(ctx context.Context) (uint64, error) { km, err := c.GetKeyManager() if err != nil { return 0, err } - account, err := c.GetAccountByAddr(km.GetAddr()) + account, err := c.GetAccountByAddr(ctx, km.GetAddr()) if err != nil { return 0, err } return account.GetSequence(), nil } -func (c *GreenfieldClient) GetNonceByAddr(addr sdk.AccAddress) (uint64, error) { - account, err := c.GetAccountByAddr(addr) +func (c *GreenfieldClient) GetNonceByAddr(ctx context.Context, addr sdk.AccAddress) (uint64, error) { + account, err := c.GetAccountByAddr(ctx, addr) if err != nil { return 0, err } return account.GetSequence(), nil } -func (c *GreenfieldClient) GetAccountByAddr(addr sdk.AccAddress) (authtypes.AccountI, error) { - acct, err := c.AuthQueryClient.Account(context.Background(), &authtypes.QueryAccountRequest{Address: addr.String()}) +func (c *GreenfieldClient) GetAccountByAddr(ctx context.Context, addr sdk.AccAddress) (authtypes.AccountI, error) { + acct, err := c.AuthQueryClient.Account(ctx, &authtypes.QueryAccountRequest{Address: addr.String()}) if err != nil { return nil, err } diff --git a/sdk/client/tx_test.go b/sdk/client/tx_test.go index d267ea139..254ce61b3 100644 --- a/sdk/client/tx_test.go +++ b/sdk/client/tx_test.go @@ -3,6 +3,7 @@ package client import ( "context" "testing" + "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" @@ -101,7 +102,7 @@ func TestSendTokenWithCustomizedNonce(t *testing.T) { transfer := banktypes.NewMsgSend(km.GetAddr(), to, sdk.NewCoins(sdk.NewInt64Coin(test.TEST_TOKEN_NAME, 100))) payerAddr, err := sdk.AccAddressFromHexUnsafe(km.GetAddr().String()) assert.NoError(t, err) - nonce, err := gnfdCli.GetNonce() + nonce, err := gnfdCli.GetNonce(context.Background()) assert.NoError(t, err) for i := 0; i < 50; i++ { txOpt := &types.TxOption{ @@ -128,7 +129,7 @@ func TestSendTxWithGrpcConn(t *testing.T) { transfer := banktypes.NewMsgSend(km.GetAddr(), to, sdk.NewCoins(sdk.NewInt64Coin(test.TEST_TOKEN_NAME, 100))) payerAddr, err := sdk.AccAddressFromHexUnsafe(km.GetAddr().String()) assert.NoError(t, err) - nonce, err := gnfdCli.GetNonce() + nonce, err := gnfdCli.GetNonce(context.Background()) assert.NoError(t, err) txOpt := &types.TxOption{ GasLimit: 123456, @@ -175,3 +176,22 @@ func TestSendTokenWithOverrideAccount(t *testing.T) { assert.Equal(t, uint32(0), response.TxResponse.Code) t.Log(response.TxResponse.String()) } + +func TestSendTXViaWebsocketClient(t *testing.T) { + km, err := keys.NewPrivateKeyManager(test.TEST_PRIVATE_KEY) + assert.NoError(t, err) + gnfdCli, err := NewGreenfieldClient(test.TEST_RPC_ADDR, test.TEST_CHAIN_ID, WithKeyManager(km), WithWebSocketClient()) + assert.NoError(t, err) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + to := sdk.MustAccAddressFromHex(test.TEST_ADDR) + nonce, _ := gnfdCli.GetNonce(ctx) + for i := 0; i < 500; i++ { + assert.NoError(t, err) + transfer := banktypes.NewMsgSend(km.GetAddr(), to, sdk.NewCoins(sdk.NewInt64Coin(test.TEST_TOKEN_NAME, 12))) + response, err := gnfdCli.BroadcastTx(ctx, []sdk.Msg{transfer}, &types.TxOption{Nonce: nonce}) + assert.NoError(t, err) + nonce++ + assert.Equal(t, uint32(0), response.TxResponse.Code) + } +} diff --git a/swagger/config.json b/swagger/config.json index 40ab54c79..19a00056e 100644 --- a/swagger/config.json +++ b/swagger/config.json @@ -46,6 +46,14 @@ } } }, + { + "url": "./tmp-swagger-gen/greenfield/virtualgroup/query.swagger.json", + "operationIds": { + "rename": { + "Params": "VirtualGroupParams" + } + } + }, { "url": "./tmp-swagger-gen/cosmos/auth/v1beta1/query.swagger.json", "operationIds": { diff --git a/swagger/static/swagger.yaml b/swagger/static/swagger.yaml index c106e626b..6d4161cfd 100644 --- a/swagger/static/swagger.yaml +++ b/swagger/static/swagger.yaml @@ -18,14 +18,14 @@ paths: description: params holds all the parameters of this module. type: object properties: - transfer_out_relayer_fee: + bsc_transfer_out_relayer_fee: type: string - title: Relayer fee for the cross chain transfer out tx - transfer_out_ack_relayer_fee: + title: Relayer fee for the cross chain transfer out tx to bsc + bsc_transfer_out_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the cross - chain transfer out tx + chain transfer out tx to bsc description: >- QueryParamsResponse is response type for the Query/Params RPC method. @@ -2185,15 +2185,6 @@ paths: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. Objects - belongs to this bucket will never - - leave this SP, unless you explicitly shift them to another - SP. global_virtual_group_family_id: type: integer format: int64 @@ -2303,15 +2294,6 @@ paths: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. Objects - belongs to this bucket will never - - leave this SP, unless you explicitly shift them to another - SP. global_virtual_group_family_id: type: integer format: int64 @@ -2366,6 +2348,109 @@ paths: type: string tags: - Query + /greenfield/storage/head_bucket_extra/{bucket_name}: + get: + summary: >- + Queries a bucket extra info (with gvg bindings and price time) with + specify name. + operationId: HeadBucketExtra + responses: + '200': + description: A successful response. + schema: + type: object + properties: + extra_info: + type: object + properties: + price_time: + type: string + format: int64 + title: >- + the time of the payment price, used to calculate the + charge rate of the bucket + total_charge_size: + type: string + format: uint64 + title: >- + the total size of the objects in the bucket, used to + calculate the charge rate of the bucket + local_virtual_groups: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the local virtual group. + global_virtual_group_id: + type: integer + format: int64 + description: >- + global_virtual_group_id is the identifier of the + global virtual group. + stored_size: + type: string + format: uint64 + description: >- + stored_size is the size of the stored data in the + local virtual group. + total_charge_size: + type: string + format: uint64 + title: >- + total_charge_size is the total charged size of the + objects in the LVG. + + Notice that the minimum unit of charge is 128K + description: >- + Local virtual group(LVG) uniquely associated with a + global virtual group. + + Each bucket maintains a mapping from local virtual group + to global virtual group + + Each local virtual group is associated with a unique + virtual payment account, + + where all object fees are streamed to. + description: local_virtual_groups contains all the lvg of this bucket. + next_local_virtual_group_id: + type: integer + format: int64 + title: >- + next_local_virtual_group_id store the next id used by + local virtual group + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: bucket_name + in: path + required: true + type: string + tags: + - Query /greenfield/storage/head_bucket_nft/{token_id}: get: summary: Queries a bucket with EIP712 standard metadata info @@ -2726,6 +2811,59 @@ paths: add omit tag to omit the field when converting to NFT metadata + global_virtual_group: + type: object + properties: + id: + type: integer + format: int64 + description: >- + ID represents the unique identifier of the global virtual + group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that + the group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the + primary storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers + of the secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects + within the group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address + associated with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by + this storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and + multiple secondary SP. + + Every global virtual group must belong to a GVG family, and + the objects of each + + bucket must be stored in a GVG within a group family. default: description: An unexpected error response. schema: @@ -2860,6 +2998,59 @@ paths: add omit tag to omit the field when converting to NFT metadata + global_virtual_group: + type: object + properties: + id: + type: integer + format: int64 + description: >- + ID represents the unique identifier of the global virtual + group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that + the group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the + primary storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers + of the secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects + within the group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address + associated with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by + this storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and + multiple secondary SP. + + Every global virtual group must belong to a GVG family, and + the objects of each + + bucket must be stored in a GVG within a group family. default: description: An unexpected error response. schema: @@ -2953,6 +3144,63 @@ paths: type: string tags: - Query + /greenfield/storage/is_price_changed/{bucket_name}: + get: + summary: Queries whether read and storage prices changed for the bucket. + operationId: QueryIsPriceChanged + responses: + '200': + description: A successful response. + schema: + type: object + properties: + changed: + type: boolean + current_read_price: + type: string + current_primary_store_price: + type: string + current_secondary_store_price: + type: string + current_validator_tax_rate: + type: string + new_read_price: + type: string + new_primary_store_price: + type: string + new_secondary_store_price: + type: string + new_validator_tax_rate: + type: string + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: bucket_name + in: path + required: true + type: string + tags: + - Query /greenfield/storage/list_buckets: get: summary: Queries a list of bucket items. @@ -3010,15 +3258,6 @@ paths: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. - Objects belongs to this bucket will never - - leave this SP, unless you explicitly shift them to - another SP. global_virtual_group_family_id: type: integer format: int64 @@ -3737,125 +3976,18 @@ paths: type: boolean tags: - Query - /greenfield/storage/params: + /greenfield/storage/lock_fee: get: - summary: Parameters queries the parameters of the module. - operationId: StorageParams + summary: Queries lock fee for storing an object + operationId: QueryLockFee responses: '200': description: A successful response. schema: type: object properties: - params: - description: params holds all the parameters of this module. - type: object - properties: - versioned_params: - type: object - properties: - max_segment_size: - type: string - format: uint64 - title: >- - max_segment_size is the maximum size of a segment. - default: 16M - redundant_data_chunk_num: - type: integer - format: int64 - title: >- - redundant_data_check_num is the num of data chunks of - EC redundancy algorithm - redundant_parity_chunk_num: - type: integer - format: int64 - title: >- - redundant_data_check_num is the num of parity chunks - of EC redundancy algorithm - min_charge_size: - type: string - format: uint64 - title: >- - min_charge_size is the minimum charge size of the - payload, objects smaller than this size will be - charged as this size - description: >- - VersionedParams defines the parameters for the storage - module with multi version, each version store with - different timestamp. - max_payload_size: - type: string - format: uint64 - title: >- - max_payload_size is the maximum size of the payload, - default: 2G - mirror_bucket_relayer_fee: - type: string - title: relayer fee for the mirror bucket tx - mirror_bucket_ack_relayer_fee: - type: string - title: >- - relayer fee for the ACK or FAIL_ACK package of the mirror - bucket tx - mirror_object_relayer_fee: - type: string - title: relayer fee for the mirror object tx - mirror_object_ack_relayer_fee: - type: string - title: >- - Relayer fee for the ACK or FAIL_ACK package of the mirror - object tx - mirror_group_relayer_fee: - type: string - title: relayer fee for the mirror object tx - mirror_group_ack_relayer_fee: - type: string - title: >- - Relayer fee for the ACK or FAIL_ACK package of the mirror - object tx - max_buckets_per_account: - type: integer - format: int64 - title: >- - The maximum number of buckets that can be created per - account - discontinue_counting_window: - type: string - format: uint64 - title: The window to count the discontinued objects or buckets - discontinue_object_max: - type: string - format: uint64 - title: The max objects can be requested in a window - discontinue_bucket_max: - type: string - format: uint64 - title: The max buckets can be requested in a window - discontinue_confirm_period: - type: string - format: int64 - title: >- - The object will be deleted after the confirm period in - seconds - discontinue_deletion_max: - type: string - format: uint64 - title: The max delete objects in each end block - stale_policy_cleanup_max: - type: string - format: uint64 - title: The max number for deleting policy in each end block - min_quota_update_interval: - type: string - format: uint64 - title: The min interval for making quota smaller in seconds - max_local_virtual_group_num_per_bucket: - type: integer - format: int64 - title: the max number of local virtual group per bucket - description: >- - QueryParamsResponse is response type for the Query/Params RPC - method. + amount: + type: string default: description: An unexpected error response. schema: @@ -3878,12 +4010,30 @@ paths: value: type: string format: byte + parameters: + - name: primary_sp_address + description: primary_sp_address is the address of the primary sp. + in: query + required: false + type: string + - name: create_at + description: create_at define the block timestamp when the object created. + in: query + required: false + type: string + format: int64 + - name: payload_size + description: payloadSize is the total size of the object payload. + in: query + required: false + type: string + format: uint64 tags: - Query - /greenfield/storage/params/{timestamp}: + /greenfield/storage/params: get: summary: Parameters queries the parameters of the module. - operationId: QueryParamsByTimestamp + operationId: StorageParams responses: '200': description: A successful response. @@ -3932,30 +4082,30 @@ paths: title: >- max_payload_size is the maximum size of the payload, default: 2G - mirror_bucket_relayer_fee: + bsc_mirror_bucket_relayer_fee: type: string - title: relayer fee for the mirror bucket tx - mirror_bucket_ack_relayer_fee: + title: relayer fee for the mirror bucket tx to bsc + bsc_mirror_bucket_ack_relayer_fee: type: string title: >- relayer fee for the ACK or FAIL_ACK package of the mirror - bucket tx - mirror_object_relayer_fee: + bucket tx to bsc + bsc_mirror_object_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_object_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_object_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror - object tx - mirror_group_relayer_fee: + object tx to bsc + bsc_mirror_group_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_group_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_group_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror - object tx + object tx to bsc max_buckets_per_account: type: integer format: int64 @@ -3997,8 +4147,8 @@ paths: format: int64 title: the max number of local virtual group per bucket description: >- - QueryVersionedParamsResponse is response type for the Query/Params - RPC method with timestamp. + QueryParamsResponse is response type for the Query/Params RPC + method. default: description: An unexpected error response. schema: @@ -4021,180 +4171,127 @@ paths: value: type: string format: byte - parameters: - - name: timestamp - description: the timestamp of the block time you want to query - in: path - required: true - type: string - format: int64 tags: - Query - /greenfield/storage/policy_by_id/{policy_id}: + /greenfield/storage/params/{timestamp}: get: - summary: Queries a policy by policy id - operationId: QueryPolicyById + summary: Parameters queries the parameters of the module. + operationId: QueryParamsByTimestamp responses: '200': description: A successful response. schema: type: object properties: - policy: + params: + description: params holds all the parameters of this module. type: object properties: - id: - type: string - title: >- - id is an unique u256 sequence for each policy. It also be - used as NFT tokenID - principal: - title: >- - principal defines the accounts/group which the permission - grants to + versioned_params: type: object properties: - type: + max_segment_size: type: string - enum: - - PRINCIPAL_TYPE_UNSPECIFIED - - PRINCIPAL_TYPE_GNFD_ACCOUNT - - PRINCIPAL_TYPE_GNFD_GROUP - default: PRINCIPAL_TYPE_UNSPECIFIED - description: >- - PrincipalType refers to the identity type of system - users or entities. - - In Greenfield, it usually refers to accounts or - groups. - value: + format: uint64 + title: >- + max_segment_size is the maximum size of a segment. + default: 16M + redundant_data_chunk_num: + type: integer + format: int64 + title: >- + redundant_data_check_num is the num of data chunks of + EC redundancy algorithm + redundant_parity_chunk_num: + type: integer + format: int64 + title: >- + redundant_data_check_num is the num of parity chunks + of EC redundancy algorithm + min_charge_size: type: string + format: uint64 title: >- - When the type is an account, its value is - sdk.AccAddress().String(); - - when the type is a group, its value is - math.Uint().String() + min_charge_size is the minimum charge size of the + payload, objects smaller than this size will be + charged as this size description: >- - Principal define the roles that can grant permissions. - Currently, it can be account or group. - resource_type: + VersionedParams defines the parameters for the storage + module with multi version, each version store with + different timestamp. + max_payload_size: + type: string + format: uint64 title: >- - resource_type defines the type of resource that grants - permission for + max_payload_size is the maximum size of the payload, + default: 2G + bsc_mirror_bucket_relayer_fee: type: string - enum: - - RESOURCE_TYPE_UNSPECIFIED - - RESOURCE_TYPE_BUCKET - - RESOURCE_TYPE_OBJECT - - RESOURCE_TYPE_GROUP - default: RESOURCE_TYPE_UNSPECIFIED - resource_id: + title: relayer fee for the mirror bucket tx to bsc + bsc_mirror_bucket_ack_relayer_fee: type: string title: >- - resource_id defines the bucket/object/group id of the - resource that grants permission for - statements: - type: array - items: - type: object - properties: - effect: - title: >- - effect define the impact of permissions, which can - be Allow/Deny - type: string - enum: - - EFFECT_UNSPECIFIED - - EFFECT_ALLOW - - EFFECT_DENY - default: EFFECT_UNSPECIFIED - actions: - type: array - items: - type: string - enum: - - ACTION_UNSPECIFIED - - ACTION_UPDATE_BUCKET_INFO - - ACTION_DELETE_BUCKET - - ACTION_CREATE_OBJECT - - ACTION_DELETE_OBJECT - - ACTION_COPY_OBJECT - - ACTION_GET_OBJECT - - ACTION_EXECUTE_OBJECT - - ACTION_LIST_OBJECT - - ACTION_UPDATE_GROUP_MEMBER - - ACTION_DELETE_GROUP - - ACTION_UPDATE_OBJECT_INFO - - ACTION_UPDATE_GROUP_EXTRA - - ACTION_TYPE_ALL - default: ACTION_UNSPECIFIED - title: >- - ActionType defines the operations you can execute - in greenfield storage network - description: >- - action_type define the operation type you can act. - greenfield defines a set of permission - - that you can specify in a permissionInfo. see - ActionType enum for detail. - resources: - type: array - items: - type: string - description: >- - CAN ONLY USED IN bucket level. Support fuzzy match - and limit to 5. - - The sub-resource name must comply with the standard - specified in the greenfield/types/grn.go file for - Greenfield resource names. - - If the sub-resources include 'grn:o:{bucket_name}/*' - in the statement, it indicates that specific - permissions is granted to all objects within the - specified bucket. - - If the sub-resources include - 'grn:o:{bucket_name}/test_*' in the statement, it - indicates that specific permissions is granted to - all objects with the `test_` prefix within the - specified bucket. - - If the sub-resources is empty, when you need to - operate(excluding CreateObject) a specified - subresource, it will be denied because it cannot - match any subresource. - expiration_time: - type: string - format: date-time - description: >- - expiration_time defines how long the permission is - valid. If not explicitly specified, it means it will - not expire. - limit_size: - description: >- - limit_size defines the total data size that is - allowed to operate. If not explicitly specified, it - means it will not limit. - type: object - properties: - value: - type: string - format: uint64 - description: The uint64 value. + relayer fee for the ACK or FAIL_ACK package of the mirror + bucket tx to bsc + bsc_mirror_object_relayer_fee: + type: string + title: relayer fee for the mirror object tx to bsc + bsc_mirror_object_ack_relayer_fee: + type: string title: >- - statements defines the details content of the permission, - including effect/actions/sub-resources - expiration_time: + Relayer fee for the ACK or FAIL_ACK package of the mirror + object tx to bsc + bsc_mirror_group_relayer_fee: + type: string + title: relayer fee for the mirror object tx to bsc + bsc_mirror_group_ack_relayer_fee: type: string - format: date-time title: >- - expiration_time defines the whole expiration time of all - the statements. - - Notices: Its priority is higher than the expiration time - inside the Statement + Relayer fee for the ACK or FAIL_ACK package of the mirror + object tx to bsc + max_buckets_per_account: + type: integer + format: int64 + title: >- + The maximum number of buckets that can be created per + account + discontinue_counting_window: + type: string + format: uint64 + title: The window to count the discontinued objects or buckets + discontinue_object_max: + type: string + format: uint64 + title: The max objects can be requested in a window + discontinue_bucket_max: + type: string + format: uint64 + title: The max buckets can be requested in a window + discontinue_confirm_period: + type: string + format: int64 + title: >- + The object will be deleted after the confirm period in + seconds + discontinue_deletion_max: + type: string + format: uint64 + title: The max delete objects in each end block + stale_policy_cleanup_max: + type: string + format: uint64 + title: The max number for deleting policy in each end block + min_quota_update_interval: + type: string + format: uint64 + title: The min interval for making quota smaller in seconds + max_local_virtual_group_num_per_bucket: + type: integer + format: int64 + title: the max number of local virtual group per bucket + description: >- + QueryVersionedParamsResponse is response type for the Query/Params + RPC method with timestamp. default: description: An unexpected error response. schema: @@ -4218,16 +4315,18 @@ paths: type: string format: byte parameters: - - name: policy_id + - name: timestamp + description: the timestamp of the block time you want to query in: path required: true type: string + format: int64 tags: - Query - /greenfield/storage/policy_for_account/{resource}/{principal_address}: + /greenfield/storage/policy_by_id/{policy_id}: get: - summary: Queries a policy which grants permission to account - operationId: QueryPolicyForAccount + summary: Queries a policy by policy id + operationId: QueryPolicyById responses: '200': description: A successful response. @@ -4412,20 +4511,214 @@ paths: type: string format: byte parameters: - - name: resource - in: path - required: true - type: string - - name: principal_address + - name: policy_id in: path required: true type: string tags: - Query - /greenfield/storage/policy_for_group/{resource}/{principal_group_id}: + /greenfield/storage/policy_for_account/{resource}/{principal_address}: get: - summary: Queries a policy that grants permission to a group - operationId: QueryPolicyForGroup + summary: Queries a policy which grants permission to account + operationId: QueryPolicyForAccount + responses: + '200': + description: A successful response. + schema: + type: object + properties: + policy: + type: object + properties: + id: + type: string + title: >- + id is an unique u256 sequence for each policy. It also be + used as NFT tokenID + principal: + title: >- + principal defines the accounts/group which the permission + grants to + type: object + properties: + type: + type: string + enum: + - PRINCIPAL_TYPE_UNSPECIFIED + - PRINCIPAL_TYPE_GNFD_ACCOUNT + - PRINCIPAL_TYPE_GNFD_GROUP + default: PRINCIPAL_TYPE_UNSPECIFIED + description: >- + PrincipalType refers to the identity type of system + users or entities. + + In Greenfield, it usually refers to accounts or + groups. + value: + type: string + title: >- + When the type is an account, its value is + sdk.AccAddress().String(); + + when the type is a group, its value is + math.Uint().String() + description: >- + Principal define the roles that can grant permissions. + Currently, it can be account or group. + resource_type: + title: >- + resource_type defines the type of resource that grants + permission for + type: string + enum: + - RESOURCE_TYPE_UNSPECIFIED + - RESOURCE_TYPE_BUCKET + - RESOURCE_TYPE_OBJECT + - RESOURCE_TYPE_GROUP + default: RESOURCE_TYPE_UNSPECIFIED + resource_id: + type: string + title: >- + resource_id defines the bucket/object/group id of the + resource that grants permission for + statements: + type: array + items: + type: object + properties: + effect: + title: >- + effect define the impact of permissions, which can + be Allow/Deny + type: string + enum: + - EFFECT_UNSPECIFIED + - EFFECT_ALLOW + - EFFECT_DENY + default: EFFECT_UNSPECIFIED + actions: + type: array + items: + type: string + enum: + - ACTION_UNSPECIFIED + - ACTION_UPDATE_BUCKET_INFO + - ACTION_DELETE_BUCKET + - ACTION_CREATE_OBJECT + - ACTION_DELETE_OBJECT + - ACTION_COPY_OBJECT + - ACTION_GET_OBJECT + - ACTION_EXECUTE_OBJECT + - ACTION_LIST_OBJECT + - ACTION_UPDATE_GROUP_MEMBER + - ACTION_DELETE_GROUP + - ACTION_UPDATE_OBJECT_INFO + - ACTION_UPDATE_GROUP_EXTRA + - ACTION_TYPE_ALL + default: ACTION_UNSPECIFIED + title: >- + ActionType defines the operations you can execute + in greenfield storage network + description: >- + action_type define the operation type you can act. + greenfield defines a set of permission + + that you can specify in a permissionInfo. see + ActionType enum for detail. + resources: + type: array + items: + type: string + description: >- + CAN ONLY USED IN bucket level. Support fuzzy match + and limit to 5. + + The sub-resource name must comply with the standard + specified in the greenfield/types/grn.go file for + Greenfield resource names. + + If the sub-resources include 'grn:o:{bucket_name}/*' + in the statement, it indicates that specific + permissions is granted to all objects within the + specified bucket. + + If the sub-resources include + 'grn:o:{bucket_name}/test_*' in the statement, it + indicates that specific permissions is granted to + all objects with the `test_` prefix within the + specified bucket. + + If the sub-resources is empty, when you need to + operate(excluding CreateObject) a specified + subresource, it will be denied because it cannot + match any subresource. + expiration_time: + type: string + format: date-time + description: >- + expiration_time defines how long the permission is + valid. If not explicitly specified, it means it will + not expire. + limit_size: + description: >- + limit_size defines the total data size that is + allowed to operate. If not explicitly specified, it + means it will not limit. + type: object + properties: + value: + type: string + format: uint64 + description: The uint64 value. + title: >- + statements defines the details content of the permission, + including effect/actions/sub-resources + expiration_time: + type: string + format: date-time + title: >- + expiration_time defines the whole expiration time of all + the statements. + + Notices: Its priority is higher than the expiration time + inside the Statement + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: resource + in: path + required: true + type: string + - name: principal_address + in: path + required: true + type: string + tags: + - Query + /greenfield/storage/policy_for_group/{resource}/{principal_group_id}: + get: + summary: Queries a policy that grants permission to a group + operationId: QueryPolicyForGroup responses: '200': description: A successful response. @@ -4696,6 +4989,532 @@ paths: type: string tags: - Query + /greenfield/virtualgroup/available_global_virtual_group_families: + get: + summary: >- + AvailableGlobalVirtualGroupFamilies filters a list of + GlobalVirtualGroupFamilies ID which are qualified to create bucket on + operationId: AvailableGlobalVirtualGroupFamilies + responses: + '200': + description: A successful response. + schema: + type: object + properties: + global_virtual_group_family_ids: + type: array + items: + type: integer + format: int64 + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: global_virtual_group_family_ids + in: query + required: false + type: array + items: + type: integer + format: int64 + collectionFormat: multi + tags: + - Query + /greenfield/virtualgroup/global_virtual_group: + get: + summary: Queries a global virtual group by its id. + operationId: GlobalVirtualGroup + responses: + '200': + description: A successful response. + schema: + type: object + properties: + global_virtual_group: + type: object + properties: + id: + type: integer + format: int64 + description: >- + ID represents the unique identifier of the global virtual + group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that + the group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the + primary storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers + of the secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects + within the group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address + associated with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by + this storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and + multiple secondary SP. + + Every global virtual group must belong to a GVG family, and + the objects of each + + bucket must be stored in a GVG within a group family. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: global_virtual_group_id + in: query + required: false + type: integer + format: int64 + tags: + - Query + /greenfield/virtualgroup/global_virtual_group_by_family_id: + get: + summary: Queries a list of global virtual groups by family id. + operationId: GlobalVirtualGroupByFamilyID + responses: + '200': + description: A successful response. + schema: + type: object + properties: + global_virtual_groups: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: >- + ID represents the unique identifier of the global + virtual group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family + that the group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the + primary storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique + identifiers of the secondary storage providers in the + group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects + within the group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address + associated with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited + by this storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and + multiple secondary SP. + + Every global virtual group must belong to a GVG family, and + the objects of each + + bucket must be stored in a GVG within a group family. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: storage_provider_id + in: query + required: false + type: integer + format: int64 + - name: global_virtual_group_family_id + in: query + required: false + type: integer + format: int64 + tags: + - Query + /greenfield/virtualgroup/global_virtual_group_families: + get: + summary: Queries a list of GlobalVirtualGroupFamilies items. + operationId: GlobalVirtualGroupFamilies + responses: + '200': + description: A successful response. + schema: + type: object + properties: + gvg_families: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the global virtual group family. + primary_sp_id: + type: integer + format: int64 + title: primary_sp_id + global_virtual_group_ids: + type: array + items: + type: integer + format: int64 + description: >- + global_virtual_group_ids is a list of identifiers of the + global virtual groups associated with the family. + virtual_payment_address: + type: string + description: >- + virtual_payment_address is the payment address + associated with the global virtual group family. + description: >- + Global virtual group family serve as a means of grouping + global virtual groups. + + Each bucket must be associated with a unique global virtual + group family and cannot cross families. + pagination: + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + PageResponse is to be embedded in gRPC response messages where + the + + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: >- + offset is a numeric offset that can be used when key is unavailable. + + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + limit is the total number of results to be returned in the result + page. + + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + count_total is set to true to indicate that the result set should + include + + a count of the total number of items available for pagination in + UIs. + + count_total is only respected when offset is used. It is ignored + when key + + is set. + in: query + required: false + type: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + tags: + - Query + /greenfield/virtualgroup/global_virtual_group_family: + get: + summary: Queries a global virtual group family by its id. + operationId: GlobalVirtualGroupFamily + responses: + '200': + description: A successful response. + schema: + type: object + properties: + global_virtual_group_family: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the global virtual group family. + primary_sp_id: + type: integer + format: int64 + title: primary_sp_id + global_virtual_group_ids: + type: array + items: + type: integer + format: int64 + description: >- + global_virtual_group_ids is a list of identifiers of the + global virtual groups associated with the family. + virtual_payment_address: + type: string + description: >- + virtual_payment_address is the payment address associated + with the global virtual group family. + description: >- + Global virtual group family serve as a means of grouping + global virtual groups. + + Each bucket must be associated with a unique global virtual + group family and cannot cross families. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: family_id + in: query + required: false + type: integer + format: int64 + tags: + - Query + /greenfield/virtualgroup/params: + get: + summary: Parameters queries the parameters of the module. + operationId: VirtualGroupParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + description: params holds all the parameters of this module. + type: object + properties: + deposit_denom: + type: string + description: deposit_denom defines the staking coin denomination. + gvg_staking_per_bytes: + type: string + title: store price, in bnb wei per charge byte + max_local_virtual_group_num_per_bucket: + type: integer + format: int64 + title: the max number of lvg which allowed in a bucket + max_global_virtual_group_num_per_family: + type: integer + format: int64 + title: the max number of gvg which can exist in a family + max_store_size_per_family: + type: string + format: uint64 + title: >- + if the store size reach the exceed, the family is not + allowed to sever more buckets + description: >- + QueryParamsResponse is response type for the Query/Params RPC + method. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query /cosmos/auth/v1beta1/account_info/{address}: get: summary: AccountInfo queries account info which is common to all account types. @@ -4812,6 +5631,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4851,7 +5674,6 @@ paths: name "y.z". - JSON @@ -5013,6 +5835,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5052,7 +5878,6 @@ paths: name "y.z". - JSON @@ -5218,6 +6043,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5257,7 +6086,6 @@ paths: name "y.z". - JSON @@ -5435,6 +6263,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5474,7 +6306,6 @@ paths: name "y.z". - JSON @@ -5680,6 +6511,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5719,7 +6554,6 @@ paths: name "y.z". - JSON @@ -5871,6 +6705,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5910,7 +6748,6 @@ paths: name "y.z". - JSON @@ -6087,6 +6924,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6126,7 +6967,6 @@ paths: name "y.z". - JSON @@ -6300,6 +7140,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6339,7 +7183,6 @@ paths: name "y.z". - JSON @@ -6497,6 +7340,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6536,7 +7383,6 @@ paths: name "y.z". - JSON @@ -6685,6 +7531,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6724,7 +7574,6 @@ paths: name "y.z". - JSON @@ -6876,6 +7725,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6915,7 +7768,6 @@ paths: name "y.z". - JSON @@ -7106,6 +7958,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7145,7 +8001,6 @@ paths: name "y.z". - JSON @@ -7300,6 +8155,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7339,7 +8198,6 @@ paths: name "y.z". - JSON @@ -7532,6 +8390,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7571,7 +8433,6 @@ paths: name "y.z". - JSON @@ -7803,6 +8664,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7842,7 +8707,6 @@ paths: name "y.z". - JSON @@ -8027,6 +8891,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8066,7 +8934,6 @@ paths: name "y.z". - JSON @@ -8287,6 +9154,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8326,7 +9197,6 @@ paths: name "y.z". - JSON @@ -8511,6 +9381,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8550,7 +9424,6 @@ paths: name "y.z". - JSON @@ -10230,6 +11103,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10269,7 +11146,6 @@ paths: name "y.z". - JSON @@ -11560,6 +12436,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -11599,7 +12479,6 @@ paths: name "y.z". - JSON @@ -12871,6 +13750,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -12910,7 +13793,6 @@ paths: name "y.z". - JSON @@ -13152,6 +14034,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13191,7 +14077,6 @@ paths: name "y.z". - JSON @@ -13360,6 +14245,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13399,7 +14288,6 @@ paths: name "y.z". - JSON @@ -13559,6 +14447,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13598,7 +14490,6 @@ paths: name "y.z". - JSON @@ -13781,6 +14672,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13820,7 +14715,6 @@ paths: name "y.z". - JSON @@ -14037,6 +14931,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -14076,7 +14974,6 @@ paths: name "y.z". - JSON @@ -14259,6 +15156,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -14298,7 +15199,6 @@ paths: name "y.z". - JSON @@ -15459,6 +16359,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15498,7 +16402,6 @@ paths: name "y.z". - JSON @@ -15675,6 +16578,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15714,7 +16621,6 @@ paths: name "y.z". - JSON @@ -15920,6 +16826,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15959,7 +16869,6 @@ paths: name "y.z". - JSON @@ -16111,6 +17020,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16150,7 +17063,6 @@ paths: name "y.z". - JSON @@ -16421,6 +17333,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16460,7 +17376,6 @@ paths: name "y.z". - JSON @@ -16750,6 +17665,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16789,7 +17708,6 @@ paths: name "y.z". - JSON @@ -17129,6 +18047,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -17168,7 +18090,6 @@ paths: name "y.z". - JSON @@ -17780,6 +18701,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -17819,7 +18744,6 @@ paths: name "y.z". - JSON @@ -17990,6 +18914,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -18029,7 +18957,6 @@ paths: name "y.z". - JSON @@ -18165,6 +19092,9 @@ paths: type: string description: 'Since: cosmos-sdk 0.47' title: Proposer is the address of the proposal sumbitter + failed_reason: + type: string + title: The reason of the failure proposal description: >- Proposal defines the core field members of a governance proposal. @@ -18306,6 +19236,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -18345,7 +19279,6 @@ paths: name "y.z". - JSON @@ -18597,6 +19530,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -18636,7 +19573,6 @@ paths: name "y.z". - JSON @@ -18771,6 +19707,9 @@ paths: type: string description: 'Since: cosmos-sdk 0.47' title: Proposer is the address of the proposal sumbitter + failed_reason: + type: string + title: The reason of the failure proposal description: >- Proposal defines the core field members of a governance proposal. @@ -18890,6 +19829,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -18929,7 +19872,6 @@ paths: name "y.z". - JSON @@ -19161,6 +20103,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -19200,7 +20146,6 @@ paths: name "y.z". - JSON @@ -19467,6 +20412,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -19506,7 +20455,6 @@ paths: name "y.z". - JSON @@ -19705,6 +20653,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -19744,7 +20696,6 @@ paths: name "y.z". - JSON @@ -19986,6 +20937,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -20025,7 +20980,6 @@ paths: name "y.z". - JSON @@ -20301,6 +21255,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -20340,7 +21298,6 @@ paths: name "y.z". - JSON @@ -21186,6 +22143,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -21225,7 +22186,6 @@ paths: name "y.z". - JSON @@ -21617,6 +22577,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -21656,7 +22620,6 @@ paths: name "y.z". - JSON @@ -21988,6 +22951,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -22027,7 +22994,6 @@ paths: name "y.z". - JSON @@ -22256,6 +23222,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -22295,7 +23265,6 @@ paths: name "y.z". - JSON @@ -22635,6 +23604,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -22674,7 +23647,6 @@ paths: name "y.z". - JSON @@ -22896,6 +23868,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -22935,7 +23911,6 @@ paths: name "y.z". - JSON @@ -23252,6 +24227,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -23291,7 +24270,6 @@ paths: name "y.z". - JSON @@ -23544,6 +24522,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -23583,7 +24565,6 @@ paths: name "y.z". - JSON @@ -23906,6 +24887,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -23945,7 +24930,6 @@ paths: name "y.z". - JSON @@ -24155,6 +25139,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -24194,7 +25182,6 @@ paths: name "y.z". - JSON @@ -24367,6 +25354,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -24406,7 +25397,6 @@ paths: name "y.z". - JSON @@ -24571,6 +25561,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -24610,7 +25604,6 @@ paths: name "y.z". - JSON @@ -24950,6 +25943,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -24989,7 +25986,6 @@ paths: name "y.z". - JSON @@ -25209,6 +26205,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -25248,7 +26248,6 @@ paths: name "y.z". - JSON @@ -25565,6 +26564,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -25604,7 +26607,6 @@ paths: name "y.z". - JSON @@ -25851,6 +26853,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -25890,7 +26896,6 @@ paths: name "y.z". - JSON @@ -26167,6 +27172,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -26206,7 +27215,6 @@ paths: name "y.z". - JSON @@ -26445,6 +27453,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -26484,7 +27496,6 @@ paths: name "y.z". - JSON @@ -26753,6 +27764,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -26792,7 +27807,6 @@ paths: name "y.z". - JSON @@ -27018,6 +28032,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -27057,7 +28075,6 @@ paths: name "y.z". - JSON @@ -27248,6 +28265,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -27287,7 +28308,6 @@ paths: name "y.z". - JSON @@ -27479,6 +28499,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -27518,7 +28542,6 @@ paths: name "y.z". - JSON @@ -27700,6 +28723,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -27739,7 +28766,6 @@ paths: name "y.z". - JSON @@ -27982,6 +29008,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -28021,7 +29051,6 @@ paths: name "y.z". - JSON @@ -28184,6 +29213,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -28223,7 +29256,6 @@ paths: name "y.z". - JSON @@ -28392,6 +29424,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -28431,7 +29467,6 @@ paths: name "y.z". - JSON @@ -28762,6 +29797,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -28801,7 +29840,6 @@ paths: name "y.z". - JSON @@ -29015,6 +30053,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -29054,7 +30096,6 @@ paths: name "y.z". - JSON @@ -29254,6 +30295,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -29293,7 +30338,6 @@ paths: name "y.z". - JSON @@ -29519,6 +30563,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -29558,7 +30606,6 @@ paths: name "y.z". - JSON @@ -29961,6 +31008,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -29996,7 +31047,6 @@ definitions: name "y.z". - JSON @@ -30033,14 +31083,14 @@ definitions: greenfield.bridge.Params: type: object properties: - transfer_out_relayer_fee: + bsc_transfer_out_relayer_fee: type: string - title: Relayer fee for the cross chain transfer out tx - transfer_out_ack_relayer_fee: + title: Relayer fee for the cross chain transfer out tx to bsc + bsc_transfer_out_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the cross chain - transfer out tx + transfer out tx to bsc description: Params defines the parameters for the module. greenfield.bridge.QueryParamsResponse: type: object @@ -30049,14 +31099,14 @@ definitions: description: params holds all the parameters of this module. type: object properties: - transfer_out_relayer_fee: + bsc_transfer_out_relayer_fee: type: string - title: Relayer fee for the cross chain transfer out tx - transfer_out_ack_relayer_fee: + title: Relayer fee for the cross chain transfer out tx to bsc + bsc_transfer_out_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the cross chain - transfer out tx + transfer out tx to bsc description: QueryParamsResponse is response type for the Query/Params RPC method. grpc.gateway.runtime.Error: type: object @@ -30165,6 +31215,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -30200,7 +31254,6 @@ definitions: name "y.z". - JSON @@ -32134,14 +33187,6 @@ definitions: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. Objects belongs to - this bucket will never - - leave this SP, unless you explicitly shift them to another SP. global_virtual_group_family_id: type: integer format: int64 @@ -32253,6 +33298,99 @@ definitions: value: type: string title: attributes + greenfield.storage.InternalBucketInfo: + type: object + properties: + price_time: + type: string + format: int64 + title: >- + the time of the payment price, used to calculate the charge rate of + the bucket + total_charge_size: + type: string + format: uint64 + title: >- + the total size of the objects in the bucket, used to calculate the + charge rate of the bucket + local_virtual_groups: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the local virtual group. + global_virtual_group_id: + type: integer + format: int64 + description: >- + global_virtual_group_id is the identifier of the global virtual + group. + stored_size: + type: string + format: uint64 + description: >- + stored_size is the size of the stored data in the local virtual + group. + total_charge_size: + type: string + format: uint64 + title: >- + total_charge_size is the total charged size of the objects in + the LVG. + + Notice that the minimum unit of charge is 128K + description: >- + Local virtual group(LVG) uniquely associated with a global virtual + group. + + Each bucket maintains a mapping from local virtual group to global + virtual group + + Each local virtual group is associated with a unique virtual payment + account, + + where all object fees are streamed to. + description: local_virtual_groups contains all the lvg of this bucket. + next_local_virtual_group_id: + type: integer + format: int64 + title: >- + next_local_virtual_group_id store the next id used by local virtual + group + greenfield.storage.LocalVirtualGroup: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the local virtual group. + global_virtual_group_id: + type: integer + format: int64 + description: global_virtual_group_id is the identifier of the global virtual group. + stored_size: + type: string + format: uint64 + description: stored_size is the size of the stored data in the local virtual group. + total_charge_size: + type: string + format: uint64 + title: |- + total_charge_size is the total charged size of the objects in the LVG. + Notice that the minimum unit of charge is 128K + description: >- + Local virtual group(LVG) uniquely associated with a global virtual group. + + Each bucket maintains a mapping from local virtual group to global virtual + group + + Each local virtual group is associated with a unique virtual payment + account, + + where all object fees are streamed to. greenfield.storage.ObjectInfo: type: object properties: @@ -32417,24 +33555,30 @@ definitions: type: string format: uint64 title: 'max_payload_size is the maximum size of the payload, default: 2G' - mirror_bucket_relayer_fee: + bsc_mirror_bucket_relayer_fee: type: string - title: relayer fee for the mirror bucket tx - mirror_bucket_ack_relayer_fee: + title: relayer fee for the mirror bucket tx to bsc + bsc_mirror_bucket_ack_relayer_fee: type: string - title: relayer fee for the ACK or FAIL_ACK package of the mirror bucket tx - mirror_object_relayer_fee: + title: >- + relayer fee for the ACK or FAIL_ACK package of the mirror bucket tx to + bsc + bsc_mirror_object_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_object_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_object_ack_relayer_fee: type: string - title: Relayer fee for the ACK or FAIL_ACK package of the mirror object tx - mirror_group_relayer_fee: + title: >- + Relayer fee for the ACK or FAIL_ACK package of the mirror object tx to + bsc + bsc_mirror_group_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_group_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_group_ack_relayer_fee: type: string - title: Relayer fee for the ACK or FAIL_ACK package of the mirror object tx + title: >- + Relayer fee for the ACK or FAIL_ACK package of the mirror object tx to + bsc max_buckets_per_account: type: integer format: int64 @@ -32528,6 +33672,71 @@ definitions: value: type: string title: attributes + greenfield.storage.QueryHeadBucketExtraResponse: + type: object + properties: + extra_info: + type: object + properties: + price_time: + type: string + format: int64 + title: >- + the time of the payment price, used to calculate the charge rate + of the bucket + total_charge_size: + type: string + format: uint64 + title: >- + the total size of the objects in the bucket, used to calculate the + charge rate of the bucket + local_virtual_groups: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the local virtual group. + global_virtual_group_id: + type: integer + format: int64 + description: >- + global_virtual_group_id is the identifier of the global + virtual group. + stored_size: + type: string + format: uint64 + description: >- + stored_size is the size of the stored data in the local + virtual group. + total_charge_size: + type: string + format: uint64 + title: >- + total_charge_size is the total charged size of the objects + in the LVG. + + Notice that the minimum unit of charge is 128K + description: >- + Local virtual group(LVG) uniquely associated with a global + virtual group. + + Each bucket maintains a mapping from local virtual group to + global virtual group + + Each local virtual group is associated with a unique virtual + payment account, + + where all object fees are streamed to. + description: local_virtual_groups contains all the lvg of this bucket. + next_local_virtual_group_id: + type: integer + format: int64 + title: >- + next_local_virtual_group_id store the next id used by local + virtual group greenfield.storage.QueryHeadBucketResponse: type: object properties: @@ -32573,14 +33782,6 @@ definitions: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. Objects belongs - to this bucket will never - - leave this SP, unless you explicitly shift them to another SP. global_virtual_group_family_id: type: integer format: int64 @@ -32735,6 +33936,78 @@ definitions: title: |- checksums define the root hash of the pieces which stored in a SP. add omit tag to omit the field when converting to NFT metadata + global_virtual_group: + type: object + properties: + id: + type: integer + format: int64 + description: ID represents the unique identifier of the global virtual group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that the + group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the primary + storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers of the + secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects within the + group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address associated + with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by this + storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and multiple + secondary SP. + + Every global virtual group must belong to a GVG family, and the + objects of each + + bucket must be stored in a GVG within a group family. + greenfield.storage.QueryIsPriceChangedResponse: + type: object + properties: + changed: + type: boolean + current_read_price: + type: string + current_primary_store_price: + type: string + current_secondary_store_price: + type: string + current_validator_tax_rate: + type: string + new_read_price: + type: string + new_primary_store_price: + type: string + new_secondary_store_price: + type: string + new_validator_tax_rate: + type: string greenfield.storage.QueryListBucketsResponse: type: object properties: @@ -32782,14 +34055,6 @@ definitions: payment_address: type: string title: payment_address is the address of the payment account - primary_sp_id: - type: integer - format: int64 - description: >- - primary_sp_id is the unique id of the primary sp. Objects - belongs to this bucket will never - - leave this SP, unless you explicitly shift them to another SP. global_virtual_group_family_id: type: integer format: int64 @@ -33015,6 +34280,11 @@ definitions: repeated Bar results = 1; PageResponse page = 2; } + greenfield.storage.QueryLockFeeResponse: + type: object + properties: + amount: + type: string greenfield.storage.QueryObjectNFTResponse: type: object properties: @@ -33084,30 +34354,30 @@ definitions: type: string format: uint64 title: 'max_payload_size is the maximum size of the payload, default: 2G' - mirror_bucket_relayer_fee: + bsc_mirror_bucket_relayer_fee: type: string - title: relayer fee for the mirror bucket tx - mirror_bucket_ack_relayer_fee: + title: relayer fee for the mirror bucket tx to bsc + bsc_mirror_bucket_ack_relayer_fee: type: string title: >- relayer fee for the ACK or FAIL_ACK package of the mirror bucket - tx - mirror_object_relayer_fee: + tx to bsc + bsc_mirror_object_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_object_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_object_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror object - tx - mirror_group_relayer_fee: + tx to bsc + bsc_mirror_group_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_group_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_group_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror object - tx + tx to bsc max_buckets_per_account: type: integer format: int64 @@ -33188,30 +34458,30 @@ definitions: type: string format: uint64 title: 'max_payload_size is the maximum size of the payload, default: 2G' - mirror_bucket_relayer_fee: + bsc_mirror_bucket_relayer_fee: type: string - title: relayer fee for the mirror bucket tx - mirror_bucket_ack_relayer_fee: + title: relayer fee for the mirror bucket tx to bsc + bsc_mirror_bucket_ack_relayer_fee: type: string title: >- relayer fee for the ACK or FAIL_ACK package of the mirror bucket - tx - mirror_object_relayer_fee: + tx to bsc + bsc_mirror_object_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_object_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_object_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror object - tx - mirror_group_relayer_fee: + tx to bsc + bsc_mirror_group_relayer_fee: type: string - title: relayer fee for the mirror object tx - mirror_group_ack_relayer_fee: + title: relayer fee for the mirror object tx to bsc + bsc_mirror_group_ack_relayer_fee: type: string title: >- Relayer fee for the ACK or FAIL_ACK package of the mirror object - tx + tx to bsc max_buckets_per_account: type: integer format: int64 @@ -33784,6 +35054,351 @@ definitions: VisibilityType is the resources public status. - VISIBILITY_TYPE_INHERIT: If the bucket Visibility is inherit, it's finally set to private. If the object Visibility is inherit, it's the same as bucket. + greenfield.virtualgroup.GlobalVirtualGroup: + type: object + properties: + id: + type: integer + format: int64 + description: ID represents the unique identifier of the global virtual group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that the group + belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the primary storage + provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers of the + secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects within the + group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address associated with + the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by this + storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and multiple + secondary SP. + + Every global virtual group must belong to a GVG family, and the objects of + each + + bucket must be stored in a GVG within a group family. + greenfield.virtualgroup.AvailableGlobalVirtualGroupFamiliesResponse: + type: object + properties: + global_virtual_group_family_ids: + type: array + items: + type: integer + format: int64 + greenfield.virtualgroup.GlobalVirtualGroupFamily: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the global virtual group family. + primary_sp_id: + type: integer + format: int64 + title: primary_sp_id + global_virtual_group_ids: + type: array + items: + type: integer + format: int64 + description: >- + global_virtual_group_ids is a list of identifiers of the global + virtual groups associated with the family. + virtual_payment_address: + type: string + description: >- + virtual_payment_address is the payment address associated with the + global virtual group family. + description: >- + Global virtual group family serve as a means of grouping global virtual + groups. + + Each bucket must be associated with a unique global virtual group family + and cannot cross families. + greenfield.virtualgroup.Params: + type: object + properties: + deposit_denom: + type: string + description: deposit_denom defines the staking coin denomination. + gvg_staking_per_bytes: + type: string + title: store price, in bnb wei per charge byte + max_local_virtual_group_num_per_bucket: + type: integer + format: int64 + title: the max number of lvg which allowed in a bucket + max_global_virtual_group_num_per_family: + type: integer + format: int64 + title: the max number of gvg which can exist in a family + max_store_size_per_family: + type: string + format: uint64 + title: >- + if the store size reach the exceed, the family is not allowed to sever + more buckets + description: Params defines the parameters for the module. + greenfield.virtualgroup.QueryGlobalVirtualGroupByFamilyIDResponse: + type: object + properties: + global_virtual_groups: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: ID represents the unique identifier of the global virtual group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that the + group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the primary + storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers of + the secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects within the + group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address + associated with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by this + storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and multiple + secondary SP. + + Every global virtual group must belong to a GVG family, and the + objects of each + + bucket must be stored in a GVG within a group family. + greenfield.virtualgroup.QueryGlobalVirtualGroupFamiliesResponse: + type: object + properties: + gvg_families: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the global virtual group family. + primary_sp_id: + type: integer + format: int64 + title: primary_sp_id + global_virtual_group_ids: + type: array + items: + type: integer + format: int64 + description: >- + global_virtual_group_ids is a list of identifiers of the global + virtual groups associated with the family. + virtual_payment_address: + type: string + description: >- + virtual_payment_address is the payment address associated with + the global virtual group family. + description: >- + Global virtual group family serve as a means of grouping global + virtual groups. + + Each bucket must be associated with a unique global virtual group + family and cannot cross families. + pagination: + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + greenfield.virtualgroup.QueryGlobalVirtualGroupFamilyResponse: + type: object + properties: + global_virtual_group_family: + type: object + properties: + id: + type: integer + format: int64 + description: id is the identifier of the global virtual group family. + primary_sp_id: + type: integer + format: int64 + title: primary_sp_id + global_virtual_group_ids: + type: array + items: + type: integer + format: int64 + description: >- + global_virtual_group_ids is a list of identifiers of the global + virtual groups associated with the family. + virtual_payment_address: + type: string + description: >- + virtual_payment_address is the payment address associated with the + global virtual group family. + description: >- + Global virtual group family serve as a means of grouping global + virtual groups. + + Each bucket must be associated with a unique global virtual group + family and cannot cross families. + greenfield.virtualgroup.QueryGlobalVirtualGroupResponse: + type: object + properties: + global_virtual_group: + type: object + properties: + id: + type: integer + format: int64 + description: ID represents the unique identifier of the global virtual group. + family_id: + type: integer + format: int64 + description: >- + Family ID represents the identifier of the GVG family that the + group belongs to. + primary_sp_id: + type: integer + format: int64 + description: >- + Primary SP ID represents the unique identifier of the primary + storage provider in the group. + secondary_sp_ids: + type: array + items: + type: integer + format: int64 + description: >- + Secondary SP IDs represents the list of unique identifiers of the + secondary storage providers in the group. + stored_size: + type: string + format: uint64 + description: >- + Stored size represents the size of the stored objects within the + group. + virtual_payment_address: + type: string + description: >- + Virtual payment address represents the payment address associated + with the group. + total_deposit: + type: string + description: >- + Total deposit represents the number of tokens deposited by this + storage provider for staking. + description: >- + A global virtual group consists of one primary SP (SP) and multiple + secondary SP. + + Every global virtual group must belong to a GVG family, and the + objects of each + + bucket must be stored in a GVG within a group family. + greenfield.virtualgroup.QueryParamsResponse: + type: object + properties: + params: + description: params holds all the parameters of this module. + type: object + properties: + deposit_denom: + type: string + description: deposit_denom defines the staking coin denomination. + gvg_staking_per_bytes: + type: string + title: store price, in bnb wei per charge byte + max_local_virtual_group_num_per_bucket: + type: integer + format: int64 + title: the max number of lvg which allowed in a bucket + max_global_virtual_group_num_per_family: + type: integer + format: int64 + title: the max number of gvg which can exist in a family + max_store_size_per_family: + type: string + format: uint64 + title: >- + if the store size reach the exceed, the family is not allowed to + sever more buckets + description: QueryParamsResponse is response type for the Query/Params RPC method. cosmos.auth.v1beta1.BaseAccount: type: object properties: @@ -33881,6 +35496,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -33916,7 +35535,6 @@ definitions: name "y.z". - JSON @@ -34097,6 +35715,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -34133,7 +35755,6 @@ definitions: name "y.z". - JSON @@ -34273,6 +35894,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -34308,7 +35933,6 @@ definitions: name "y.z". - JSON @@ -34445,6 +36069,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -34480,7 +36108,6 @@ definitions: name "y.z". - JSON @@ -34635,6 +36262,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -34670,7 +36301,6 @@ definitions: name "y.z". - JSON @@ -34807,6 +36437,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -34842,7 +36476,6 @@ definitions: name "y.z". - JSON @@ -35000,6 +36633,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -35035,188 +36672,6 @@ definitions: name "y.z". - - JSON - - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with an - - additional field `@type` which contains the type URL. Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom JSON - - representation, that representation will be embedded adding a field - - `value` which holds the custom JSON in addition to the `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - expiration: - type: string - format: date-time - title: >- - time when the grant will expire and will be pruned. If null, then the - grant - - doesn't have a time expiration (other conditions in `authorization` - - may apply to invalidate the grant) - description: |- - Grant gives permissions to execute - the provide method with expiration time. - cosmos.authz.v1beta1.GrantAuthorization: - type: object - properties: - granter: - type: string - grantee: - type: string - authorization: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of the - serialized - - protocol buffer message. This string must contain at least - - one "/" character. The last segment of the URL's path must - represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in a - canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary all types - that they - - expect it to use in the context of Any. However, for URLs which - use the - - scheme `http`, `https`, or no scheme, one can optionally set up a - type - - server that maps type URLs to message definitions as follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in the - official - - protobuf release, and it is not used for type URLs beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above specified - type. - description: >- - `Any` contains an arbitrary serialized protocol buffer message along - with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values in the - form - - of utility functions or additional generated methods of the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by default use - - 'type.googleapis.com/full.type.name' as the type URL and the unpack - - methods only use the fully qualified type name after the last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield type - - name "y.z". - - - JSON @@ -35253,226 +36708,196 @@ definitions: expiration: type: string format: date-time - title: >- - GrantAuthorization extends a grant with both the addresses of the grantee - and granter. + title: >- + time when the grant will expire and will be pruned. If null, then the + grant - It is used in genesis.proto and query.proto - cosmos.authz.v1beta1.QueryGranteeGrantsResponse: + doesn't have a time expiration (other conditions in `authorization` + + may apply to invalidate the grant) + description: |- + Grant gives permissions to execute + the provide method with expiration time. + cosmos.authz.v1beta1.GrantAuthorization: type: object properties: - grants: - type: array - items: - type: object - properties: - granter: - type: string - grantee: - type: string - authorization: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of the - serialized - - protocol buffer message. This string must contain at least - - one "/" character. The last segment of the URL's path must - represent + granter: + type: string + grantee: + type: string + authorization: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized - the fully qualified name of the type (as in + protocol buffer message. This string must contain at least - `path/google.protobuf.Duration`). The name should be in a - canonical form + one "/" character. The last segment of the URL's path must + represent - (e.g., leading "." is not accepted). + the fully qualified name of the type (as in + `path/google.protobuf.Duration`). The name should be in a + canonical form - In practice, teams usually precompile into the binary all - types that they + (e.g., leading "." is not accepted). - expect it to use in the context of Any. However, for URLs - which use the - scheme `http`, `https`, or no scheme, one can optionally set - up a type + In practice, teams usually precompile into the binary all types + that they - server that maps type URLs to message definitions as - follows: + expect it to use in the context of Any. However, for URLs which + use the + scheme `http`, `https`, or no scheme, one can optionally set up a + type - * If no scheme is provided, `https` is assumed. + server that maps type URLs to message definitions as follows: - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based on - the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - Note: this functionality is not currently available in the - official + * If no scheme is provided, `https` is assumed. - protobuf release, and it is not used for type URLs beginning - with + * An HTTP GET on the URL must yield a [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) - type.googleapis.com. + Note: this functionality is not currently available in the + official + protobuf release, and it is not used for type URLs beginning with - Schemes other than `http`, `https` (or the empty scheme) - might be + type.googleapis.com. - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer message - along with a - URL that describes the type of the serialized message. + Schemes other than `http`, `https` (or the empty scheme) might be + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above specified + type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message along + with a - Protobuf library provides support to pack/unpack Any values in - the form + URL that describes the type of the serialized message. - of utility functions or additional generated methods of the Any - type. + Protobuf library provides support to pack/unpack Any values in the + form - Example 1: Pack and unpack a message in C++. + of utility functions or additional generated methods of the Any type. - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - Example 2: Pack and unpack a message in Java. + Example 1: Pack and unpack a message in C++. - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } - Example 3: Pack and unpack a message in Python. + Example 2: Pack and unpack a message in Java. - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } - Example 4: Pack and unpack a message in Go + Example 3: Pack and unpack a message in Python. - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... - The pack methods provided by protobuf library will by default - use + Example 4: Pack and unpack a message in Go - 'type.googleapis.com/full.type.name' as the type URL and the - unpack + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } - methods only use the fully qualified type name after the last - '/' + The pack methods provided by protobuf library will by default use - in the type URL, for example "foo.bar.com/x/y.z" will yield type + 'type.googleapis.com/full.type.name' as the type URL and the unpack - name "y.z". + methods only use the fully qualified type name after the last '/' + in the type URL, for example "foo.bar.com/x/y.z" will yield type + name "y.z". - JSON + JSON - The JSON representation of an `Any` value uses the regular - representation of the deserialized, embedded message, with an + The JSON representation of an `Any` value uses the regular - additional field `@type` which contains the type URL. Example: + representation of the deserialized, embedded message, with an - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } + additional field `@type` which contains the type URL. Example: - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } - If the embedded message type is well-known and has a custom JSON + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } - representation, that representation will be embedded adding a - field + If the embedded message type is well-known and has a custom JSON - `value` which holds the custom JSON in addition to the `@type` + representation, that representation will be embedded adding a field - field. Example (for message [google.protobuf.Duration][]): + `value` which holds the custom JSON in addition to the `@type` - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - expiration: - type: string - format: date-time - title: >- - GrantAuthorization extends a grant with both the addresses of the - grantee and granter. + field. Example (for message [google.protobuf.Duration][]): - It is used in genesis.proto and query.proto - description: grants is a list of grants granted to the grantee. - pagination: - description: pagination defines an pagination for the response. - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + expiration: + type: string + format: date-time + title: >- + GrantAuthorization extends a grant with both the addresses of the grantee + and granter. - was set, its value is undefined otherwise - description: >- - QueryGranteeGrantsResponse is the response type for the - Query/GranteeGrants RPC method. - cosmos.authz.v1beta1.QueryGranterGrantsResponse: + It is used in genesis.proto and query.proto + cosmos.authz.v1beta1.QueryGranteeGrantsResponse: type: object properties: grants: @@ -35582,6 +37007,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -35620,7 +37049,6 @@ definitions: name "y.z". - JSON @@ -35663,7 +37091,7 @@ definitions: grantee and granter. It is used in genesis.proto and query.proto - description: grants is a list of grants granted by the granter. + description: grants is a list of grants granted to the grantee. pagination: description: pagination defines an pagination for the response. type: object @@ -35684,9 +37112,9 @@ definitions: was set, its value is undefined otherwise description: >- - QueryGranterGrantsResponse is the response type for the - Query/GranterGrants RPC method. - cosmos.authz.v1beta1.QueryGrantsResponse: + QueryGranteeGrantsResponse is the response type for the + Query/GranteeGrants RPC method. + cosmos.authz.v1beta1.QueryGranterGrantsResponse: type: object properties: grants: @@ -35694,6 +37122,10 @@ definitions: items: type: object properties: + granter: + type: string + grantee: + type: string authorization: type: object properties: @@ -35792,6 +37224,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -35830,6 +37266,218 @@ definitions: name "y.z". + JSON + + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + expiration: + type: string + format: date-time + title: >- + GrantAuthorization extends a grant with both the addresses of the + grantee and granter. + + It is used in genesis.proto and query.proto + description: grants is a list of grants granted by the granter. + pagination: + description: pagination defines an pagination for the response. + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + QueryGranterGrantsResponse is the response type for the + Query/GranterGrants RPC method. + cosmos.authz.v1beta1.QueryGrantsResponse: + type: object + properties: + grants: + type: array + items: + type: object + properties: + authorization: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all + types that they + + expect it to use in the context of Any. However, for URLs + which use the + + scheme `http`, `https`, or no scheme, one can optionally set + up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on + the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs beginning + with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message + along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in + the form + + of utility functions or additional generated methods of the Any + type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default + use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the last + '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + JSON @@ -39527,6 +41175,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -39565,7 +41217,6 @@ definitions: name "y.z". - JSON @@ -39823,6 +41474,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -39861,7 +41516,6 @@ definitions: name "y.z". - JSON @@ -40176,6 +41830,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -40211,7 +41869,6 @@ definitions: name "y.z". - JSON @@ -43196,6 +44853,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -43231,7 +44892,6 @@ definitions: name "y.z". - JSON @@ -43385,6 +45045,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -43420,7 +45084,6 @@ definitions: name "y.z". - JSON @@ -44244,6 +45907,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -44279,7 +45946,6 @@ definitions: name "y.z". - JSON @@ -44394,6 +46060,9 @@ definitions: type: string description: 'Since: cosmos-sdk 0.47' title: Proposer is the address of the proposal sumbitter + failed_reason: + type: string + title: The reason of the failure proposal description: Proposal defines the core field members of a governance proposal. cosmos.gov.v1.ProposalStatus: type: string @@ -44762,6 +46431,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -44800,7 +46473,6 @@ definitions: name "y.z". - JSON @@ -44922,6 +46594,9 @@ definitions: type: string description: 'Since: cosmos-sdk 0.47' title: Proposer is the address of the proposal sumbitter + failed_reason: + type: string + title: The reason of the failure proposal description: Proposal defines the core field members of a governance proposal. description: >- QueryProposalResponse is the response type for the Query/Proposal RPC @@ -45038,6 +46713,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -45077,7 +46756,6 @@ definitions: name "y.z". - JSON @@ -45201,6 +46879,9 @@ definitions: type: string description: 'Since: cosmos-sdk 0.47' title: Proposer is the address of the proposal sumbitter + failed_reason: + type: string + title: The reason of the failure proposal description: Proposal defines the core field members of a governance proposal. description: proposals defines all the requested governance proposals. pagination: @@ -46167,6 +47848,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -46205,7 +47890,6 @@ definitions: name "y.z". - JSON @@ -46765,6 +48449,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -46801,7 +48489,6 @@ definitions: name "y.z". - JSON @@ -47100,6 +48787,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -47138,7 +48829,6 @@ definitions: name "y.z". - JSON @@ -47541,6 +49231,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -47580,7 +49274,6 @@ definitions: name "y.z". - JSON @@ -48223,6 +49916,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -48259,7 +49956,6 @@ definitions: name "y.z". - JSON @@ -48638,6 +50334,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -48676,7 +50376,6 @@ definitions: name "y.z". - JSON @@ -49331,6 +51030,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -49366,7 +51069,6 @@ definitions: name "y.z". - JSON @@ -49761,6 +51463,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -49796,7 +51502,6 @@ definitions: name "y.z". - JSON @@ -50030,6 +51735,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -50065,7 +51774,6 @@ definitions: name "y.z". - JSON @@ -50566,6 +52274,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -50602,7 +52314,6 @@ definitions: name "y.z". - JSON @@ -51515,6 +53226,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -51551,7 +53266,6 @@ definitions: name "y.z". - JSON @@ -51836,6 +53550,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -51874,7 +53592,6 @@ definitions: name "y.z". - JSON @@ -52292,6 +54009,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -52327,7 +54048,6 @@ definitions: name "y.z". - JSON @@ -52574,6 +54294,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -52612,7 +54336,6 @@ definitions: name "y.z". - JSON @@ -52788,6 +54511,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -52826,7 +54553,6 @@ definitions: name "y.z". - JSON @@ -52996,6 +54722,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -53034,7 +54764,6 @@ definitions: name "y.z". - JSON @@ -53177,6 +54906,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -53215,7 +54948,6 @@ definitions: name "y.z". - JSON @@ -53378,6 +55110,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -53413,7 +55149,6 @@ definitions: name "y.z". - JSON @@ -53576,6 +55311,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -53611,7 +55350,6 @@ definitions: name "y.z". - JSON @@ -53749,6 +55487,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -53784,7 +55526,6 @@ definitions: name "y.z". - JSON diff --git a/x/challenge/abci.go b/x/challenge/abci.go index f300ede0c..7b94fd83e 100644 --- a/x/challenge/abci.go +++ b/x/challenge/abci.go @@ -76,7 +76,7 @@ func EndBlocker(ctx sdk.Context, keeper k.Keeper) { } redundancyIndex := k.RandomRedundancyIndex(seed, uint64(len(gvg.SecondarySpIds)+1)) if redundancyIndex == types.RedundancyIndexPrimary { // primary sp - spOperatorId = bucket.PrimarySpId + spOperatorId = gvg.PrimarySpId } else { spOperatorId = gvg.SecondarySpIds[redundancyIndex] } diff --git a/x/challenge/keeper/msg_server_attest.go b/x/challenge/keeper/msg_server_attest.go index 6d3e8fad7..74b52918d 100644 --- a/x/challenge/keeper/msg_server_attest.go +++ b/x/challenge/keeper/msg_server_attest.go @@ -13,6 +13,7 @@ import ( "github.com/bnb-chain/greenfield/x/challenge/types" paymentmoduletypes "github.com/bnb-chain/greenfield/x/payment/types" sptypes "github.com/bnb-chain/greenfield/x/sp/types" + storagetypes "github.com/bnb-chain/greenfield/x/storage/types" ) // Attest handles user's request for attesting a challenge. @@ -65,8 +66,14 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M } //for migrating buckets, or swapping out, the process could be done when offline service does the verification - bucketInfo, _ := k.StorageKeeper.GetBucketInfo(ctx, objectInfo.BucketName) - if bucketInfo.PrimarySpId != sp.Id { + bucketInfo, found := k.StorageKeeper.GetBucketInfo(ctx, objectInfo.BucketName) + if !found { + return nil, storagetypes.ErrNoSuchBucket.Wrapf("bucket not found when attest") + } + + spInState := k.StorageKeeper.MustGetPrimarySPForBucket(ctx, bucketInfo) + + if spInState.Id != sp.Id { gvg, _ := k.StorageKeeper.GetObjectGVG(ctx, bucketInfo.Id, objectInfo.LocalVirtualGroupId) found = false for _, id := range gvg.SecondarySpIds { diff --git a/x/challenge/keeper/msg_server_attest_test.go b/x/challenge/keeper/msg_server_attest_test.go index 602832673..176c140dc 100644 --- a/x/challenge/keeper/msg_server_attest_test.go +++ b/x/challenge/keeper/msg_server_attest_test.go @@ -131,9 +131,9 @@ func (s *TestSuite) TestAttest_Heartbeat() { Return(historicalInfo, true).AnyTimes() existBucket := &storagetypes.BucketInfo{ - Id: math.NewUint(10), - BucketName: "existbucket", - PrimarySpId: 1, + Id: math.NewUint(10), + GlobalVirtualGroupFamilyId: 10, + BucketName: "existbucket", } s.storageKeeper.EXPECT().GetBucketInfo(gomock.Any(), gomock.Eq(existBucket.BucketName)). Return(existBucket, true).AnyTimes() @@ -154,9 +154,12 @@ func (s *TestSuite) TestAttest_Heartbeat() { spOperatorAcc := sample.RandAccAddress() sp := &sptypes.StorageProvider{Id: 10, OperatorAddress: spOperatorAcc.String()} + s.spKeeper.EXPECT().GetStorageProviderByOperatorAddr(gomock.Any(), gomock.Any()). Return(sp, true).AnyTimes() + s.storageKeeper.EXPECT().MustGetPrimarySPForBucket(gomock.Any(), gomock.Any()).Return(sp).AnyTimes() + gvg := &virtualgrouptypes.GlobalVirtualGroup{ SecondarySpIds: []uint32{10}, } @@ -211,9 +214,8 @@ func (s *TestSuite) TestAttest_Normal() { Return(historicalInfo, true).AnyTimes() existBucket := &storagetypes.BucketInfo{ - Id: math.NewUint(10), - BucketName: "existbucket", - PrimarySpId: 1, + Id: math.NewUint(10), + BucketName: "existbucket", } s.storageKeeper.EXPECT().GetBucketInfo(gomock.Any(), gomock.Eq(existBucket.BucketName)). Return(existBucket, true).AnyTimes() @@ -235,7 +237,7 @@ func (s *TestSuite) TestAttest_Normal() { Return(nil).AnyTimes() s.spKeeper.EXPECT().GetStorageProviderByOperatorAddr(gomock.Any(), gomock.Any()). Return(sp, true).AnyTimes() - + s.storageKeeper.EXPECT().MustGetPrimarySPForBucket(gomock.Any(), gomock.Any()).Return(sp).AnyTimes() attestMsg := &types.MsgAttest{ Submitter: validSubmitter.String(), ChallengeId: challengeId, diff --git a/x/challenge/keeper/msg_server_submit.go b/x/challenge/keeper/msg_server_submit.go index 61f34b83c..d8b845e1b 100644 --- a/x/challenge/keeper/msg_server_submit.go +++ b/x/challenge/keeper/msg_server_submit.go @@ -23,10 +23,7 @@ func (k msgServer) Submit(goCtx context.Context, msg *types.MsgSubmit) (*types.M if !found { return nil, types.ErrUnknownBucketObject } - sp, found := k.SpKeeper.GetStorageProvider(ctx, bucketInfo.PrimarySpId) - if !found { - return nil, types.ErrUnknownSp - } + sp := k.StorageKeeper.MustGetPrimarySPForBucket(ctx, bucketInfo) if sp.Status != sptypes.STATUS_IN_SERVICE && sp.Status != sptypes.STATUS_GRACEFUL_EXITING { return nil, types.ErrInvalidSpStatus } @@ -44,12 +41,7 @@ func (k msgServer) Submit(goCtx context.Context, msg *types.MsgSubmit) (*types.M stored := false redundancyIndex := types.RedundancyIndexPrimary - // check primary sp - tmpSp, found := k.SpKeeper.GetStorageProvider(ctx, bucketInfo.PrimarySpId) - if !found { - return nil, errors.Wrapf(types.ErrUnknownSp, "cannot find storage provider: %d", bucketInfo.PrimarySpId) - } - if spOperator.Equals(sdk.MustAccAddressFromHex(tmpSp.OperatorAddress)) { + if spOperator.Equals(sdk.MustAccAddressFromHex(sp.OperatorAddress)) { stored = true } diff --git a/x/challenge/keeper/msg_server_submit_test.go b/x/challenge/keeper/msg_server_submit_test.go index 45744abfe..6b9bebaa9 100644 --- a/x/challenge/keeper/msg_server_submit_test.go +++ b/x/challenge/keeper/msg_server_submit_test.go @@ -19,6 +19,7 @@ func (s *TestSuite) TestSubmit() { existSp := &sptypes.StorageProvider{Status: sptypes.STATUS_IN_SERVICE, Id: 100, OperatorAddress: existSpAddr.String()} s.spKeeper.EXPECT().GetStorageProvider(gomock.Any(), gomock.Eq(existSp.Id)). Return(existSp, true).AnyTimes() + s.storageKeeper.EXPECT().MustGetPrimarySPForBucket(gomock.Any(), gomock.Any()).Return(existSp).AnyTimes() existBucketName, existObjectName := "existbucket", "existobject" existObject := &storagetypes.ObjectInfo{ @@ -33,8 +34,8 @@ func (s *TestSuite) TestSubmit() { Return(nil, false).AnyTimes() existBucket := &storagetypes.BucketInfo{ - BucketName: existBucketName, - PrimarySpId: existSp.Id} + BucketName: existBucketName, + } s.storageKeeper.EXPECT().GetBucketInfo(gomock.Any(), gomock.Eq(existBucketName)). Return(existBucket, true).AnyTimes() s.storageKeeper.EXPECT().GetBucketInfo(gomock.Any(), gomock.Any()). diff --git a/x/challenge/types/expected_keepers.go b/x/challenge/types/expected_keepers.go index 2781ae473..5c1b354ad 100644 --- a/x/challenge/types/expected_keepers.go +++ b/x/challenge/types/expected_keepers.go @@ -30,6 +30,7 @@ type StorageKeeper interface { GetBucketInfo(ctx sdk.Context, bucketName string) (*storage.BucketInfo, bool) MaxSegmentSize(ctx sdk.Context) (res uint64) GetObjectGVG(ctx sdk.Context, bucketID sdkmath.Uint, lvgID uint32) (*types.GlobalVirtualGroup, bool) + MustGetPrimarySPForBucket(ctx sdk.Context, bucketInfo *storage.BucketInfo) *sp.StorageProvider } type PaymentKeeper interface { diff --git a/x/challenge/types/expected_keepers_mocks.go b/x/challenge/types/expected_keepers_mocks.go index dd9db9fba..7df45a070 100644 --- a/x/challenge/types/expected_keepers_mocks.go +++ b/x/challenge/types/expected_keepers_mocks.go @@ -261,6 +261,20 @@ func (mr *MockStorageKeeperMockRecorder) MaxSegmentSize(ctx interface{}) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxSegmentSize", reflect.TypeOf((*MockStorageKeeper)(nil).MaxSegmentSize), ctx) } +// MustGetPrimarySPForBucket mocks base method. +func (m *MockStorageKeeper) MustGetPrimarySPForBucket(ctx types2.Context, bucketInfo *types0.BucketInfo) *types.StorageProvider { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MustGetPrimarySPForBucket", ctx, bucketInfo) + ret0, _ := ret[0].(*types.StorageProvider) + return ret0 +} + +// MustGetPrimarySPForBucket indicates an expected call of MustGetPrimarySPForBucket. +func (mr *MockStorageKeeperMockRecorder) MustGetPrimarySPForBucket(ctx, bucketInfo interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MustGetPrimarySPForBucket", reflect.TypeOf((*MockStorageKeeper)(nil).MustGetPrimarySPForBucket), ctx, bucketInfo) +} + // MockPaymentKeeper is a mock of PaymentKeeper interface. type MockPaymentKeeper struct { ctrl *gomock.Controller diff --git a/x/payment/keeper/auto_resume_record.go b/x/payment/keeper/auto_resume_record.go index 2654e529e..961013e58 100644 --- a/x/payment/keeper/auto_resume_record.go +++ b/x/payment/keeper/auto_resume_record.go @@ -66,7 +66,7 @@ func (k Keeper) ExistsAutoResumeRecord( exists := false for ; iterator.Valid(); iterator.Next() { record := types.ParseAutoResumeRecordKey(iterator.Key()) - if record.Timestamp > timestamp { + if timestamp > 0 && record.Timestamp > timestamp { break } if sdk.MustAccAddressFromHex(record.Addr).Equals(addr) { diff --git a/x/payment/keeper/msg_server_withdraw.go b/x/payment/keeper/msg_server_withdraw.go index 8d8cec396..cf2ff42f8 100644 --- a/x/payment/keeper/msg_server_withdraw.go +++ b/x/payment/keeper/msg_server_withdraw.go @@ -17,6 +17,10 @@ func (k msgServer) Withdraw(goCtx context.Context, msg *types.MsgWithdraw) (*typ if !found { return nil, types.ErrStreamRecordNotFound } + // check status + if streamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN { + return nil, errors.Wrapf(types.ErrInvalidStreamAccountStatus, "stream record is frozen") + } // check whether creator can withdraw if msg.Creator != msg.From { paymentAccount, found := k.Keeper.GetPaymentAccount(ctx, from) diff --git a/x/payment/keeper/out_flow.go b/x/payment/keeper/out_flow.go index ab76aec05..0049babfb 100644 --- a/x/payment/keeper/out_flow.go +++ b/x/payment/keeper/out_flow.go @@ -65,10 +65,19 @@ func (k Keeper) DeleteOutFlow(ctx sdk.Context, key []byte) { // MergeActiveOutFlows merge active OutFlows and save them in the store func (k Keeper) MergeActiveOutFlows(ctx sdk.Context, addr sdk.AccAddress, outFlows []types.OutFlow) int { + return k.mergeOutFlows(ctx, addr, types.OUT_FLOW_STATUS_ACTIVE, outFlows) +} + +// MergeFrozenOutFlows merge frozen OutFlows and save them in the store +func (k Keeper) MergeFrozenOutFlows(ctx sdk.Context, addr sdk.AccAddress, outFlows []types.OutFlow) int { + return k.mergeOutFlows(ctx, addr, types.OUT_FLOW_STATUS_FROZEN, outFlows) +} + +func (k Keeper) mergeOutFlows(ctx sdk.Context, addr sdk.AccAddress, status types.OutFlowStatus, outFlows []types.OutFlow) int { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OutFlowKeyPrefix) deltaCount := 0 for _, outFlow := range outFlows { - outFlow.Status = types.OUT_FLOW_STATUS_ACTIVE + outFlow.Status = status key := types.OutFlowKey(addr, outFlow.Status, sdk.MustAccAddressFromHex(outFlow.ToAddress)) value := store.Get(key) if value == nil { diff --git a/x/payment/keeper/storage_fee_charge.go b/x/payment/keeper/storage_fee_charge.go index da215a57e..c5d3239df 100644 --- a/x/payment/keeper/storage_fee_charge.go +++ b/x/payment/keeper/storage_fee_charge.go @@ -52,47 +52,106 @@ func (k Keeper) ApplyStreamRecordChanges(ctx sdk.Context, streamRecordChanges [] func (k Keeper) ApplyUserFlowsList(ctx sdk.Context, userFlowsList []types.UserFlows) (err error) { userFlowsList = k.MergeUserFlows(userFlowsList) currentTime := ctx.BlockTime().Unix() - var streamRecordChanges []types.StreamRecordChange + for _, userFlows := range userFlowsList { from := userFlows.From streamRecord, found := k.GetStreamRecord(ctx, from) if !found { streamRecord = types.NewStreamRecord(from, currentTime) } - // calculate rate changes in flowChanges - totalRate := sdk.ZeroInt() - for _, flowChange := range userFlows.Flows { - streamRecordChanges = append(streamRecordChanges, *types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(flowChange.ToAddress)).WithRateChange(flowChange.Rate)) - totalRate = totalRate.Add(flowChange.Rate) - } - streamRecordChange := types.NewDefaultStreamRecordChangeWithAddr(from).WithRateChange(totalRate.Neg()) - // storage fee preview - if ctx.IsCheckTx() { - reserveTime := k.GetParams(ctx).VersionedParams.ReserveTime - changeRate := totalRate.Neg() - event := &types.EventFeePreview{ - Account: from.String(), - Amount: changeRate.Mul(sdkmath.NewIntFromUint64(reserveTime)).Abs(), + if streamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE { + err = k.applyActiveUerFlows(ctx, userFlows, from, streamRecord) + if err != nil { + return err } - if changeRate.IsPositive() { - event.FeePreviewType = types.FEE_PREVIEW_TYPE_UNLOCKED_FEE - } else { - event.FeePreviewType = types.FEE_PREVIEW_TYPE_PRELOCKED_FEE + } else { // frozen status, should be called in end block for stop serving + err = k.applyFrozenUserFlows(ctx, userFlows, from, streamRecord) + if err != nil { + return err } - _ = ctx.EventManager().EmitTypedEvents(event) } - err = k.UpdateStreamRecord(ctx, streamRecord, streamRecordChange) - if err != nil { - return fmt.Errorf("apply stream record changes for user failed: %w", err) + } + return nil +} + +func (k Keeper) applyActiveUerFlows(ctx sdk.Context, userFlows types.UserFlows, from sdk.AccAddress, streamRecord *types.StreamRecord) error { + var rateChanges []types.StreamRecordChange + totalRate := sdk.ZeroInt() + for _, flowChange := range userFlows.Flows { + rateChanges = append(rateChanges, *types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(flowChange.ToAddress)).WithRateChange(flowChange.Rate)) + totalRate = totalRate.Add(flowChange.Rate) + } + streamRecordChange := types.NewDefaultStreamRecordChangeWithAddr(from).WithRateChange(totalRate.Neg()) + // storage fee preview + if ctx.IsCheckTx() { + reserveTime := k.GetParams(ctx).VersionedParams.ReserveTime + changeRate := totalRate.Neg() + event := &types.EventFeePreview{ + Account: from.String(), + Amount: changeRate.Mul(sdkmath.NewIntFromUint64(reserveTime)).Abs(), + } + if changeRate.IsPositive() { + event.FeePreviewType = types.FEE_PREVIEW_TYPE_UNLOCKED_FEE + } else { + event.FeePreviewType = types.FEE_PREVIEW_TYPE_PRELOCKED_FEE } + _ = ctx.EventManager().EmitTypedEvents(event) + } + err := k.UpdateStreamRecord(ctx, streamRecord, streamRecordChange) + if err != nil { + return fmt.Errorf("apply stream record changes for user failed: %w", err) + } - // update flows - deltaFlowCount := k.MergeActiveOutFlows(ctx, from, userFlows.Flows) // deltaFlowCount can be negative - streamRecord.OutFlowCount = uint64(int64(streamRecord.OutFlowCount) + int64(deltaFlowCount)) + // update flows + deltaFlowCount := k.MergeActiveOutFlows(ctx, from, userFlows.Flows) // deltaFlowCount can be negative + streamRecord.OutFlowCount = uint64(int64(streamRecord.OutFlowCount) + int64(deltaFlowCount)) - k.SetStreamRecord(ctx, streamRecord) + k.SetStreamRecord(ctx, streamRecord) + err = k.ApplyStreamRecordChanges(ctx, rateChanges) + if err != nil { + return fmt.Errorf("apply stream record changes failed: %w", err) } - err = k.ApplyStreamRecordChanges(ctx, streamRecordChanges) + return nil +} + +func (k Keeper) applyFrozenUserFlows(ctx sdk.Context, userFlows types.UserFlows, from sdk.AccAddress, streamRecord *types.StreamRecord) error { + forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) + if !forced { + return fmt.Errorf("stream record %s is frozen", streamRecord.Account) + } + + // the stream record could be totally frozen, or in the process of resuming + var activeOutFlows, frozenOutFlows []types.OutFlow + var activeRateChanges []types.StreamRecordChange + //var frozenRateChanges []types.StreamRecordChange + totalActiveRate, totalFrozenRate := sdk.ZeroInt(), sdk.ZeroInt() + for _, flowChange := range userFlows.Flows { + outFlow := k.GetOutFlow(ctx, sdk.MustAccAddressFromHex(streamRecord.Account), types.OUT_FLOW_STATUS_FROZEN, sdk.MustAccAddressFromHex(flowChange.ToAddress)) + if outFlow != nil { + frozenOutFlows = append(frozenOutFlows, flowChange) + //frozenRateChanges = append(frozenRateChanges, *types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(flowChange.ToAddress)).WithFrozenRateChange(flowChange.Rate)) + totalFrozenRate = totalFrozenRate.Add(flowChange.Rate) + } else { + activeOutFlows = append(activeOutFlows, flowChange) + activeRateChanges = append(activeRateChanges, *types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(flowChange.ToAddress)).WithRateChange(flowChange.Rate)) + totalActiveRate = totalActiveRate.Add(flowChange.Rate) + } + } + streamRecordChange := types.NewDefaultStreamRecordChangeWithAddr(from). + WithRateChange(totalActiveRate.Neg()).WithFrozenRateChange(totalFrozenRate.Neg()) + err := k.UpdateFrozenStreamRecord(ctx, streamRecord, streamRecordChange) + if err != nil { + return fmt.Errorf("apply stream record changes for user failed: %w", err) + } + + // update flows + deltaActiveFlowCount := k.MergeActiveOutFlows(ctx, from, activeOutFlows) // can be negative + deltaFrozenFlowCount := k.MergeFrozenOutFlows(ctx, from, frozenOutFlows) // can be negative + streamRecord.OutFlowCount = uint64(int64(streamRecord.OutFlowCount) + int64(deltaActiveFlowCount) + int64(deltaFrozenFlowCount)) + + k.SetStreamRecord(ctx, streamRecord) + //only apply activeRateChanges, for frozen rate changes, the out flow to gvg & gvg family had been deducted when settling + err = k.ApplyStreamRecordChanges(ctx, activeRateChanges) if err != nil { return fmt.Errorf("apply stream record changes failed: %w", err) } diff --git a/x/payment/keeper/storage_fee_charge_test.go b/x/payment/keeper/storage_fee_charge_test.go index 13d2a85b4..7faf16db7 100644 --- a/x/payment/keeper/storage_fee_charge_test.go +++ b/x/payment/keeper/storage_fee_charge_test.go @@ -25,6 +25,15 @@ func TestApplyFlowChanges(t *testing.T) { *types.NewDefaultStreamRecordChangeWithAddr(user).WithStaticBalanceChange(userInitBalance).WithRateChange(rate.Neg()), *types.NewDefaultStreamRecordChangeWithAddr(sp).WithRateChange(rate), } + sr := &types.StreamRecord{Account: user.String(), + OutFlowCount: 1, + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + NetflowRate: sdkmath.ZeroInt(), + FrozenNetflowRate: sdkmath.ZeroInt(), + } + keeper.SetStreamRecord(ctx, sr) err := keeper.ApplyStreamRecordChanges(ctx, flowChanges) require.NoError(t, err) userStreamRecord, found := keeper.GetStreamRecord(ctx, user) @@ -47,6 +56,15 @@ func TestSettleStreamRecord(t *testing.T) { rate := sdkmath.NewInt(-100) staticBalance := sdkmath.NewInt(1e10) change := types.NewDefaultStreamRecordChangeWithAddr(user).WithRateChange(rate).WithStaticBalanceChange(staticBalance) + sr := &types.StreamRecord{Account: user.String(), + OutFlowCount: 1, + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + NetflowRate: sdkmath.ZeroInt(), + FrozenNetflowRate: sdkmath.ZeroInt(), + } + keeper.SetStreamRecord(ctx, sr) _, err := keeper.UpdateStreamRecordByAddr(ctx, change) require.NoError(t, err) // check @@ -166,6 +184,7 @@ func TestAutoForceSettle(t *testing.T) { usrBeforeForceSettle, _ := keeper.GetStreamRecord(ctx, user) t.Logf("usrBeforeForceSettle: %s", usrBeforeForceSettle) + ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true) time.Sleep(1 * time.Second) keeper.AutoSettle(ctx) diff --git a/x/payment/keeper/stream_record.go b/x/payment/keeper/stream_record.go index 5765af0d4..a965f44e9 100644 --- a/x/payment/keeper/stream_record.go +++ b/x/payment/keeper/stream_record.go @@ -6,6 +6,7 @@ import ( sdkmath "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/store/prefix" storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/bnb-chain/greenfield/x/payment/types" @@ -27,12 +28,18 @@ func (k Keeper) CheckStreamRecord(streamRecord *types.StreamRecord) { if streamRecord.NetflowRate.IsNil() { panic(fmt.Sprintf("invalid streamRecord netflowRate %s", streamRecord.NetflowRate)) } + if !streamRecord.FrozenNetflowRate.IsNil() && streamRecord.FrozenNetflowRate.IsPositive() { + panic(fmt.Sprintf("invalid streamRecord frozenNetflowRate %s", streamRecord.NetflowRate)) + } if streamRecord.LockBalance.IsNil() || streamRecord.LockBalance.IsNegative() { panic(fmt.Sprintf("invalid streamRecord lockBalance %s", streamRecord.LockBalance)) } if streamRecord.BufferBalance.IsNil() || streamRecord.BufferBalance.IsNegative() { panic(fmt.Sprintf("invalid streamRecord bufferBalance %s", streamRecord.BufferBalance)) } + if streamRecord.NetflowRate.IsNegative() && streamRecord.OutFlowCount == 0 { + panic(fmt.Sprintf("invalid streamRecord netflowRate %s when outFlowCount is zero", streamRecord.NetflowRate)) + } } // SetStreamRecord set a specific streamRecord in the store from its index @@ -107,8 +114,6 @@ func (k Keeper) GetAllStreamRecord(ctx sdk.Context) (list []types.StreamRecord) // it only handles the lock balance change and ignore the other changes(since the streams are already changed and the // accumulated OutFlows are changed outside this function) func (k Keeper) UpdateFrozenStreamRecord(ctx sdk.Context, streamRecord *types.StreamRecord, change *types.StreamRecordChange) error { - currentTimestamp := ctx.BlockTime().Unix() - streamRecord.CrudTimestamp = currentTimestamp // update lock balance if !change.LockBalanceChange.IsZero() { streamRecord.LockBalance = streamRecord.LockBalance.Add(change.LockBalanceChange) @@ -117,18 +122,17 @@ func (k Keeper) UpdateFrozenStreamRecord(ctx sdk.Context, streamRecord *types.St return fmt.Errorf("lock balance can not become negative, current: %s", streamRecord.LockBalance) } } + if !change.RateChange.IsZero() { + streamRecord.NetflowRate = streamRecord.NetflowRate.Add(change.RateChange) + } + if !change.FrozenRateChange.IsZero() { + streamRecord.FrozenNetflowRate = streamRecord.FrozenNetflowRate.Add(change.FrozenRateChange) + } return nil } func (k Keeper) UpdateStreamRecord(ctx sdk.Context, streamRecord *types.StreamRecord, change *types.StreamRecordChange) error { forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) // force update in end block - if streamRecord.Status != types.STREAM_ACCOUNT_STATUS_ACTIVE { - if forced { //stream record is frozen - return k.UpdateFrozenStreamRecord(ctx, streamRecord, change) - } - return fmt.Errorf("stream account %s is frozen", streamRecord.Account) - } - isPay := change.StaticBalanceChange.IsNegative() || change.RateChange.IsNegative() currentTimestamp := ctx.BlockTime().Unix() timestamp := streamRecord.CrudTimestamp @@ -150,16 +154,15 @@ func (k Keeper) UpdateStreamRecord(ctx sdk.Context, streamRecord *types.StreamRe } } // update buffer balance - if !change.RateChange.IsZero() { - streamRecord.NetflowRate = streamRecord.NetflowRate.Add(change.RateChange) - newBufferBalance := sdkmath.ZeroInt() - if streamRecord.NetflowRate.IsNegative() { - newBufferBalance = streamRecord.NetflowRate.Abs().Mul(sdkmath.NewIntFromUint64(params.VersionedParams.ReserveTime)) - } - if !newBufferBalance.Equal(streamRecord.BufferBalance) { - streamRecord.StaticBalance = streamRecord.StaticBalance.Sub(newBufferBalance).Add(streamRecord.BufferBalance) - streamRecord.BufferBalance = newBufferBalance - } + // because reserve time could be changed, so we need to re-calculate buffer balance even rate change is zero + streamRecord.NetflowRate = streamRecord.NetflowRate.Add(change.RateChange) + newBufferBalance := sdkmath.ZeroInt() + if streamRecord.NetflowRate.IsNegative() { + newBufferBalance = streamRecord.NetflowRate.Abs().Mul(sdkmath.NewIntFromUint64(params.VersionedParams.ReserveTime)) + } + if !newBufferBalance.Equal(streamRecord.BufferBalance) { + streamRecord.StaticBalance = streamRecord.StaticBalance.Sub(newBufferBalance).Add(streamRecord.BufferBalance) + streamRecord.BufferBalance = newBufferBalance } // update static balance if !change.StaticBalanceChange.IsZero() { @@ -178,7 +181,7 @@ func (k Keeper) UpdateStreamRecord(ctx sdk.Context, streamRecord *types.StreamRe } } } - // if the change is a pay(which decreases the static balance or netflow rate), the left static balance should be enough + // if the change is a pay (which decreases the static balance or netflow rate), the left static balance should be enough if !forced && isPay && streamRecord.StaticBalance.IsNegative() { return fmt.Errorf("stream account %s balance not enough, lack of %s BNB", streamRecord.Account, streamRecord.StaticBalance.Abs()) } @@ -188,57 +191,17 @@ func (k Keeper) UpdateStreamRecord(ctx sdk.Context, streamRecord *types.StreamRe payDuration := streamRecord.StaticBalance.Add(streamRecord.BufferBalance).Quo(streamRecord.NetflowRate.Abs()) if payDuration.LTE(sdkmath.NewIntFromUint64(params.ForcedSettleTime)) { if !forced { - return fmt.Errorf("stream account %s balance not enough, lack of %s BNB", streamRecord.Account, streamRecord.StaticBalance.Abs()) - } - } - settleTimestamp = currentTimestamp - int64(params.ForcedSettleTime) + payDuration.Int64() - } - k.UpdateAutoSettleRecord(ctx, sdk.MustAccAddressFromHex(streamRecord.Account), streamRecord.SettleTimestamp, settleTimestamp) - streamRecord.SettleTimestamp = settleTimestamp - return nil -} - -func (k Keeper) SettleStreamRecord(ctx sdk.Context, streamRecord *types.StreamRecord) error { - currentTimestamp := ctx.BlockTime().Unix() - crudTimestamp := streamRecord.CrudTimestamp - params := k.GetParams(ctx) - - if currentTimestamp != crudTimestamp { - if !streamRecord.NetflowRate.IsZero() { - flowDelta := streamRecord.NetflowRate.MulRaw(currentTimestamp - crudTimestamp) - streamRecord.StaticBalance = streamRecord.StaticBalance.Add(flowDelta) - } - streamRecord.CrudTimestamp = currentTimestamp - } - - if streamRecord.StaticBalance.IsNegative() { - account := sdk.MustAccAddressFromHex(streamRecord.Account) - hasBankAccount := k.accountKeeper.HasAccount(ctx, account) - if hasBankAccount { - coins := sdk.NewCoins(sdk.NewCoin(params.FeeDenom, streamRecord.StaticBalance.Abs())) - err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, account, types.ModuleName, coins) - if err != nil { - ctx.Logger().Info("auto transfer failed when settling", "account", streamRecord.Account, "err", err, "coins", coins) - } else { - streamRecord.StaticBalance = sdkmath.ZeroInt() + return fmt.Errorf("stream account %s lacks of %s BNB", streamRecord.Account, streamRecord.StaticBalance.Abs()) } - } - } - - if streamRecord.NetflowRate.IsNegative() { - payDuration := streamRecord.StaticBalance.Add(streamRecord.BufferBalance).Quo(streamRecord.NetflowRate.Abs()) - if payDuration.LTE(sdkmath.NewIntFromUint64(params.ForcedSettleTime)) { err := k.ForceSettle(ctx, streamRecord) if err != nil { - return err + return fmt.Errorf("check and force settle failed, err: %w", err) } - } else { - settleTimestamp := currentTimestamp - int64(params.ForcedSettleTime) + payDuration.Int64() - k.UpdateAutoSettleRecord(ctx, sdk.MustAccAddressFromHex(streamRecord.Account), streamRecord.SettleTimestamp, settleTimestamp) - streamRecord.SettleTimestamp = settleTimestamp } + settleTimestamp = currentTimestamp - int64(params.ForcedSettleTime) + payDuration.Int64() } - + k.UpdateAutoSettleRecord(ctx, sdk.MustAccAddressFromHex(streamRecord.Account), streamRecord.SettleTimestamp, settleTimestamp) + streamRecord.SettleTimestamp = settleTimestamp return nil } @@ -258,6 +221,7 @@ func (k Keeper) ForceSettle(ctx sdk.Context, streamRecord *types.StreamRecord) e change := types.NewDefaultStreamRecordChangeWithAddr(types.GovernanceAddress).WithStaticBalanceChange(totalBalance) _, err := k.UpdateStreamRecordByAddr(ctx, change) if err != nil { + telemetry.IncrCounter(1, types.GovernanceAddressLackBalanceLabel) return fmt.Errorf("update governance stream record failed: %w", err) } } @@ -298,7 +262,7 @@ func (k Keeper) AutoSettle(ctx sdk.Context) { if streamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE { count++ // add one for a stream record - err := k.SettleStreamRecord(ctx, streamRecord) + err := k.UpdateStreamRecord(ctx, streamRecord, types.NewDefaultStreamRecordChangeWithAddr(addr)) if err != nil { ctx.Logger().Error("auto settle, settle stream record failed", "err", err.Error()) continue @@ -348,6 +312,7 @@ func (k Keeper) AutoSettle(ctx sdk.Context) { _, err := k.UpdateStreamRecordByAddr(ctx, flowChange) if err != nil { ctx.Logger().Error("auto settle, update stream record failed", "address", outFlow.ToAddress, "rate", outFlow.Rate.Neg()) + panic("should not happen") } flowStore.Delete(flowIterator.Key()) @@ -369,6 +334,7 @@ func (k Keeper) AutoSettle(ctx sdk.Context) { if !flowIterator.Valid() || finished { if !streamRecord.NetflowRate.IsZero() { ctx.Logger().Error("should not happen, stream netflow rate is not zero", "address", streamRecord.Account) + panic("should not happen") } k.RemoveAutoSettleRecord(ctx, record.Timestamp, addr) } @@ -382,8 +348,9 @@ func (k Keeper) TryResumeStreamRecord(ctx sdk.Context, streamRecord *types.Strea return fmt.Errorf("stream account %s status is not frozen", streamRecord.Account) } - if !streamRecord.NetflowRate.IsNil() && !streamRecord.NetflowRate.IsZero() { // the account is resuming - return fmt.Errorf("stream account %s status is resuming, although it is frozen now", streamRecord.Account) + exists := k.ExistsAutoResumeRecord(ctx, 0, sdk.MustAccAddressFromHex(streamRecord.Account)) + if exists { + return fmt.Errorf("stream account %s status is resuming, please wait", streamRecord.Account) } params := k.GetParams(ctx) @@ -501,7 +468,7 @@ func (k Keeper) AutoResume(ctx sdk.Context) { _, err := k.UpdateStreamRecordByAddr(ctx, flowChange) if err != nil { ctx.Logger().Error("auto resume, update receiver stream record failed", "address", outFlow.ToAddress, "err", err.Error()) - break + panic("should not happen") } flowStore.Delete(flowIterator.Key()) @@ -522,12 +489,14 @@ func (k Keeper) AutoResume(ctx sdk.Context) { if !flowIterator.Valid() || finished { if !streamRecord.FrozenNetflowRate.IsZero() { ctx.Logger().Error("should not happen, stream frozen netflow rate is not zero", "address", streamRecord.Account) + panic("should not happen") } streamRecord.Status = types.STREAM_ACCOUNT_STATUS_ACTIVE change := types.NewDefaultStreamRecordChangeWithAddr(addr) err := k.UpdateStreamRecord(ctx, streamRecord, change) if err != nil { ctx.Logger().Error("auto resume, update stream record failed", "err", err.Error()) + panic("should not happen") } k.RemoveAutoResumeRecord(ctx, record.Timestamp, addr) } diff --git a/x/payment/keeper/stream_record_test.go b/x/payment/keeper/stream_record_test.go index 5fddae9ae..a726888d4 100644 --- a/x/payment/keeper/stream_record_test.go +++ b/x/payment/keeper/stream_record_test.go @@ -14,18 +14,26 @@ import ( "github.com/bnb-chain/greenfield/x/payment/types" ) -func TestTryResumeStreamRecord_InResuming(t *testing.T) { +func TestTryResumeStreamRecord_InResumingOrSettling(t *testing.T) { keeper, ctx, _ := makePaymentKeeper(t) ctx = ctx.WithBlockTime(time.Now()) - // further deposit to a resuming account is not allowed + account := sample.RandAccAddress() + // deposit to a resuming account is not allowed streamRecord := &types.StreamRecord{ + Account: account.String(), Status: types.STREAM_ACCOUNT_STATUS_FROZEN, NetflowRate: sdkmath.NewInt(-100), } + + keeper.SetAutoResumeRecord(ctx, &types.AutoResumeRecord{ + Timestamp: ctx.BlockTime().Unix() + 10, + Addr: account.String(), + }) + deposit := sdkmath.NewInt(100) err := keeper.TryResumeStreamRecord(ctx, streamRecord, deposit) - require.ErrorContains(t, err, "resuming") + require.ErrorContains(t, err, "is resuming") } func TestTryResumeStreamRecord_ResumeInOneBlock(t *testing.T) { @@ -122,6 +130,109 @@ func TestTryResumeStreamRecord_ResumeInMultipleBlocks(t *testing.T) { } keeper.SetOutFlow(ctx, user, outFlow3) + // try to resume stream record + err := keeper.TryResumeStreamRecord(ctx, streamRecord, rate.SubRaw(10).MulRaw(int64(params.VersionedParams.ReserveTime))) + require.NoError(t, err) //only added static balance + found := keeper.ExistsAutoResumeRecord(ctx, ctx.BlockTime().Unix(), user) + require.True(t, !found) + streamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, streamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + err = keeper.TryResumeStreamRecord(ctx, streamRecord, rate.MulRaw(int64(params.VersionedParams.ReserveTime))) + require.NoError(t, err) + + // still frozen + userStreamRecord, _ := keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + _, found = keeper.GetAutoResumeRecord(ctx, ctx.BlockTime().Unix(), user) + require.True(t, found) + + // resume in end block + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + // resume in end block + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + // resume in end block + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, userStreamRecord.NetflowRate, rate.Neg()) + require.Equal(t, userStreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg1StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg1) + require.True(t, gvg1StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg1StreamRecord.NetflowRate, gvg1Rate) + require.Equal(t, gvg1StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg2StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg2) + require.True(t, gvg2StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg2StreamRecord.NetflowRate, gvg2Rate) + require.Equal(t, gvg2StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg3StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg3) + require.True(t, gvg3StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg3StreamRecord.NetflowRate, gvg3Rate) + require.Equal(t, gvg3StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) +} + +func TestTryResumeStreamRecord_ResumeInMultipleBlocks_BalanceNotEnoughFinally(t *testing.T) { + keeper, ctx, depKeepers := makePaymentKeeper(t) + ctx = ctx.WithBlockTime(time.Now()) + + // resume account in multiple blocks + params := keeper.GetParams(ctx) + params.MaxAutoResumeFlowCount = 1 + _ = keeper.SetParams(ctx, params) + + rate := sdkmath.NewInt(300) + user := sample.RandAccAddress() + streamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: user.String(), + Status: types.STREAM_ACCOUNT_STATUS_FROZEN, + NetflowRate: sdkmath.NewInt(0), + FrozenNetflowRate: rate.Neg(), + OutFlowCount: 3, + } + keeper.SetStreamRecord(ctx, streamRecord) + + gvgAddress := []sdk.AccAddress{sample.RandAccAddress(), sample.RandAccAddress(), sample.RandAccAddress()} + + gvg1 := gvgAddress[0] + gvg1Rate := sdk.NewInt(50) + outFlow1 := &types.OutFlow{ + ToAddress: gvg1.String(), + Rate: gvg1Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow1) + + gvg2 := gvgAddress[1] + gvg2Rate := sdk.NewInt(100) + outFlow2 := &types.OutFlow{ + ToAddress: gvg2.String(), + Rate: gvg2Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow2) + + gvg3 := gvgAddress[2] + gvg3Rate := sdk.NewInt(150) + outFlow3 := &types.OutFlow{ + ToAddress: gvg3.String(), + Rate: gvg3Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow3) + err := keeper.TryResumeStreamRecord(ctx, streamRecord, rate.MulRaw(int64(params.VersionedParams.ReserveTime))) require.NoError(t, err) @@ -142,7 +253,137 @@ func TestTryResumeStreamRecord_ResumeInMultipleBlocks(t *testing.T) { userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + // time flies + timestamp := ctx.BlockTime().Unix() + int64(params.VersionedParams.ReserveTime)*2 + ctx = ctx.WithBlockTime(time.Unix(timestamp, 0)) + + depKeepers.AccountKeeper.EXPECT().HasAccount(gomock.Any(), gomock.Any()). + Return(true).AnyTimes() + depKeepers.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("fail to transfer")).AnyTimes() + // resume in end block + ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true) + + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + require.Equal(t, userStreamRecord.NetflowRate, rate.Neg()) + require.Equal(t, userStreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg1StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg1) + require.True(t, gvg1StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg1StreamRecord.NetflowRate, gvg1Rate) + require.Equal(t, gvg1StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg2StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg2) + require.True(t, gvg2StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg2StreamRecord.NetflowRate, gvg2Rate) + require.Equal(t, gvg2StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg3StreamRecord, _ := keeper.GetStreamRecord(ctx, gvg3) + require.True(t, gvg3StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg3StreamRecord.NetflowRate, gvg3Rate) + require.Equal(t, gvg3StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + // there will be an auto settle record + autoSettles := keeper.GetAllAutoSettleRecord(ctx) + found = false + for _, settle := range autoSettles { + if settle.GetAddr() == user.String() { + found = true + } + } + require.True(t, found, "") + + keeper.AutoSettle(ctx) + keeper.AutoSettle(ctx) + keeper.AutoSettle(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + require.Equal(t, userStreamRecord.NetflowRate, sdkmath.ZeroInt()) + require.Equal(t, userStreamRecord.FrozenNetflowRate, rate.Neg()) +} + +func TestAutoSettle_AccountIsInResuming(t *testing.T) { + keeper, ctx, _ := makePaymentKeeper(t) + ctx = ctx.WithBlockTime(time.Now()) + + // resume account in multiple blocks + params := keeper.GetParams(ctx) + params.MaxAutoResumeFlowCount = 1 + _ = keeper.SetParams(ctx, params) + + rate := sdkmath.NewInt(300) + user := sample.RandAccAddress() + streamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: user.String(), + Status: types.STREAM_ACCOUNT_STATUS_FROZEN, + NetflowRate: sdkmath.NewInt(0), + FrozenNetflowRate: rate.Neg(), + OutFlowCount: 3, + } + keeper.SetStreamRecord(ctx, streamRecord) + + gvgAddress := []sdk.AccAddress{sample.RandAccAddress(), sample.RandAccAddress(), sample.RandAccAddress()} + + gvg1 := gvgAddress[0] + gvg1Rate := sdk.NewInt(50) + outFlow1 := &types.OutFlow{ + ToAddress: gvg1.String(), + Rate: gvg1Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow1) + + gvg2 := gvgAddress[1] + gvg2Rate := sdk.NewInt(100) + outFlow2 := &types.OutFlow{ + ToAddress: gvg2.String(), + Rate: gvg2Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow2) + + gvg3 := gvgAddress[2] + gvg3Rate := sdk.NewInt(150) + outFlow3 := &types.OutFlow{ + ToAddress: gvg3.String(), + Rate: gvg3Rate, + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow3) + + err := keeper.TryResumeStreamRecord(ctx, streamRecord, rate.MulRaw(int64(params.VersionedParams.ReserveTime))) + require.NoError(t, err) + + // still frozen + userStreamRecord, _ := keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + _, found := keeper.GetAutoResumeRecord(ctx, ctx.BlockTime().Unix(), user) + require.True(t, found) + + // add auto settle record + keeper.SetAutoSettleRecord(ctx, &types.AutoSettleRecord{ + Timestamp: ctx.BlockTime().Unix(), + Addr: user.String(), + }) + + keeper.AutoSettle(ctx) + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + keeper.AutoSettle(ctx) + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + keeper.AutoSettle(ctx) keeper.AutoResume(ctx) userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) @@ -165,7 +406,7 @@ func TestTryResumeStreamRecord_ResumeInMultipleBlocks(t *testing.T) { require.Equal(t, gvg3StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) } -func TestAutoSettle_FreezeInOneBlock(t *testing.T) { +func TestAutoSettle_SettleInOneBlock(t *testing.T) { keeper, ctx, depKeepers := makePaymentKeeper(t) ctx = ctx.WithBlockTime(time.Now()) @@ -196,7 +437,7 @@ func TestAutoSettle_FreezeInOneBlock(t *testing.T) { LockBalance: sdkmath.ZeroInt(), Account: gvg.String(), Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, - NetflowRate: sdkmath.NewInt(0), + NetflowRate: rate, FrozenNetflowRate: sdkmath.NewInt(0), OutFlowCount: 0, } @@ -214,6 +455,7 @@ func TestAutoSettle_FreezeInOneBlock(t *testing.T) { Addr: user.String(), }) + ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true) keeper.AutoSettle(ctx) userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) @@ -226,7 +468,7 @@ func TestAutoSettle_FreezeInOneBlock(t *testing.T) { require.Equal(t, gvgOutFlow.Rate, rate) } -func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { +func TestAutoSettle_SettleInMultipleBlocks(t *testing.T) { keeper, ctx, depKeepers := makePaymentKeeper(t) ctx = ctx.WithBlockTime(time.Now()) @@ -263,7 +505,7 @@ func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { LockBalance: sdkmath.ZeroInt(), Account: gvg1.String(), Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, - NetflowRate: sdkmath.NewInt(0), + NetflowRate: sdkmath.NewInt(50), FrozenNetflowRate: sdkmath.NewInt(0), OutFlowCount: 0, } @@ -283,7 +525,7 @@ func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { LockBalance: sdkmath.ZeroInt(), Account: gvg2.String(), Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, - NetflowRate: sdkmath.NewInt(0), + NetflowRate: sdkmath.NewInt(100), FrozenNetflowRate: sdkmath.NewInt(0), OutFlowCount: 0, } @@ -303,7 +545,7 @@ func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { LockBalance: sdkmath.ZeroInt(), Account: gvg3.String(), Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, - NetflowRate: sdkmath.NewInt(0), + NetflowRate: sdkmath.NewInt(150), FrozenNetflowRate: sdkmath.NewInt(0), OutFlowCount: 0, } @@ -321,6 +563,7 @@ func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { Addr: user.String(), }) + ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true) keeper.AutoSettle(ctx) // this is for settle stream, it is counted userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) @@ -355,3 +598,157 @@ func TestAutoSettle_FreezeInMultipleBlocks(t *testing.T) { require.Equal(t, gvg3OutFlow.Status, types.OUT_FLOW_STATUS_FROZEN) require.Equal(t, gvg3OutFlow.Rate, sdkmath.NewInt(150)) } + +func TestAutoSettle_SettleInMultipleBlocks_AutoResumeExists(t *testing.T) { + keeper, ctx, depKeepers := makePaymentKeeper(t) + ctx = ctx.WithBlockTime(time.Now()) + + // freeze account in multiple blocks + params := keeper.GetParams(ctx) + params.MaxAutoSettleFlowCount = 1 + params.MaxAutoResumeFlowCount = 1 + _ = keeper.SetParams(ctx, params) + + depKeepers.AccountKeeper.EXPECT().HasAccount(gomock.Any(), gomock.Any()). + Return(true).AnyTimes() + depKeepers.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(errors.New("fail to transfer")).AnyTimes() + + rate := sdkmath.NewInt(300) + user := sample.RandAccAddress() + userStreamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: user.String(), + Status: types.STREAM_ACCOUNT_STATUS_FROZEN, + NetflowRate: sdk.ZeroInt(), + FrozenNetflowRate: rate.Neg(), + OutFlowCount: 3, + } + keeper.SetStreamRecord(ctx, userStreamRecord) + + gvgAddress := []sdk.AccAddress{sample.RandAccAddress(), sample.RandAccAddress(), sample.RandAccAddress()} + + gvg1 := gvgAddress[0] + gvg1StreamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: gvg1.String(), + Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, + NetflowRate: sdkmath.NewInt(0), + FrozenNetflowRate: sdkmath.NewInt(0), + OutFlowCount: 0, + } + keeper.SetStreamRecord(ctx, gvg1StreamRecord) + + outFlow1 := &types.OutFlow{ + ToAddress: gvg1.String(), + Rate: sdkmath.NewInt(50), + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow1) + + gvg2 := gvgAddress[1] + gvg2StreamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: gvg2.String(), + Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, + NetflowRate: sdkmath.NewInt(0), + FrozenNetflowRate: sdkmath.NewInt(0), + OutFlowCount: 0, + } + keeper.SetStreamRecord(ctx, gvg2StreamRecord) + + outFlow2 := &types.OutFlow{ + ToAddress: gvg2.String(), + Rate: sdkmath.NewInt(100), + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow2) + + gvg3 := gvgAddress[2] + gvg3StreamRecord := &types.StreamRecord{ + StaticBalance: sdkmath.ZeroInt(), + BufferBalance: sdkmath.ZeroInt(), + LockBalance: sdkmath.ZeroInt(), + Account: gvg3.String(), + Status: types.STREAM_ACCOUNT_STATUS_ACTIVE, + NetflowRate: sdkmath.NewInt(0), + FrozenNetflowRate: sdkmath.NewInt(0), + OutFlowCount: 0, + } + keeper.SetStreamRecord(ctx, gvg3StreamRecord) + + outFlow3 := &types.OutFlow{ + ToAddress: gvg3.String(), + Rate: sdkmath.NewInt(150), + Status: types.OUT_FLOW_STATUS_FROZEN, + } + keeper.SetOutFlow(ctx, user, outFlow3) + + // resume the stream record + err := keeper.TryResumeStreamRecord(ctx, userStreamRecord, rate.MulRaw(int64(params.VersionedParams.ReserveTime))) + require.NoError(t, err) //only added static balance + found := keeper.ExistsAutoResumeRecord(ctx, ctx.BlockTime().Unix(), user) + require.True(t, found) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + // add auto settle record + settleTime := ctx.BlockTime().Unix() + keeper.SetAutoSettleRecord(ctx, &types.AutoSettleRecord{ + Timestamp: settleTime, + Addr: user.String(), + }) + + keeper.AutoSettle(ctx) // this is for settle stream, it is counted + keeper.AutoSettle(ctx) + keeper.AutoSettle(ctx) + keeper.AutoSettle(ctx) + keeper.AutoSettle(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN) + + keeper.AutoResume(ctx) + keeper.AutoResume(ctx) + keeper.AutoResume(ctx) + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + + timestamp := ctx.BlockTime().Unix() + ctx = ctx.WithBlockTime(time.Unix(timestamp+10, 0)) + keeper.AutoSettle(ctx) // it will pick up the auto settle record + autoSettles := keeper.GetAllAutoSettleRecord(ctx) + var record types.AutoSettleRecord + for _, settle := range autoSettles { + if settle.GetAddr() == user.String() { + record = settle + } + } + // old settle record removed, new settle record added + require.True(t, record.Timestamp != settleTime, "") + + userStreamRecord, _ = keeper.GetStreamRecord(ctx, user) + require.True(t, userStreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.True(t, userStreamRecord.NetflowRate.Equal(rate.Neg())) + require.True(t, userStreamRecord.FrozenNetflowRate.IsZero()) + + gvg1StreamRecord, _ = keeper.GetStreamRecord(ctx, gvg1) + require.True(t, gvg1StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg1StreamRecord.NetflowRate, sdk.NewInt(50)) + require.Equal(t, gvg1StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg2StreamRecord, _ = keeper.GetStreamRecord(ctx, gvg2) + require.True(t, gvg2StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg2StreamRecord.NetflowRate, sdk.NewInt(100)) + require.Equal(t, gvg2StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) + + gvg3StreamRecord, _ = keeper.GetStreamRecord(ctx, gvg3) + require.True(t, gvg3StreamRecord.Status == types.STREAM_ACCOUNT_STATUS_ACTIVE) + require.Equal(t, gvg3StreamRecord.NetflowRate, sdk.NewInt(150)) + require.Equal(t, gvg3StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt()) +} diff --git a/x/payment/module.go b/x/payment/module.go index 228832500..3dc2e77e5 100644 --- a/x/payment/module.go +++ b/x/payment/module.go @@ -145,6 +145,8 @@ func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} // EndBlock contains the logic that is automatically triggered at the end of each block func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + // set ForceUpdateStreamRecordKey to true in context to force update frozen stream record + ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true) am.keeper.AutoResume(ctx) am.keeper.AutoSettle(ctx) return []abci.ValidatorUpdate{} diff --git a/x/payment/types/params.go b/x/payment/types/params.go index 13c9532f8..bc1fb52bd 100644 --- a/x/payment/types/params.go +++ b/x/payment/types/params.go @@ -109,6 +109,10 @@ func (p Params) Validate() error { return err } + if p.VersionedParams.ReserveTime <= p.ForcedSettleTime { + return fmt.Errorf("reserve time must be greater than force settle time") + } + return nil } diff --git a/x/payment/types/price.go b/x/payment/types/price.go index a1b144ae8..6b67c292b 100644 --- a/x/payment/types/price.go +++ b/x/payment/types/price.go @@ -10,6 +10,7 @@ type StreamRecordChange struct { RateChange sdkmath.Int StaticBalanceChange sdkmath.Int LockBalanceChange sdkmath.Int + FrozenRateChange sdkmath.Int } func NewDefaultStreamRecordChangeWithAddr(addr sdk.AccAddress) *StreamRecordChange { @@ -18,6 +19,7 @@ func NewDefaultStreamRecordChangeWithAddr(addr sdk.AccAddress) *StreamRecordChan RateChange: sdkmath.ZeroInt(), StaticBalanceChange: sdkmath.ZeroInt(), LockBalanceChange: sdkmath.ZeroInt(), + FrozenRateChange: sdkmath.ZeroInt(), } } @@ -36,6 +38,11 @@ func (change *StreamRecordChange) WithLockBalanceChange(lockBalanceChange sdkmat return change } +func (change *StreamRecordChange) WithFrozenRateChange(frozenRateChange sdkmath.Int) *StreamRecordChange { + change.FrozenRateChange = frozenRateChange + return change +} + type StoragePriceParams struct { PrimarySp uint32 PriceTime int64 diff --git a/x/payment/types/stream_record.go b/x/payment/types/stream_record.go index 22269dbf8..898d8b82a 100644 --- a/x/payment/types/stream_record.go +++ b/x/payment/types/stream_record.go @@ -13,5 +13,6 @@ func NewStreamRecord(account sdk.AccAddress, crudTimestamp int64) *StreamRecord BufferBalance: sdkmath.ZeroInt(), NetflowRate: sdkmath.ZeroInt(), LockBalance: sdkmath.ZeroInt(), + Status: STREAM_ACCOUNT_STATUS_ACTIVE, } } diff --git a/x/payment/types/types.go b/x/payment/types/types.go index 251b1ba17..64bbfa295 100644 --- a/x/payment/types/types.go +++ b/x/payment/types/types.go @@ -14,3 +14,8 @@ var ( const ( ForceUpdateStreamRecordKey = "force_update_stream_record" ) + +const ( + // GovernanceAddressLackBalanceLabel is the metrics label to notify that the governance account has no enough balance + GovernanceAddressLackBalanceLabel = "governance_address_lack_balance" +) diff --git a/x/payment/types/types_test.go b/x/payment/types/types_test.go new file mode 100644 index 000000000..70eae0762 --- /dev/null +++ b/x/payment/types/types_test.go @@ -0,0 +1,12 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestVerifyModuleAddress(t *testing.T) { + require.Equal(t, "0x25b2f7C1aA3cCCeF718e8e3A7Ec1A7C521eef2a9", GovernanceAddress.String()) + require.Equal(t, "0xdF5F0588f6B09f0B9E58D3426252db25Dc74E7a1", ValidatorTaxPoolAddress.String()) +} diff --git a/x/sp/client/cli/tx.go b/x/sp/client/cli/tx.go index 87c2c793a..e02c951ca 100644 --- a/x/sp/client/cli/tx.go +++ b/x/sp/client/cli/tx.go @@ -10,7 +10,11 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" + govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -28,6 +32,7 @@ func GetTxCmd() *cobra.Command { } spTxCmd.AddCommand( + CmdCreateStorageProvider(), CmdDeposit(), CmdEditStorageProvider(), CmdGrantDepositAuthorization(), @@ -38,6 +43,111 @@ func GetTxCmd() *cobra.Command { return spTxCmd } +func CmdCreateStorageProvider() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-storage-provider [path/to/create_storage_provider_proposal.json]", + Short: "submit a create new storage provider proposal", + Args: cobra.ExactArgs(1), + Long: `Submit a create new storage provider proposal by submitting a JSON file with the new storage provider details, once the proposal has been passed, create a new storage provider initialized with a self deposit.`, + Example: strings.TrimSpace( + fmt.Sprintf(` +$ %s tx sp create-storage-provider path/to/create_validator_proposal.json --from keyname +Where create_storagep_provider.json contains: +{ + "messages": [ + { + "@type": "/greenfield.sp.MsgCreateStorageProvider", + "description": { + "moniker": "sp0", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "sp_address": "0x012Eadb23D670db68Ba8e67e6F34DE6ACE55b547", + "funding_address": "0x84b3307313e253eF5787b55616BB1F6F7139C2c0", + "seal_address": "0xbBD6cD73Cd376c3Dda20de0c4CBD8Fb1Bca2410D", + "approval_address": "0xdCE01bfaBc7c9c0865bCCeF872493B4BE3b343E8", + "gc_address": "0x0a1C8982C619B93bA7100411Fc58382306ab431b", + "endpoint": "https://sp0.greenfield.io", + "deposit": { + "denom": "BNB", + "amount": "1000000000000000000000" + }, + "read_price": "0.108", + "store_price": "0.016", + "free_read_quota": 1073741824, + "creator": "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + "bls_key": "af8c586885a490a1775bcbef95e6162de1904777f3fb91e3bfd0ffd690fe0d477d0984f11852c64dc77d4583c99f34cb", + "bls_proof": "8bbce5330c5a46416ec41bfb93d938e8fb2e01d0a4035bd7b87efb98762e5e71faf00427d991003680325b7f97b362640f8e58e69bf774cd59e2267bdfe5a2e6578194b6834531893a39253c718edae2511977991895cdc8dd9e1136e43d721c" + } + ], + "title": "create sp for test", + "summary": "test", + "metadata": "4pIMOgIGx1vZGU=", + "deposit": "1000000000000000000BNB" +} +modify the related configrations as you need. Example: +1) read_price = $0.09/1024/1024/1024/300(bnb price)*10^18/30/24/60/60 = 0.108 wei/bytes/s +2) store_price = $0.023*(1-6*0.07)/1024/1024/1024/300(bnb price)*10^18/30/24/60/60 = 0.016 wei/bytes/s. (0.07 division for each secondary SP) +3) free_read_quota defines free read quota for each bucket, uint bytes. +`, version.AppName)), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msgs, metadata, title, summary, deposit, err := govcli.ParseSubmitProposal(clientCtx.Codec, args[0]) + if err != nil { + return err + } + + govMsg, err := v1.NewMsgSubmitProposal(msgs, deposit, clientCtx.GetFromAddress().String(), metadata, title, summary) + if err != nil { + return fmt.Errorf("invalid message: %w", err) + } + + if len(msgs) != 1 { + return fmt.Errorf("invalid message length: %d", len(msgs)) + } + + spMsg, ok := msgs[0].(*types.MsgCreateStorageProvider) + if !ok || spMsg.ValidateBasic() != nil { + return fmt.Errorf("invalid create storage provider message") + } + + fundingAddr, err := sdk.AccAddressFromHexUnsafe(spMsg.FundingAddress) + if err != nil { + return err + } + if !fundingAddr.Equals(clientCtx.GetFromAddress()) { + return fmt.Errorf("the from address should be the funding address: %s", fundingAddr.String()) + } + + spAddr, err := sdk.AccAddressFromHexUnsafe(spMsg.SpAddress) + if err != nil { + return err + } + + grantee := authtypes.NewModuleAddress(govtypes.ModuleName) + authorization := types.NewDepositAuthorization(spAddr, &spMsg.Deposit) + authzMsg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, nil) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), authzMsg, govMsg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + _ = cmd.MarkFlagRequired(flags.FlagFrom) + + return cmd +} + func CmdEditStorageProvider() *cobra.Command { cmd := &cobra.Command{ Use: "edit-storage-provider [sp-address]", diff --git a/x/sp/keeper/msg_server.go b/x/sp/keeper/msg_server.go index fd013c855..74c0c42af 100644 --- a/x/sp/keeper/msg_server.go +++ b/x/sp/keeper/msg_server.go @@ -354,7 +354,7 @@ func (k msgServer) checkBlsProof(blsPk []byte, sig string) error { return types.ErrStorageProviderInvalidBlsKey } if !signature.Verify(blsPubKey, tmhash.Sum(blsPk)) { - return sdkerrors.ErrorInvalidSigner + return sdkerrors.ErrorInvalidSigner.Wrapf("check bls proof failed.") } return nil } diff --git a/x/storage/abci.go b/x/storage/abci.go index e42e1b51b..b395f512c 100644 --- a/x/storage/abci.go +++ b/x/storage/abci.go @@ -31,6 +31,7 @@ func EndBlocker(ctx sdk.Context, keeper k.Keeper) { deleted, err := keeper.DeleteDiscontinueObjectsUntil(ctx, blockTime, deletionMax) if err != nil { ctx.Logger().Error("should not happen, fail to delete objects, err " + err.Error()) + panic("should not happen") } if deleted >= deletionMax { @@ -41,6 +42,7 @@ func EndBlocker(ctx sdk.Context, keeper k.Keeper) { _, err = keeper.DeleteDiscontinueBucketsUntil(ctx, blockTime, deletionMax-deleted) if err != nil { ctx.Logger().Error("should not happen, fail to delete buckets, err " + err.Error()) + panic("should not happen") } keeper.PersistDeleteInfo(ctx) diff --git a/x/storage/keeper/grpc_query.go b/x/storage/keeper/grpc_query.go index 6e9972a20..ddcc0e4dd 100644 --- a/x/storage/keeper/grpc_query.go +++ b/x/storage/keeper/grpc_query.go @@ -71,3 +71,50 @@ func (k Keeper) QueryLockFee(c context.Context, req *types.QueryLockFeeRequest) return &types.QueryLockFeeResponse{Amount: amount}, nil } + +func (k Keeper) HeadBucketExtra(c context.Context, req *types.QueryHeadBucketExtraRequest) (*types.QueryHeadBucketExtraResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + bucketInfo, found := k.GetBucketInfo(ctx, req.BucketName) + if !found { + return nil, types.ErrNoSuchBucket + } + + internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) + + return &types.QueryHeadBucketExtraResponse{ + ExtraInfo: internalBucketInfo, + }, nil +} + +func (k Keeper) QueryIsPriceChanged(c context.Context, req *types.QueryIsPriceChangedRequest) (*types.QueryIsPriceChangedResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + bucketInfo, found := k.GetBucketInfo(ctx, req.BucketName) + if !found { + return nil, types.ErrNoSuchBucket + } + + primarySp := k.MustGetPrimarySPForBucket(ctx, bucketInfo) + internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) + changed, currentPrice, currentTaxRate, newPrice, newTaxRate, err := k.IsPriceChanged(ctx, primarySp.Id, internalBucketInfo.PriceTime) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryIsPriceChangedResponse{ + Changed: changed, + CurrentReadPrice: currentPrice.ReadPrice, + CurrentPrimaryStorePrice: currentPrice.PrimaryStorePrice, + CurrentSecondaryStorePrice: currentPrice.ReadPrice, + CurrentValidatorTaxRate: currentTaxRate, + NewReadPrice: newPrice.ReadPrice, + NewPrimaryStorePrice: newPrice.PrimaryStorePrice, + NewSecondaryStorePrice: newPrice.SecondaryStorePrice, + NewValidatorTaxRate: newTaxRate, + }, nil +} diff --git a/x/storage/keeper/keeper.go b/x/storage/keeper/keeper.go index 1bd440a11..76430a572 100644 --- a/x/storage/keeper/keeper.go +++ b/x/storage/keeper/keeper.go @@ -111,11 +111,11 @@ func (k Keeper) CreateBucket( if opts.PrimarySpApproval.ExpiredHeight < uint64(ctx.BlockHeight()) { return sdkmath.ZeroUint(), errors.Wrapf(types.ErrInvalidApproval, "The approval of sp is expired.") } - err = k.VerifySPAndSignature(ctx, sp.Id, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) + err = k.VerifySPAndSignature(ctx, sp, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) if err != nil { return sdkmath.ZeroUint(), err } - gvgFamily, err := k.virtualGroupKeeper.GetAndCheckGVGFamilyAvailableForNewBucket(ctx, sp.Id, opts.PrimarySpApproval.GlobalVirtualGroupFamilyId) + gvgFamily, err := k.virtualGroupKeeper.GetAndCheckGVGFamilyAvailableForNewBucket(ctx, opts.PrimarySpApproval.GlobalVirtualGroupFamilyId) if err != nil { return sdkmath.ZeroUint(), err } @@ -129,7 +129,6 @@ func (k Keeper) CreateBucket( BucketStatus: types.BUCKET_STATUS_CREATED, ChargedReadQuota: opts.ChargedReadQuota, PaymentAddress: paymentAcc.String(), - PrimarySpId: sp.Id, GlobalVirtualGroupFamilyId: gvgFamily.Id, } @@ -163,7 +162,7 @@ func (k Keeper) CreateBucket( Status: bucketInfo.BucketStatus, ChargedReadQuota: bucketInfo.ChargedReadQuota, PaymentAddress: bucketInfo.PaymentAddress, - PrimarySpId: bucketInfo.PrimarySpId, + PrimarySpId: sp.Id, GlobalVirtualGroupFamilyId: bucketInfo.GlobalVirtualGroupFamilyId, }); err != nil { return sdkmath.Uint{}, err @@ -222,15 +221,32 @@ func (k Keeper) doDeleteBucket(ctx sdk.Context, operator sdk.AccAddress, bucketI return err } err = ctx.EventManager().EmitTypedEvents(&types.EventDeleteBucket{ - Operator: operator.String(), - Owner: bucketInfo.Owner, - BucketName: bucketInfo.BucketName, - BucketId: bucketInfo.Id, - PrimarySpId: bucketInfo.PrimarySpId, + Operator: operator.String(), + Owner: bucketInfo.Owner, + BucketName: bucketInfo.BucketName, + BucketId: bucketInfo.Id, + GlobalVirtualGroupFamilyId: bucketInfo.GlobalVirtualGroupFamilyId, }) return err } +func (k Keeper) GetPrimarySPForBucket(ctx sdk.Context, bucketInfo *types.BucketInfo) (*sptypes.StorageProvider, error) { + gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) + if !found { + return nil, virtualgroupmoduletypes.ErrGVGFamilyNotExist.Wrapf("gvg family (%d) not found.", bucketInfo.GlobalVirtualGroupFamilyId) + } + sp := k.spKeeper.MustGetStorageProvider(ctx, gvgFamily.PrimarySpId) + return sp, nil +} + +func (k Keeper) MustGetPrimarySPForBucket(ctx sdk.Context, bucketInfo *types.BucketInfo) *sptypes.StorageProvider { + sp, err := k.GetPrimarySPForBucket(ctx, bucketInfo) + if err != nil { + panic(err) + } + return sp +} + // ForceDeleteBucket will delete bucket without permission check, it is used for discontinue request from sps. // The cap parameter will limit the max objects can be deleted in the call. // It will also return 1) whether the bucket is deleted, 2) the objects deleted, and 3) error if there is @@ -242,7 +258,7 @@ func (k Keeper) ForceDeleteBucket(ctx sdk.Context, bucketId sdkmath.Uint, cap ui bucketDeleted := false - sp := k.spKeeper.MustGetStorageProvider(ctx, bucketInfo.PrimarySpId) + sp := k.MustGetPrimarySPForBucket(ctx, bucketInfo) spOperatorAddr := sdk.MustAccAddressFromHex(sp.OperatorAddress) store := ctx.KVStore(k.storeKey) @@ -251,8 +267,8 @@ func (k Keeper) ForceDeleteBucket(ctx sdk.Context, bucketId sdkmath.Uint, cap ui defer iter.Close() u256Seq := sequence.Sequence[sdkmath.Uint]{} - var err error deleted := uint64(0) // deleted object count + var err error for ; iter.Valid(); iter.Next() { if deleted >= cap { return false, deleted, nil // break is also fine here @@ -282,13 +298,13 @@ func (k Keeper) ForceDeleteBucket(ctx sdk.Context, bucketId sdkmath.Uint, cap ui } if objectStatus == types.OBJECT_STATUS_CREATED { - if err = k.UnlockObjectStoreFee(ctx, bucketInfo, &objectInfo); err != nil { + if err = k.UnlockObjectStoreFee(ctx, sp.Id, bucketInfo, &objectInfo); err != nil { ctx.Logger().Error("unlock store fee error", "err", err) return false, deleted, err } } else if objectStatus == types.OBJECT_STATUS_SEALED { internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) - if err = k.UnChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, &objectInfo); err != nil { + if err = k.UnChargeObjectStoreFee(ctx, sp.Id, bucketInfo, internalBucketInfo, &objectInfo); err != nil { ctx.Logger().Error("charge delete object error", "err", err) return false, deleted, err } @@ -383,14 +399,13 @@ func (k Keeper) UpdateBucketInfo(ctx sdk.Context, operator sdk.AccAddress, bucke k.SetInternalBucketInfo(ctx, bucketInfo.Id, internalBucketInfo) if err := ctx.EventManager().EmitTypedEvents(&types.EventUpdateBucketInfo{ - Operator: operator.String(), - BucketName: bucketName, - BucketId: bucketInfo.Id, - ChargedReadQuotaBefore: bucketInfo.ChargedReadQuota, - ChargedReadQuotaAfter: *opts.ChargedReadQuota, - PaymentAddressBefore: bucketInfo.PaymentAddress, - PaymentAddressAfter: paymentAcc.String(), - Visibility: bucketInfo.Visibility, + Operator: operator.String(), + BucketName: bucketName, + BucketId: bucketInfo.Id, + ChargedReadQuota: bucketInfo.ChargedReadQuota, + PaymentAddress: bucketInfo.PaymentAddress, + Visibility: bucketInfo.Visibility, + GlobalVirtualGroupFamilyId: bucketInfo.GlobalVirtualGroupFamilyId, }); err != nil { return err } @@ -414,9 +429,11 @@ func (k Keeper) DiscontinueBucket(ctx sdk.Context, operator sdk.AccAddress, buck return types.ErrInvalidBucketStatus } - if sp.Id != bucketInfo.PrimarySpId { + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) + + if sp.Id != spInState.Id { return errors.Wrapf(types.ErrAccessDenied, - "only primary sp is allowed to do discontinue bucket, expect sp id : %d", bucketInfo.PrimarySpId) + "only primary sp is allowed to do discontinue bucket, expect sp id : %d", spInState.Id) } count := k.getDiscontinueBucketCount(ctx, operator) @@ -500,6 +517,9 @@ func (k Keeper) CreateObject( return sdkmath.ZeroUint(), err } + // primary sp + sp := k.MustGetPrimarySPForBucket(ctx, bucketInfo) + // verify permission verifyOpts := &permtypes.VerifyOptions{ WantedSize: &payloadSize, @@ -521,7 +541,7 @@ func (k Keeper) CreateObject( return sdkmath.ZeroUint(), errors.Wrapf(types.ErrInvalidApproval, "The approval of sp is expired.") } - err = k.VerifySPAndSignature(ctx, bucketInfo.PrimarySpId, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) + err = k.VerifySPAndSignature(ctx, sp, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) if err != nil { return sdkmath.ZeroUint(), err } @@ -564,7 +584,7 @@ func (k Keeper) CreateObject( } } else { // Lock Fee - err = k.LockObjectStoreFee(ctx, bucketInfo, &objectInfo) + err = k.LockObjectStoreFee(ctx, sp.Id, bucketInfo, &objectInfo) if err != nil { return sdkmath.ZeroUint(), err } @@ -587,7 +607,7 @@ func (k Keeper) CreateObject( CreateAt: objectInfo.CreateAt, PayloadSize: objectInfo.PayloadSize, Visibility: objectInfo.Visibility, - PrimarySpId: bucketInfo.PrimarySpId, + PrimarySpId: sp.Id, ContentType: objectInfo.ContentType, Status: objectInfo.ObjectStatus, RedundancyType: objectInfo.RedundancyType, @@ -656,7 +676,9 @@ func (k Keeper) SealObject( return errors.Wrapf(types.ErrNoSuchStorageProvider, "SP seal address: %s", spSealAcc.String()) } - if sp.Id != bucketInfo.PrimarySpId { + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) + + if sp.Id != spInState.Id { return errors.Wrapf(types.ErrAccessDenied, "Only SP's seal address is allowed to SealObject") } @@ -674,7 +696,7 @@ func (k Keeper) SealObject( return virtualgroupmoduletypes.ErrGVGNotExist } - if gvg.FamilyId != bucketInfo.GlobalVirtualGroupFamilyId || gvg.PrimarySpId != bucketInfo.PrimarySpId { + if gvg.FamilyId != bucketInfo.GlobalVirtualGroupFamilyId || gvg.PrimarySpId != spInState.Id { return types.ErrInvalidGlobalVirtualGroup.Wrapf("Global virtual group mismatch, familyID: %d, bucket family ID: %d", gvg.FamilyId, bucketInfo.GlobalVirtualGroupFamilyId) } @@ -731,6 +753,8 @@ func (k Keeper) CancelCreateObject( return types.ErrNoSuchObject } + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) + if objectInfo.ObjectStatus != types.OBJECT_STATUS_CREATED { return types.ErrObjectNotCreated.Wrapf("Object status: %s", objectInfo.ObjectStatus.String()) } @@ -748,7 +772,7 @@ func (k Keeper) CancelCreateObject( return errors.Wrapf(types.ErrAccessDenied, "Only allowed owner/creator to do cancel create object") } - err := k.UnlockObjectStoreFee(ctx, bucketInfo, objectInfo) + err := k.UnlockObjectStoreFee(ctx, spInState.Id, bucketInfo, objectInfo) if err != nil { return err } @@ -764,7 +788,7 @@ func (k Keeper) CancelCreateObject( BucketName: bucketInfo.BucketName, ObjectName: objectInfo.ObjectName, ObjectId: objectInfo.Id, - PrimarySpId: bucketInfo.PrimarySpId, + PrimarySpId: spInState.Id, }); err != nil { return err } @@ -801,8 +825,10 @@ func (k Keeper) DeleteObject( operator.String(), bucketName, objectName) } + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) - err := k.UnChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, objectInfo) + + err := k.UnChargeObjectStoreFee(ctx, spInState.Id, bucketInfo, internalBucketInfo, objectInfo) if err != nil { return err } @@ -824,12 +850,15 @@ func (k Keeper) doDeleteObject(ctx sdk.Context, operator sdk.AccAddress, bucketI store.Delete(types.GetObjectKey(bucketInfo.BucketName, objectInfo.ObjectName)) store.Delete(types.GetObjectByIDKey(objectInfo.Id)) - err := k.DeleteObjectFromVirtualGroup(ctx, bucketInfo, objectInfo) - if err != nil { - return err + // when object was not sealed, the lvg id is 0 by default. + if objectInfo.LocalVirtualGroupId != 0 { + err := k.DeleteObjectFromVirtualGroup(ctx, bucketInfo, objectInfo) + if err != nil { + return err + } } - err = k.appendResourceIdForGarbageCollection(ctx, resource.RESOURCE_TYPE_OBJECT, objectInfo.Id) + err := k.appendResourceIdForGarbageCollection(ctx, resource.RESOURCE_TYPE_OBJECT, objectInfo.Id) if err != nil { return err } @@ -861,19 +890,16 @@ func (k Keeper) ForceDeleteObject(ctx sdk.Context, objectId sdkmath.Uint) error return err } - sp, found := k.spKeeper.GetStorageProvider(ctx, bucketInfo.PrimarySpId) - if !found { - return sptypes.ErrStorageProviderNotFound - } + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) if objectStatus == types.OBJECT_STATUS_CREATED { - err := k.UnlockObjectStoreFee(ctx, bucketInfo, objectInfo) + err := k.UnlockObjectStoreFee(ctx, spInState.Id, bucketInfo, objectInfo) if err != nil { ctx.Logger().Error("unlock store fee error", "err", err) return err } } else if objectStatus == types.OBJECT_STATUS_SEALED { internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) - err := k.UnChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, objectInfo) + err := k.UnChargeObjectStoreFee(ctx, spInState.Id, bucketInfo, internalBucketInfo, objectInfo) if err != nil { ctx.Logger().Error("charge delete object error", "err", err) return err @@ -881,7 +907,7 @@ func (k Keeper) ForceDeleteObject(ctx sdk.Context, objectId sdkmath.Uint) error k.SetInternalBucketInfo(ctx, bucketInfo.Id, internalBucketInfo) } - err = k.doDeleteObject(ctx, sdk.MustAccAddressFromHex(sp.OperatorAddress), bucketInfo, objectInfo) + err = k.doDeleteObject(ctx, sdk.MustAccAddressFromHex(spInState.OperatorAddress), bucketInfo, objectInfo) if err != nil { ctx.Logger().Error("do delete object err", "err", err) return err @@ -905,6 +931,8 @@ func (k Keeper) CopyObject( return sdkmath.ZeroUint(), errors.Wrapf(types.ErrNoSuchBucket, "dst bucket name (%s)", dstBucketName) } + dstPrimarySP := k.MustGetPrimarySPForBucket(ctx, dstBucketInfo) + err := dstBucketInfo.CheckBucketStatus() if err != nil { return sdkmath.ZeroUint(), err @@ -931,7 +959,7 @@ func (k Keeper) CopyObject( return sdkmath.ZeroUint(), errors.Wrapf(types.ErrInvalidApproval, "The approval of sp is expired.") } - err = k.VerifySPAndSignature(ctx, dstBucketInfo.PrimarySpId, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) + err = k.VerifySPAndSignature(ctx, dstPrimarySP, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig) if err != nil { return sdkmath.ZeroUint(), err } @@ -966,7 +994,7 @@ func (k Keeper) CopyObject( return sdkmath.ZeroUint(), err } } else { - err = k.LockObjectStoreFee(ctx, dstBucketInfo, &objectInfo) + err = k.LockObjectStoreFee(ctx, dstPrimarySP.Id, dstBucketInfo, &objectInfo) if err != nil { return sdkmath.ZeroUint(), err } @@ -1003,6 +1031,7 @@ func (k Keeper) RejectSealObject(ctx sdk.Context, operator sdk.AccAddress, bucke if !found { return types.ErrNoSuchObject } + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) if objectInfo.ObjectStatus != types.OBJECT_STATUS_CREATED { return types.ErrObjectNotCreated.Wrapf("Object status: %s", objectInfo.ObjectStatus.String()) @@ -1015,11 +1044,11 @@ func (k Keeper) RejectSealObject(ctx sdk.Context, operator sdk.AccAddress, bucke if sp.Status != sptypes.STATUS_IN_SERVICE { return sptypes.ErrStorageProviderNotInService } - if sp.Id != bucketInfo.PrimarySpId { + if sp.Id != spInState.Id { return errors.Wrapf(types.ErrAccessDenied, "Only allowed primary SP to do cancel create object") } - err := k.UnlockObjectStoreFee(ctx, bucketInfo, objectInfo) + err := k.UnlockObjectStoreFee(ctx, spInState.Id, bucketInfo, objectInfo) if err != nil { return err } @@ -1058,8 +1087,9 @@ func (k Keeper) DiscontinueObject(ctx sdk.Context, operator sdk.AccAddress, buck if bucketInfo.BucketStatus == types.BUCKET_STATUS_DISCONTINUED { return types.ErrInvalidBucketStatus } + spInState := k.MustGetPrimarySPForBucket(ctx, bucketInfo) - if sp.Id != bucketInfo.PrimarySpId { + if sp.Id != spInState.Id { return errors.Wrapf(types.ErrAccessDenied, "only primary sp is allowed to do discontinue objects") } @@ -1368,11 +1398,7 @@ func (k Keeper) UpdateGroupExtra(ctx sdk.Context, operator sdk.AccAddress, group return nil } -func (k Keeper) VerifySPAndSignature(ctx sdk.Context, spID uint32, sigData []byte, signature []byte) error { - sp, found := k.spKeeper.GetStorageProvider(ctx, spID) - if !found { - return errors.Wrapf(types.ErrNoSuchStorageProvider, "SP id: %d", spID) - } +func (k Keeper) VerifySPAndSignature(ctx sdk.Context, sp *sptypes.StorageProvider, sigData []byte, signature []byte) error { if sp.Status != sptypes.STATUS_IN_SERVICE { return sptypes.ErrStorageProviderNotInService } @@ -1754,10 +1780,7 @@ func (k Keeper) MigrateBucket(ctx sdk.Context, operator sdk.AccAddress, bucketNa return types.ErrInvalidBucketStatus.Wrapf("The bucket already been migrating") } - srcSP, found := k.spKeeper.GetStorageProvider(ctx, bucketInfo.PrimarySpId) - if !found { - return sptypes.ErrStorageProviderNotFound.Wrapf("src sp not found") - } + srcSP := k.MustGetPrimarySPForBucket(ctx, bucketInfo) dstSP, found := k.spKeeper.GetStorageProvider(ctx, dstPrimarySPID) if !found { @@ -1773,7 +1796,7 @@ func (k Keeper) MigrateBucket(ctx sdk.Context, operator sdk.AccAddress, bucketNa if dstPrimarySPApproval.ExpiredHeight < (uint64)(ctx.BlockHeight()) { return types.ErrInvalidApproval.Wrap("dst primary sp approval timeout") } - err := k.VerifySPAndSignature(ctx, dstSP.Id, approvalBytes, dstPrimarySPApproval.Sig) + err := k.VerifySPAndSignature(ctx, dstSP, approvalBytes, dstPrimarySPApproval.Sig) if err != nil { return err } @@ -1831,17 +1854,17 @@ func (k Keeper) CompleteMigrateBucket(ctx sdk.Context, operator sdk.AccAddress, return types.ErrMigrationBucketFailed.Wrapf("dst sp info not match") } - _, found = k.virtualGroupKeeper.GetGVGFamily(ctx, dstSP.Id, gvgFamilyID) + _, found = k.virtualGroupKeeper.GetGVGFamily(ctx, gvgFamilyID) if !found { return virtualgroupmoduletypes.ErrGVGFamilyNotExist } - srcGvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) + srcGvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) if !found { return virtualgroupmoduletypes.ErrGVGFamilyNotExist } - sp, _ := k.spKeeper.GetStorageProvider(ctx, bucketInfo.PrimarySpId) + sp := k.MustGetPrimarySPForBucket(ctx, bucketInfo) err := k.virtualGroupKeeper.SettleAndDistributeGVGFamily(ctx, sp, srcGvgFamily) if err != nil { @@ -1854,7 +1877,6 @@ func (k Keeper) CompleteMigrateBucket(ctx sdk.Context, operator sdk.AccAddress, return types.ErrMigrationBucketFailed.Wrapf("cancel charge bucket failed, err: %s", err) } - bucketInfo.PrimarySpId = migrationBucketInfo.DstSpId bucketInfo.GlobalVirtualGroupFamilyId = gvgFamilyID // check secondary sp signature @@ -1878,7 +1900,19 @@ func (k Keeper) CompleteMigrateBucket(ctx sdk.Context, operator sdk.AccAddress, BucketName: bucketName, BucketId: bucketInfo.Id, GlobalVirtualGroupFamilyId: gvgFamilyID, - GvgMappings: gvgMappings, + SrcPrimarySpId: srcGvgFamily.Id, + }); err != nil { + return err + } + + if err = ctx.EventManager().EmitTypedEvents(&types.EventUpdateBucketInfo{ + Operator: operator.String(), + BucketName: bucketName, + BucketId: bucketInfo.Id, + ChargedReadQuota: bucketInfo.ChargedReadQuota, + PaymentAddress: bucketInfo.PaymentAddress, + Visibility: bucketInfo.Visibility, + GlobalVirtualGroupFamilyId: bucketInfo.GlobalVirtualGroupFamilyId, }); err != nil { return err } diff --git a/x/storage/keeper/payment.go b/x/storage/keeper/payment.go index 637e62fcf..7d324b9d9 100644 --- a/x/storage/keeper/payment.go +++ b/x/storage/keeper/payment.go @@ -57,19 +57,19 @@ func (k Keeper) GetBucketReadBill(ctx sdk.Context, bucketInfo *storagetypes.Buck if bucketInfo.ChargedReadQuota == 0 { return userFlows, nil } + gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) + if !found { + return userFlows, fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) + } + price, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ - PrimarySp: bucketInfo.PrimarySpId, + PrimarySp: gvgFamily.PrimarySpId, PriceTime: internalBucketInfo.PriceTime, }) if err != nil { return userFlows, fmt.Errorf("get storage price failed: %w", err) } - gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) - if !found { - return userFlows, fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) - } - // primary sp total rate primaryTotalFlowRate := price.ReadPrice.MulInt(sdkmath.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() @@ -108,9 +108,9 @@ func (k Keeper) UpdateBucketInfoAndCharge(ctx sdk.Context, bucketInfo *storagety return err } -func (k Keeper) LockObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, objectInfo *storagetypes.ObjectInfo) error { +func (k Keeper) LockObjectStoreFee(ctx sdk.Context, primarySpId uint32, bucketInfo *storagetypes.BucketInfo, objectInfo *storagetypes.ObjectInfo) error { paymentAddr := sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress) - amount, err := k.GetObjectLockFee(ctx, bucketInfo.PrimarySpId, objectInfo.CreateAt, objectInfo.PayloadSize) + amount, err := k.GetObjectLockFee(ctx, primarySpId, objectInfo.CreateAt, objectInfo.PayloadSize) if err != nil { return fmt.Errorf("get object store fee rate failed: %w", err) } @@ -134,8 +134,9 @@ func (k Keeper) LockObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.Buc } // UnlockObjectStoreFee unlock store fee if the object is deleted in INIT state -func (k Keeper) UnlockObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, objectInfo *storagetypes.ObjectInfo) error { - lockedBalance, err := k.GetObjectLockFee(ctx, bucketInfo.PrimarySpId, objectInfo.CreateAt, objectInfo.PayloadSize) +func (k Keeper) UnlockObjectStoreFee(ctx sdk.Context, primarySpId uint32, bucketInfo *storagetypes.BucketInfo, objectInfo *storagetypes.ObjectInfo) error { + + lockedBalance, err := k.GetObjectLockFee(ctx, primarySpId, objectInfo.CreateAt, objectInfo.PayloadSize) if err != nil { return fmt.Errorf("get object store fee rate failed: %w", err) } @@ -148,46 +149,58 @@ func (k Keeper) UnlockObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.B return nil } -func (k Keeper) UnlockAndChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, +func (k Keeper) UnlockAndChargeObjectStoreFee(ctx sdk.Context, primarySpId uint32, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo, objectInfo *storagetypes.ObjectInfo) error { // unlock store fee - err := k.UnlockObjectStoreFee(ctx, bucketInfo, objectInfo) + err := k.UnlockObjectStoreFee(ctx, primarySpId, bucketInfo, objectInfo) if err != nil { return fmt.Errorf("unlock store fee failed: %w", err) } - return k.ChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, objectInfo) + return k.ChargeObjectStoreFee(ctx, primarySpId, bucketInfo, internalBucketInfo, objectInfo) } -func (k Keeper) IsPriceChanged(ctx sdk.Context, primarySpId uint32, priceTime int64) (bool, error) { +func (k Keeper) IsPriceChanged(ctx sdk.Context, primarySpId uint32, priceTime int64) (bool, *types.StoragePrice, sdk.Dec, *types.StoragePrice, sdk.Dec, error) { prePrice, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ PrimarySp: primarySpId, PriceTime: priceTime, }) if err != nil { - return false, fmt.Errorf("get storage price failed: %w", err) + return false, nil, sdk.ZeroDec(), nil, sdk.ZeroDec(), err } currentPrice, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ PrimarySp: primarySpId, PriceTime: ctx.BlockTime().Unix(), }) if err != nil { - return false, fmt.Errorf("get storage price failed: %w", err) + return false, nil, sdk.ZeroDec(), nil, sdk.ZeroDec(), err + } + + preParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, priceTime) + if err != nil { + return false, nil, sdk.ZeroDec(), nil, sdk.ZeroDec(), err + } + + currentParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, ctx.BlockTime().Unix()) + if err != nil { + return false, nil, sdk.ZeroDec(), nil, sdk.ZeroDec(), err } return !(prePrice.ReadPrice.Equal(currentPrice.ReadPrice) && - prePrice.PrimaryStorePrice.Equal(currentPrice.PrimaryStorePrice) && - prePrice.SecondaryStorePrice.Equal(currentPrice.SecondaryStorePrice)), nil + prePrice.PrimaryStorePrice.Equal(currentPrice.PrimaryStorePrice) && + prePrice.SecondaryStorePrice.Equal(currentPrice.SecondaryStorePrice) && + preParams.ValidatorTaxRate.Equal(currentParams.ValidatorTaxRate)), + &prePrice, preParams.ValidatorTaxRate, ¤tPrice, currentParams.ValidatorTaxRate, nil } -func (k Keeper) ChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, +func (k Keeper) ChargeObjectStoreFee(ctx sdk.Context, primarySpId uint32, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo, objectInfo *storagetypes.ObjectInfo) error { chargeSize, err := k.GetObjectChargeSize(ctx, objectInfo.PayloadSize, objectInfo.CreateAt) if err != nil { return fmt.Errorf("get charge size error: %w", err) } - priceChanged, err := k.IsPriceChanged(ctx, bucketInfo.PrimarySpId, internalBucketInfo.PriceTime) + priceChanged, _, _, _, _, err := k.IsPriceChanged(ctx, primarySpId, internalBucketInfo.PriceTime) if err != nil { return fmt.Errorf("check whether price changed error: %w", err) } @@ -204,7 +217,7 @@ func (k Keeper) ChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.B ibi.TotalChargeSize += chargeSize for _, lvg := range ibi.LocalVirtualGroups { if lvg.Id == objectInfo.LocalVirtualGroupId { - lvg.TotalChargeSize += lvg.TotalChargeSize + chargeSize + lvg.TotalChargeSize = lvg.TotalChargeSize + chargeSize break } } @@ -212,53 +225,26 @@ func (k Keeper) ChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.B }) } -func (k Keeper) UnChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, +func (k Keeper) UnChargeObjectStoreFee(ctx sdk.Context, primarySpId uint32, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo, objectInfo *storagetypes.ObjectInfo) error { chargeSize, err := k.GetObjectChargeSize(ctx, objectInfo.PayloadSize, objectInfo.CreateAt) if err != nil { return fmt.Errorf("get charge size error: %w", err) } - priceChanged, err := k.IsPriceChanged(ctx, bucketInfo.PrimarySpId, internalBucketInfo.PriceTime) + err = k.ChargeViaObjectChange(ctx, bucketInfo, internalBucketInfo, objectInfo, chargeSize, true) if err != nil { - return fmt.Errorf("check whether price changed error: %w", err) - } - - oldInternalBucketInfo := &storagetypes.InternalBucketInfo{ - PriceTime: internalBucketInfo.PriceTime, - TotalChargeSize: internalBucketInfo.TotalChargeSize, - LocalVirtualGroups: internalBucketInfo.LocalVirtualGroups, - } - - if !priceChanged { - err = k.ChargeViaObjectChange(ctx, bucketInfo, internalBucketInfo, objectInfo, chargeSize, true) - if err != nil { - return fmt.Errorf("apply object store bill error: %w", err) - } - } else { - err = k.ChargeViaBucketChange(ctx, bucketInfo, internalBucketInfo, func(bi *storagetypes.BucketInfo, ibi *storagetypes.InternalBucketInfo) error { - ibi.TotalChargeSize -= chargeSize - for _, lvg := range ibi.LocalVirtualGroups { - if lvg.Id == objectInfo.LocalVirtualGroupId { - lvg.TotalChargeSize -= chargeSize - break - } - } - return nil - }) - if err != nil { - return fmt.Errorf("apply object store bill error: %w", err) - } + return fmt.Errorf("apply object store bill error: %w", err) } blockTime := ctx.BlockTime().Unix() - versionParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, oldInternalBucketInfo.PriceTime) + versionParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, internalBucketInfo.PriceTime) if err != nil { return fmt.Errorf("failed to get versioned params: %w", err) } timeToPay := objectInfo.CreateAt + int64(versionParams.ReserveTime) - blockTime if timeToPay > 0 { // store less than reserve time - err = k.ChargeObjectStoreFeeForEarlyDeletion(ctx, bucketInfo, oldInternalBucketInfo, objectInfo, chargeSize, timeToPay) + err = k.ChargeObjectStoreFeeForEarlyDeletion(ctx, bucketInfo, internalBucketInfo, objectInfo, chargeSize, timeToPay) forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) // force update in end block if !forced && err != nil { return fmt.Errorf("fail to pay for early deletion, error: %w", err) @@ -270,9 +256,14 @@ func (k Keeper) UnChargeObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes func (k Keeper) ChargeObjectStoreFeeForEarlyDeletion(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo, objectInfo *storagetypes.ObjectInfo, chargeSize uint64, timeToPay int64) error { + gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) + if !found { + return fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) + } + paymentAddr := sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress) price, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ - PrimarySp: bucketInfo.PrimarySpId, + PrimarySp: gvgFamily.PrimarySpId, PriceTime: internalBucketInfo.PriceTime, }) if err != nil { @@ -282,16 +273,11 @@ func (k Keeper) ChargeObjectStoreFeeForEarlyDeletion(ctx sdk.Context, bucketInfo // primary sp total rate primaryTotalFlowRate := sdk.ZeroInt() - gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) - if !found { - return fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) - } - primaryRate := price.PrimaryStorePrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() if primaryRate.IsPositive() { primaryTotalFlowRate = primaryRate - err = k.paymentKeeper.Withdraw(ctx, paymentAddr, sdk.MustAccAddressFromHex(gvgFamily.VirtualPaymentAddress), - primaryTotalFlowRate.MulRaw(timeToPay)) + _, err = k.paymentKeeper.UpdateStreamRecordByAddr(ctx, types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(gvgFamily.VirtualPaymentAddress)). + WithStaticBalanceChange(primaryTotalFlowRate.MulRaw(timeToPay))) if err != nil { return fmt.Errorf("fail to pay GVG family: %s", err) } @@ -317,8 +303,8 @@ func (k Keeper) ChargeObjectStoreFeeForEarlyDeletion(ctx sdk.Context, bucketInfo secondaryRate = secondaryRate.MulRaw(int64(len(gvg.SecondarySpIds))) if secondaryRate.IsPositive() { secondaryTotalFlowRate = secondaryTotalFlowRate.Add(secondaryRate) - err = k.paymentKeeper.Withdraw(ctx, paymentAddr, sdk.MustAccAddressFromHex(gvg.VirtualPaymentAddress), - secondaryTotalFlowRate.MulRaw(timeToPay)) + _, err = k.paymentKeeper.UpdateStreamRecordByAddr(ctx, types.NewDefaultStreamRecordChangeWithAddr(sdk.MustAccAddressFromHex(gvg.VirtualPaymentAddress)). + WithStaticBalanceChange(secondaryTotalFlowRate.MulRaw(timeToPay))) if err != nil { return fmt.Errorf("fail to pay GVG: %s", err) } @@ -331,13 +317,20 @@ func (k Keeper) ChargeObjectStoreFeeForEarlyDeletion(ctx sdk.Context, bucketInfo } validatorTaxRate := versionedParams.ValidatorTaxRate.MulInt(primaryTotalFlowRate.Add(secondaryTotalFlowRate)).TruncateInt() if validatorTaxRate.IsPositive() { - err = k.paymentKeeper.Withdraw(ctx, paymentAddr, types.ValidatorTaxPoolAddress, - validatorTaxRate.MulRaw(timeToPay)) + _, err = k.paymentKeeper.UpdateStreamRecordByAddr(ctx, types.NewDefaultStreamRecordChangeWithAddr(types.ValidatorTaxPoolAddress). + WithStaticBalanceChange(validatorTaxRate.MulRaw(timeToPay))) if err != nil { return fmt.Errorf("fail to pay validator: %s", err) } } + total := primaryTotalFlowRate.Add(secondaryTotalFlowRate).Add(validatorTaxRate).MulRaw(timeToPay) + _, err = k.paymentKeeper.UpdateStreamRecordByAddr(ctx, types.NewDefaultStreamRecordChangeWithAddr(paymentAddr). + WithStaticBalanceChange(total.Neg())) + if err != nil { + return fmt.Errorf("fail to substrct from payment account: %s", err) + } + return nil } @@ -354,7 +347,6 @@ func (k Keeper) ChargeViaBucketChange(ctx sdk.Context, bucketInfo *storagetypes. if err = changeFunc(bucketInfo, internalBucketInfo); err != nil { return errors.Wrapf(err, "change bucket internal info failed") } - // calculate new bill internalBucketInfo.PriceTime = ctx.BlockTime().Unix() newBill, err := k.GetBucketReadStoreBill(ctx, bucketInfo, internalBucketInfo) @@ -377,26 +369,19 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. From: sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), Flows: make([]types.OutFlow, 0), } + gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) + if !found { + return fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) + } price, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ - PrimarySp: bucketInfo.PrimarySpId, + PrimarySp: gvgFamily.PrimarySpId, PriceTime: internalBucketInfo.PriceTime, }) if err != nil { return fmt.Errorf("get storage price failed: %w", err) } - gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) - if !found { - return fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) - } - - // primary sp total rate - primaryTotalFlowRate := sdk.ZeroInt() - - // secondary sp total rate - secondaryTotalFlowRate := sdk.ZeroInt() - var lvg *storagetypes.LocalVirtualGroup for _, l := range internalBucketInfo.LocalVirtualGroups { if l.Id == objectInfo.LocalVirtualGroupId { @@ -408,7 +393,10 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. // primary sp primaryRate := price.PrimaryStorePrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() if primaryRate.IsPositive() { - primaryTotalFlowRate = primaryTotalFlowRate.Add(primaryRate) + userFlows.Flows = append(userFlows.Flows, types.OutFlow{ + ToAddress: gvgFamily.VirtualPaymentAddress, + Rate: primaryRate, + }) } //secondary sp @@ -424,21 +412,13 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. ToAddress: gvg.VirtualPaymentAddress, Rate: secondaryRate, }) - secondaryTotalFlowRate = secondaryTotalFlowRate.Add(secondaryRate) - } - - if primaryTotalFlowRate.IsPositive() { - userFlows.Flows = append(userFlows.Flows, types.OutFlow{ - ToAddress: gvgFamily.VirtualPaymentAddress, - Rate: primaryTotalFlowRate, - }) } versionedParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, internalBucketInfo.PriceTime) if err != nil { return fmt.Errorf("failed to get validator tax rate: %w, time: %d", err, internalBucketInfo.PriceTime) } - validatorTaxRate := versionedParams.ValidatorTaxRate.MulInt(primaryTotalFlowRate.Add(secondaryTotalFlowRate)).TruncateInt() + validatorTaxRate := versionedParams.ValidatorTaxRate.MulInt(primaryRate.Add(secondaryRate)).TruncateInt() if validatorTaxRate.IsPositive() { userFlows.Flows = append(userFlows.Flows, types.OutFlow{ ToAddress: types.ValidatorTaxPoolAddress.String(), @@ -467,22 +447,23 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. func (k Keeper) GetBucketReadStoreBill(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo) (userFlows types.UserFlows, err error) { userFlows.From = sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress) + + gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) + if !found { + return userFlows, fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) + } + if internalBucketInfo.TotalChargeSize == 0 && bucketInfo.ChargedReadQuota == 0 { return userFlows, nil } price, err := k.paymentKeeper.GetStoragePrice(ctx, types.StoragePriceParams{ - PrimarySp: bucketInfo.PrimarySpId, + PrimarySp: gvgFamily.PrimarySpId, PriceTime: internalBucketInfo.PriceTime, }) if err != nil { return userFlows, fmt.Errorf("get storage price failed: %w", err) } - gvgFamily, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) - if !found { - return userFlows, fmt.Errorf("get GVG family failed: %d", bucketInfo.GlobalVirtualGroupFamilyId) - } - // primary sp total rate primaryTotalFlowRate := price.ReadPrice.MulInt(sdkmath.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() @@ -592,12 +573,20 @@ func (k Keeper) GetObjectLockFee(ctx sdk.Context, primarySpId uint32, priceTime if err != nil { return amount, fmt.Errorf("get charge size error: %w", err) } + + primaryRate := price.PrimaryStorePrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + secondarySPNum := int64(k.GetExpectSecondarySPNumForECObject(ctx, priceTime)) - rate := price.PrimaryStorePrice.Add(price.SecondaryStorePrice.MulInt64(secondarySPNum)).MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + secondaryRate := price.SecondaryStorePrice.MulInt(sdkmath.NewIntFromUint64(chargeSize)).TruncateInt() + secondaryRate = secondaryRate.MulRaw(int64(secondarySPNum)) + versionedParams, err := k.paymentKeeper.GetVersionedParamsWithTs(ctx, priceTime) if err != nil { return amount, fmt.Errorf("get versioned reserve time error: %w", err) } + validatorTaxRate := versionedParams.ValidatorTaxRate.MulInt(primaryRate.Add(secondaryRate)).TruncateInt() + + rate := primaryRate.Add(secondaryRate).Add(validatorTaxRate) // should also lock for validator tax pool amount = rate.Mul(sdkmath.NewIntFromUint64(versionedParams.ReserveTime)) return amount, nil } diff --git a/x/storage/keeper/payment_test.go b/x/storage/keeper/payment_test.go index 477aac26c..1d3d087e1 100644 --- a/x/storage/keeper/payment_test.go +++ b/x/storage/keeper/payment_test.go @@ -122,17 +122,18 @@ func (s *TestSuite) TestGetObjectLockFee() { amount, err := s.storageKeeper.GetObjectLockFee(s.ctx, 100, time.Now().Unix(), uint64(payloadSize)) s.Require().NoError(err) secondarySPNum := int64(s.storageKeeper.GetExpectSecondarySPNumForECObject(s.ctx, time.Now().Unix())) - expectedAmount := price.PrimaryStorePrice.Add(price.SecondaryStorePrice.MulInt64(secondarySPNum)). - MulInt64(payloadSize).MulInt64(int64(params.VersionedParams.ReserveTime)).TruncateInt() + spRate := price.PrimaryStorePrice.Add(price.SecondaryStorePrice.MulInt64(secondarySPNum)).MulInt64(payloadSize) + validatorTaxRate := params.VersionedParams.ValidatorTaxRate.MulInt(spRate.TruncateInt()) + expectedAmount := spRate.Add(validatorTaxRate).MulInt64(int64(params.VersionedParams.ReserveTime)).TruncateInt() s.Require().True(amount.Equal(expectedAmount)) } -func (s *TestSuite) TestGetBucketBill() { +func (s *TestSuite) TestGetBucketReadBill() { gvgFamily := &virtualgroupmoduletypes.GlobalVirtualGroupFamily{ Id: 1, VirtualPaymentAddress: sample.RandAccAddress().String(), } - s.virtualGroupKeeper.EXPECT().GetGVGFamily(gomock.Any(), gomock.Any(), gomock.Any()). + s.virtualGroupKeeper.EXPECT().GetGVGFamily(gomock.Any(), gomock.Any()). Return(gvgFamily, true).AnyTimes() primarySp := &sptypes.StorageProvider{ @@ -160,7 +161,6 @@ func (s *TestSuite) TestGetBucketBill() { BucketName: "bucketname", Id: sdk.NewUint(1), PaymentAddress: sample.RandAccAddress().String(), - PrimarySpId: primarySp.Id, GlobalVirtualGroupFamilyId: gvgFamily.Id, ChargedReadQuota: 0, } @@ -175,7 +175,6 @@ func (s *TestSuite) TestGetBucketBill() { BucketName: "bucketname", Id: sdk.NewUint(1), PaymentAddress: sample.RandAccAddress().String(), - PrimarySpId: primarySp.Id, GlobalVirtualGroupFamilyId: gvgFamily.Id, ChargedReadQuota: 100, } @@ -188,19 +187,46 @@ func (s *TestSuite) TestGetBucketBill() { taxPoolRate := params.VersionedParams.ValidatorTaxRate.MulInt(readRate).TruncateInt() s.Require().Equal(flows.Flows[1].ToAddress, paymenttypes.ValidatorTaxPoolAddress.String()) s.Require().Equal(flows.Flows[1].Rate, taxPoolRate) +} + +func (s *TestSuite) TestGetBucketReadStoreBill() { + gvgFamily := &virtualgroupmoduletypes.GlobalVirtualGroupFamily{ + Id: 1, + VirtualPaymentAddress: sample.RandAccAddress().String(), + } + s.virtualGroupKeeper.EXPECT().GetGVGFamily(gomock.Any(), gomock.Any()). + Return(gvgFamily, true).AnyTimes() + + primarySp := &sptypes.StorageProvider{ + Status: sptypes.STATUS_IN_SERVICE, + Id: 100, + OperatorAddress: sample.RandAccAddress().String(), + FundingAddress: sample.RandAccAddress().String()} + s.spKeeper.EXPECT().GetStorageProvider(gomock.Any(), gomock.Eq(primarySp.Id)). + Return(primarySp, true).AnyTimes() + + price := paymenttypes.StoragePrice{ + ReadPrice: sdk.NewDec(100), + PrimaryStorePrice: sdk.NewDec(1000), + SecondaryStorePrice: sdk.NewDec(500), + } + s.paymentKeeper.EXPECT().GetStoragePrice(gomock.Any(), gomock.Any()). + Return(price, nil).AnyTimes() + params := paymenttypes.DefaultParams() + s.paymentKeeper.EXPECT().GetVersionedParamsWithTs(gomock.Any(), gomock.Any()). + Return(params.VersionedParams, nil).AnyTimes() // none empty bucket - bucketInfo = &types.BucketInfo{ + bucketInfo := &types.BucketInfo{ Owner: "", BucketName: "bucketname", Id: sdk.NewUint(1), PaymentAddress: sample.RandAccAddress().String(), - PrimarySpId: primarySp.Id, GlobalVirtualGroupFamilyId: gvgFamily.Id, ChargedReadQuota: 100, } - internalBucketInfo = &types.InternalBucketInfo{ + internalBucketInfo := &types.InternalBucketInfo{ TotalChargeSize: 300, LocalVirtualGroups: []*types.LocalVirtualGroup{ { @@ -232,7 +258,7 @@ func (s *TestSuite) TestGetBucketBill() { s.virtualGroupKeeper.EXPECT().GetGVG(gomock.Any(), gvg2.Id). Return(gvg2, true).AnyTimes() - flows, err = s.storageKeeper.GetBucketReadStoreBill(s.ctx, bucketInfo, internalBucketInfo) + flows, err := s.storageKeeper.GetBucketReadStoreBill(s.ctx, bucketInfo, internalBucketInfo) s.Require().NoError(err) gvg1StoreSize := internalBucketInfo.LocalVirtualGroups[0].TotalChargeSize * uint64(len(gvg1.SecondarySpIds)) @@ -245,13 +271,13 @@ func (s *TestSuite) TestGetBucketBill() { s.Require().Equal(flows.Flows[1].ToAddress, gvg2.VirtualPaymentAddress) s.Require().Equal(flows.Flows[1].Rate, gvg2StoreRate) - readRate = price.ReadPrice.MulInt64(int64(bucketInfo.ChargedReadQuota)).TruncateInt() + readRate := price.ReadPrice.MulInt64(int64(bucketInfo.ChargedReadQuota)).TruncateInt() primaryStoreRate := price.PrimaryStorePrice.MulInt64(int64(internalBucketInfo.TotalChargeSize)).TruncateInt() s.Require().Equal(flows.Flows[2].ToAddress, gvgFamily.VirtualPaymentAddress) s.Require().Equal(flows.Flows[2].Rate, readRate.Add(primaryStoreRate)) totalRate := readRate.Add(primaryStoreRate).Add(gvg1StoreRate).Add(gvg2StoreRate) - taxPoolRate = params.VersionedParams.ValidatorTaxRate.MulInt(totalRate).TruncateInt() + taxPoolRate := params.VersionedParams.ValidatorTaxRate.MulInt(totalRate).TruncateInt() s.Require().Equal(flows.Flows[3].ToAddress, paymenttypes.ValidatorTaxPoolAddress.String()) s.Require().Equal(flows.Flows[3].Rate, taxPoolRate) } diff --git a/x/storage/keeper/virtualgroup.go b/x/storage/keeper/virtualgroup.go index 06fc7ff0d..7353322fd 100644 --- a/x/storage/keeper/virtualgroup.go +++ b/x/storage/keeper/virtualgroup.go @@ -22,17 +22,41 @@ func (k Keeper) DeleteObjectFromVirtualGroup(ctx sdk.Context, bucketInfo *types. return vgtypes.ErrGVGNotExist } - // TODO: if the store size is 0, remove it. lvg.StoredSize -= objectInfo.PayloadSize gvg.StoredSize -= objectInfo.PayloadSize - k.virtualGroupKeeper.SetGVG(ctx, gvg) + // delete lvg when total charge size is 0 + if lvg.TotalChargeSize == 0 { + if lvg.StoredSize != 0 { + panic("The store size is non-zero when total charge size is zero.") + } + internalBucketInfo.DeleteLVG(lvg.Id) + if err := ctx.EventManager().EmitTypedEvents(&vgtypes.EventDeleteLocalVirtualGroup{ + Id: lvg.Id, + BucketId: bucketInfo.Id, + }); err != nil { + return err + } + } + + if err := k.virtualGroupKeeper.SetGVGAndEmitUpdateEvent(ctx, gvg); err != nil { + return err + } + + if err := ctx.EventManager().EmitTypedEvents(&vgtypes.EventUpdateLocalVirtualGroup{ + Id: lvg.Id, + BucketId: bucketInfo.Id, + GlobalVirtualGroupId: lvg.GlobalVirtualGroupId, + StoredSize: lvg.StoredSize, + }); err != nil { + return err + } + k.SetInternalBucketInfo(ctx, bucketInfo.Id, internalBucketInfo) return nil } func (k Keeper) RebindingVirtualGroup(ctx sdk.Context, bucketInfo *types.BucketInfo, internalBucketInfo *types.InternalBucketInfo, gvgMappings []*types.GVGMapping) error { - gvgsMap := make(map[uint32]uint32) for _, mapping := range gvgMappings { gvgsMap[mapping.SrcGlobalVirtualGroupId] = mapping.DstGlobalVirtualGroupId @@ -64,8 +88,21 @@ func (k Keeper) RebindingVirtualGroup(ctx sdk.Context, bucketInfo *types.BucketI lvg.GlobalVirtualGroupId = dstGVGID - k.virtualGroupKeeper.SetGVG(ctx, srcGVG) - k.virtualGroupKeeper.SetGVG(ctx, dstGVG) + if err := k.virtualGroupKeeper.SetGVGAndEmitUpdateEvent(ctx, srcGVG); err != nil { + return types.ErrVirtualGroupOperateFailed.Wrapf("fail to set src gvg. ID: %d, err: %s", srcGVG.Id, err) + } + if err := k.virtualGroupKeeper.SetGVGAndEmitUpdateEvent(ctx, dstGVG); err != nil { + return types.ErrVirtualGroupOperateFailed.Wrapf("fail to set dst gvg. ID: %d, err: %s", dstGVG.Id, err) + } + + if err := ctx.EventManager().EmitTypedEvents(&vgtypes.EventUpdateLocalVirtualGroup{ + Id: lvg.Id, + BucketId: bucketInfo.Id, + GlobalVirtualGroupId: lvg.GlobalVirtualGroupId, + StoredSize: lvg.StoredSize, + }); err != nil { + return err + } } err := k.ChargeBucketReadStoreFee(ctx, bucketInfo, internalBucketInfo) @@ -111,31 +148,32 @@ func (k Keeper) SealObjectOnVirtualGroup(ctx sdk.Context, bucketInfo *types.Buck lvg = &types.LocalVirtualGroup{ Id: internalBucketInfo.GetMaxLVGID() + 1, GlobalVirtualGroupId: gvg.Id, - StoredSize: objectInfo.PayloadSize, + StoredSize: 0, } internalBucketInfo.AppendLVG(lvg) - } else { - lvg.StoredSize += objectInfo.PayloadSize } - gvg.StoredSize += objectInfo.PayloadSize + lvg.StoredSize += objectInfo.PayloadSize + gvg.StoredSize += objectInfo.PayloadSize objectInfo.LocalVirtualGroupId = lvg.Id if objectInfo.PayloadSize == 0 { // unlock and charge store fee - err = k.ChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, objectInfo) + err = k.ChargeObjectStoreFee(ctx, gvg.PrimarySpId, bucketInfo, internalBucketInfo, objectInfo) if err != nil { return nil, err } } else { // unlock and charge store fee - err = k.UnlockAndChargeObjectStoreFee(ctx, bucketInfo, internalBucketInfo, objectInfo) + err = k.UnlockAndChargeObjectStoreFee(ctx, gvg.PrimarySpId, bucketInfo, internalBucketInfo, objectInfo) if err != nil { return nil, err } } - k.virtualGroupKeeper.SetGVG(ctx, gvg) + if err := k.virtualGroupKeeper.SetGVGAndEmitUpdateEvent(ctx, gvg); err != nil { + return nil, err + } k.SetInternalBucketInfo(ctx, bucketInfo.Id, internalBucketInfo) if !found { @@ -150,6 +188,7 @@ func (k Keeper) SealObjectOnVirtualGroup(ctx sdk.Context, bucketInfo *types.Buck } else { if err := ctx.EventManager().EmitTypedEvents(&vgtypes.EventUpdateLocalVirtualGroup{ Id: lvg.Id, + BucketId: bucketInfo.Id, GlobalVirtualGroupId: lvg.GlobalVirtualGroupId, StoredSize: lvg.StoredSize, }); err != nil { @@ -161,7 +200,7 @@ func (k Keeper) SealObjectOnVirtualGroup(ctx sdk.Context, bucketInfo *types.Buck } func (k Keeper) SealEmptyObjectOnVirtualGroup(ctx sdk.Context, bucketInfo *types.BucketInfo, objectInfo *types.ObjectInfo) (*types.LocalVirtualGroup, error) { - family, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.PrimarySpId, bucketInfo.GlobalVirtualGroupFamilyId) + family, found := k.virtualGroupKeeper.GetGVGFamily(ctx, bucketInfo.GlobalVirtualGroupFamilyId) if !found { return nil, vgtypes.ErrGVGFamilyNotExist } diff --git a/x/storage/types/common.pb.go b/x/storage/types/common.pb.go index bb90a208a..c499a8049 100644 --- a/x/storage/types/common.pb.go +++ b/x/storage/types/common.pb.go @@ -382,12 +382,12 @@ type LocalVirtualGroup struct { // id is the identifier of the local virtual group. Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // global_virtual_group_id is the identifier of the global virtual group. - GlobalVirtualGroupId uint32 `protobuf:"varint,3,opt,name=global_virtual_group_id,json=globalVirtualGroupId,proto3" json:"global_virtual_group_id,omitempty"` + GlobalVirtualGroupId uint32 `protobuf:"varint,2,opt,name=global_virtual_group_id,json=globalVirtualGroupId,proto3" json:"global_virtual_group_id,omitempty"` // stored_size is the size of the stored data in the local virtual group. - StoredSize uint64 `protobuf:"varint,4,opt,name=stored_size,json=storedSize,proto3" json:"stored_size,omitempty"` + StoredSize uint64 `protobuf:"varint,3,opt,name=stored_size,json=storedSize,proto3" json:"stored_size,omitempty"` // total_charge_size is the total charged size of the objects in the LVG. // Notice that the minimum unit of charge is 128K - TotalChargeSize uint64 `protobuf:"varint,5,opt,name=total_charge_size,json=totalChargeSize,proto3" json:"total_charge_size,omitempty"` + TotalChargeSize uint64 `protobuf:"varint,4,opt,name=total_charge_size,json=totalChargeSize,proto3" json:"total_charge_size,omitempty"` } func (m *LocalVirtualGroup) Reset() { *m = LocalVirtualGroup{} } @@ -466,58 +466,58 @@ func init() { func init() { proto.RegisterFile("greenfield/storage/common.proto", fileDescriptor_4eff6c0fa4aaf4c9) } var fileDescriptor_4eff6c0fa4aaf4c9 = []byte{ - // 815 bytes of a gzipped FileDescriptorProto + // 811 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0x4f, 0x6f, 0xe3, 0x44, - 0x18, 0xc6, 0xe3, 0x34, 0x0b, 0xdb, 0xd9, 0x52, 0x52, 0xab, 0x90, 0x36, 0x41, 0x4e, 0xe9, 0xa9, - 0x54, 0xda, 0xe6, 0x80, 0x90, 0x56, 0x62, 0x2f, 0xb6, 0x33, 0x64, 0x87, 0x4d, 0x9d, 0x68, 0xc6, - 0x89, 0x54, 0x2e, 0x23, 0xff, 0x19, 0xdc, 0xa1, 0x8e, 0xc7, 0xf2, 0x8c, 0x11, 0xdd, 0x4f, 0xc0, - 0x11, 0xf1, 0x05, 0x38, 0x70, 0xe0, 0x0b, 0xf0, 0x15, 0x40, 0x7b, 0x5c, 0x71, 0x42, 0x1c, 0x56, - 0xa8, 0xfd, 0x22, 0xc8, 0x76, 0x92, 0x4d, 0x44, 0x88, 0x56, 0xe2, 0x96, 0x79, 0x9f, 0x5f, 0xde, - 0xf7, 0x79, 0xdf, 0x79, 0x6d, 0x83, 0x6e, 0x94, 0x31, 0x96, 0x7c, 0xcd, 0x59, 0x1c, 0xf6, 0xa4, - 0x12, 0x99, 0x17, 0xb1, 0x5e, 0x20, 0x66, 0x33, 0x91, 0x5c, 0xa4, 0x99, 0x50, 0x42, 0xd7, 0xdf, - 0x00, 0x17, 0x73, 0xa0, 0x7d, 0x1c, 0x08, 0x39, 0x13, 0x92, 0x96, 0x44, 0xaf, 0x3a, 0x54, 0x78, - 0xfb, 0x30, 0x12, 0x91, 0xa8, 0xe2, 0xc5, 0xaf, 0x2a, 0x7a, 0xfa, 0xbb, 0x06, 0x3e, 0x22, 0x2c, - 0x10, 0x49, 0xe8, 0x65, 0xb7, 0x24, 0x25, 0xcc, 0x8b, 0x47, 0xfe, 0x37, 0x2c, 0x50, 0x84, 0x47, - 0x49, 0x5f, 0x04, 0xfa, 0x31, 0x78, 0x18, 0x5c, 0x7b, 0x3c, 0xa1, 0x3c, 0x3c, 0xd2, 0x4e, 0xb4, - 0xb3, 0x5d, 0xfc, 0x6e, 0x79, 0x46, 0xa1, 0xfe, 0x19, 0x68, 0x45, 0xb1, 0xf0, 0xbd, 0x98, 0x7e, - 0xcb, 0x33, 0x95, 0x7b, 0x31, 0x8d, 0x32, 0x91, 0xa7, 0x05, 0x59, 0x3f, 0xd1, 0xce, 0xde, 0xc3, - 0x87, 0x95, 0x3c, 0xad, 0xd4, 0x41, 0x21, 0xa2, 0x50, 0x7f, 0x02, 0x76, 0x45, 0x59, 0xa2, 0x00, - 0x77, 0x8a, 0x94, 0x56, 0xe7, 0xe5, 0xeb, 0x6e, 0xed, 0xaf, 0xd7, 0xdd, 0xc6, 0x84, 0x27, 0xea, - 0x8f, 0x5f, 0x1f, 0x3f, 0x9a, 0x3b, 0x2f, 0x8e, 0xf8, 0x61, 0x45, 0xa3, 0x50, 0x6f, 0x17, 0x5e, - 0x58, 0x70, 0x23, 0xf3, 0xd9, 0x51, 0xe3, 0x44, 0x3b, 0xdb, 0xc3, 0xcb, 0xf3, 0xe9, 0x6f, 0x1a, - 0x00, 0x83, 0xe9, 0xe0, 0xd2, 0x4b, 0x53, 0x9e, 0x44, 0xfa, 0x53, 0xd0, 0x91, 0x59, 0x40, 0xff, - 0xcb, 0x9f, 0x56, 0xfa, 0x6b, 0xc9, 0x2c, 0x18, 0x6c, 0xb2, 0xf8, 0x14, 0x74, 0x42, 0xa9, 0xe8, - 0xf6, 0xee, 0x5a, 0xa1, 0x54, 0x1b, 0xff, 0xfd, 0x39, 0x68, 0xcb, 0xc5, 0x48, 0xa9, 0x4c, 0xa9, - 0x1f, 0x4b, 0x2a, 0x79, 0x94, 0x78, 0x2a, 0xcf, 0x58, 0xd9, 0xf1, 0x1e, 0x6e, 0xc9, 0x37, 0x43, - 0xb7, 0x62, 0x49, 0x16, 0xf2, 0xe9, 0x4f, 0x75, 0xf0, 0xf1, 0xca, 0x85, 0x5c, 0xf2, 0x28, 0xf3, - 0x14, 0x17, 0x89, 0x95, 0x07, 0x37, 0xec, 0x6d, 0x6e, 0xe5, 0x13, 0x70, 0x50, 0x78, 0x4f, 0x33, - 0x3e, 0x9b, 0xd7, 0x5f, 0x3a, 0xde, 0x0f, 0xa5, 0x1a, 0x57, 0x71, 0x32, 0x6f, 0x73, 0xdb, 0x90, - 0x76, 0xfe, 0xd7, 0x90, 0x1a, 0xdb, 0x87, 0xf4, 0x04, 0xec, 0xfa, 0x65, 0x4b, 0x05, 0xfb, 0xe0, - 0x2d, 0xb6, 0xa0, 0xa2, 0x51, 0x78, 0xfa, 0x8b, 0x06, 0x0e, 0x86, 0x22, 0x58, 0xcf, 0xa8, 0xef, - 0x83, 0xfa, 0xf2, 0x5e, 0xeb, 0x7c, 0xeb, 0x72, 0xee, 0x6c, 0x59, 0xce, 0x2e, 0x78, 0x54, 0x3c, - 0x4b, 0x2c, 0xa4, 0x92, 0xbf, 0x60, 0x65, 0x13, 0x0d, 0x0c, 0xaa, 0x10, 0xe1, 0x2f, 0x98, 0x7e, - 0x0e, 0x0e, 0x94, 0x50, 0x5e, 0x4c, 0x83, 0x6b, 0x2f, 0x8b, 0x58, 0x85, 0x3d, 0x28, 0xb1, 0xf7, - 0x4b, 0xc1, 0x2e, 0xe3, 0x05, 0x7b, 0x7e, 0x03, 0x00, 0x11, 0x79, 0x16, 0x30, 0xf7, 0x36, 0x65, - 0xfa, 0x87, 0x40, 0x27, 0xa3, 0x09, 0xb6, 0x21, 0x75, 0xaf, 0xc6, 0x90, 0x8e, 0x30, 0x1a, 0x20, - 0xa7, 0x59, 0xd3, 0xbb, 0xa0, 0xb3, 0x1a, 0xb7, 0x88, 0x4d, 0x6d, 0x3c, 0x22, 0x84, 0xda, 0xcf, - 0x4c, 0xe4, 0x34, 0x35, 0xdd, 0x00, 0xed, 0x55, 0xe0, 0x12, 0x61, 0x3c, 0xc2, 0x74, 0x0c, 0x9d, - 0x3e, 0x72, 0x06, 0xcd, 0x7a, 0xbb, 0xf1, 0xfd, 0xcf, 0x46, 0xed, 0x3c, 0x06, 0x7b, 0xf3, 0x1d, - 0x51, 0x9e, 0xca, 0xa5, 0x7e, 0x0c, 0x3e, 0xb0, 0x26, 0xf6, 0x73, 0xe8, 0x52, 0xe2, 0x9a, 0xee, - 0x84, 0x50, 0x1b, 0x43, 0xd3, 0x85, 0xfd, 0x66, 0xad, 0x48, 0xb8, 0x2e, 0xf5, 0x11, 0xb1, 0x47, - 0x8e, 0x8b, 0x9c, 0x09, 0xec, 0x37, 0x35, 0xbd, 0x03, 0x5a, 0xeb, 0xfa, 0x25, 0x1a, 0x60, 0xd3, - 0x5d, 0xad, 0xf6, 0x1c, 0xec, 0x63, 0x16, 0xe6, 0x49, 0xe8, 0x25, 0xc1, 0xed, 0xa2, 0x3d, 0x0c, - 0xfb, 0x13, 0xa7, 0x6f, 0x3a, 0xf6, 0x15, 0x85, 0x76, 0x69, 0xb6, 0x59, 0x2b, 0x92, 0xad, 0xc4, - 0x31, 0x1c, 0x0f, 0x91, 0x6d, 0x56, 0xa2, 0x36, 0x4f, 0xc6, 0xc1, 0xde, 0xfc, 0xa5, 0xb3, 0xb4, - 0x3e, 0xb2, 0xbe, 0x84, 0xf6, 0x06, 0xeb, 0x47, 0xe0, 0x70, 0x5d, 0x22, 0xd0, 0x1c, 0x96, 0xa6, - 0x0d, 0xd0, 0x5e, 0x57, 0xd6, 0x9a, 0x5a, 0xf8, 0xfe, 0x51, 0x03, 0xfb, 0x53, 0x2e, 0xb9, 0xcf, - 0x63, 0xae, 0x2a, 0xe3, 0x5d, 0xd0, 0x99, 0x22, 0x82, 0x2c, 0x34, 0x44, 0xee, 0x55, 0x35, 0xe2, - 0x89, 0x43, 0xc6, 0xd0, 0x46, 0x5f, 0xa0, 0xb2, 0xe6, 0x06, 0x60, 0x3c, 0xb1, 0x86, 0xc8, 0xa6, - 0x18, 0x9a, 0xf3, 0x79, 0xfd, 0x0b, 0xc0, 0x68, 0x6a, 0xba, 0xb0, 0x59, 0xdf, 0x24, 0x22, 0xe7, - 0x19, 0xc4, 0xc8, 0x6d, 0xee, 0x54, 0xa6, 0x2c, 0xf4, 0xf2, 0xce, 0xd0, 0x5e, 0xdd, 0x19, 0xda, - 0xdf, 0x77, 0x86, 0xf6, 0xc3, 0xbd, 0x51, 0x7b, 0x75, 0x6f, 0xd4, 0xfe, 0xbc, 0x37, 0x6a, 0x5f, - 0xf5, 0x22, 0xae, 0xae, 0x73, 0xff, 0x22, 0x10, 0xb3, 0x9e, 0x9f, 0xf8, 0x8f, 0xcb, 0x87, 0xbc, - 0xb7, 0xf2, 0x65, 0xf8, 0x6e, 0xf9, 0x6d, 0x50, 0xb7, 0x29, 0x93, 0xfe, 0x3b, 0xe5, 0x6b, 0xfd, - 0xd3, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x82, 0x66, 0xda, 0x32, 0x3e, 0x06, 0x00, 0x00, + 0x18, 0xc6, 0xe3, 0x34, 0xc0, 0x76, 0xb6, 0x94, 0xd4, 0x2a, 0xa4, 0x4d, 0x90, 0x53, 0x7a, 0x2a, + 0x95, 0xb6, 0x39, 0x20, 0xa4, 0x95, 0xd8, 0x8b, 0xed, 0x98, 0xec, 0xb0, 0xa9, 0x13, 0xcd, 0x38, + 0x91, 0xca, 0x65, 0xe4, 0x3f, 0x83, 0x3b, 0xd4, 0xf1, 0x58, 0x9e, 0x31, 0xa2, 0xfb, 0x09, 0x38, + 0x22, 0xbe, 0x00, 0x07, 0x0e, 0x7c, 0x01, 0xbe, 0x02, 0x68, 0x8f, 0x2b, 0x4e, 0x88, 0xc3, 0x0a, + 0xb5, 0x5f, 0x04, 0xd9, 0xe3, 0x66, 0x13, 0x11, 0xaa, 0x15, 0xdc, 0x32, 0xef, 0xf3, 0xcb, 0xfb, + 0x3e, 0xef, 0xfb, 0x8e, 0x6d, 0xd0, 0x8f, 0x73, 0x4a, 0xd3, 0xaf, 0x18, 0x4d, 0xa2, 0x81, 0x90, + 0x3c, 0xf7, 0x63, 0x3a, 0x08, 0xf9, 0x62, 0xc1, 0xd3, 0xb3, 0x2c, 0xe7, 0x92, 0xeb, 0xfa, 0x6b, + 0xe0, 0xac, 0x06, 0xba, 0x87, 0x21, 0x17, 0x0b, 0x2e, 0x48, 0x45, 0x0c, 0xd4, 0x41, 0xe1, 0xdd, + 0xfd, 0x98, 0xc7, 0x5c, 0xc5, 0xcb, 0x5f, 0x2a, 0x7a, 0xfc, 0x9b, 0x06, 0x3e, 0xc4, 0x34, 0xe4, + 0x69, 0xe4, 0xe7, 0xd7, 0x38, 0xc3, 0xd4, 0x4f, 0x26, 0xc1, 0xd7, 0x34, 0x94, 0x98, 0xc5, 0xe9, + 0x90, 0x87, 0xfa, 0x21, 0x78, 0x10, 0x5e, 0xfa, 0x2c, 0x25, 0x2c, 0x3a, 0xd0, 0x8e, 0xb4, 0x93, + 0x6d, 0xf4, 0x4e, 0x75, 0x86, 0x91, 0xfe, 0x29, 0xe8, 0xc4, 0x09, 0x0f, 0xfc, 0x84, 0x7c, 0xc3, + 0x72, 0x59, 0xf8, 0x09, 0x89, 0x73, 0x5e, 0x64, 0x25, 0xd9, 0x3c, 0xd2, 0x4e, 0xde, 0x45, 0xfb, + 0x4a, 0x9e, 0x2b, 0x75, 0x54, 0x8a, 0x30, 0xd2, 0x1f, 0x83, 0x6d, 0x5e, 0x95, 0x28, 0xc1, 0xad, + 0x32, 0xa5, 0xd5, 0x7b, 0xf1, 0xaa, 0xdf, 0xf8, 0xf3, 0x55, 0xbf, 0x35, 0x63, 0xa9, 0xfc, 0xfd, + 0x97, 0x47, 0x0f, 0x6b, 0xe7, 0xe5, 0x11, 0x3d, 0x50, 0x34, 0x8c, 0xf4, 0x6e, 0xe9, 0x85, 0x86, + 0x57, 0xa2, 0x58, 0x1c, 0xb4, 0x8e, 0xb4, 0x93, 0x1d, 0xb4, 0x3c, 0x1f, 0xff, 0xaa, 0x01, 0x30, + 0x9a, 0x8f, 0xce, 0xfd, 0x2c, 0x63, 0x69, 0xac, 0x3f, 0x01, 0x3d, 0x91, 0x87, 0xe4, 0xdf, 0xfc, + 0x69, 0x95, 0xbf, 0x8e, 0xc8, 0xc3, 0xd1, 0x26, 0x8b, 0x4f, 0x40, 0x2f, 0x12, 0x92, 0xdc, 0xdf, + 0x5d, 0x27, 0x12, 0x72, 0xe3, 0xbf, 0x3f, 0x03, 0x5d, 0x71, 0x37, 0x52, 0x22, 0x32, 0x12, 0x24, + 0x82, 0x08, 0x16, 0xa7, 0xbe, 0x2c, 0x72, 0x5a, 0x75, 0xbc, 0x83, 0x3a, 0xe2, 0xf5, 0xd0, 0xad, + 0x44, 0xe0, 0x3b, 0xf9, 0xf8, 0xc7, 0x26, 0xf8, 0x68, 0x65, 0x21, 0xe7, 0x2c, 0xce, 0x7d, 0xc9, + 0x78, 0x6a, 0x15, 0xe1, 0x15, 0x7d, 0x93, 0xad, 0x7c, 0x0c, 0xf6, 0x4a, 0xef, 0x59, 0xce, 0x16, + 0x75, 0xfd, 0xa5, 0xe3, 0xdd, 0x48, 0xc8, 0xa9, 0x8a, 0xe3, 0xba, 0xcd, 0xfb, 0x86, 0xb4, 0xf5, + 0xbf, 0x86, 0xd4, 0xba, 0x7f, 0x48, 0x8f, 0xc1, 0x76, 0x50, 0xb5, 0x54, 0xb2, 0x6f, 0xbd, 0xc1, + 0x2d, 0x50, 0x34, 0x8c, 0x8e, 0x7f, 0xd6, 0xc0, 0xde, 0x98, 0x87, 0xeb, 0x19, 0xf5, 0x5d, 0xd0, + 0x5c, 0xee, 0xb5, 0xc9, 0xfe, 0xf3, 0xe5, 0xec, 0x83, 0x87, 0xe5, 0xb3, 0x44, 0x23, 0x22, 0xd8, + 0x73, 0xb5, 0xac, 0x16, 0x02, 0x2a, 0x84, 0xd9, 0x73, 0xaa, 0x9f, 0x82, 0x3d, 0xc9, 0xa5, 0x9f, + 0x90, 0xf0, 0xd2, 0xcf, 0x63, 0xaa, 0xb0, 0x56, 0x85, 0xbd, 0x57, 0x09, 0x76, 0x15, 0x2f, 0xd9, + 0xd3, 0x2b, 0x00, 0x30, 0x2f, 0xf2, 0x90, 0x7a, 0xd7, 0x19, 0xd5, 0x3f, 0x00, 0x3a, 0x9e, 0xcc, + 0x90, 0xed, 0x10, 0xef, 0x62, 0xea, 0x90, 0x09, 0x82, 0x23, 0xe8, 0xb6, 0x1b, 0x7a, 0x1f, 0xf4, + 0x56, 0xe3, 0x16, 0xb6, 0x89, 0x8d, 0x26, 0x18, 0x13, 0xfb, 0xa9, 0x09, 0xdd, 0xb6, 0xa6, 0x1b, + 0xa0, 0xbb, 0x0a, 0x9c, 0x43, 0x84, 0x26, 0x88, 0x4c, 0x1d, 0x77, 0x08, 0xdd, 0x51, 0xbb, 0xd9, + 0x6d, 0x7d, 0xf7, 0x93, 0xd1, 0x38, 0x4d, 0xc0, 0x4e, 0x7d, 0x47, 0xa4, 0x2f, 0x0b, 0xa1, 0x1f, + 0x82, 0xf7, 0xad, 0x99, 0xfd, 0xcc, 0xf1, 0x08, 0xf6, 0x4c, 0x6f, 0x86, 0x89, 0x8d, 0x1c, 0xd3, + 0x73, 0x86, 0xed, 0x46, 0x99, 0x70, 0x5d, 0x1a, 0x42, 0x6c, 0x4f, 0x5c, 0x0f, 0xba, 0x33, 0x67, + 0xd8, 0xd6, 0xf4, 0x1e, 0xe8, 0xac, 0xeb, 0xe7, 0x70, 0x84, 0x4c, 0x6f, 0xb5, 0xda, 0x33, 0xb0, + 0x8b, 0x68, 0x54, 0xa4, 0x91, 0x9f, 0x86, 0xd7, 0x77, 0xed, 0x21, 0x67, 0x38, 0x73, 0x87, 0xa6, + 0x6b, 0x5f, 0x10, 0xc7, 0xae, 0xcc, 0xb6, 0x1b, 0x65, 0xb2, 0x95, 0x38, 0x72, 0xa6, 0x63, 0x68, + 0x9b, 0x4a, 0xd4, 0xea, 0x64, 0x0c, 0xec, 0xd4, 0x2f, 0x9d, 0xa5, 0xf5, 0x89, 0xf5, 0x85, 0x63, + 0x6f, 0xb0, 0x7e, 0x00, 0xf6, 0xd7, 0x25, 0xec, 0x98, 0xe3, 0xca, 0xb4, 0x01, 0xba, 0xeb, 0xca, + 0x5a, 0x53, 0x77, 0xbe, 0x7f, 0xd0, 0xc0, 0xee, 0x9c, 0x09, 0x16, 0xb0, 0x84, 0x49, 0x65, 0xbc, + 0x0f, 0x7a, 0x73, 0x88, 0xa1, 0x05, 0xc7, 0xd0, 0xbb, 0x50, 0x23, 0x9e, 0xb9, 0x78, 0xea, 0xd8, + 0xf0, 0x73, 0x58, 0xd5, 0xdc, 0x00, 0x4c, 0x67, 0xd6, 0x18, 0xda, 0x04, 0x39, 0x66, 0x3d, 0xaf, + 0x7f, 0x00, 0x08, 0xce, 0x4d, 0xcf, 0x69, 0x37, 0x37, 0x89, 0xd0, 0x7d, 0xea, 0x20, 0xe8, 0xb5, + 0xb7, 0x94, 0x29, 0x0b, 0xbe, 0xb8, 0x31, 0xb4, 0x97, 0x37, 0x86, 0xf6, 0xd7, 0x8d, 0xa1, 0x7d, + 0x7f, 0x6b, 0x34, 0x5e, 0xde, 0x1a, 0x8d, 0x3f, 0x6e, 0x8d, 0xc6, 0x97, 0x83, 0x98, 0xc9, 0xcb, + 0x22, 0x38, 0x0b, 0xf9, 0x62, 0x10, 0xa4, 0xc1, 0xa3, 0xea, 0x21, 0x1f, 0xac, 0x7c, 0x19, 0xbe, + 0x5d, 0x7e, 0x1b, 0xe4, 0x75, 0x46, 0x45, 0xf0, 0x76, 0xf5, 0x5a, 0xff, 0xe4, 0xef, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x41, 0x5f, 0x07, 0x5d, 0x3e, 0x06, 0x00, 0x00, } func (m *SecondarySpSealObjectSignDoc) Marshal() (dAtA []byte, err error) { @@ -690,17 +690,17 @@ func (m *LocalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.TotalChargeSize != 0 { i = encodeVarintCommon(dAtA, i, uint64(m.TotalChargeSize)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x20 } if m.StoredSize != 0 { i = encodeVarintCommon(dAtA, i, uint64(m.StoredSize)) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x18 } if m.GlobalVirtualGroupId != 0 { i = encodeVarintCommon(dAtA, i, uint64(m.GlobalVirtualGroupId)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x10 } if m.Id != 0 { i = encodeVarintCommon(dAtA, i, uint64(m.Id)) @@ -1325,7 +1325,7 @@ func (m *LocalVirtualGroup) Unmarshal(dAtA []byte) error { break } } - case 3: + case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupId", wireType) } @@ -1344,7 +1344,7 @@ func (m *LocalVirtualGroup) Unmarshal(dAtA []byte) error { break } } - case 4: + case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StoredSize", wireType) } @@ -1363,7 +1363,7 @@ func (m *LocalVirtualGroup) Unmarshal(dAtA []byte) error { break } } - case 5: + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TotalChargeSize", wireType) } diff --git a/x/storage/types/events.pb.go b/x/storage/types/events.pb.go index aa8189302..9a23d9396 100644 --- a/x/storage/types/events.pb.go +++ b/x/storage/types/events.pb.go @@ -163,8 +163,8 @@ type EventDeleteBucket struct { BucketName string `protobuf:"bytes,3,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` // bucket_id define an u256 id for bucket BucketId Uint `protobuf:"bytes,4,opt,name=bucket_id,json=bucketId,proto3,customtype=Uint" json:"bucket_id"` - // primary_sp_id is the unique id of primary sp. - PrimarySpId uint32 `protobuf:"varint,5,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` + // global_virtual_group_family_id defines the unique id of gvg family + GlobalVirtualGroupFamilyId uint32 `protobuf:"varint,5,opt,name=global_virtual_group_family_id,json=globalVirtualGroupFamilyId,proto3" json:"global_virtual_group_family_id,omitempty"` } func (m *EventDeleteBucket) Reset() { *m = EventDeleteBucket{} } @@ -221,9 +221,9 @@ func (m *EventDeleteBucket) GetBucketName() string { return "" } -func (m *EventDeleteBucket) GetPrimarySpId() uint32 { +func (m *EventDeleteBucket) GetGlobalVirtualGroupFamilyId() uint32 { if m != nil { - return m.PrimarySpId + return m.GlobalVirtualGroupFamilyId } return 0 } @@ -236,16 +236,14 @@ type EventUpdateBucketInfo struct { BucketName string `protobuf:"bytes,2,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` // bucket_id define an u256 id for bucket BucketId Uint `protobuf:"bytes,3,opt,name=bucket_id,json=bucketId,proto3,customtype=Uint" json:"bucket_id"` - // charged_read_quota_before define the read quota before updated - ChargedReadQuotaBefore uint64 `protobuf:"varint,4,opt,name=charged_read_quota_before,json=chargedReadQuotaBefore,proto3" json:"charged_read_quota_before,omitempty"` // charged_read_quota_after define the read quota after updated - ChargedReadQuotaAfter uint64 `protobuf:"varint,5,opt,name=charged_read_quota_after,json=chargedReadQuotaAfter,proto3" json:"charged_read_quota_after,omitempty"` - // payment_address_before define the payment address before updated - PaymentAddressBefore string `protobuf:"bytes,6,opt,name=payment_address_before,json=paymentAddressBefore,proto3" json:"payment_address_before,omitempty"` - // payment_address_after define the payment address after updated - PaymentAddressAfter string `protobuf:"bytes,7,opt,name=payment_address_after,json=paymentAddressAfter,proto3" json:"payment_address_after,omitempty"` + ChargedReadQuota uint64 `protobuf:"varint,4,opt,name=charged_read_quota,json=chargedReadQuota,proto3" json:"charged_read_quota,omitempty"` + // payment_address define the payment address after updated + PaymentAddress string `protobuf:"bytes,5,opt,name=payment_address,json=paymentAddress,proto3" json:"payment_address,omitempty"` // visibility defines the highest permission of object. - Visibility VisibilityType `protobuf:"varint,8,opt,name=visibility,proto3,enum=greenfield.storage.VisibilityType" json:"visibility,omitempty"` + Visibility VisibilityType `protobuf:"varint,6,opt,name=visibility,proto3,enum=greenfield.storage.VisibilityType" json:"visibility,omitempty"` + // global_virtual_group_family_id defines the gvg family id after migrated. + GlobalVirtualGroupFamilyId uint32 `protobuf:"varint,7,opt,name=global_virtual_group_family_id,json=globalVirtualGroupFamilyId,proto3" json:"global_virtual_group_family_id,omitempty"` } func (m *EventUpdateBucketInfo) Reset() { *m = EventUpdateBucketInfo{} } @@ -295,39 +293,32 @@ func (m *EventUpdateBucketInfo) GetBucketName() string { return "" } -func (m *EventUpdateBucketInfo) GetChargedReadQuotaBefore() uint64 { - if m != nil { - return m.ChargedReadQuotaBefore - } - return 0 -} - -func (m *EventUpdateBucketInfo) GetChargedReadQuotaAfter() uint64 { +func (m *EventUpdateBucketInfo) GetChargedReadQuota() uint64 { if m != nil { - return m.ChargedReadQuotaAfter + return m.ChargedReadQuota } return 0 } -func (m *EventUpdateBucketInfo) GetPaymentAddressBefore() string { +func (m *EventUpdateBucketInfo) GetPaymentAddress() string { if m != nil { - return m.PaymentAddressBefore + return m.PaymentAddress } return "" } -func (m *EventUpdateBucketInfo) GetPaymentAddressAfter() string { +func (m *EventUpdateBucketInfo) GetVisibility() VisibilityType { if m != nil { - return m.PaymentAddressAfter + return m.Visibility } - return "" + return VISIBILITY_TYPE_UNSPECIFIED } -func (m *EventUpdateBucketInfo) GetVisibility() VisibilityType { +func (m *EventUpdateBucketInfo) GetGlobalVirtualGroupFamilyId() uint32 { if m != nil { - return m.Visibility + return m.GlobalVirtualGroupFamilyId } - return VISIBILITY_TYPE_UNSPECIFIED + return 0 } // EventDiscontinueBucket is emitted on MsgDiscontinueBucket @@ -2056,8 +2047,8 @@ type EventCompleteMigrationBucket struct { BucketId Uint `protobuf:"bytes,3,opt,name=bucket_id,json=bucketId,proto3,customtype=Uint" json:"bucket_id"` // The family id that the bucket to be migrated to GlobalVirtualGroupFamilyId uint32 `protobuf:"varint,4,opt,name=global_virtual_group_family_id,json=globalVirtualGroupFamilyId,proto3" json:"global_virtual_group_family_id,omitempty"` - // The src and dst gvg mapping - GvgMappings []*GVGMapping `protobuf:"bytes,5,rep,name=gvg_mappings,json=gvgMappings,proto3" json:"gvg_mappings,omitempty"` + // The src_primary_sp_id defines the primary sp id of the bucket before migrate. + SrcPrimarySpId uint32 `protobuf:"varint,5,opt,name=src_primary_sp_id,json=srcPrimarySpId,proto3" json:"src_primary_sp_id,omitempty"` } func (m *EventCompleteMigrationBucket) Reset() { *m = EventCompleteMigrationBucket{} } @@ -2114,11 +2105,11 @@ func (m *EventCompleteMigrationBucket) GetGlobalVirtualGroupFamilyId() uint32 { return 0 } -func (m *EventCompleteMigrationBucket) GetGvgMappings() []*GVGMapping { +func (m *EventCompleteMigrationBucket) GetSrcPrimarySpId() uint32 { if m != nil { - return m.GvgMappings + return m.SrcPrimarySpId } - return nil + return 0 } func init() { @@ -2154,107 +2145,103 @@ func init() { func init() { proto.RegisterFile("greenfield/storage/events.proto", fileDescriptor_946dcba4f763ddc4) } var fileDescriptor_946dcba4f763ddc4 = []byte{ - // 1585 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xbf, 0x6f, 0xdb, 0xc6, - 0x17, 0x37, 0x25, 0x4a, 0x96, 0x4f, 0x96, 0x9d, 0x30, 0x8e, 0xc3, 0x38, 0xf9, 0xca, 0x0a, 0x87, - 0xc0, 0x5f, 0xa0, 0xb1, 0x01, 0x27, 0x6d, 0xd3, 0xa5, 0x81, 0xed, 0xa4, 0x81, 0xd0, 0xe6, 0x47, - 0xa9, 0x24, 0x43, 0x17, 0xe2, 0x44, 0x9e, 0x69, 0x36, 0x24, 0x8f, 0x3d, 0x9e, 0xd4, 0x28, 0xff, - 0x43, 0x81, 0xae, 0xdd, 0x3b, 0x14, 0x28, 0x0a, 0x74, 0x08, 0xba, 0x75, 0x4f, 0x3b, 0xa5, 0xe9, - 0xd2, 0x1f, 0x40, 0x50, 0x24, 0x53, 0xba, 0x74, 0x2d, 0x3a, 0x15, 0xbc, 0x3b, 0x51, 0xa4, 0x28, - 0x47, 0xa6, 0x52, 0xc7, 0xce, 0x26, 0x3e, 0x7d, 0xde, 0xdd, 0x7b, 0x9f, 0xfb, 0xdc, 0xbb, 0xc7, - 0x23, 0x58, 0xb6, 0x09, 0x42, 0xfe, 0xb6, 0x83, 0x5c, 0x6b, 0x2d, 0xa4, 0x98, 0x40, 0x1b, 0xad, - 0xa1, 0x2e, 0xf2, 0x69, 0xb8, 0x1a, 0x10, 0x4c, 0xb1, 0xa2, 0x0c, 0x00, 0xab, 0x02, 0xb0, 0x74, - 0xd2, 0xc4, 0xa1, 0x87, 0x43, 0x83, 0x21, 0xd6, 0xf8, 0x03, 0x87, 0x2f, 0x2d, 0xd8, 0xd8, 0xc6, - 0xdc, 0x1e, 0xfd, 0x12, 0xd6, 0x51, 0xb3, 0x98, 0xd8, 0xf3, 0xb0, 0x2f, 0x00, 0xf5, 0x11, 0x00, - 0xda, 0x0b, 0x90, 0x18, 0x56, 0xfb, 0x59, 0x06, 0x47, 0xaf, 0x44, 0x61, 0x6d, 0x11, 0x04, 0x29, - 0xda, 0xec, 0x98, 0x77, 0x11, 0x55, 0x56, 0x41, 0x09, 0x7f, 0xea, 0x23, 0xa2, 0x4a, 0x0d, 0x69, - 0x65, 0x66, 0x53, 0x7d, 0xfc, 0xe0, 0xdc, 0x82, 0x88, 0x66, 0xc3, 0xb2, 0x08, 0x0a, 0xc3, 0x16, - 0x25, 0x8e, 0x6f, 0xeb, 0x1c, 0xa6, 0x2c, 0x83, 0x6a, 0x9b, 0x79, 0x1a, 0x3e, 0xf4, 0x90, 0x5a, - 0x88, 0xbc, 0x74, 0xc0, 0x4d, 0xd7, 0xa1, 0x87, 0x94, 0x4d, 0x00, 0xba, 0x4e, 0xe8, 0xb4, 0x1d, - 0xd7, 0xa1, 0x3d, 0xb5, 0xd8, 0x90, 0x56, 0xe6, 0xd6, 0xb5, 0xd5, 0x2c, 0x03, 0xab, 0x77, 0x62, - 0xd4, 0xad, 0x5e, 0x80, 0xf4, 0x84, 0x97, 0x72, 0x0a, 0xcc, 0x98, 0x2c, 0x48, 0x03, 0x52, 0x55, - 0x6e, 0x48, 0x2b, 0x45, 0xbd, 0xc2, 0x0d, 0x1b, 0x54, 0xb9, 0x08, 0x66, 0x44, 0x04, 0x8e, 0xa5, - 0x96, 0x58, 0xd4, 0xa7, 0x1e, 0x3e, 0x59, 0x9e, 0xfa, 0xed, 0xc9, 0xb2, 0x7c, 0xdb, 0xf1, 0xe9, - 0xe3, 0x07, 0xe7, 0xaa, 0x22, 0x83, 0xe8, 0x51, 0xaf, 0x70, 0x74, 0xd3, 0x52, 0x2e, 0x81, 0x6a, - 0x88, 0x3b, 0xc4, 0x44, 0x46, 0xc4, 0x8b, 0x5a, 0x66, 0xb1, 0xd5, 0x47, 0xc5, 0xd6, 0x62, 0x30, - 0x1e, 0x57, 0x18, 0xff, 0x56, 0xde, 0x00, 0x8a, 0xb9, 0x03, 0x89, 0x8d, 0x2c, 0x83, 0x20, 0x68, - 0x19, 0x9f, 0x74, 0x30, 0x85, 0xea, 0x74, 0x43, 0x5a, 0x91, 0xf5, 0x23, 0xe2, 0x1f, 0x1d, 0x41, - 0xeb, 0xc3, 0xc8, 0xae, 0x6c, 0x80, 0xf9, 0x00, 0xf6, 0x3c, 0xe4, 0x53, 0x03, 0x72, 0x2a, 0xd5, - 0xca, 0x18, 0x92, 0xe7, 0x84, 0x83, 0xb0, 0x2a, 0x1a, 0xa8, 0x05, 0xc4, 0xf1, 0x20, 0xe9, 0x19, - 0x61, 0x10, 0xe5, 0x3b, 0xd3, 0x90, 0x56, 0x6a, 0x7a, 0x55, 0x18, 0x5b, 0x41, 0xd3, 0x52, 0x36, - 0x41, 0xdd, 0x76, 0x71, 0x1b, 0xba, 0x46, 0xd7, 0x21, 0xb4, 0x03, 0x5d, 0xc3, 0x26, 0xb8, 0x13, - 0x18, 0xdb, 0xd0, 0x73, 0xdc, 0x5e, 0xe4, 0x04, 0x98, 0xd3, 0x12, 0x47, 0xdd, 0xe1, 0xa0, 0xab, - 0x11, 0xe6, 0x3d, 0x06, 0x69, 0x5a, 0xca, 0x45, 0x50, 0x0e, 0x29, 0xa4, 0x9d, 0x50, 0xad, 0x32, - 0x52, 0x1a, 0xa3, 0x48, 0xe1, 0x8a, 0x69, 0x31, 0x9c, 0x2e, 0xf0, 0xda, 0xdf, 0x92, 0x50, 0xd5, - 0x65, 0xe4, 0xa2, 0x58, 0x55, 0x17, 0x40, 0x05, 0x07, 0x88, 0x40, 0x8a, 0xc7, 0x0b, 0x2b, 0x46, - 0x0e, 0xb4, 0x58, 0x98, 0x48, 0x8b, 0xc5, 0x8c, 0x16, 0x53, 0x52, 0x91, 0xf3, 0x48, 0x25, 0x43, - 0x7c, 0x29, 0x43, 0xbc, 0xf6, 0x63, 0x11, 0x1c, 0x67, 0xa9, 0xdf, 0x0e, 0xac, 0x78, 0x43, 0x35, - 0xfd, 0x6d, 0x3c, 0x61, 0xfa, 0x63, 0xb7, 0x56, 0x2a, 0x9d, 0x62, 0x9e, 0x74, 0xde, 0x01, 0x27, - 0xb3, 0xc2, 0x35, 0xda, 0x68, 0x1b, 0x13, 0xc4, 0x88, 0x91, 0xf5, 0xc5, 0x61, 0xfd, 0x6e, 0xb2, - 0x7f, 0x95, 0xb7, 0x81, 0x3a, 0xc2, 0x15, 0x6e, 0x53, 0x44, 0x18, 0x29, 0xb2, 0x7e, 0x7c, 0xd8, - 0x73, 0x23, 0xfa, 0x53, 0xb9, 0x00, 0x16, 0x87, 0xe4, 0xdf, 0x9f, 0xb0, 0xcc, 0x32, 0x5b, 0x48, - 0x6b, 0x5d, 0x4c, 0xb7, 0x0e, 0x8e, 0x0f, 0x7b, 0xf1, 0xb9, 0xa6, 0x99, 0xd3, 0xb1, 0xb4, 0x13, - 0x9f, 0x29, 0x5d, 0x72, 0x2a, 0x93, 0x94, 0x1c, 0xed, 0x2b, 0x09, 0x2c, 0x72, 0x1d, 0x3b, 0xa1, - 0x89, 0x7d, 0xea, 0xf8, 0x9d, 0xbe, 0x98, 0x53, 0xb4, 0x4b, 0x79, 0x68, 0x1f, 0xbb, 0xa2, 0x8b, - 0xa0, 0x4c, 0x10, 0x0c, 0xb1, 0x2f, 0xc4, 0x2b, 0x9e, 0xa2, 0x02, 0x68, 0xb1, 0xfd, 0x94, 0x28, - 0x80, 0xdc, 0xb0, 0x41, 0xb5, 0x27, 0xa5, 0x54, 0x21, 0xbf, 0xd1, 0xfe, 0x18, 0x99, 0x54, 0x59, - 0x07, 0xd3, 0xac, 0x44, 0xee, 0x41, 0x72, 0x7d, 0xe0, 0x7f, 0xbf, 0xe1, 0x96, 0x41, 0x15, 0xb3, - 0x70, 0x38, 0x40, 0xe6, 0x00, 0x6e, 0xca, 0x4a, 0xb8, 0x9c, 0x87, 0xcb, 0x8b, 0x60, 0x46, 0x0c, - 0xed, 0x58, 0x5c, 0x0c, 0x63, 0x3c, 0x39, 0x7a, 0xd4, 0x5e, 0xae, 0x64, 0x8b, 0xe8, 0x19, 0x30, - 0x1b, 0xc0, 0x9e, 0x8b, 0xa1, 0x65, 0x84, 0xce, 0x7d, 0xc4, 0xea, 0xac, 0xac, 0x57, 0x85, 0xad, - 0xe5, 0xdc, 0x1f, 0x3e, 0xd8, 0xc0, 0x44, 0x07, 0xdb, 0x19, 0x30, 0x1b, 0x89, 0x2b, 0x52, 0x37, - 0x3b, 0x82, 0xaa, 0x8c, 0xa0, 0xaa, 0xb0, 0xb1, 0x33, 0x26, 0x75, 0xf6, 0xcd, 0x66, 0xce, 0xbe, - 0x7e, 0x9d, 0xae, 0xed, 0x5e, 0xa7, 0xb9, 0x20, 0xd2, 0x75, 0x5a, 0x79, 0x1f, 0xcc, 0x13, 0x64, - 0x75, 0x7c, 0x0b, 0xfa, 0x66, 0x8f, 0x4f, 0x3e, 0xb7, 0x7b, 0x0a, 0x7a, 0x0c, 0x65, 0x29, 0xcc, - 0x91, 0xd4, 0xf3, 0xf0, 0x41, 0x3a, 0x9f, 0xfb, 0x20, 0x3d, 0x0d, 0x66, 0xcc, 0x1d, 0x64, 0xde, - 0x0d, 0x3b, 0x5e, 0xa8, 0x1e, 0x69, 0x14, 0x57, 0x66, 0xf5, 0x81, 0x41, 0xfb, 0x4b, 0x02, 0x27, - 0xb8, 0xc0, 0xa1, 0x6f, 0x22, 0x37, 0x25, 0xf3, 0x7d, 0x2a, 0xad, 0x43, 0xc2, 0x2d, 0x66, 0x84, - 0x9b, 0x11, 0x91, 0x9c, 0x15, 0x51, 0x4a, 0xa2, 0xe5, 0x1c, 0x12, 0xd5, 0x9e, 0x17, 0xc0, 0x3c, - 0xcb, 0xb8, 0x85, 0xa0, 0x7b, 0xc0, 0x99, 0xa6, 0xb2, 0x28, 0xe5, 0xd9, 0x68, 0x03, 0x75, 0x96, - 0x73, 0xaa, 0xf3, 0x4d, 0x70, 0x62, 0x64, 0x0f, 0x23, 0xb6, 0x7a, 0x4d, 0x5f, 0xc8, 0x36, 0x2f, - 0x4d, 0x4b, 0x39, 0x0f, 0x16, 0x5d, 0x6c, 0x8e, 0xf2, 0xe2, 0x5b, 0xfc, 0x18, 0xfb, 0x37, 0xed, - 0x34, 0xe0, 0x7a, 0x0b, 0x07, 0xbd, 0x97, 0xe2, 0xfa, 0x2c, 0x98, 0x0f, 0x89, 0x69, 0x64, 0xf9, - 0xae, 0x85, 0xc4, 0xdc, 0x1c, 0x50, 0x2e, 0x70, 0x59, 0xda, 0x23, 0xdc, 0x8d, 0x01, 0xf3, 0x67, - 0xc1, 0xbc, 0x15, 0xd2, 0xd4, 0x78, 0xbc, 0x82, 0xd6, 0xac, 0x90, 0xa6, 0xc7, 0x8b, 0x70, 0xc9, - 0xf1, 0x4a, 0x31, 0x2e, 0x31, 0xde, 0x25, 0x50, 0x4b, 0xcc, 0xbb, 0x37, 0x4d, 0x56, 0xe3, 0x90, - 0x58, 0xc3, 0x5c, 0x4b, 0x4c, 0xb4, 0xb7, 0xba, 0x5b, 0x8d, 0x63, 0x68, 0x5a, 0xda, 0x3f, 0xe9, - 0xee, 0xf0, 0x30, 0x29, 0x5b, 0xce, 0xa3, 0xec, 0xdd, 0x85, 0x56, 0xda, 0x5d, 0x68, 0x3f, 0x48, - 0xa2, 0x3f, 0xd4, 0x11, 0x93, 0xfc, 0x21, 0xdb, 0xda, 0x79, 0x08, 0x18, 0xd9, 0x1e, 0x89, 0x64, - 0x86, 0xc2, 0x92, 0x46, 0xb5, 0xad, 0x83, 0x59, 0x0b, 0x79, 0x68, 0x9f, 0xa8, 0x3d, 0xfa, 0xac, - 0x90, 0x6a, 0xcb, 0x85, 0x16, 0xf7, 0xb1, 0x2d, 0xdf, 0x47, 0xdd, 0xa5, 0x7b, 0x8e, 0xd2, 0x44, - 0x9d, 0xed, 0x97, 0x05, 0x70, 0x24, 0xd1, 0x2e, 0x32, 0x75, 0xe6, 0x7e, 0xed, 0xff, 0x1f, 0x00, - 0x5c, 0xf2, 0x09, 0x0e, 0x66, 0x98, 0x85, 0x65, 0xf8, 0x16, 0xa8, 0xc4, 0x3b, 0x62, 0x0f, 0x2f, - 0x26, 0xd3, 0xb6, 0x28, 0xe0, 0x43, 0x8d, 0x84, 0x9c, 0xbb, 0x91, 0x58, 0x07, 0xd3, 0x1e, 0xf2, - 0xda, 0x88, 0x84, 0x6a, 0xa9, 0x51, 0x7c, 0x71, 0xd7, 0x2b, 0x80, 0xca, 0x02, 0x28, 0xa1, 0x7b, - 0x94, 0x40, 0xf1, 0x1e, 0xc2, 0x1f, 0xb4, 0x2f, 0x24, 0x41, 0x13, 0x2f, 0x55, 0x43, 0x34, 0x15, - 0x26, 0xa1, 0xa9, 0xf8, 0x22, 0x9a, 0xe4, 0xbd, 0xd3, 0xa4, 0xfd, 0x2a, 0x89, 0x23, 0xeb, 0x03, - 0x04, 0xbb, 0x22, 0xb4, 0x4b, 0x60, 0x8e, 0x27, 0x14, 0x5f, 0x2e, 0x8c, 0x5b, 0xca, 0x1a, 0xc7, - 0xf7, 0xef, 0x16, 0x0e, 0x49, 0x6e, 0xbf, 0x17, 0x44, 0x65, 0xe1, 0xdb, 0x95, 0x25, 0x77, 0x8d, - 0x05, 0xfa, 0x8a, 0x6e, 0x11, 0xf6, 0x27, 0x2f, 0xe5, 0xdd, 0xfe, 0xfa, 0x84, 0x06, 0xc5, 0xd1, - 0x1a, 0x8d, 0x15, 0xe8, 0xac, 0xc0, 0xdf, 0xc2, 0x1b, 0x96, 0xa5, 0x5c, 0x06, 0x47, 0x13, 0xfe, - 0xbc, 0xba, 0xa9, 0xe5, 0x31, 0x43, 0xcc, 0xc7, 0x43, 0x70, 0x15, 0x6b, 0x7f, 0x4a, 0xa9, 0x62, - 0xc8, 0xd8, 0xbd, 0x12, 0xe9, 0xfd, 0xf5, 0x26, 0x37, 0xde, 0xc2, 0xa5, 0xe4, 0x16, 0x7e, 0xd8, - 0xef, 0x36, 0xae, 0x39, 0x84, 0x60, 0xf2, 0x52, 0x77, 0x51, 0xf9, 0x2e, 0x63, 0xf2, 0xde, 0x2d, - 0x59, 0x28, 0xa4, 0x86, 0xb9, 0x03, 0x1d, 0x3f, 0x71, 0xb7, 0x14, 0x19, 0xb7, 0x22, 0x5b, 0xd3, - 0xd2, 0xbe, 0xed, 0xbf, 0x02, 0x25, 0x53, 0xd1, 0x51, 0xd8, 0x71, 0x69, 0x74, 0x2a, 0x8a, 0x36, - 0x5b, 0x62, 0x8e, 0xfd, 0x26, 0xfa, 0x80, 0x43, 0x7e, 0x9e, 0x66, 0xff, 0xb5, 0xed, 0xf5, 0xf6, - 0x92, 0xeb, 0x4f, 0xe9, 0xe5, 0xe1, 0xb9, 0xbe, 0xec, 0xf2, 0x1c, 0x70, 0x4e, 0xdf, 0xf7, 0x0f, - 0x40, 0x9e, 0xd3, 0xa1, 0xea, 0x13, 0x32, 0xf1, 0xcb, 0xd9, 0xf8, 0xbf, 0xee, 0xb7, 0xa8, 0x89, - 0xf8, 0xc7, 0x2c, 0xc9, 0x01, 0x46, 0xdb, 0x15, 0x02, 0x6a, 0x51, 0xe8, 0xa2, 0x9b, 0xd8, 0x75, - 0xcc, 0xde, 0x96, 0x8b, 0xa0, 0xdf, 0x09, 0x94, 0x25, 0x50, 0x69, 0xbb, 0xd8, 0xbc, 0x7b, 0xbd, - 0xe3, 0xb1, 0x78, 0x8b, 0x7a, 0xfc, 0x1c, 0x35, 0x4c, 0xa2, 0xf3, 0x75, 0xfc, 0x6d, 0xcc, 0x42, - 0xae, 0x8e, 0x6e, 0x98, 0xf8, 0x01, 0x10, 0xf5, 0xbd, 0x3a, 0xb0, 0xe2, 0xdf, 0xda, 0x63, 0x09, - 0x2c, 0x08, 0x96, 0x6c, 0x02, 0xa9, 0x83, 0xfd, 0x57, 0x58, 0x26, 0x73, 0xdd, 0x59, 0xff, 0x1f, - 0x1c, 0x8d, 0x5e, 0x3e, 0x47, 0xdd, 0xba, 0xcc, 0x59, 0x21, 0xbd, 0x99, 0xb8, 0x89, 0xff, 0x46, - 0x02, 0x4b, 0x89, 0x0b, 0xa3, 0xc3, 0x9e, 0x9a, 0xf6, 0x5d, 0x01, 0x9c, 0x16, 0x57, 0x10, 0x5e, - 0x10, 0x2d, 0xcd, 0xa1, 0x5f, 0x8c, 0xf1, 0x1f, 0x99, 0xe4, 0xb1, 0x1f, 0x99, 0x36, 0xc0, 0xac, - 0xdd, 0xb5, 0x0d, 0x0f, 0x06, 0x81, 0xe3, 0xdb, 0xbc, 0x61, 0xdf, 0x45, 0xbc, 0x57, 0xef, 0x5c, - 0xbd, 0xc6, 0x61, 0x7a, 0xd5, 0xee, 0xda, 0xe2, 0x77, 0xb8, 0xd9, 0x7c, 0xf8, 0xb4, 0x2e, 0x3d, - 0x7a, 0x5a, 0x97, 0xfe, 0x78, 0x5a, 0x97, 0x3e, 0x7f, 0x56, 0x9f, 0x7a, 0xf4, 0xac, 0x3e, 0xf5, - 0xcb, 0xb3, 0xfa, 0xd4, 0x47, 0x6b, 0xb6, 0x43, 0x77, 0x3a, 0xed, 0x55, 0x13, 0x7b, 0x6b, 0x6d, - 0xbf, 0x7d, 0x8e, 0xed, 0xbd, 0xb5, 0xc4, 0x27, 0xd1, 0x7b, 0xe9, 0x8f, 0xa2, 0xed, 0x32, 0xfb, - 0x2a, 0x7a, 0xfe, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x5a, 0x77, 0xe1, 0xbe, 0x1d, 0x00, - 0x00, + // 1525 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xbf, 0x6f, 0xdb, 0x46, + 0x1b, 0x36, 0x25, 0x4a, 0xb6, 0x4f, 0x96, 0x14, 0xf3, 0xf3, 0x97, 0xe8, 0x73, 0xf2, 0xc9, 0x0a, + 0x87, 0xd4, 0x01, 0x1a, 0x1b, 0x48, 0xda, 0x22, 0x53, 0x03, 0xdb, 0x49, 0x0b, 0xa1, 0xcd, 0x8f, + 0x52, 0x49, 0x86, 0x2e, 0xc4, 0x89, 0x3c, 0xcb, 0x6c, 0x48, 0x1e, 0x7b, 0x77, 0x72, 0xa3, 0xfc, + 0x03, 0x9d, 0x0a, 0x74, 0x6c, 0x97, 0x4e, 0x1d, 0x0a, 0x14, 0x05, 0x3a, 0x64, 0xed, 0x9e, 0x6e, + 0x69, 0xba, 0xf4, 0x07, 0x10, 0x14, 0xc9, 0x94, 0x2e, 0xdd, 0x3b, 0x15, 0xbc, 0x3b, 0x51, 0xa4, + 0x28, 0x87, 0xa6, 0x52, 0xc7, 0xce, 0x26, 0xbe, 0x7a, 0xee, 0xf8, 0xbe, 0xcf, 0x3d, 0xef, 0x7b, + 0xef, 0x1d, 0xc1, 0x4a, 0x8f, 0x20, 0xe4, 0x6f, 0x3b, 0xc8, 0xb5, 0xd7, 0x29, 0xc3, 0x04, 0xf6, + 0xd0, 0x3a, 0xda, 0x45, 0x3e, 0xa3, 0x6b, 0x01, 0xc1, 0x0c, 0x6b, 0xda, 0x08, 0xb0, 0x26, 0x01, + 0xcb, 0xff, 0xb3, 0x30, 0xf5, 0x30, 0x35, 0x39, 0x62, 0x5d, 0x3c, 0x08, 0xf8, 0xf2, 0x52, 0x0f, + 0xf7, 0xb0, 0xb0, 0x87, 0xbf, 0xa4, 0x75, 0xd2, 0x5b, 0x2c, 0xec, 0x79, 0xd8, 0x97, 0x80, 0xe6, + 0x04, 0x00, 0x1b, 0x04, 0x48, 0x4e, 0xab, 0xff, 0xac, 0x82, 0xc5, 0x2b, 0xa1, 0x5b, 0x5b, 0x04, + 0x41, 0x86, 0x36, 0xfb, 0xd6, 0x1d, 0xc4, 0xb4, 0x35, 0x50, 0xc2, 0x9f, 0xf8, 0x88, 0x34, 0x94, + 0x96, 0xb2, 0x3a, 0xbf, 0xd9, 0x78, 0x74, 0xff, 0xdc, 0x92, 0xf4, 0x66, 0xc3, 0xb6, 0x09, 0xa2, + 0xb4, 0xc3, 0x88, 0xe3, 0xf7, 0x0c, 0x01, 0xd3, 0x56, 0x40, 0xa5, 0xcb, 0x47, 0x9a, 0x3e, 0xf4, + 0x50, 0xa3, 0x10, 0x8e, 0x32, 0x80, 0x30, 0x5d, 0x83, 0x1e, 0xd2, 0x36, 0x01, 0xd8, 0x75, 0xa8, + 0xd3, 0x75, 0x5c, 0x87, 0x0d, 0x1a, 0xc5, 0x96, 0xb2, 0x5a, 0x3b, 0xaf, 0xaf, 0xa5, 0x19, 0x58, + 0xbb, 0x1d, 0xa1, 0x6e, 0x0e, 0x02, 0x64, 0xc4, 0x46, 0x69, 0x27, 0xc1, 0xbc, 0xc5, 0x9d, 0x34, + 0x21, 0x6b, 0xa8, 0x2d, 0x65, 0xb5, 0x68, 0xcc, 0x09, 0xc3, 0x06, 0xd3, 0x2e, 0x82, 0x79, 0xe9, + 0x81, 0x63, 0x37, 0x4a, 0xdc, 0xeb, 0x93, 0x0f, 0x1e, 0xaf, 0xcc, 0xfc, 0xf6, 0x78, 0x45, 0xbd, + 0xe5, 0xf8, 0xec, 0xd1, 0xfd, 0x73, 0x15, 0x19, 0x41, 0xf8, 0x68, 0xcc, 0x09, 0x74, 0xdb, 0xd6, + 0x2e, 0x81, 0x0a, 0xc5, 0x7d, 0x62, 0x21, 0x33, 0xe4, 0xa5, 0x51, 0xe6, 0xbe, 0x35, 0x27, 0xf9, + 0xd6, 0xe1, 0x30, 0xe1, 0x17, 0x8d, 0x7e, 0x6b, 0xaf, 0x03, 0xcd, 0xda, 0x81, 0xa4, 0x87, 0x6c, + 0x93, 0x20, 0x68, 0x9b, 0x1f, 0xf7, 0x31, 0x83, 0x8d, 0xd9, 0x96, 0xb2, 0xaa, 0x1a, 0xc7, 0xe4, + 0x3f, 0x06, 0x82, 0xf6, 0x07, 0xa1, 0x5d, 0xdb, 0x00, 0xf5, 0x00, 0x0e, 0x3c, 0xe4, 0x33, 0x13, + 0x0a, 0x2a, 0x1b, 0x73, 0x19, 0x24, 0xd7, 0xe4, 0x00, 0x69, 0xd5, 0x74, 0x50, 0x0d, 0x88, 0xe3, + 0x41, 0x32, 0x30, 0x69, 0x10, 0xc6, 0x3b, 0xdf, 0x52, 0x56, 0xab, 0x46, 0x45, 0x1a, 0x3b, 0x41, + 0xdb, 0xd6, 0x36, 0x41, 0xb3, 0xe7, 0xe2, 0x2e, 0x74, 0xcd, 0x5d, 0x87, 0xb0, 0x3e, 0x74, 0xcd, + 0x1e, 0xc1, 0xfd, 0xc0, 0xdc, 0x86, 0x9e, 0xe3, 0x0e, 0xc2, 0x41, 0x80, 0x0f, 0x5a, 0x16, 0xa8, + 0xdb, 0x02, 0xf4, 0x6e, 0x88, 0x79, 0x87, 0x43, 0xda, 0xb6, 0x76, 0x11, 0x94, 0x29, 0x83, 0xac, + 0x4f, 0x1b, 0x15, 0x4e, 0x4a, 0x6b, 0x12, 0x29, 0x42, 0x31, 0x1d, 0x8e, 0x33, 0x24, 0x5e, 0xff, + 0xa2, 0x20, 0x55, 0x75, 0x19, 0xb9, 0x28, 0x52, 0xd5, 0x1b, 0x60, 0x0e, 0x07, 0x88, 0x40, 0x86, + 0xb3, 0x85, 0x15, 0x21, 0x47, 0x5a, 0x2c, 0x4c, 0xa5, 0xc5, 0x62, 0x4a, 0x8b, 0x09, 0xa9, 0xa8, + 0x79, 0xa4, 0x92, 0x4d, 0x6a, 0x29, 0x8b, 0x54, 0xfd, 0xd3, 0x22, 0xf8, 0x2f, 0xa7, 0xe6, 0x56, + 0x60, 0x47, 0x09, 0xd7, 0xf6, 0xb7, 0xf1, 0x94, 0xf4, 0x64, 0xa6, 0x5e, 0x22, 0xdc, 0x62, 0x9e, + 0x70, 0x27, 0x0b, 0x5b, 0xdd, 0x43, 0xd8, 0xaf, 0xa5, 0x85, 0xcd, 0xf3, 0x30, 0x25, 0xdf, 0x64, + 0x2d, 0x28, 0x4f, 0x55, 0x0b, 0xb2, 0x57, 0x62, 0x36, 0x73, 0x25, 0xbe, 0x51, 0xc0, 0x71, 0x21, + 0x52, 0x87, 0x5a, 0xd8, 0x67, 0x8e, 0xdf, 0x1f, 0x2a, 0x35, 0xc1, 0x99, 0x92, 0x87, 0xb3, 0xcc, + 0xe5, 0x38, 0x0e, 0xca, 0x04, 0x41, 0x8a, 0x7d, 0xa9, 0x4c, 0xf9, 0x14, 0x56, 0x37, 0x9b, 0x27, + 0x4b, 0xac, 0xba, 0x09, 0xc3, 0x06, 0xd3, 0x1f, 0x97, 0x12, 0x55, 0xfa, 0x7a, 0xf7, 0x23, 0x64, + 0x31, 0xed, 0x3c, 0x98, 0xe5, 0xf5, 0x6f, 0x1f, 0x7a, 0x19, 0x02, 0xff, 0xfd, 0x6c, 0x5a, 0x01, + 0x15, 0xcc, 0xdd, 0x11, 0x00, 0x55, 0x00, 0x84, 0x29, 0xad, 0xbf, 0x72, 0x1e, 0x2e, 0x2f, 0x82, + 0x79, 0x39, 0xb5, 0x5c, 0xcf, 0xac, 0x91, 0x02, 0xdd, 0xb6, 0xd3, 0x15, 0x72, 0x2e, 0x5d, 0x21, + 0x4f, 0x83, 0x85, 0x00, 0x0e, 0x5c, 0x0c, 0x6d, 0x93, 0x3a, 0xf7, 0x10, 0x2f, 0xa2, 0xaa, 0x51, + 0x91, 0xb6, 0x8e, 0x73, 0x6f, 0x7c, 0xd7, 0x02, 0x53, 0x29, 0xf5, 0x34, 0x58, 0x08, 0xc5, 0x15, + 0xa6, 0x05, 0xdf, 0x5f, 0x2a, 0x9c, 0xa0, 0x8a, 0xb4, 0xf1, 0x0d, 0x24, 0xb1, 0xb1, 0x2d, 0xa4, + 0x36, 0xb6, 0x61, 0x11, 0xae, 0xee, 0x5d, 0x84, 0x85, 0x20, 0x92, 0x45, 0x58, 0x7b, 0x0f, 0xd4, + 0x09, 0xb2, 0xfb, 0xbe, 0x0d, 0x7d, 0x6b, 0x20, 0x5e, 0x5e, 0xdb, 0x3b, 0x04, 0x23, 0x82, 0xf2, + 0x10, 0x6a, 0x24, 0xf1, 0x3c, 0xbe, 0x4b, 0xd6, 0x73, 0xef, 0x92, 0xa7, 0xc0, 0xbc, 0xb5, 0x83, + 0xac, 0x3b, 0xb4, 0xef, 0xd1, 0xc6, 0xb1, 0x56, 0x71, 0x75, 0xc1, 0x18, 0x19, 0xf4, 0xbf, 0x14, + 0x70, 0x42, 0x08, 0x1c, 0xfa, 0x16, 0x72, 0x13, 0x32, 0x3f, 0xa0, 0xba, 0x38, 0x26, 0xdc, 0x62, + 0x4a, 0xb8, 0x29, 0x11, 0xa9, 0x69, 0x11, 0x25, 0x24, 0x5a, 0xce, 0x21, 0x51, 0xfd, 0x59, 0x01, + 0xd4, 0x79, 0xc4, 0x1d, 0x04, 0xdd, 0x43, 0x8e, 0x34, 0x11, 0x45, 0x29, 0x4f, 0xa2, 0x8d, 0xd4, + 0x59, 0xce, 0xa9, 0xce, 0x37, 0xc1, 0x89, 0x89, 0x15, 0x3c, 0x2a, 0xdd, 0x4b, 0xe9, 0xd2, 0xdd, + 0xb6, 0xb5, 0x0b, 0xe0, 0xb8, 0x8b, 0xad, 0x49, 0xa3, 0x44, 0x8a, 0xff, 0x87, 0xff, 0x9b, 0x1c, + 0x34, 0xe2, 0x7a, 0x0b, 0x07, 0x83, 0x17, 0xe2, 0xfa, 0x0c, 0xa8, 0x53, 0x62, 0x99, 0x69, 0xbe, + 0xab, 0x94, 0x58, 0x9b, 0x23, 0xca, 0x25, 0x2e, 0x4d, 0x7b, 0x88, 0xbb, 0x3e, 0x62, 0xfe, 0x0c, + 0xa8, 0xdb, 0x94, 0x25, 0xe6, 0x13, 0x15, 0xb4, 0x6a, 0x53, 0x96, 0x9c, 0x2f, 0xc4, 0xc5, 0xe7, + 0x2b, 0x45, 0xb8, 0xd8, 0x7c, 0x97, 0x40, 0x35, 0xf6, 0xde, 0xfd, 0x69, 0xb2, 0x12, 0xb9, 0xc4, + 0xbb, 0xe1, 0x6a, 0xec, 0x45, 0xfb, 0xab, 0xbb, 0x95, 0xc8, 0x87, 0xb6, 0xad, 0xff, 0xad, 0x24, + 0x5a, 0xbf, 0xa3, 0xa4, 0x6c, 0x35, 0x8f, 0xb2, 0xf7, 0x16, 0x5a, 0x69, 0x6f, 0xa1, 0xfd, 0xa8, + 0xc8, 0xe6, 0xce, 0x40, 0x5c, 0xf2, 0x47, 0x2c, 0xb5, 0xf3, 0x10, 0x30, 0xb1, 0x3d, 0x92, 0xc1, + 0x8c, 0xb9, 0xa5, 0x4c, 0xea, 0x39, 0x47, 0x6f, 0x2d, 0xe4, 0xa1, 0x7d, 0xaa, 0xf6, 0xe8, 0xb3, + 0x42, 0xa2, 0xa7, 0x96, 0x5a, 0x3c, 0xc0, 0x9e, 0xfa, 0x00, 0x75, 0x97, 0xec, 0x39, 0x4a, 0xd3, + 0xf4, 0x1c, 0xfa, 0xd7, 0x05, 0x70, 0x2c, 0xd6, 0x2e, 0x72, 0x75, 0xe6, 0x3e, 0xd3, 0xff, 0x1f, + 0x00, 0x21, 0xf9, 0x18, 0x07, 0xf3, 0xdc, 0xc2, 0x23, 0x7c, 0x0b, 0xcc, 0x45, 0x19, 0xb1, 0x8f, + 0x53, 0xc5, 0x6c, 0x4f, 0x16, 0xf0, 0xb1, 0x46, 0x42, 0xcd, 0xdd, 0x48, 0x9c, 0x07, 0xb3, 0x1e, + 0xf2, 0xba, 0x88, 0x84, 0xe7, 0x8b, 0xe2, 0xf3, 0xbb, 0x5e, 0x09, 0xd4, 0x96, 0x40, 0x09, 0xdd, + 0x65, 0x04, 0x8a, 0x72, 0x68, 0x88, 0x07, 0xfd, 0x4b, 0x45, 0xd2, 0x24, 0x4a, 0xd5, 0x18, 0x4d, + 0x85, 0x69, 0x68, 0x2a, 0x3e, 0x8f, 0x26, 0x75, 0xff, 0x34, 0xe9, 0xbf, 0x2a, 0x72, 0xcb, 0x7a, + 0x1f, 0xc1, 0x5d, 0xe9, 0xda, 0x25, 0x50, 0x13, 0x01, 0x45, 0x07, 0xac, 0xac, 0xa5, 0xac, 0x0a, + 0xfc, 0xf0, 0xe4, 0x75, 0x44, 0x62, 0xfb, 0xbd, 0x20, 0x2b, 0x8b, 0x48, 0x57, 0x1e, 0xdc, 0x55, + 0xee, 0xe8, 0x4b, 0xba, 0x22, 0x38, 0x98, 0xb8, 0xb4, 0xb7, 0x87, 0xeb, 0x43, 0x4d, 0x86, 0xc3, + 0x35, 0xca, 0x14, 0xe8, 0x82, 0xc4, 0xdf, 0xc4, 0x1b, 0xb6, 0xad, 0x5d, 0x06, 0x8b, 0xb1, 0xf1, + 0xa2, 0xba, 0x35, 0xca, 0x19, 0x53, 0xd4, 0xa3, 0x29, 0x84, 0x8a, 0xf5, 0x3f, 0x95, 0x44, 0x31, + 0xe4, 0xec, 0x5e, 0x09, 0xf5, 0xfe, 0x6a, 0x93, 0x1b, 0xa5, 0x70, 0x29, 0x9e, 0xc2, 0x0f, 0x86, + 0xdd, 0xc6, 0x55, 0x87, 0x10, 0x4c, 0x5e, 0xe8, 0xa2, 0x29, 0xdf, 0x4d, 0x4a, 0xae, 0x8b, 0x23, + 0x1d, 0x54, 0x6d, 0x44, 0x99, 0x69, 0xed, 0x40, 0xc7, 0x1f, 0xf5, 0x10, 0x95, 0xd0, 0xb8, 0x15, + 0xda, 0xda, 0xb6, 0xfe, 0xfd, 0xf0, 0x08, 0x14, 0x0f, 0xc5, 0x40, 0xb4, 0xef, 0xb2, 0x70, 0x57, + 0x94, 0x6d, 0xb6, 0xc2, 0x07, 0x0e, 0x9b, 0xe8, 0x43, 0x76, 0xf9, 0x59, 0x92, 0xfd, 0x57, 0xb6, + 0xd7, 0xdb, 0x4f, 0xac, 0x3f, 0x25, 0x97, 0x47, 0xc4, 0xfa, 0xa2, 0xcb, 0x73, 0xc8, 0x31, 0xfd, + 0x30, 0xdc, 0x00, 0x45, 0x4c, 0x47, 0xaa, 0x4f, 0x48, 0xf9, 0xaf, 0xa6, 0xfd, 0xff, 0x76, 0xd8, + 0xa2, 0xc6, 0xfc, 0xcf, 0x58, 0x92, 0x43, 0xf4, 0x76, 0x57, 0x0a, 0xa8, 0xc3, 0xa0, 0x8b, 0x6e, + 0x60, 0xd7, 0xb1, 0x06, 0x5b, 0x2e, 0x82, 0x7e, 0x3f, 0xd0, 0x96, 0xc1, 0x5c, 0xd7, 0xc5, 0xd6, + 0x9d, 0x6b, 0x7d, 0x8f, 0xfb, 0x5b, 0x34, 0xa2, 0xe7, 0xb0, 0x61, 0x92, 0x9d, 0xaf, 0xe3, 0x6f, + 0x63, 0xee, 0x72, 0x65, 0x72, 0xc3, 0x24, 0x36, 0x80, 0xb0, 0xef, 0x35, 0x80, 0x1d, 0xfd, 0xd6, + 0x1f, 0x29, 0x60, 0x49, 0xb2, 0xd4, 0x23, 0x90, 0x39, 0xd8, 0x7f, 0x89, 0x65, 0x32, 0xd7, 0x85, + 0xf3, 0x59, 0xb0, 0x18, 0x1e, 0x3e, 0x27, 0xdd, 0xba, 0xd4, 0x6c, 0xca, 0x6e, 0x8c, 0x2e, 0x5e, + 0xf4, 0xef, 0x14, 0xb0, 0x1c, 0xbb, 0x30, 0x3a, 0xea, 0xa1, 0xe9, 0x5f, 0x15, 0xc0, 0x29, 0x79, + 0x05, 0xe1, 0x05, 0xe1, 0xd2, 0x1c, 0xf9, 0xc5, 0xc8, 0xbe, 0x62, 0x57, 0x33, 0xbf, 0x20, 0x9d, + 0x05, 0x8b, 0x94, 0x58, 0x63, 0x0b, 0x2a, 0x0a, 0x51, 0x8d, 0x12, 0x2b, 0xb6, 0xa0, 0x9b, 0xed, + 0x07, 0x4f, 0x9a, 0xca, 0xc3, 0x27, 0x4d, 0xe5, 0x8f, 0x27, 0x4d, 0xe5, 0xf3, 0xa7, 0xcd, 0x99, + 0x87, 0x4f, 0x9b, 0x33, 0xbf, 0x3c, 0x6d, 0xce, 0x7c, 0xb8, 0xde, 0x73, 0xd8, 0x4e, 0xbf, 0xbb, + 0x66, 0x61, 0x6f, 0xbd, 0xeb, 0x77, 0xcf, 0xf1, 0x1c, 0x5b, 0x8f, 0x7d, 0xd7, 0xbc, 0x9b, 0xfc, + 0xb2, 0xd9, 0x2d, 0xf3, 0x4f, 0x9b, 0x17, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x30, 0xf3, 0x5c, + 0x69, 0x83, 0x1d, 0x00, 0x00, } func (m *EventCreateBucket) Marshal() (dAtA []byte, err error) { @@ -2366,8 +2353,8 @@ func (m *EventDeleteBucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.PrimarySpId != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) + if m.GlobalVirtualGroupFamilyId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.GlobalVirtualGroupFamilyId)) i-- dAtA[i] = 0x28 } @@ -2425,32 +2412,25 @@ func (m *EventUpdateBucketInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Visibility != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.Visibility)) - i-- - dAtA[i] = 0x40 - } - if len(m.PaymentAddressAfter) > 0 { - i -= len(m.PaymentAddressAfter) - copy(dAtA[i:], m.PaymentAddressAfter) - i = encodeVarintEvents(dAtA, i, uint64(len(m.PaymentAddressAfter))) + if m.GlobalVirtualGroupFamilyId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.GlobalVirtualGroupFamilyId)) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x38 } - if len(m.PaymentAddressBefore) > 0 { - i -= len(m.PaymentAddressBefore) - copy(dAtA[i:], m.PaymentAddressBefore) - i = encodeVarintEvents(dAtA, i, uint64(len(m.PaymentAddressBefore))) + if m.Visibility != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.Visibility)) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x30 } - if m.ChargedReadQuotaAfter != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.ChargedReadQuotaAfter)) + if len(m.PaymentAddress) > 0 { + i -= len(m.PaymentAddress) + copy(dAtA[i:], m.PaymentAddress) + i = encodeVarintEvents(dAtA, i, uint64(len(m.PaymentAddress))) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x2a } - if m.ChargedReadQuotaBefore != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.ChargedReadQuotaBefore)) + if m.ChargedReadQuota != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.ChargedReadQuota)) i-- dAtA[i] = 0x20 } @@ -3868,19 +3848,10 @@ func (m *EventCompleteMigrationBucket) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l - if len(m.GvgMappings) > 0 { - for iNdEx := len(m.GvgMappings) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.GvgMappings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } + if m.SrcPrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.SrcPrimarySpId)) + i-- + dAtA[i] = 0x28 } if m.GlobalVirtualGroupFamilyId != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.GlobalVirtualGroupFamilyId)) @@ -3989,8 +3960,8 @@ func (m *EventDeleteBucket) Size() (n int) { } l = m.BucketId.Size() n += 1 + l + sovEvents(uint64(l)) - if m.PrimarySpId != 0 { - n += 1 + sovEvents(uint64(m.PrimarySpId)) + if m.GlobalVirtualGroupFamilyId != 0 { + n += 1 + sovEvents(uint64(m.GlobalVirtualGroupFamilyId)) } return n } @@ -4011,23 +3982,19 @@ func (m *EventUpdateBucketInfo) Size() (n int) { } l = m.BucketId.Size() n += 1 + l + sovEvents(uint64(l)) - if m.ChargedReadQuotaBefore != 0 { - n += 1 + sovEvents(uint64(m.ChargedReadQuotaBefore)) - } - if m.ChargedReadQuotaAfter != 0 { - n += 1 + sovEvents(uint64(m.ChargedReadQuotaAfter)) - } - l = len(m.PaymentAddressBefore) - if l > 0 { - n += 1 + l + sovEvents(uint64(l)) + if m.ChargedReadQuota != 0 { + n += 1 + sovEvents(uint64(m.ChargedReadQuota)) } - l = len(m.PaymentAddressAfter) + l = len(m.PaymentAddress) if l > 0 { n += 1 + l + sovEvents(uint64(l)) } if m.Visibility != 0 { n += 1 + sovEvents(uint64(m.Visibility)) } + if m.GlobalVirtualGroupFamilyId != 0 { + n += 1 + sovEvents(uint64(m.GlobalVirtualGroupFamilyId)) + } return n } @@ -4650,11 +4617,8 @@ func (m *EventCompleteMigrationBucket) Size() (n int) { if m.GlobalVirtualGroupFamilyId != 0 { n += 1 + sovEvents(uint64(m.GlobalVirtualGroupFamilyId)) } - if len(m.GvgMappings) > 0 { - for _, e := range m.GvgMappings { - l = e.Size() - n += 1 + l + sovEvents(uint64(l)) - } + if m.SrcPrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.SrcPrimarySpId)) } return n } @@ -5139,9 +5103,9 @@ func (m *EventDeleteBucket) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilyId", wireType) } - m.PrimarySpId = 0 + m.GlobalVirtualGroupFamilyId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -5151,7 +5115,7 @@ func (m *EventDeleteBucket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.PrimarySpId |= uint32(b&0x7F) << shift + m.GlobalVirtualGroupFamilyId |= uint32(b&0x7F) << shift if b < 0x80 { break } @@ -5306,9 +5270,9 @@ func (m *EventUpdateBucketInfo) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChargedReadQuotaBefore", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChargedReadQuota", wireType) } - m.ChargedReadQuotaBefore = 0 + m.ChargedReadQuota = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -5318,33 +5282,14 @@ func (m *EventUpdateBucketInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChargedReadQuotaBefore |= uint64(b&0x7F) << shift + m.ChargedReadQuota |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChargedReadQuotaAfter", wireType) - } - m.ChargedReadQuotaAfter = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ChargedReadQuotaAfter |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PaymentAddressBefore", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PaymentAddress", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5372,13 +5317,13 @@ func (m *EventUpdateBucketInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PaymentAddressBefore = string(dAtA[iNdEx:postIndex]) + m.PaymentAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PaymentAddressAfter", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Visibility", wireType) } - var stringLen uint64 + m.Visibility = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -5388,29 +5333,16 @@ func (m *EventUpdateBucketInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Visibility |= VisibilityType(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PaymentAddressAfter = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: + case 7: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Visibility", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilyId", wireType) } - m.Visibility = 0 + m.GlobalVirtualGroupFamilyId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -5420,7 +5352,7 @@ func (m *EventUpdateBucketInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Visibility |= VisibilityType(b&0x7F) << shift + m.GlobalVirtualGroupFamilyId |= uint32(b&0x7F) << shift if b < 0x80 { break } @@ -10124,10 +10056,10 @@ func (m *EventCompleteMigrationBucket) Unmarshal(dAtA []byte) error { } } case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GvgMappings", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SrcPrimarySpId", wireType) } - var msglen int + m.SrcPrimarySpId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -10137,26 +10069,11 @@ func (m *EventCompleteMigrationBucket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.SrcPrimarySpId |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GvgMappings = append(m.GvgMappings, &GVGMapping{}) - if err := m.GvgMappings[len(m.GvgMappings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/x/storage/types/expected_keepers.go b/x/storage/types/expected_keepers.go index e3d5ecb79..5bc76a07f 100644 --- a/x/storage/types/expected_keepers.go +++ b/x/storage/types/expected_keepers.go @@ -82,11 +82,11 @@ type CrossChainKeeper interface { } type VirtualGroupKeeper interface { - SetGVG(ctx sdk.Context, gvg *types.GlobalVirtualGroup) - GetGVGFamily(ctx sdk.Context, spID, familyID uint32) (*types.GlobalVirtualGroupFamily, bool) + SetGVGAndEmitUpdateEvent(ctx sdk.Context, gvg *types.GlobalVirtualGroup) error + GetGVGFamily(ctx sdk.Context, familyID uint32) (*types.GlobalVirtualGroupFamily, bool) GetGVG(ctx sdk.Context, gvgID uint32) (*types.GlobalVirtualGroup, bool) SettleAndDistributeGVGFamily(ctx sdk.Context, sp *sptypes.StorageProvider, family *types.GlobalVirtualGroupFamily) error SettleAndDistributeGVG(ctx sdk.Context, gvg *types.GlobalVirtualGroup) error - GetAndCheckGVGFamilyAvailableForNewBucket(ctx sdk.Context, spID, familyID uint32) (*types.GlobalVirtualGroupFamily, error) + GetAndCheckGVGFamilyAvailableForNewBucket(ctx sdk.Context, familyID uint32) (*types.GlobalVirtualGroupFamily, error) GetGlobalVirtualGroupIfAvailable(ctx sdk.Context, gvgID uint32, expectedStoreSize uint64) (*types.GlobalVirtualGroup, error) } diff --git a/x/storage/types/expected_keepers_mocks.go b/x/storage/types/expected_keepers_mocks.go index 5ad3b7cdb..64ce48f30 100644 --- a/x/storage/types/expected_keepers_mocks.go +++ b/x/storage/types/expected_keepers_mocks.go @@ -746,18 +746,18 @@ func (m *MockVirtualGroupKeeper) EXPECT() *MockVirtualGroupKeeperMockRecorder { } // GetAndCheckGVGFamilyAvailableForNewBucket mocks base method. -func (m *MockVirtualGroupKeeper) GetAndCheckGVGFamilyAvailableForNewBucket(ctx types3.Context, spID, familyID uint32) (*types2.GlobalVirtualGroupFamily, error) { +func (m *MockVirtualGroupKeeper) GetAndCheckGVGFamilyAvailableForNewBucket(ctx types3.Context, familyID uint32) (*types2.GlobalVirtualGroupFamily, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAndCheckGVGFamilyAvailableForNewBucket", ctx, spID, familyID) + ret := m.ctrl.Call(m, "GetAndCheckGVGFamilyAvailableForNewBucket", ctx, familyID) ret0, _ := ret[0].(*types2.GlobalVirtualGroupFamily) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAndCheckGVGFamilyAvailableForNewBucket indicates an expected call of GetAndCheckGVGFamilyAvailableForNewBucket. -func (mr *MockVirtualGroupKeeperMockRecorder) GetAndCheckGVGFamilyAvailableForNewBucket(ctx, spID, familyID interface{}) *gomock.Call { +func (mr *MockVirtualGroupKeeperMockRecorder) GetAndCheckGVGFamilyAvailableForNewBucket(ctx, familyID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAndCheckGVGFamilyAvailableForNewBucket", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).GetAndCheckGVGFamilyAvailableForNewBucket), ctx, spID, familyID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAndCheckGVGFamilyAvailableForNewBucket", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).GetAndCheckGVGFamilyAvailableForNewBucket), ctx, familyID) } // GetGVG mocks base method. @@ -776,18 +776,18 @@ func (mr *MockVirtualGroupKeeperMockRecorder) GetGVG(ctx, gvgID interface{}) *go } // GetGVGFamily mocks base method. -func (m *MockVirtualGroupKeeper) GetGVGFamily(ctx types3.Context, spID, familyID uint32) (*types2.GlobalVirtualGroupFamily, bool) { +func (m *MockVirtualGroupKeeper) GetGVGFamily(ctx types3.Context, familyID uint32) (*types2.GlobalVirtualGroupFamily, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetGVGFamily", ctx, spID, familyID) + ret := m.ctrl.Call(m, "GetGVGFamily", ctx, familyID) ret0, _ := ret[0].(*types2.GlobalVirtualGroupFamily) ret1, _ := ret[1].(bool) return ret0, ret1 } // GetGVGFamily indicates an expected call of GetGVGFamily. -func (mr *MockVirtualGroupKeeperMockRecorder) GetGVGFamily(ctx, spID, familyID interface{}) *gomock.Call { +func (mr *MockVirtualGroupKeeperMockRecorder) GetGVGFamily(ctx, familyID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGVGFamily", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).GetGVGFamily), ctx, spID, familyID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGVGFamily", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).GetGVGFamily), ctx, familyID) } // GetGlobalVirtualGroupIfAvailable mocks base method. @@ -805,16 +805,18 @@ func (mr *MockVirtualGroupKeeperMockRecorder) GetGlobalVirtualGroupIfAvailable(c return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGlobalVirtualGroupIfAvailable", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).GetGlobalVirtualGroupIfAvailable), ctx, gvgID, expectedStoreSize) } -// SetGVG mocks base method. -func (m *MockVirtualGroupKeeper) SetGVG(ctx types3.Context, gvg *types2.GlobalVirtualGroup) { +// SetGVGAndEmitUpdateEvent mocks base method. +func (m *MockVirtualGroupKeeper) SetGVGAndEmitUpdateEvent(ctx types3.Context, gvg *types2.GlobalVirtualGroup) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetGVG", ctx, gvg) + ret := m.ctrl.Call(m, "SetGVGAndEmitUpdateEvent", ctx, gvg) + ret0, _ := ret[0].(error) + return ret0 } -// SetGVG indicates an expected call of SetGVG. -func (mr *MockVirtualGroupKeeperMockRecorder) SetGVG(ctx, gvg interface{}) *gomock.Call { +// SetGVGAndEmitUpdateEvent indicates an expected call of SetGVGAndEmitUpdateEvent. +func (mr *MockVirtualGroupKeeperMockRecorder) SetGVGAndEmitUpdateEvent(ctx, gvg interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetGVG", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).SetGVG), ctx, gvg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetGVGAndEmitUpdateEvent", reflect.TypeOf((*MockVirtualGroupKeeper)(nil).SetGVGAndEmitUpdateEvent), ctx, gvg) } // SettleAndDistributeGVG mocks base method. diff --git a/x/storage/types/message.go b/x/storage/types/message.go index 81d040ab8..e2b937fe6 100644 --- a/x/storage/types/message.go +++ b/x/storage/types/message.go @@ -880,6 +880,9 @@ func (msg *MsgCreateGroup) ValidateBasic() error { if len(msg.Members) > MaxGroupMemberLimitOnce { return gnfderrors.ErrInvalidParameter.Wrapf("Once update group member limit exceeded") } + if len(msg.Extra) > MaxGroupExtraInfoLimit { + return errors.Wrapf(gnfderrors.ErrInvalidParameter, "extra is too long with length %d, limit to %d", len(msg.Extra), MaxGroupExtraInfoLimit) + } return nil } @@ -1106,7 +1109,7 @@ func (msg *MsgUpdateGroupExtra) ValidateBasic() error { return err } if len(msg.Extra) > MaxGroupExtraInfoLimit { - return errors.Wrapf(gnfderrors.ErrInvalidParameter, "extra is too long with length %d", len(msg.Extra)) + return errors.Wrapf(gnfderrors.ErrInvalidParameter, "extra is too long with length %d, limit to %d", len(msg.Extra), MaxGroupExtraInfoLimit) } return nil diff --git a/x/storage/types/query.pb.go b/x/storage/types/query.pb.go index ee814f80c..8a84a7bcb 100644 --- a/x/storage/types/query.pb.go +++ b/x/storage/types/query.pb.go @@ -1713,6 +1713,190 @@ func (m *QueryLockFeeResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryLockFeeResponse proto.InternalMessageInfo +type QueryHeadBucketExtraRequest struct { + BucketName string `protobuf:"bytes,1,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` +} + +func (m *QueryHeadBucketExtraRequest) Reset() { *m = QueryHeadBucketExtraRequest{} } +func (m *QueryHeadBucketExtraRequest) String() string { return proto.CompactTextString(m) } +func (*QueryHeadBucketExtraRequest) ProtoMessage() {} +func (*QueryHeadBucketExtraRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b1b80b580af04cb0, []int{35} +} +func (m *QueryHeadBucketExtraRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryHeadBucketExtraRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryHeadBucketExtraRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryHeadBucketExtraRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryHeadBucketExtraRequest.Merge(m, src) +} +func (m *QueryHeadBucketExtraRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryHeadBucketExtraRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryHeadBucketExtraRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryHeadBucketExtraRequest proto.InternalMessageInfo + +func (m *QueryHeadBucketExtraRequest) GetBucketName() string { + if m != nil { + return m.BucketName + } + return "" +} + +type QueryHeadBucketExtraResponse struct { + ExtraInfo *InternalBucketInfo `protobuf:"bytes,1,opt,name=extra_info,json=extraInfo,proto3" json:"extra_info,omitempty"` +} + +func (m *QueryHeadBucketExtraResponse) Reset() { *m = QueryHeadBucketExtraResponse{} } +func (m *QueryHeadBucketExtraResponse) String() string { return proto.CompactTextString(m) } +func (*QueryHeadBucketExtraResponse) ProtoMessage() {} +func (*QueryHeadBucketExtraResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_b1b80b580af04cb0, []int{36} +} +func (m *QueryHeadBucketExtraResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryHeadBucketExtraResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryHeadBucketExtraResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryHeadBucketExtraResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryHeadBucketExtraResponse.Merge(m, src) +} +func (m *QueryHeadBucketExtraResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryHeadBucketExtraResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryHeadBucketExtraResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryHeadBucketExtraResponse proto.InternalMessageInfo + +func (m *QueryHeadBucketExtraResponse) GetExtraInfo() *InternalBucketInfo { + if m != nil { + return m.ExtraInfo + } + return nil +} + +type QueryIsPriceChangedRequest struct { + BucketName string `protobuf:"bytes,1,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` +} + +func (m *QueryIsPriceChangedRequest) Reset() { *m = QueryIsPriceChangedRequest{} } +func (m *QueryIsPriceChangedRequest) String() string { return proto.CompactTextString(m) } +func (*QueryIsPriceChangedRequest) ProtoMessage() {} +func (*QueryIsPriceChangedRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b1b80b580af04cb0, []int{37} +} +func (m *QueryIsPriceChangedRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIsPriceChangedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIsPriceChangedRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryIsPriceChangedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIsPriceChangedRequest.Merge(m, src) +} +func (m *QueryIsPriceChangedRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryIsPriceChangedRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIsPriceChangedRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIsPriceChangedRequest proto.InternalMessageInfo + +func (m *QueryIsPriceChangedRequest) GetBucketName() string { + if m != nil { + return m.BucketName + } + return "" +} + +type QueryIsPriceChangedResponse struct { + Changed bool `protobuf:"varint,1,opt,name=changed,proto3" json:"changed,omitempty"` + CurrentReadPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=current_read_price,json=currentReadPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"current_read_price"` + CurrentPrimaryStorePrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=current_primary_store_price,json=currentPrimaryStorePrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"current_primary_store_price"` + CurrentSecondaryStorePrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=current_secondary_store_price,json=currentSecondaryStorePrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"current_secondary_store_price"` + CurrentValidatorTaxRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=current_validator_tax_rate,json=currentValidatorTaxRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"current_validator_tax_rate"` + NewReadPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=new_read_price,json=newReadPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_read_price"` + NewPrimaryStorePrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=new_primary_store_price,json=newPrimaryStorePrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_primary_store_price"` + NewSecondaryStorePrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,8,opt,name=new_secondary_store_price,json=newSecondaryStorePrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_secondary_store_price"` + NewValidatorTaxRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,9,opt,name=new_validator_tax_rate,json=newValidatorTaxRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_validator_tax_rate"` +} + +func (m *QueryIsPriceChangedResponse) Reset() { *m = QueryIsPriceChangedResponse{} } +func (m *QueryIsPriceChangedResponse) String() string { return proto.CompactTextString(m) } +func (*QueryIsPriceChangedResponse) ProtoMessage() {} +func (*QueryIsPriceChangedResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_b1b80b580af04cb0, []int{38} +} +func (m *QueryIsPriceChangedResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIsPriceChangedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIsPriceChangedResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryIsPriceChangedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIsPriceChangedResponse.Merge(m, src) +} +func (m *QueryIsPriceChangedResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryIsPriceChangedResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIsPriceChangedResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIsPriceChangedResponse proto.InternalMessageInfo + +func (m *QueryIsPriceChangedResponse) GetChanged() bool { + if m != nil { + return m.Changed + } + return false +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "greenfield.storage.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "greenfield.storage.QueryParamsResponse") @@ -1749,135 +1933,160 @@ func init() { proto.RegisterType((*QueryPolicyByIdResponse)(nil), "greenfield.storage.QueryPolicyByIdResponse") proto.RegisterType((*QueryLockFeeRequest)(nil), "greenfield.storage.QueryLockFeeRequest") proto.RegisterType((*QueryLockFeeResponse)(nil), "greenfield.storage.QueryLockFeeResponse") + proto.RegisterType((*QueryHeadBucketExtraRequest)(nil), "greenfield.storage.QueryHeadBucketExtraRequest") + proto.RegisterType((*QueryHeadBucketExtraResponse)(nil), "greenfield.storage.QueryHeadBucketExtraResponse") + proto.RegisterType((*QueryIsPriceChangedRequest)(nil), "greenfield.storage.QueryIsPriceChangedRequest") + proto.RegisterType((*QueryIsPriceChangedResponse)(nil), "greenfield.storage.QueryIsPriceChangedResponse") } func init() { proto.RegisterFile("greenfield/storage/query.proto", fileDescriptor_b1b80b580af04cb0) } var fileDescriptor_b1b80b580af04cb0 = []byte{ - // 1956 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x8f, 0x1c, 0x47, - 0x15, 0x77, 0xef, 0x9a, 0x65, 0xb7, 0x66, 0xb1, 0x43, 0xb1, 0x01, 0xa7, 0xb3, 0x1e, 0xdb, 0x1d, - 0xb0, 0x37, 0x8e, 0x77, 0xda, 0xeb, 0xc4, 0x88, 0x55, 0x3e, 0xd0, 0x0e, 0xf1, 0x2e, 0x23, 0xf9, - 0x8b, 0xf1, 0xca, 0x88, 0x95, 0x50, 0xab, 0xa6, 0xbb, 0x66, 0xdc, 0xec, 0x74, 0x57, 0xbb, 0xbb, - 0xc7, 0x30, 0x19, 0xcd, 0x81, 0x5c, 0xe0, 0x88, 0x40, 0x48, 0x11, 0x22, 0x12, 0x08, 0x81, 0x80, - 0x0b, 0x97, 0x5c, 0x38, 0x71, 0xe1, 0x10, 0x09, 0x21, 0x45, 0xe1, 0x82, 0x72, 0x88, 0x90, 0xcd, - 0x1f, 0x12, 0x75, 0xd5, 0xeb, 0xee, 0xea, 0xaf, 0xe9, 0xd9, 0xec, 0x9e, 0x76, 0xba, 0xfa, 0xbd, - 0x57, 0xbf, 0xf7, 0x51, 0xaf, 0xde, 0xaf, 0x17, 0x35, 0x07, 0x3e, 0xa5, 0x6e, 0xdf, 0xa6, 0x43, - 0x4b, 0x0f, 0x42, 0xe6, 0x93, 0x01, 0xd5, 0x1f, 0x8f, 0xa8, 0x3f, 0x6e, 0x79, 0x3e, 0x0b, 0x19, - 0xc6, 0xe9, 0xfb, 0x16, 0xbc, 0x57, 0xaf, 0x9a, 0x2c, 0x70, 0x58, 0xa0, 0xf7, 0x48, 0x00, 0xc2, - 0xfa, 0x93, 0xad, 0x1e, 0x0d, 0xc9, 0x96, 0xee, 0x91, 0x81, 0xed, 0x92, 0xd0, 0x66, 0xae, 0xd0, - 0x57, 0x5f, 0x10, 0xb2, 0x06, 0x7f, 0xd2, 0xc5, 0x03, 0xbc, 0x5a, 0x1b, 0xb0, 0x01, 0x13, 0xeb, - 0xd1, 0x2f, 0x58, 0x5d, 0x1f, 0x30, 0x36, 0x18, 0x52, 0x9d, 0x78, 0xb6, 0x4e, 0x5c, 0x97, 0x85, - 0xdc, 0x5a, 0xac, 0xa3, 0x49, 0x70, 0x3d, 0xea, 0x3b, 0x76, 0x10, 0xd8, 0xcc, 0xd5, 0x4d, 0xe6, - 0x38, 0xc9, 0x96, 0x97, 0xca, 0x65, 0xc2, 0xb1, 0x47, 0x63, 0x33, 0x17, 0x4a, 0xbc, 0xf6, 0x88, - 0x4f, 0x9c, 0x58, 0xa0, 0x2c, 0x2c, 0xb2, 0x81, 0x97, 0xa4, 0xf7, 0x4f, 0x6c, 0x3f, 0x1c, 0x91, - 0xe1, 0xc0, 0x67, 0x23, 0x4f, 0x16, 0xd2, 0xd6, 0x10, 0xfe, 0x5e, 0x14, 0x9d, 0xfb, 0xdc, 0x72, - 0x97, 0x3e, 0x1e, 0xd1, 0x20, 0xd4, 0xee, 0xa1, 0xaf, 0x64, 0x56, 0x03, 0x8f, 0xb9, 0x01, 0xc5, - 0xdf, 0x42, 0x4b, 0x02, 0xc1, 0x39, 0xe5, 0xa2, 0xb2, 0xd1, 0xb8, 0xa1, 0xb6, 0x8a, 0x91, 0x6f, - 0x09, 0x9d, 0xf6, 0xe9, 0x0f, 0x3f, 0xbd, 0x70, 0xaa, 0x0b, 0xf2, 0xda, 0x9b, 0xe8, 0xbc, 0x64, - 0xb0, 0x3d, 0xde, 0xb7, 0x1d, 0x1a, 0x84, 0xc4, 0xf1, 0x60, 0x47, 0xbc, 0x8e, 0x56, 0xc2, 0x78, - 0x8d, 0x5b, 0x5f, 0xec, 0xa6, 0x0b, 0xda, 0x01, 0x6a, 0x56, 0xa9, 0x1f, 0x1b, 0xda, 0x36, 0xfa, - 0x2a, 0xb7, 0xfd, 0x5d, 0x4a, 0xac, 0xf6, 0xc8, 0x3c, 0xa4, 0x61, 0x8c, 0xe9, 0x02, 0x6a, 0xf4, - 0xf8, 0x82, 0xe1, 0x12, 0x87, 0x72, 0xc3, 0x2b, 0x5d, 0x24, 0x96, 0xee, 0x12, 0x87, 0x6a, 0xdb, - 0x48, 0xcd, 0xa9, 0xb6, 0xc7, 0x1d, 0x2b, 0x56, 0x7f, 0x11, 0xad, 0x80, 0xba, 0x6d, 0x81, 0xf2, - 0xb2, 0x58, 0xe8, 0x58, 0xda, 0x01, 0xfa, 0x5a, 0x61, 0x57, 0x70, 0xe5, 0xdb, 0xc9, 0xb6, 0xb6, - 0xdb, 0x67, 0xe0, 0x4f, 0xb3, 0xcc, 0x1f, 0xa1, 0xd8, 0x71, 0xfb, 0x2c, 0x86, 0x15, 0xfd, 0xd6, - 0x0e, 0x24, 0x8f, 0xee, 0xf5, 0x7e, 0x44, 0xcd, 0xb9, 0x3d, 0x8a, 0x04, 0x18, 0xd7, 0x10, 0x02, - 0x0b, 0x42, 0x40, 0x2c, 0x15, 0x5c, 0x16, 0xb6, 0x73, 0x2e, 0x83, 0x7a, 0xea, 0xb2, 0x58, 0xe8, - 0x58, 0xda, 0xdf, 0x15, 0xc9, 0xe7, 0x18, 0x57, 0xea, 0x73, 0xac, 0x58, 0xe3, 0xb3, 0x50, 0x14, - 0x3e, 0xb3, 0xe4, 0x37, 0xfe, 0x21, 0x5a, 0x1b, 0x0c, 0x59, 0x8f, 0x0c, 0x0d, 0x28, 0x75, 0x83, - 0xd7, 0x3a, 0xf7, 0xa0, 0x71, 0xe3, 0x15, 0xd9, 0x92, 0x7c, 0x16, 0x5a, 0x7b, 0x5c, 0xe9, 0xa1, - 0x58, 0xda, 0x8b, 0x96, 0xba, 0x78, 0x50, 0x58, 0xd3, 0x08, 0x40, 0xbf, 0x6d, 0x07, 0xa1, 0x88, - 0x7a, 0x7c, 0x56, 0xf0, 0x2e, 0x42, 0x69, 0x47, 0x01, 0xe4, 0x97, 0x5b, 0xd0, 0x45, 0xa2, 0xf6, - 0xd3, 0x12, 0xbd, 0x0a, 0xda, 0x4f, 0xeb, 0x3e, 0x19, 0x50, 0xd0, 0xed, 0x4a, 0x9a, 0xda, 0x9f, - 0x14, 0x74, 0xae, 0xb8, 0x07, 0xc4, 0x67, 0x07, 0xad, 0x4a, 0x35, 0x11, 0x15, 0xf9, 0xe2, 0x1c, - 0x45, 0xd1, 0x48, 0x8b, 0x22, 0xc0, 0x7b, 0x19, 0x9c, 0x22, 0x2e, 0x57, 0x6a, 0x71, 0x8a, 0xfd, - 0x33, 0x40, 0xdf, 0x55, 0xa4, 0x60, 0x88, 0x74, 0x9c, 0x74, 0x30, 0xf2, 0x85, 0xba, 0x50, 0x38, - 0x7a, 0x3f, 0x57, 0xd0, 0xa5, 0x3c, 0x88, 0xf6, 0x18, 0x7c, 0xb7, 0x4e, 0x1a, 0x4e, 0xe6, 0x28, - 0x2f, 0xe4, 0x8e, 0x72, 0x26, 0x71, 0x49, 0x3c, 0xd2, 0xc4, 0x49, 0x85, 0x3d, 0x33, 0x71, 0x52, - 0x65, 0x37, 0xd2, 0xca, 0x3e, 0xc1, 0xc4, 0x5d, 0x43, 0x67, 0x39, 0xce, 0xbb, 0xbb, 0xfb, 0x71, - 0x80, 0x5e, 0x40, 0xcb, 0x21, 0x3b, 0xa4, 0x6e, 0x7a, 0x5e, 0xbf, 0xc8, 0x9f, 0x3b, 0x96, 0xf6, - 0x03, 0xe8, 0x22, 0x22, 0xa6, 0x5c, 0x27, 0x39, 0xac, 0x2b, 0x0e, 0x0d, 0x89, 0x61, 0x91, 0x90, - 0x40, 0x50, 0xb5, 0xea, 0x4a, 0xbc, 0x43, 0x43, 0xf2, 0x36, 0x09, 0x49, 0x77, 0xd9, 0x81, 0x5f, - 0x89, 0x69, 0xe1, 0xf1, 0xe7, 0x31, 0x2d, 0x34, 0x4b, 0x4c, 0x7f, 0x1f, 0x3d, 0xcf, 0x4d, 0xf3, - 0x63, 0x2b, 0x5b, 0x7e, 0xab, 0x68, 0xf9, 0x52, 0x99, 0x65, 0xae, 0x58, 0x62, 0xf8, 0xa7, 0x0a, - 0x5a, 0x17, 0x77, 0x10, 0x1b, 0xda, 0xe6, 0x78, 0x97, 0xf9, 0x3b, 0xa6, 0xc9, 0x46, 0x6e, 0xd2, - 0x5b, 0x55, 0xb4, 0xec, 0xd3, 0x80, 0x8d, 0x7c, 0x33, 0x6e, 0xac, 0xc9, 0x33, 0xbe, 0x85, 0xbe, - 0xec, 0xf9, 0xb6, 0x6b, 0xda, 0x1e, 0x19, 0x1a, 0xc4, 0xb2, 0x7c, 0x1a, 0x04, 0xa2, 0x8e, 0xda, - 0xe7, 0x3e, 0xfe, 0x60, 0x73, 0x0d, 0x92, 0xb9, 0x23, 0xde, 0x3c, 0x08, 0x7d, 0xdb, 0x1d, 0x74, - 0x9f, 0x4b, 0x54, 0x60, 0x5d, 0x7b, 0x18, 0xdf, 0xa2, 0x05, 0x08, 0xe0, 0xe4, 0x4d, 0xb4, 0xe4, - 0xf1, 0x77, 0xe0, 0xe1, 0x79, 0xd9, 0xc3, 0x74, 0xce, 0x68, 0x09, 0x03, 0x5d, 0x10, 0xd6, 0x3e, - 0x89, 0x7d, 0x7b, 0x48, 0x7d, 0xbb, 0x3f, 0xbe, 0x9f, 0x08, 0xc6, 0xbe, 0xbd, 0x86, 0x96, 0x99, - 0x47, 0x7d, 0x12, 0x32, 0x5f, 0xf8, 0x36, 0x03, 0x76, 0x22, 0x59, 0x7b, 0x88, 0xf3, 0xb7, 0xcd, - 0x62, 0xfe, 0xb6, 0xc1, 0x6d, 0xd4, 0x20, 0x66, 0x54, 0xbb, 0x46, 0x34, 0xb3, 0x9c, 0x3b, 0x7d, - 0x51, 0xd9, 0x38, 0x93, 0x4d, 0x9b, 0xe4, 0xd4, 0x0e, 0x97, 0xdc, 0x1f, 0x7b, 0xb4, 0x8b, 0x48, - 0xf2, 0x3b, 0x09, 0x5a, 0xd1, 0xb7, 0x34, 0x68, 0xb4, 0xdf, 0xa7, 0x66, 0xc8, 0x5d, 0x3b, 0x53, - 0x19, 0xb4, 0x5b, 0x5c, 0xa8, 0x0b, 0xc2, 0xda, 0x63, 0xa8, 0xb4, 0xe8, 0x36, 0x13, 0x17, 0x07, - 0x04, 0x6b, 0x1b, 0x35, 0xf8, 0xdd, 0x62, 0xb0, 0x1f, 0xbb, 0xb4, 0x3e, 0x5e, 0x88, 0x0b, 0xdf, - 0x8b, 0x64, 0xf1, 0x79, 0x24, 0x9e, 0xe4, 0x80, 0xad, 0xf0, 0x15, 0xde, 0xf4, 0x1e, 0x4a, 0x17, - 0x3b, 0x6c, 0x09, 0x3e, 0xbc, 0x11, 0x2b, 0x4a, 0xd7, 0xe7, 0xf9, 0xca, 0xf2, 0xe6, 0x3d, 0x46, - 0xd8, 0xe5, 0x03, 0xc3, 0x6f, 0x14, 0xf0, 0x25, 0xea, 0x60, 0x19, 0x5f, 0x4e, 0xaa, 0x81, 0xe6, - 0x62, 0xb2, 0x30, 0x7f, 0x4c, 0xb4, 0xdf, 0x2b, 0xe0, 0xb5, 0x04, 0x0e, 0xbc, 0xde, 0x2b, 0x41, - 0xf7, 0x79, 0x3a, 0x23, 0x7e, 0x2b, 0x86, 0x27, 0x9a, 0xf4, 0x02, 0x6f, 0xd2, 0x35, 0xf1, 0x43, - 0x49, 0xfc, 0x02, 0xed, 0x2f, 0x0a, 0x7a, 0x31, 0x9b, 0x99, 0x3b, 0xd4, 0xe9, 0x51, 0x3f, 0x0e, - 0xe3, 0x75, 0xb4, 0xe4, 0xf0, 0x85, 0xda, 0x6a, 0x00, 0xb9, 0x63, 0x04, 0x2c, 0x57, 0x44, 0x8b, - 0xf9, 0x22, 0xa2, 0x70, 0xd6, 0x0b, 0x50, 0x21, 0xa8, 0xb7, 0xd0, 0xaa, 0x50, 0x97, 0x10, 0xe7, - 0xba, 0xb0, 0x74, 0x28, 0x64, 0x0b, 0x02, 0xb1, 0x78, 0xd0, 0xfa, 0x30, 0x28, 0x26, 0xbd, 0x2a, - 0x53, 0x57, 0xb3, 0x9a, 0xe5, 0x35, 0x84, 0xd3, 0x66, 0x09, 0x69, 0x89, 0x6f, 0xdd, 0xb4, 0x27, - 0x8a, 0x44, 0x58, 0xda, 0x3e, 0x44, 0x3e, 0xbf, 0xcf, 0xf1, 0x3a, 0xe2, 0x4d, 0xa8, 0x39, 0xb1, - 0x9c, 0x1b, 0x71, 0x85, 0x8c, 0x34, 0xe2, 0x8a, 0x85, 0x8e, 0xa5, 0xdd, 0x87, 0xc9, 0x48, 0x56, - 0x3b, 0x1e, 0x90, 0xf7, 0x15, 0xa0, 0x62, 0xb7, 0x99, 0x79, 0xb8, 0x4b, 0x69, 0x7a, 0x30, 0xa3, - 0x20, 0x39, 0xc4, 0x1f, 0x1b, 0x81, 0x97, 0x5c, 0x29, 0xca, 0x1c, 0x57, 0x4a, 0xa4, 0xf3, 0xc0, - 0x83, 0xf5, 0xc8, 0x1d, 0xd3, 0xa7, 0x24, 0xa4, 0x06, 0x09, 0x79, 0x8c, 0x17, 0xbb, 0xcb, 0x62, - 0x61, 0x27, 0xc4, 0x97, 0xd0, 0xaa, 0x47, 0xc6, 0x43, 0x46, 0x2c, 0x23, 0xb0, 0xdf, 0x11, 0xb5, - 0x74, 0xba, 0xdb, 0x80, 0xb5, 0x07, 0xf6, 0x3b, 0x54, 0x1b, 0xa2, 0xb5, 0x2c, 0x3c, 0x70, 0x77, - 0x1f, 0x2d, 0x11, 0x27, 0xba, 0x9b, 0x00, 0xd3, 0x1b, 0x11, 0xe7, 0xfa, 0xe4, 0xd3, 0x0b, 0x97, - 0x07, 0x76, 0xf8, 0x68, 0xd4, 0x6b, 0x99, 0xcc, 0x01, 0xa6, 0x0d, 0x7f, 0x36, 0x03, 0xeb, 0x10, - 0x98, 0x69, 0xc7, 0x0d, 0x3f, 0xfe, 0x60, 0x13, 0x81, 0x07, 0x1d, 0x37, 0xec, 0x82, 0xad, 0x1b, - 0xef, 0xab, 0xe8, 0x0b, 0x7c, 0x3b, 0x3c, 0x45, 0x4b, 0x82, 0xcd, 0xe1, 0xcb, 0x65, 0xc7, 0xb4, - 0xc8, 0x69, 0xd5, 0x2b, 0xb5, 0x72, 0x02, 0xba, 0xa6, 0xbd, 0xfb, 0x9f, 0xff, 0xff, 0x6a, 0x61, - 0x1d, 0xab, 0x7a, 0x25, 0x03, 0xc7, 0x7f, 0x8b, 0x9b, 0x52, 0x81, 0x91, 0xe2, 0xad, 0x9a, 0x7d, - 0x8a, 0xe4, 0x57, 0xbd, 0x71, 0x14, 0x15, 0x40, 0xd9, 0xe2, 0x28, 0x37, 0xf0, 0xe5, 0x6a, 0x94, - 0xfa, 0x24, 0x61, 0xd0, 0x53, 0xfc, 0x5b, 0x05, 0xa1, 0x94, 0x6c, 0xe2, 0xab, 0x95, 0x5b, 0x16, - 0x78, 0xb0, 0xfa, 0xca, 0x5c, 0xb2, 0x80, 0xeb, 0x26, 0xc7, 0xa5, 0xe3, 0xcd, 0x32, 0x5c, 0x8f, - 0x28, 0xb1, 0x0c, 0x31, 0x00, 0xe8, 0x13, 0x69, 0x36, 0x98, 0xe2, 0x3f, 0x2b, 0xe8, 0x4c, 0x96, - 0x46, 0xe3, 0xd6, 0x1c, 0xdb, 0x4a, 0x27, 0xf3, 0x68, 0x30, 0xb7, 0x39, 0xcc, 0x57, 0xf1, 0x56, - 0x0d, 0x4c, 0xa3, 0x17, 0x1d, 0xf4, 0x04, 0xac, 0x6d, 0x4d, 0xf1, 0x7b, 0x0a, 0xfa, 0x52, 0x6a, - 0xf1, 0xee, 0xee, 0x3e, 0x7e, 0xa9, 0x72, 0xe7, 0x74, 0xd4, 0x56, 0xab, 0x23, 0x5e, 0x98, 0xb0, - 0xb5, 0x6f, 0x72, 0x74, 0xd7, 0x71, 0xab, 0x0e, 0x9d, 0xdb, 0x0f, 0xf5, 0x49, 0x3c, 0xc1, 0x4f, - 0xf1, 0x5f, 0x21, 0xc9, 0x62, 0x3c, 0xae, 0x49, 0x72, 0xe6, 0xd3, 0x40, 0x4d, 0xf4, 0xb2, 0x74, - 0x5d, 0xfb, 0x0e, 0xc7, 0xf7, 0x26, 0x7e, 0xbd, 0x12, 0x9f, 0x18, 0xe2, 0xb2, 0x49, 0xd6, 0x27, - 0xd2, 0xb4, 0x97, 0xa6, 0x3c, 0xfd, 0x8c, 0x50, 0x93, 0xf2, 0xc2, 0xf7, 0x86, 0xa3, 0x81, 0xae, - 0x4f, 0x39, 0xc0, 0x83, 0x94, 0x27, 0x5f, 0x32, 0xd2, 0x94, 0x27, 0x84, 0xe5, 0xb8, 0x29, 0x2f, - 0x30, 0x9f, 0x39, 0x52, 0x1e, 0x07, 0x2f, 0x9b, 0xf2, 0x5f, 0x2a, 0xa8, 0x21, 0x7d, 0x31, 0xc0, - 0xd5, 0x21, 0x29, 0x7e, 0xbb, 0x50, 0xaf, 0xcd, 0x27, 0x0c, 0x10, 0x37, 0x38, 0x44, 0x0d, 0x5f, - 0x2c, 0x83, 0x38, 0xb4, 0x83, 0x10, 0xaa, 0x32, 0xc0, 0xbf, 0x03, 0x50, 0xc0, 0x86, 0x6b, 0x40, - 0x65, 0xbf, 0x21, 0xd4, 0x80, 0xca, 0x11, 0xec, 0xd9, 0x71, 0xe3, 0xa0, 0x44, 0xdc, 0x82, 0x5c, - 0xc3, 0xf9, 0x87, 0x82, 0x9e, 0x2f, 0xfd, 0x76, 0x80, 0x6f, 0xce, 0xb3, 0x7f, 0xe1, 0x5b, 0xc3, - 0x11, 0x61, 0xef, 0x70, 0xd8, 0xaf, 0xe3, 0xed, 0x3a, 0xd8, 0x51, 0x35, 0x26, 0xcd, 0x27, 0xd3, - 0x87, 0x7e, 0xad, 0xa0, 0xd5, 0x64, 0x88, 0x9b, 0xbb, 0x26, 0x5f, 0xae, 0x14, 0xca, 0x53, 0xe6, - 0x39, 0x5a, 0x39, 0xcc, 0x99, 0xd9, 0x8a, 0xfc, 0x57, 0xcc, 0x26, 0xf2, 0x34, 0x15, 0x5f, 0xaf, - 0xbe, 0xe7, 0xca, 0x49, 0xb5, 0xba, 0x75, 0x04, 0x0d, 0x40, 0x7d, 0x87, 0xa3, 0xde, 0xc3, 0xb7, - 0x4a, 0x2f, 0x46, 0x31, 0xba, 0xf5, 0x99, 0x6f, 0x10, 0xa1, 0xa7, 0x4f, 0xe2, 0xc1, 0x73, 0xaa, - 0x4f, 0x0a, 0x24, 0x7d, 0x8a, 0xff, 0xad, 0xa0, 0xe7, 0xf2, 0xd4, 0x71, 0x86, 0x23, 0x15, 0x0c, - 0x7a, 0x86, 0x23, 0x55, 0xbc, 0x54, 0xdb, 0xe7, 0x8e, 0xdc, 0xc5, 0xb7, 0xcb, 0x1c, 0x79, 0xc2, - 0xb5, 0x0c, 0xe9, 0x7f, 0x07, 0x93, 0x98, 0x77, 0x4f, 0xf3, 0x5d, 0x57, 0xa2, 0xd0, 0x53, 0xfc, - 0x47, 0x05, 0xad, 0x24, 0x55, 0x83, 0x5f, 0x9e, 0xd9, 0x40, 0xe5, 0x91, 0x5d, 0xbd, 0x3a, 0x8f, - 0xe8, 0x3c, 0xd5, 0x9d, 0x56, 0x8e, 0x3e, 0x91, 0x38, 0xce, 0x34, 0x7e, 0x12, 0xe7, 0xf3, 0x3d, - 0x05, 0xad, 0x24, 0x8c, 0x6f, 0x06, 0xce, 0x3c, 0x65, 0x9d, 0x81, 0xb3, 0x40, 0x20, 0xb5, 0xd7, - 0x38, 0xce, 0x16, 0xbe, 0x56, 0x79, 0x0a, 0x4b, 0x70, 0xe2, 0x3f, 0x28, 0xe8, 0x6c, 0x8e, 0x3d, - 0x61, 0xbd, 0x3e, 0x3a, 0x19, 0x4a, 0xa8, 0x5e, 0x9f, 0x5f, 0x01, 0xc0, 0x6e, 0x72, 0xb0, 0x57, - 0xf0, 0x37, 0x6a, 0x8e, 0x23, 0x30, 0xc8, 0x7f, 0xc6, 0xcc, 0x21, 0xcb, 0x8c, 0x66, 0xdc, 0xb1, - 0xa5, 0x54, 0x4d, 0xd5, 0xe7, 0x96, 0x07, 0x9c, 0xb7, 0x39, 0xce, 0x5d, 0xfc, 0x76, 0xcd, 0x01, - 0x84, 0xd0, 0x96, 0x1e, 0xbf, 0x98, 0xf6, 0x4d, 0xa3, 0xab, 0xe4, 0x6c, 0x8e, 0x53, 0xcd, 0x98, - 0x6b, 0x0a, 0x7c, 0x6d, 0xc6, 0x88, 0x50, 0x24, 0x69, 0xb3, 0xeb, 0x01, 0xa0, 0xc3, 0x74, 0x90, - 0x90, 0xc0, 0x29, 0xfe, 0x99, 0x82, 0x56, 0x65, 0x12, 0x84, 0xab, 0xa9, 0x46, 0x96, 0xc5, 0xa9, - 0x1b, 0xf5, 0x82, 0x80, 0xec, 0xeb, 0x1c, 0x59, 0x13, 0xaf, 0x97, 0x56, 0x2a, 0x33, 0x0f, 0x8d, - 0x3e, 0xa5, 0xed, 0xce, 0x87, 0x4f, 0x9b, 0xca, 0x47, 0x4f, 0x9b, 0xca, 0xff, 0x9e, 0x36, 0x95, - 0x5f, 0x3c, 0x6b, 0x9e, 0xfa, 0xe8, 0x59, 0xf3, 0xd4, 0x7f, 0x9f, 0x35, 0x4f, 0x1d, 0xe8, 0x12, - 0xef, 0xea, 0xb9, 0xbd, 0x4d, 0xf3, 0x11, 0xb1, 0x5d, 0xd9, 0xd6, 0x4f, 0xb2, 0xff, 0x43, 0xec, - 0x2d, 0xf1, 0xff, 0x0f, 0xbe, 0xfa, 0x59, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x18, 0x28, 0xf4, - 0x7d, 0x1d, 0x00, 0x00, + // 2290 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0xdb, 0x6f, 0xdc, 0x58, + 0x19, 0xaf, 0x93, 0x6e, 0x9a, 0x9c, 0x09, 0x6d, 0x39, 0x9b, 0xdd, 0xa6, 0xd3, 0x66, 0xda, 0x7a, + 0xa1, 0xcd, 0x76, 0x9b, 0x71, 0x93, 0x36, 0x88, 0xd0, 0x6d, 0x51, 0xb2, 0x4d, 0xc2, 0x48, 0xbd, + 0x04, 0x37, 0x0a, 0xa2, 0x12, 0xb2, 0xce, 0xd8, 0x67, 0xa6, 0xde, 0xcc, 0xd8, 0xae, 0xed, 0x69, + 0x3a, 0x3b, 0x1a, 0x21, 0xf6, 0x01, 0x78, 0x44, 0x20, 0xa4, 0x15, 0x02, 0x09, 0x84, 0x40, 0xc0, + 0x0b, 0x02, 0xed, 0x0b, 0x4f, 0xbc, 0xf0, 0xb0, 0x12, 0x42, 0x5a, 0x2d, 0x2f, 0x68, 0x1f, 0x56, + 0xd0, 0xf2, 0x87, 0xac, 0x7c, 0xce, 0x67, 0xfb, 0xf8, 0x32, 0xe3, 0xc9, 0x66, 0x9e, 0x3a, 0x3e, + 0xfe, 0x2e, 0xbf, 0xef, 0x72, 0xbe, 0x73, 0xfc, 0x6b, 0x50, 0xa5, 0xe9, 0x52, 0x6a, 0x35, 0x4c, + 0xda, 0x32, 0x14, 0xcf, 0xb7, 0x5d, 0xd2, 0xa4, 0xca, 0xd3, 0x0e, 0x75, 0xbb, 0x55, 0xc7, 0xb5, + 0x7d, 0x1b, 0xe3, 0xf8, 0x7d, 0x15, 0xde, 0x97, 0xaf, 0xea, 0xb6, 0xd7, 0xb6, 0x3d, 0xa5, 0x4e, + 0x3c, 0x10, 0x56, 0x9e, 0x2d, 0xd7, 0xa9, 0x4f, 0x96, 0x15, 0x87, 0x34, 0x4d, 0x8b, 0xf8, 0xa6, + 0x6d, 0x71, 0xfd, 0xf2, 0x59, 0x2e, 0xab, 0xb1, 0x27, 0x85, 0x3f, 0xc0, 0xab, 0xb9, 0xa6, 0xdd, + 0xb4, 0xf9, 0x7a, 0xf0, 0x0b, 0x56, 0xcf, 0x37, 0x6d, 0xbb, 0xd9, 0xa2, 0x0a, 0x71, 0x4c, 0x85, + 0x58, 0x96, 0xed, 0x33, 0x6b, 0xa1, 0x8e, 0x2c, 0xc0, 0x75, 0xa8, 0xdb, 0x36, 0x3d, 0xcf, 0xb4, + 0x2d, 0x45, 0xb7, 0xdb, 0xed, 0xc8, 0xe5, 0xa5, 0x7c, 0x19, 0xbf, 0xeb, 0xd0, 0xd0, 0xcc, 0x85, + 0x9c, 0xa8, 0x1d, 0xe2, 0x92, 0x76, 0x28, 0x90, 0x97, 0x16, 0xd1, 0xc0, 0x1b, 0xc2, 0xfb, 0x67, + 0xa6, 0xeb, 0x77, 0x48, 0xab, 0xe9, 0xda, 0x1d, 0x47, 0x14, 0x92, 0xe7, 0x10, 0xfe, 0x76, 0x90, + 0x9d, 0x1d, 0x66, 0x59, 0xa5, 0x4f, 0x3b, 0xd4, 0xf3, 0xe5, 0x87, 0xe8, 0xd5, 0xc4, 0xaa, 0xe7, + 0xd8, 0x96, 0x47, 0xf1, 0xd7, 0xd1, 0x14, 0x47, 0x30, 0x2f, 0x5d, 0x94, 0x16, 0x4b, 0x2b, 0xe5, + 0x6a, 0x36, 0xf3, 0x55, 0xae, 0xb3, 0x71, 0xfc, 0xa3, 0xcf, 0x2e, 0x1c, 0x53, 0x41, 0x5e, 0xbe, + 0x8d, 0x16, 0x04, 0x83, 0x1b, 0xdd, 0x5d, 0xb3, 0x4d, 0x3d, 0x9f, 0xb4, 0x1d, 0xf0, 0x88, 0xcf, + 0xa3, 0x19, 0x3f, 0x5c, 0x63, 0xd6, 0x27, 0xd5, 0x78, 0x41, 0x7e, 0x8c, 0x2a, 0x83, 0xd4, 0x8f, + 0x0c, 0x6d, 0x0d, 0xbd, 0xce, 0x6c, 0x7f, 0x8b, 0x12, 0x63, 0xa3, 0xa3, 0xef, 0x53, 0x3f, 0xc4, + 0x74, 0x01, 0x95, 0xea, 0x6c, 0x41, 0xb3, 0x48, 0x9b, 0x32, 0xc3, 0x33, 0x2a, 0xe2, 0x4b, 0x0f, + 0x48, 0x9b, 0xca, 0x6b, 0xa8, 0x9c, 0x52, 0xdd, 0xe8, 0xd6, 0x8c, 0x50, 0xfd, 0x1c, 0x9a, 0x01, + 0x75, 0xd3, 0x00, 0xe5, 0x69, 0xbe, 0x50, 0x33, 0xe4, 0xc7, 0xe8, 0x4c, 0xc6, 0x2b, 0x84, 0xf2, + 0xcd, 0xc8, 0xad, 0x69, 0x35, 0x6c, 0x88, 0xa7, 0x92, 0x17, 0x0f, 0x57, 0xac, 0x59, 0x0d, 0x3b, + 0x84, 0x15, 0xfc, 0x96, 0x1f, 0x0b, 0x11, 0x3d, 0xac, 0xbf, 0x4b, 0xf5, 0x91, 0x23, 0x0a, 0x04, + 0x6c, 0xa6, 0xc1, 0x05, 0x26, 0xb8, 0x00, 0x5f, 0xca, 0x84, 0xcc, 0x6d, 0xa7, 0x42, 0x06, 0xf5, + 0x38, 0x64, 0xbe, 0x50, 0x33, 0xe4, 0xbf, 0x49, 0x42, 0xcc, 0x21, 0xae, 0x38, 0xe6, 0x50, 0xb1, + 0x20, 0x66, 0xae, 0xc8, 0x63, 0xb6, 0xa3, 0xdf, 0xf8, 0x7b, 0x68, 0xae, 0xd9, 0xb2, 0xeb, 0xa4, + 0xa5, 0x41, 0xab, 0x6b, 0xac, 0xd7, 0x59, 0x04, 0xa5, 0x95, 0xb7, 0x44, 0x4b, 0xe2, 0x5e, 0xa8, + 0x6e, 0x33, 0xa5, 0x3d, 0xbe, 0xb4, 0x1d, 0x2c, 0xa9, 0xb8, 0x99, 0x59, 0x93, 0x09, 0x40, 0xbf, + 0x67, 0x7a, 0x3e, 0xcf, 0x7a, 0xb8, 0x57, 0xf0, 0x16, 0x42, 0xf1, 0x44, 0x01, 0xe4, 0x97, 0xab, + 0x30, 0x45, 0x82, 0xf1, 0x53, 0xe5, 0xb3, 0x0a, 0xc6, 0x4f, 0x75, 0x87, 0x34, 0x29, 0xe8, 0xaa, + 0x82, 0xa6, 0xfc, 0x7b, 0x09, 0xcd, 0x67, 0x7d, 0x40, 0x7e, 0xd6, 0xd1, 0xac, 0xd0, 0x13, 0x41, + 0x93, 0x4f, 0x8e, 0xd0, 0x14, 0xa5, 0xb8, 0x29, 0x3c, 0xbc, 0x9d, 0xc0, 0xc9, 0xf3, 0x72, 0xa5, + 0x10, 0x27, 0xf7, 0x9f, 0x00, 0xfa, 0xbe, 0x24, 0x24, 0x83, 0x97, 0x63, 0xdc, 0xc9, 0x48, 0x37, + 0xea, 0x44, 0x66, 0xeb, 0xfd, 0x58, 0x42, 0x97, 0xd2, 0x20, 0x36, 0xba, 0x10, 0xbb, 0x31, 0x6e, + 0x38, 0x89, 0xad, 0x3c, 0x91, 0xda, 0xca, 0x89, 0xc2, 0x45, 0xf9, 0x88, 0x0b, 0x27, 0x34, 0xf6, + 0xd0, 0xc2, 0x09, 0x9d, 0x5d, 0x8a, 0x3b, 0x7b, 0x8c, 0x85, 0xbb, 0x86, 0x4e, 0x31, 0x9c, 0x0f, + 0xb6, 0x76, 0xc3, 0x04, 0x9d, 0x45, 0xd3, 0xbe, 0xbd, 0x4f, 0xad, 0x78, 0xbf, 0x9e, 0x60, 0xcf, + 0x35, 0x43, 0xfe, 0x2e, 0x4c, 0x11, 0x9e, 0x53, 0xa6, 0x13, 0x6d, 0xd6, 0x99, 0x36, 0xf5, 0x89, + 0x66, 0x10, 0x9f, 0x40, 0x52, 0xe5, 0xc1, 0x9d, 0x78, 0x9f, 0xfa, 0xe4, 0x2e, 0xf1, 0x89, 0x3a, + 0xdd, 0x86, 0x5f, 0x91, 0x69, 0x1e, 0xf1, 0x17, 0x31, 0xcd, 0x35, 0x73, 0x4c, 0x7f, 0x07, 0xbd, + 0xc6, 0x4c, 0xb3, 0x6d, 0x2b, 0x5a, 0xbe, 0x93, 0xb5, 0x7c, 0x29, 0xcf, 0x32, 0x53, 0xcc, 0x31, + 0xfc, 0x03, 0x09, 0x9d, 0xe7, 0x67, 0x90, 0xdd, 0x32, 0xf5, 0xee, 0x96, 0xed, 0xae, 0xeb, 0xba, + 0xdd, 0xb1, 0xa2, 0xd9, 0x5a, 0x46, 0xd3, 0x2e, 0xf5, 0xec, 0x8e, 0xab, 0x87, 0x83, 0x35, 0x7a, + 0xc6, 0x9b, 0xe8, 0xcb, 0x8e, 0x6b, 0x5a, 0xba, 0xe9, 0x90, 0x96, 0x46, 0x0c, 0xc3, 0xa5, 0x9e, + 0xc7, 0xfb, 0x68, 0x63, 0xfe, 0x93, 0x0f, 0x97, 0xe6, 0xa0, 0x98, 0xeb, 0xfc, 0xcd, 0x23, 0xdf, + 0x35, 0xad, 0xa6, 0x7a, 0x3a, 0x52, 0x81, 0x75, 0x79, 0x2f, 0x3c, 0x45, 0x33, 0x10, 0x20, 0xc8, + 0x55, 0x34, 0xe5, 0xb0, 0x77, 0x10, 0xe1, 0x82, 0x18, 0x61, 0x7c, 0xcf, 0xa8, 0x72, 0x03, 0x2a, + 0x08, 0xcb, 0x9f, 0x86, 0xb1, 0xed, 0x51, 0xd7, 0x6c, 0x74, 0x77, 0x22, 0xc1, 0x30, 0xb6, 0x9b, + 0x68, 0xda, 0x76, 0xa8, 0x4b, 0x7c, 0xdb, 0xe5, 0xb1, 0x0d, 0x81, 0x1d, 0x49, 0x16, 0x6e, 0xe2, + 0xf4, 0x69, 0x33, 0x99, 0x3e, 0x6d, 0xf0, 0x06, 0x2a, 0x11, 0x3d, 0xe8, 0x5d, 0x2d, 0xb8, 0xb3, + 0xcc, 0x1f, 0xbf, 0x28, 0x2d, 0x9e, 0x4c, 0x96, 0x4d, 0x08, 0x6a, 0x9d, 0x49, 0xee, 0x76, 0x1d, + 0xaa, 0x22, 0x12, 0xfd, 0x8e, 0x92, 0x96, 0x8d, 0x2d, 0x4e, 0x1a, 0x6d, 0x34, 0xa8, 0xee, 0xb3, + 0xd0, 0x4e, 0x0e, 0x4c, 0xda, 0x26, 0x13, 0x52, 0x41, 0x58, 0x7e, 0x0a, 0x9d, 0x16, 0x9c, 0x66, + 0xfc, 0xe0, 0x80, 0x64, 0xad, 0xa1, 0x12, 0x3b, 0x5b, 0x34, 0xfb, 0xc0, 0xa2, 0xc5, 0xf9, 0x42, + 0x4c, 0xf8, 0x61, 0x20, 0x8b, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x36, 0xc3, 0x56, 0xd8, 0xd0, 0xdb, + 0x13, 0x0e, 0x76, 0x70, 0x09, 0x31, 0xbc, 0x1d, 0x2a, 0x0a, 0xc7, 0xe7, 0xc2, 0xc0, 0xf6, 0x66, + 0x33, 0x86, 0xdb, 0x65, 0x17, 0x86, 0x5f, 0x48, 0x10, 0x4b, 0x30, 0xc1, 0x12, 0xb1, 0x8c, 0x6b, + 0x80, 0xa6, 0x72, 0x32, 0x31, 0x7a, 0x4e, 0xe4, 0xdf, 0x48, 0x10, 0xb5, 0x00, 0x0e, 0xa2, 0xde, + 0xce, 0x41, 0xf7, 0x45, 0x26, 0x23, 0xbe, 0x13, 0xc2, 0xe3, 0x43, 0x7a, 0x82, 0x0d, 0xe9, 0x82, + 0xfc, 0xa1, 0x28, 0x7f, 0x9e, 0xfc, 0x47, 0x09, 0x9d, 0x4b, 0x56, 0xe6, 0x3e, 0x6d, 0xd7, 0xa9, + 0x1b, 0xa6, 0xf1, 0x3a, 0x9a, 0x6a, 0xb3, 0x85, 0xc2, 0x6e, 0x00, 0xb9, 0x23, 0x24, 0x2c, 0xd5, + 0x44, 0x93, 0xe9, 0x26, 0xa2, 0xb0, 0xd7, 0x33, 0x50, 0x21, 0xa9, 0x9b, 0x68, 0x96, 0xab, 0x0b, + 0x88, 0x53, 0x53, 0x58, 0xd8, 0x14, 0xa2, 0x05, 0x8e, 0x98, 0x3f, 0xc8, 0x0d, 0xb8, 0x28, 0x46, + 0xb3, 0x2a, 0xd1, 0x57, 0xc3, 0x86, 0xe5, 0x35, 0x84, 0xe3, 0x61, 0x09, 0x65, 0x09, 0x4f, 0xdd, + 0x78, 0x26, 0xf2, 0x42, 0x18, 0xf2, 0x2e, 0x64, 0x3e, 0xed, 0xe7, 0x68, 0x13, 0x71, 0x15, 0x7a, + 0x8e, 0x2f, 0xa7, 0xae, 0xb8, 0x5c, 0x46, 0xb8, 0xe2, 0xf2, 0x85, 0x9a, 0x21, 0xef, 0xc0, 0xcd, + 0x48, 0x54, 0x3b, 0x1a, 0x90, 0x5f, 0x49, 0xf0, 0x29, 0x76, 0xcf, 0xd6, 0xf7, 0xb7, 0x28, 0x8d, + 0x37, 0x66, 0x90, 0xa4, 0x36, 0x71, 0xbb, 0x9a, 0xe7, 0x44, 0x47, 0x8a, 0x34, 0xc2, 0x91, 0x12, + 0xe8, 0x3c, 0x72, 0x60, 0x3d, 0x08, 0x47, 0x77, 0x29, 0xf1, 0xa9, 0x46, 0x7c, 0x96, 0xe3, 0x49, + 0x75, 0x9a, 0x2f, 0xac, 0xfb, 0xf8, 0x12, 0x9a, 0x75, 0x48, 0xb7, 0x65, 0x13, 0x43, 0xf3, 0xcc, + 0xf7, 0x78, 0x2f, 0x1d, 0x57, 0x4b, 0xb0, 0xf6, 0xc8, 0x7c, 0x8f, 0xca, 0x2d, 0x34, 0x97, 0x84, + 0x07, 0xe1, 0xee, 0xa2, 0x29, 0xd2, 0x0e, 0xce, 0x26, 0xc0, 0xf4, 0x76, 0xf0, 0xcd, 0xf5, 0xe9, + 0x67, 0x17, 0x2e, 0x37, 0x4d, 0xff, 0x49, 0xa7, 0x5e, 0xd5, 0xed, 0x36, 0x7c, 0x69, 0xc3, 0x3f, + 0x4b, 0x9e, 0xb1, 0x0f, 0x5f, 0xa6, 0x35, 0xcb, 0xff, 0xe4, 0xc3, 0x25, 0x04, 0x11, 0xd4, 0x2c, + 0x5f, 0x05, 0x5b, 0xf2, 0x1d, 0x61, 0x9b, 0xf1, 0xdb, 0xc5, 0xe6, 0x73, 0xdf, 0x25, 0x23, 0x7f, + 0xb0, 0x89, 0xbd, 0x9f, 0xd0, 0x8f, 0x7a, 0x1f, 0xd1, 0x60, 0x41, 0x1c, 0xa3, 0x97, 0xf3, 0xc6, + 0x40, 0xcd, 0xf2, 0xa9, 0x6b, 0x91, 0x96, 0x70, 0xd9, 0x9e, 0x61, 0x9a, 0x6c, 0x9e, 0xde, 0x86, + 0xde, 0xaf, 0x79, 0x3b, 0xae, 0xa9, 0xd3, 0x77, 0x9e, 0x10, 0xab, 0x49, 0x8d, 0x91, 0x51, 0xfe, + 0xef, 0x04, 0x84, 0x99, 0xd6, 0x07, 0x94, 0xf3, 0xe8, 0x84, 0xce, 0x97, 0x98, 0xf2, 0xb4, 0x1a, + 0x3e, 0xe2, 0x77, 0x11, 0xd6, 0x3b, 0xae, 0x4b, 0x2d, 0x5f, 0x73, 0x29, 0x31, 0x34, 0x27, 0x50, + 0x87, 0xe1, 0x71, 0x98, 0x0a, 0xdc, 0xa5, 0xba, 0x50, 0x81, 0xbb, 0x54, 0x57, 0x4f, 0x83, 0x5d, + 0x95, 0x12, 0x83, 0x81, 0xc2, 0x3d, 0x74, 0x2e, 0xf4, 0x15, 0x75, 0xa2, 0x6f, 0xbb, 0x14, 0x9c, + 0x4e, 0x8e, 0xc1, 0xe9, 0x3c, 0x38, 0xd8, 0x81, 0xae, 0x0d, 0xcc, 0x73, 0xe7, 0xdf, 0x47, 0x0b, + 0xa1, 0x73, 0x8f, 0xea, 0xb6, 0x65, 0xa4, 0xdd, 0x1f, 0x1f, 0x83, 0xfb, 0x32, 0xb8, 0x78, 0x14, + 0x7a, 0x10, 0x00, 0x74, 0x51, 0xf8, 0x56, 0x7b, 0x46, 0x5a, 0xa6, 0x11, 0x5c, 0x78, 0x34, 0x9f, + 0x3c, 0xd7, 0x5c, 0xe2, 0xd3, 0xf9, 0x57, 0xc6, 0xe0, 0xfd, 0x0c, 0xd8, 0xdf, 0x0b, 0xcd, 0xef, + 0x92, 0xe7, 0x2a, 0xf1, 0x29, 0xae, 0xa3, 0x93, 0x16, 0x3d, 0x10, 0x0b, 0x3c, 0x35, 0x06, 0x77, + 0xb3, 0x16, 0x3d, 0x88, 0x8b, 0xeb, 0xa1, 0x33, 0x81, 0x8f, 0xbc, 0xc2, 0x9e, 0x18, 0x83, 0xb3, + 0x39, 0x8b, 0x1e, 0x64, 0x8b, 0x7a, 0x80, 0xce, 0x06, 0x4e, 0xf3, 0x0b, 0x3a, 0x3d, 0x06, 0xb7, + 0xaf, 0x5b, 0xf4, 0x20, 0xaf, 0x98, 0x4f, 0x51, 0xf0, 0x26, 0xaf, 0x90, 0x33, 0x63, 0xf0, 0xfa, + 0xaa, 0x45, 0x0f, 0xd2, 0x45, 0x5c, 0xf9, 0xe1, 0x02, 0x7a, 0x85, 0xed, 0x71, 0xdc, 0x47, 0x53, + 0x9c, 0x97, 0xc2, 0xb9, 0x93, 0x26, 0xcb, 0xce, 0x95, 0xaf, 0x14, 0xca, 0xf1, 0x41, 0x21, 0xcb, + 0xef, 0xff, 0xfb, 0xff, 0x3f, 0x9b, 0x38, 0x8f, 0xcb, 0xca, 0x40, 0x2e, 0x11, 0xff, 0x39, 0xbc, + 0x5e, 0x65, 0xb8, 0x35, 0xbc, 0x5c, 0xe0, 0x27, 0x4b, 0xe3, 0x95, 0x57, 0x0e, 0xa3, 0x02, 0x28, + 0xab, 0x0c, 0xe5, 0x22, 0xbe, 0x3c, 0x18, 0xa5, 0xd2, 0x8b, 0xb8, 0xc0, 0x3e, 0xfe, 0xa5, 0x84, + 0x50, 0x3c, 0xc0, 0xf1, 0xd5, 0x81, 0x2e, 0x33, 0x8c, 0x5e, 0xf9, 0xad, 0x91, 0x64, 0x01, 0xd7, + 0x2a, 0xc3, 0xa5, 0xe0, 0xa5, 0x3c, 0x5c, 0x4f, 0x82, 0xdd, 0xc7, 0x67, 0xb6, 0xd2, 0x13, 0xc6, + 0x79, 0x1f, 0xff, 0x41, 0x42, 0x27, 0x93, 0x84, 0x20, 0xae, 0x8e, 0xe0, 0x56, 0xb8, 0x63, 0x1c, + 0x0e, 0xe6, 0x1a, 0x83, 0x79, 0x03, 0x2f, 0x17, 0xc0, 0xd4, 0xea, 0xc1, 0x95, 0x25, 0x02, 0x6b, + 0x1a, 0x7d, 0xfc, 0x81, 0x84, 0xbe, 0x14, 0x5b, 0x7c, 0xb0, 0xb5, 0x8b, 0xdf, 0x18, 0xe8, 0x39, + 0x26, 0x0d, 0xca, 0x83, 0x33, 0x9e, 0xe1, 0x0a, 0xe4, 0xaf, 0x31, 0x74, 0xd7, 0x71, 0xb5, 0x08, + 0x9d, 0xd5, 0xf0, 0x95, 0x5e, 0xc8, 0x45, 0xf4, 0xf1, 0x9f, 0xa0, 0xc8, 0xfc, 0x43, 0xbf, 0xa0, + 0xc8, 0x09, 0x92, 0xb3, 0x20, 0x7b, 0x49, 0xe2, 0x51, 0x7e, 0x87, 0xe1, 0xbb, 0x8d, 0x6f, 0x0d, + 0xc4, 0xc7, 0x3f, 0x47, 0x93, 0x45, 0x56, 0x7a, 0xc2, 0x77, 0x6b, 0x5c, 0xf2, 0x98, 0x10, 0x2d, + 0x28, 0x79, 0x86, 0x39, 0x3d, 0x1c, 0xe8, 0xe2, 0x92, 0x03, 0x3c, 0x28, 0x79, 0xc4, 0xc9, 0xc6, + 0x25, 0x8f, 0xa8, 0x97, 0xa3, 0x96, 0x3c, 0xc3, 0xe1, 0x8c, 0x50, 0xf2, 0x30, 0x79, 0xc9, 0x92, + 0xff, 0x54, 0x42, 0x25, 0x81, 0xfb, 0xc4, 0x83, 0x53, 0x92, 0x65, 0x61, 0xcb, 0xd7, 0x46, 0x13, + 0x06, 0x88, 0x8b, 0x0c, 0xa2, 0x8c, 0x2f, 0xe6, 0x41, 0x6c, 0x99, 0x9e, 0x0f, 0x5d, 0xe9, 0xe1, + 0x5f, 0x03, 0x28, 0xe0, 0xf5, 0x0a, 0x40, 0x25, 0xd9, 0xd0, 0x02, 0x50, 0x29, 0xaa, 0x70, 0x78, + 0xde, 0x18, 0x28, 0x9e, 0x37, 0x2f, 0x35, 0x70, 0xfe, 0x2e, 0xa1, 0xd7, 0x72, 0x59, 0x50, 0xbc, + 0x3a, 0x8a, 0xff, 0x0c, 0x6b, 0x7a, 0x48, 0xd8, 0xeb, 0x0c, 0xf6, 0x2d, 0xbc, 0x56, 0x04, 0x3b, + 0xe8, 0xc6, 0x68, 0xf8, 0x24, 0xe6, 0xd0, 0xcf, 0x25, 0x34, 0x1b, 0x7d, 0x8e, 0x8e, 0xdc, 0x93, + 0x6f, 0x0e, 0x14, 0x4a, 0x93, 0x7f, 0x23, 0x8c, 0x72, 0xf8, 0x62, 0x4e, 0x76, 0xe4, 0x3f, 0x43, + 0x5e, 0x24, 0x4d, 0xb8, 0xe1, 0xeb, 0x83, 0xcf, 0xb9, 0x7c, 0x7a, 0xb0, 0xbc, 0x7c, 0x08, 0x0d, + 0x40, 0x7d, 0x9f, 0xa1, 0xde, 0xc6, 0x9b, 0xb9, 0x07, 0x23, 0xff, 0x08, 0x6d, 0xd8, 0xae, 0x46, + 0xb8, 0x9e, 0xd2, 0x0b, 0x3f, 0xa1, 0xfb, 0x4a, 0x2f, 0x43, 0x37, 0xf6, 0xf1, 0xbf, 0x24, 0x74, + 0x3a, 0x4d, 0x82, 0x0d, 0x09, 0x64, 0x00, 0x17, 0x38, 0x24, 0x90, 0x41, 0x0c, 0x9b, 0xbc, 0xcb, + 0x02, 0x79, 0x80, 0xef, 0xe5, 0x05, 0xf2, 0x8c, 0x69, 0x69, 0xc2, 0xff, 0x82, 0xf6, 0x42, 0x06, + 0xb1, 0x9f, 0x9e, 0xba, 0x02, 0x19, 0xd8, 0xc7, 0xbf, 0x93, 0xd0, 0x4c, 0xd4, 0x35, 0xf8, 0xcd, + 0xa1, 0x03, 0x54, 0x24, 0x1f, 0xca, 0x57, 0x47, 0x11, 0x1d, 0xa5, 0xbb, 0xe3, 0xce, 0x51, 0x7a, + 0x02, 0x5b, 0xd3, 0x0f, 0x9f, 0xf8, 0xfe, 0xfc, 0x40, 0x42, 0x33, 0x11, 0x77, 0x35, 0x04, 0x67, + 0x9a, 0x7c, 0x1b, 0x82, 0x33, 0x43, 0x85, 0xc9, 0x37, 0x19, 0xce, 0x2a, 0xbe, 0x36, 0x70, 0x17, + 0xe6, 0xe0, 0xc4, 0xbf, 0x95, 0xd0, 0xa9, 0x14, 0x0f, 0x84, 0x95, 0xe2, 0xec, 0x24, 0xc8, 0xad, + 0xf2, 0xf5, 0xd1, 0x15, 0x00, 0xec, 0x12, 0x03, 0x7b, 0x05, 0x7f, 0xb5, 0x60, 0x3b, 0x02, 0x17, + 0xf6, 0x8f, 0x90, 0x03, 0x49, 0x72, 0x3c, 0x43, 0xce, 0xd8, 0x5c, 0xd2, 0xa9, 0xac, 0x8c, 0x2c, + 0x0f, 0x38, 0xef, 0x31, 0x9c, 0x5b, 0xf8, 0x6e, 0xc1, 0x06, 0x84, 0xd4, 0xe6, 0x6e, 0xbf, 0x90, + 0xc0, 0xea, 0x07, 0x47, 0xc9, 0xa9, 0x14, 0x3b, 0x34, 0xe4, 0x5e, 0x93, 0x61, 0x9e, 0x86, 0x5c, + 0x11, 0xb2, 0x74, 0xd3, 0xf0, 0x7e, 0x00, 0xe8, 0x70, 0x3b, 0x88, 0xe8, 0xac, 0x3e, 0xfe, 0x91, + 0x84, 0x66, 0x45, 0x3a, 0x07, 0x0f, 0xfe, 0xd4, 0x48, 0xf2, 0x51, 0xe5, 0xc5, 0x62, 0x41, 0x40, + 0xf6, 0x15, 0x86, 0xac, 0x82, 0xcf, 0xe7, 0x76, 0xaa, 0xad, 0xef, 0x6b, 0x0d, 0x4a, 0xf1, 0x5f, + 0xa0, 0x33, 0x05, 0x96, 0xa6, 0xa0, 0x33, 0xb3, 0x7c, 0x50, 0x41, 0x67, 0xe6, 0x10, 0x40, 0xf2, + 0x2d, 0x06, 0x6e, 0x15, 0xdf, 0x28, 0xba, 0xae, 0x32, 0xb2, 0x27, 0x75, 0x10, 0xff, 0x35, 0xec, + 0xd3, 0x24, 0x6f, 0x33, 0xa4, 0x4f, 0x73, 0x09, 0xa2, 0x21, 0x7d, 0x9a, 0x4f, 0x08, 0xc9, 0xdf, + 0x60, 0xa8, 0x6f, 0xe2, 0x95, 0x3c, 0xd4, 0xa6, 0xc7, 0xbf, 0xa0, 0x35, 0x20, 0x89, 0x92, 0xa0, + 0x37, 0x6a, 0x1f, 0xbd, 0xa8, 0x48, 0x1f, 0xbf, 0xa8, 0x48, 0xff, 0x7d, 0x51, 0x91, 0x7e, 0xf2, + 0xb2, 0x72, 0xec, 0xe3, 0x97, 0x95, 0x63, 0xff, 0x79, 0x59, 0x39, 0xf6, 0x58, 0x11, 0xbe, 0x76, + 0xeb, 0x56, 0x7d, 0x49, 0x7f, 0x42, 0x4c, 0x4b, 0xf4, 0xf0, 0x3c, 0xf9, 0x67, 0x27, 0xf5, 0x29, + 0xf6, 0x27, 0x25, 0x37, 0x3e, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x32, 0xdd, 0xcd, 0x59, 0xb0, 0x23, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1932,6 +2141,10 @@ type QueryClient interface { QueryPolicyById(ctx context.Context, in *QueryPolicyByIdRequest, opts ...grpc.CallOption) (*QueryPolicyByIdResponse, error) // Queries lock fee for storing an object QueryLockFee(ctx context.Context, in *QueryLockFeeRequest, opts ...grpc.CallOption) (*QueryLockFeeResponse, error) + // Queries a bucket extra info (with gvg bindings and price time) with specify name. + HeadBucketExtra(ctx context.Context, in *QueryHeadBucketExtraRequest, opts ...grpc.CallOption) (*QueryHeadBucketExtraResponse, error) + // Queries whether read and storage prices changed for the bucket. + QueryIsPriceChanged(ctx context.Context, in *QueryIsPriceChangedRequest, opts ...grpc.CallOption) (*QueryIsPriceChangedResponse, error) } type queryClient struct { @@ -2122,6 +2335,24 @@ func (c *queryClient) QueryLockFee(ctx context.Context, in *QueryLockFeeRequest, return out, nil } +func (c *queryClient) HeadBucketExtra(ctx context.Context, in *QueryHeadBucketExtraRequest, opts ...grpc.CallOption) (*QueryHeadBucketExtraResponse, error) { + out := new(QueryHeadBucketExtraResponse) + err := c.cc.Invoke(ctx, "/greenfield.storage.Query/HeadBucketExtra", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QueryIsPriceChanged(ctx context.Context, in *QueryIsPriceChangedRequest, opts ...grpc.CallOption) (*QueryIsPriceChangedResponse, error) { + out := new(QueryIsPriceChangedResponse) + err := c.cc.Invoke(ctx, "/greenfield.storage.Query/QueryIsPriceChanged", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -2164,6 +2395,10 @@ type QueryServer interface { QueryPolicyById(context.Context, *QueryPolicyByIdRequest) (*QueryPolicyByIdResponse, error) // Queries lock fee for storing an object QueryLockFee(context.Context, *QueryLockFeeRequest) (*QueryLockFeeResponse, error) + // Queries a bucket extra info (with gvg bindings and price time) with specify name. + HeadBucketExtra(context.Context, *QueryHeadBucketExtraRequest) (*QueryHeadBucketExtraResponse, error) + // Queries whether read and storage prices changed for the bucket. + QueryIsPriceChanged(context.Context, *QueryIsPriceChangedRequest) (*QueryIsPriceChangedResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -2230,6 +2465,12 @@ func (*UnimplementedQueryServer) QueryPolicyById(ctx context.Context, req *Query func (*UnimplementedQueryServer) QueryLockFee(ctx context.Context, req *QueryLockFeeRequest) (*QueryLockFeeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryLockFee not implemented") } +func (*UnimplementedQueryServer) HeadBucketExtra(ctx context.Context, req *QueryHeadBucketExtraRequest) (*QueryHeadBucketExtraResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method HeadBucketExtra not implemented") +} +func (*UnimplementedQueryServer) QueryIsPriceChanged(ctx context.Context, req *QueryIsPriceChangedRequest) (*QueryIsPriceChangedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryIsPriceChanged not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -2595,6 +2836,42 @@ func _Query_QueryLockFee_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Query_HeadBucketExtra_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryHeadBucketExtraRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).HeadBucketExtra(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/greenfield.storage.Query/HeadBucketExtra", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).HeadBucketExtra(ctx, req.(*QueryHeadBucketExtraRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QueryIsPriceChanged_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIsPriceChangedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryIsPriceChanged(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/greenfield.storage.Query/QueryIsPriceChanged", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryIsPriceChanged(ctx, req.(*QueryIsPriceChangedRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "greenfield.storage.Query", HandlerType: (*QueryServer)(nil), @@ -2679,6 +2956,14 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryLockFee", Handler: _Query_QueryLockFee_Handler, }, + { + MethodName: "HeadBucketExtra", + Handler: _Query_HeadBucketExtra_Handler, + }, + { + MethodName: "QueryIsPriceChanged", + Handler: _Query_QueryIsPriceChanged_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "greenfield/storage/query.proto", @@ -3963,89 +4248,297 @@ func (m *QueryLockFeeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryHeadBucketExtraRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n +func (m *QueryHeadBucketExtraRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryParamsByTimestampRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryHeadBucketExtraRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Timestamp != 0 { - n += 1 + sovQuery(uint64(m.Timestamp)) + if len(m.BucketName) > 0 { + i -= len(m.BucketName) + copy(dAtA[i:], m.BucketName) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BucketName))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryParamsByTimestampResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryHeadBucketExtraResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return dAtA[:n], nil } -func (m *QueryHeadBucketRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.BucketName) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n +func (m *QueryHeadBucketExtraResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryHeadBucketByIdRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryHeadBucketExtraResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.BucketId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.ExtraInfo != nil { + { + size, err := m.ExtraInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryHeadBucketResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryIsPriceChangedRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryIsPriceChangedRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIsPriceChangedRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BucketName) > 0 { + i -= len(m.BucketName) + copy(dAtA[i:], m.BucketName) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BucketName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryIsPriceChangedResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryIsPriceChangedResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIsPriceChangedResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.NewValidatorTaxRate.Size() + i -= size + if _, err := m.NewValidatorTaxRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + { + size := m.NewSecondaryStorePrice.Size() + i -= size + if _, err := m.NewSecondaryStorePrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + { + size := m.NewPrimaryStorePrice.Size() + i -= size + if _, err := m.NewPrimaryStorePrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size := m.NewReadPrice.Size() + i -= size + if _, err := m.NewReadPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size := m.CurrentValidatorTaxRate.Size() + i -= size + if _, err := m.CurrentValidatorTaxRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size := m.CurrentSecondaryStorePrice.Size() + i -= size + if _, err := m.CurrentSecondaryStorePrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size := m.CurrentPrimaryStorePrice.Size() + i -= size + if _, err := m.CurrentPrimaryStorePrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size := m.CurrentReadPrice.Size() + i -= size + if _, err := m.CurrentReadPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.Changed { + i-- + if m.Changed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryParamsByTimestampRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Timestamp != 0 { + n += 1 + sovQuery(uint64(m.Timestamp)) + } + return n +} + +func (m *QueryParamsByTimestampResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryHeadBucketRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BucketName) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryHeadBucketByIdRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BucketId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryHeadBucketResponse) Size() (n int) { + if m == nil { + return 0 } var l int _ = l @@ -4492,6 +4985,73 @@ func (m *QueryLockFeeResponse) Size() (n int) { return n } +func (m *QueryHeadBucketExtraRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BucketName) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryHeadBucketExtraResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtraInfo != nil { + l = m.ExtraInfo.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryIsPriceChangedRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BucketName) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryIsPriceChangedResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Changed { + n += 2 + } + l = m.CurrentReadPrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.CurrentPrimaryStorePrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.CurrentSecondaryStorePrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.CurrentValidatorTaxRate.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.NewReadPrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.NewPrimaryStorePrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.NewSecondaryStorePrice.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.NewValidatorTaxRate.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -7929,6 +8489,598 @@ func (m *QueryLockFeeResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryHeadBucketExtraRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryHeadBucketExtraRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryHeadBucketExtraRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BucketName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BucketName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryHeadBucketExtraResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryHeadBucketExtraResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryHeadBucketExtraResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExtraInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExtraInfo == nil { + m.ExtraInfo = &InternalBucketInfo{} + } + if err := m.ExtraInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryIsPriceChangedRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryIsPriceChangedRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIsPriceChangedRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BucketName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BucketName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryIsPriceChangedResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryIsPriceChangedResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIsPriceChangedResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Changed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Changed = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.CurrentReadPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentPrimaryStorePrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.CurrentPrimaryStorePrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentSecondaryStorePrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.CurrentSecondaryStorePrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentValidatorTaxRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.CurrentValidatorTaxRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewReadPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NewReadPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewPrimaryStorePrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NewPrimaryStorePrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewSecondaryStorePrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NewSecondaryStorePrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewValidatorTaxRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NewValidatorTaxRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/storage/types/query.pb.gw.go b/x/storage/types/query.pb.gw.go index 8b05ed2f9..f66bbd84e 100644 --- a/x/storage/types/query.pb.gw.go +++ b/x/storage/types/query.pb.gw.go @@ -1234,6 +1234,114 @@ func local_request_Query_QueryLockFee_0(ctx context.Context, marshaler runtime.M } +func request_Query_HeadBucketExtra_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryHeadBucketExtraRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bucket_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bucket_name") + } + + protoReq.BucketName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bucket_name", err) + } + + msg, err := client.HeadBucketExtra(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_HeadBucketExtra_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryHeadBucketExtraRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bucket_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bucket_name") + } + + protoReq.BucketName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bucket_name", err) + } + + msg, err := server.HeadBucketExtra(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_QueryIsPriceChanged_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIsPriceChangedRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bucket_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bucket_name") + } + + protoReq.BucketName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bucket_name", err) + } + + msg, err := client.QueryIsPriceChanged(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryIsPriceChanged_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIsPriceChangedRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bucket_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bucket_name") + } + + protoReq.BucketName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bucket_name", err) + } + + msg, err := server.QueryIsPriceChanged(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1700,6 +1808,52 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_HeadBucketExtra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_HeadBucketExtra_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_HeadBucketExtra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryIsPriceChanged_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryIsPriceChanged_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryIsPriceChanged_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2141,6 +2295,46 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_HeadBucketExtra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_HeadBucketExtra_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_HeadBucketExtra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryIsPriceChanged_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryIsPriceChanged_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryIsPriceChanged_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2184,6 +2378,10 @@ var ( pattern_Query_QueryPolicyById_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"greenfield", "storage", "policy_by_id", "policy_id"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_QueryLockFee_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "storage", "lock_fee"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_HeadBucketExtra_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"greenfield", "storage", "head_bucket_extra", "bucket_name"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryIsPriceChanged_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"greenfield", "storage", "is_price_changed", "bucket_name"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -2226,4 +2424,8 @@ var ( forward_Query_QueryPolicyById_0 = runtime.ForwardResponseMessage forward_Query_QueryLockFee_0 = runtime.ForwardResponseMessage + + forward_Query_HeadBucketExtra_0 = runtime.ForwardResponseMessage + + forward_Query_QueryIsPriceChanged_0 = runtime.ForwardResponseMessage ) diff --git a/x/storage/types/types.go b/x/storage/types/types.go index d0f8d68b6..8a69491a6 100644 --- a/x/storage/types/types.go +++ b/x/storage/types/types.go @@ -128,3 +128,12 @@ func (b *InternalBucketInfo) MustGetLVG(lvgID uint32) *LocalVirtualGroup { } return lvg } + +func (b *InternalBucketInfo) DeleteLVG(lvgID uint32) { + for i, lvg := range b.LocalVirtualGroups { + if lvg.Id == lvgID { + b.LocalVirtualGroups = append(b.LocalVirtualGroups[:i], b.LocalVirtualGroups[i+1:]...) + break + } + } +} diff --git a/x/storage/types/types.pb.go b/x/storage/types/types.pb.go index 150248e84..ab312aaf3 100644 --- a/x/storage/types/types.pb.go +++ b/x/storage/types/types.pb.go @@ -41,17 +41,14 @@ type BucketInfo struct { CreateAt int64 `protobuf:"varint,6,opt,name=create_at,json=createAt,proto3" json:"create_at,omitempty"` // payment_address is the address of the payment account PaymentAddress string `protobuf:"bytes,7,opt,name=payment_address,json=paymentAddress,proto3" json:"payment_address,omitempty"` - // primary_sp_id is the unique id of the primary sp. Objects belongs to this bucket will never - // leave this SP, unless you explicitly shift them to another SP. - PrimarySpId uint32 `protobuf:"varint,8,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` // global_virtual_group_family_id defines the unique id of gvg family - GlobalVirtualGroupFamilyId uint32 `protobuf:"varint,9,opt,name=global_virtual_group_family_id,json=globalVirtualGroupFamilyId,proto3" json:"global_virtual_group_family_id,omitempty"` + GlobalVirtualGroupFamilyId uint32 `protobuf:"varint,8,opt,name=global_virtual_group_family_id,json=globalVirtualGroupFamilyId,proto3" json:"global_virtual_group_family_id,omitempty"` // charged_read_quota defines the traffic quota for read in bytes per month. // The available read data for each user is the sum of the free read data provided by SP and // the ChargeReadQuota specified here. - ChargedReadQuota uint64 `protobuf:"varint,10,opt,name=charged_read_quota,json=chargedReadQuota,proto3" json:"charged_read_quota,omitempty"` + ChargedReadQuota uint64 `protobuf:"varint,9,opt,name=charged_read_quota,json=chargedReadQuota,proto3" json:"charged_read_quota,omitempty"` // bucket_status define the status of the bucket. - BucketStatus BucketStatus `protobuf:"varint,11,opt,name=bucket_status,json=bucketStatus,proto3,enum=greenfield.storage.BucketStatus" json:"bucket_status,omitempty"` + BucketStatus BucketStatus `protobuf:"varint,10,opt,name=bucket_status,json=bucketStatus,proto3,enum=greenfield.storage.BucketStatus" json:"bucket_status,omitempty"` } func (m *BucketInfo) Reset() { *m = BucketInfo{} } @@ -129,13 +126,6 @@ func (m *BucketInfo) GetPaymentAddress() string { return "" } -func (m *BucketInfo) GetPrimarySpId() uint32 { - if m != nil { - return m.PrimarySpId - } - return 0 -} - func (m *BucketInfo) GetGlobalVirtualGroupFamilyId() uint32 { if m != nil { return m.GlobalVirtualGroupFamilyId @@ -930,81 +920,80 @@ func init() { func init() { proto.RegisterFile("greenfield/storage/types.proto", fileDescriptor_bf95fa2efdc74d97) } var fileDescriptor_bf95fa2efdc74d97 = []byte{ - // 1180 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdf, 0x6e, 0xdb, 0xb6, - 0x17, 0x8e, 0x22, 0xbb, 0x89, 0x8e, 0xe2, 0xf4, 0x57, 0xd5, 0xf8, 0x55, 0x4d, 0x51, 0xdb, 0x15, - 0xb0, 0xc1, 0xd8, 0x56, 0x1b, 0x4d, 0x87, 0x62, 0x18, 0x0a, 0x14, 0xf5, 0xda, 0x15, 0xc6, 0xd6, - 0x0d, 0x53, 0xda, 0x0e, 0xd8, 0x8d, 0x40, 0x49, 0x8c, 0xc2, 0x55, 0x12, 0x3d, 0x92, 0x4a, 0xe3, - 0x3e, 0xc5, 0x9e, 0x65, 0xe8, 0x0b, 0xec, 0xae, 0x18, 0x36, 0xa0, 0xe8, 0xd5, 0xb0, 0x8b, 0x60, - 0x48, 0xde, 0x60, 0x17, 0xbb, 0x1e, 0x44, 0xd2, 0xa9, 0x62, 0x3b, 0xcd, 0x1f, 0xb4, 0x77, 0xe6, - 0xe1, 0x77, 0xc4, 0x73, 0xbe, 0xf3, 0x9d, 0x43, 0x1a, 0x5a, 0x09, 0xc3, 0x38, 0xdf, 0x24, 0x38, - 0x8d, 0xfb, 0x5c, 0x50, 0x86, 0x12, 0xdc, 0x17, 0xe3, 0x11, 0xe6, 0xbd, 0x11, 0xa3, 0x82, 0x3a, - 0xce, 0x9b, 0xfd, 0x9e, 0xde, 0x5f, 0x6b, 0x45, 0x94, 0x67, 0x94, 0xf7, 0x43, 0xc4, 0x71, 0x7f, - 0xfb, 0x46, 0x88, 0x05, 0xba, 0xd1, 0x8f, 0x28, 0xc9, 0x95, 0xcf, 0xda, 0x65, 0xb5, 0x1f, 0xc8, - 0x55, 0x5f, 0x2d, 0xf4, 0x56, 0x33, 0xa1, 0x09, 0x55, 0xf6, 0xf2, 0x97, 0xb6, 0x5e, 0xab, 0x04, - 0x31, 0x42, 0xe3, 0x0c, 0xe7, 0xa2, 0x4f, 0x0b, 0x11, 0x6c, 0xa6, 0xf4, 0x99, 0x86, 0x7c, 0x38, - 0x07, 0xc2, 0x05, 0xc3, 0x28, 0x0b, 0x18, 0x8e, 0x28, 0x8b, 0x35, 0xae, 0x3d, 0x27, 0x9f, 0x88, - 0x66, 0x19, 0xd5, 0xc1, 0x79, 0xbf, 0xd7, 0x00, 0x06, 0x45, 0xf4, 0x14, 0x8b, 0x61, 0xbe, 0x49, - 0x9d, 0x1e, 0xd4, 0xe9, 0xb3, 0x1c, 0x33, 0xd7, 0xe8, 0x18, 0x5d, 0x6b, 0xe0, 0xbe, 0x7e, 0x71, - 0xbd, 0xa9, 0x23, 0xbe, 0x1b, 0xc7, 0x0c, 0x73, 0xbe, 0x21, 0x18, 0xc9, 0x13, 0x5f, 0xc1, 0x9c, - 0x36, 0xd8, 0xa1, 0xf4, 0x0e, 0x72, 0x94, 0x61, 0x77, 0xb1, 0xf4, 0xf2, 0x41, 0x99, 0xbe, 0x41, - 0x19, 0x76, 0x06, 0x00, 0xdb, 0x84, 0x93, 0x90, 0xa4, 0x44, 0x8c, 0x5d, 0xb3, 0x63, 0x74, 0x57, - 0xd7, 0xbd, 0xde, 0x2c, 0x8b, 0xbd, 0x27, 0x07, 0xa8, 0x47, 0xe3, 0x11, 0xf6, 0x2b, 0x5e, 0xce, - 0xc7, 0xb0, 0x48, 0x62, 0xb7, 0x26, 0x23, 0xba, 0xf2, 0x72, 0xb7, 0xbd, 0xf0, 0xd7, 0x6e, 0xbb, - 0xf6, 0x98, 0xe4, 0xe2, 0xf5, 0x8b, 0xeb, 0xb6, 0x8e, 0xae, 0x5c, 0xfa, 0x8b, 0x24, 0x76, 0xee, - 0x80, 0xcd, 0x69, 0xc1, 0x22, 0x1c, 0x94, 0x75, 0x73, 0xeb, 0xf2, 0xc4, 0xd6, 0xbc, 0x13, 0x37, - 0x24, 0x4c, 0x9d, 0xc6, 0x0f, 0x7e, 0x3b, 0x57, 0xc0, 0x8a, 0x18, 0x46, 0x02, 0x07, 0x48, 0xb8, - 0xe7, 0x3a, 0x46, 0xd7, 0xf4, 0x97, 0x95, 0xe1, 0xae, 0x70, 0xee, 0xc2, 0x79, 0x4d, 0x77, 0x80, - 0x14, 0x1f, 0xee, 0xd2, 0x31, 0x4c, 0xad, 0x6a, 0x07, 0x6d, 0x75, 0x3c, 0x68, 0x8c, 0x18, 0xc9, - 0x10, 0x1b, 0x07, 0x7c, 0x14, 0x90, 0xd8, 0x5d, 0xee, 0x18, 0xdd, 0x86, 0x6f, 0x6b, 0xe3, 0xc6, - 0x68, 0x18, 0x3b, 0x03, 0x68, 0x25, 0x29, 0x0d, 0x51, 0x1a, 0x6c, 0x13, 0x26, 0x0a, 0x94, 0x06, - 0x09, 0xa3, 0xc5, 0x28, 0xd8, 0x44, 0x19, 0x49, 0xc7, 0xa5, 0x93, 0x25, 0x9d, 0xd6, 0x14, 0xea, - 0x89, 0x02, 0x3d, 0x28, 0x31, 0x5f, 0x4a, 0xc8, 0x30, 0x76, 0x3e, 0x01, 0x27, 0xda, 0x42, 0x2c, - 0xc1, 0x71, 0xc0, 0x30, 0x8a, 0x83, 0x9f, 0x0a, 0x2a, 0x90, 0x0b, 0x1d, 0xa3, 0x5b, 0xf3, 0xff, - 0xa7, 0x77, 0x7c, 0x8c, 0xe2, 0xef, 0x4a, 0xbb, 0x73, 0x1f, 0x1a, 0xba, 0x90, 0x5c, 0x20, 0x51, - 0x70, 0xd7, 0x96, 0xc4, 0x75, 0xe6, 0x11, 0xa7, 0xf4, 0xb2, 0x21, 0x71, 0xfe, 0x4a, 0x58, 0x59, - 0x79, 0xff, 0x1a, 0xe0, 0x0c, 0x73, 0x81, 0x59, 0x8e, 0xd2, 0x8a, 0xac, 0xae, 0x02, 0x8c, 0x18, - 0x29, 0x6b, 0x42, 0x32, 0x2c, 0xb5, 0x65, 0xfa, 0x96, 0xb4, 0x3c, 0x22, 0x19, 0x76, 0x3e, 0x82, - 0x0b, 0x82, 0x0a, 0x94, 0x06, 0x2a, 0xac, 0x80, 0x93, 0xe7, 0x4a, 0x4b, 0x35, 0xff, 0xbc, 0xdc, - 0xf8, 0x42, 0xda, 0x37, 0xc8, 0x73, 0xec, 0x7c, 0x0f, 0xcd, 0x94, 0x46, 0xd3, 0xcc, 0x70, 0xd7, - 0xec, 0x98, 0x5d, 0x7b, 0xfd, 0x83, 0x79, 0xf1, 0x7e, 0x5d, 0xe2, 0xab, 0x1c, 0xf9, 0x4e, 0x3a, - 0x6d, 0xe2, 0xce, 0x6d, 0xb8, 0x92, 0xe3, 0x1d, 0x11, 0xcc, 0xf9, 0x7a, 0xa0, 0xe5, 0xd7, 0xf0, - 0x2f, 0x95, 0x90, 0x99, 0xef, 0x0d, 0x63, 0xef, 0xd7, 0x3a, 0xc0, 0xb7, 0xe1, 0x8f, 0x38, 0x3a, - 0x5b, 0x1f, 0xad, 0xc3, 0x92, 0xd4, 0x18, 0x65, 0xaa, 0x87, 0xde, 0xe2, 0x31, 0x01, 0x4e, 0xf7, - 0x9e, 0x39, 0xd3, 0x7b, 0x6d, 0xb0, 0xa9, 0x0c, 0x49, 0x01, 0x6a, 0x0a, 0xa0, 0x4c, 0x12, 0xa0, - 0x1a, 0xab, 0x7e, 0xb2, 0xc6, 0xba, 0x09, 0xff, 0x3f, 0x82, 0x9a, 0x73, 0x92, 0x9a, 0x8b, 0xe9, - 0x2c, 0x2d, 0xce, 0x35, 0x58, 0x19, 0xa1, 0x71, 0x4a, 0x51, 0xac, 0x8a, 0xba, 0x24, 0x8b, 0x6a, - 0x6b, 0x9b, 0x2c, 0xe8, 0xe1, 0x09, 0xb1, 0x7c, 0xa6, 0x09, 0x71, 0x0d, 0x56, 0x22, 0x9a, 0x8b, - 0xb2, 0x2d, 0x65, 0xd7, 0x5b, 0x32, 0x55, 0x5b, 0xdb, 0x66, 0xdb, 0x1a, 0xa6, 0xda, 0xfa, 0x3e, - 0x34, 0x34, 0x53, 0xc7, 0xab, 0x5f, 0x55, 0x79, 0xa2, 0x7e, 0x5a, 0x59, 0x39, 0x5f, 0xc1, 0x79, - 0x86, 0xe3, 0x22, 0x8f, 0x51, 0x1e, 0x8d, 0x55, 0x24, 0x2b, 0x47, 0xe7, 0xe3, 0x1f, 0x40, 0x65, - 0x3e, 0xab, 0xec, 0xd0, 0x7a, 0x7a, 0x90, 0x35, 0x4e, 0x3d, 0xc8, 0xfa, 0x60, 0x45, 0x5b, 0x38, - 0x7a, 0xca, 0x8b, 0x8c, 0xbb, 0xab, 0x1d, 0xb3, 0xbb, 0x32, 0xb8, 0xf0, 0xcf, 0x6e, 0xbb, 0x21, - 0x18, 0x22, 0x82, 0x7f, 0xee, 0xd1, 0x8c, 0x08, 0xcf, 0x7f, 0x83, 0xf1, 0x76, 0x0d, 0xb0, 0x54, - 0xe1, 0xce, 0x22, 0xe1, 0xab, 0x00, 0x4a, 0x11, 0x95, 0x9b, 0xc0, 0x92, 0x16, 0xa9, 0xb5, 0xa9, - 0x74, 0xcc, 0x53, 0xa7, 0x73, 0xaa, 0x5b, 0xa0, 0x09, 0x75, 0xbc, 0x23, 0x18, 0x52, 0xe2, 0xf6, - 0xd5, 0xc2, 0xbb, 0x0d, 0xf5, 0x47, 0x65, 0xf2, 0x65, 0xac, 0x92, 0x05, 0x15, 0x8b, 0xa1, 0x62, - 0x95, 0x16, 0x79, 0x54, 0x13, 0xea, 0xdb, 0x28, 0x2d, 0x26, 0x59, 0xa8, 0x85, 0xf7, 0x87, 0x01, - 0xab, 0x6a, 0xa6, 0x3d, 0xc4, 0x02, 0xdd, 0x43, 0x02, 0x39, 0x1d, 0xb0, 0x63, 0xcc, 0x23, 0x46, - 0x46, 0x82, 0xd0, 0x5c, 0x7f, 0xa8, 0x6a, 0x2a, 0x95, 0x89, 0x77, 0xd4, 0x3c, 0x0c, 0x0a, 0x96, - 0xea, 0x2f, 0xda, 0x13, 0xdb, 0x63, 0x96, 0x1e, 0xdf, 0xc7, 0x4d, 0xa8, 0x93, 0x0c, 0x25, 0x93, - 0x0e, 0x56, 0x0b, 0xe7, 0x0e, 0x00, 0x12, 0x82, 0x91, 0xb0, 0x10, 0x98, 0xbb, 0x75, 0x39, 0xfe, - 0x2e, 0xcf, 0xe3, 0x53, 0xa6, 0x3c, 0xa8, 0x95, 0x94, 0xf9, 0x15, 0x17, 0x99, 0x8f, 0x12, 0xf3, - 0x3b, 0xcf, 0xa7, 0x3a, 0x76, 0xcc, 0x99, 0xb1, 0xf3, 0x9e, 0xf2, 0xf9, 0xcd, 0x80, 0x86, 0x94, - 0xef, 0xbb, 0x4d, 0xe7, 0xb0, 0xae, 0xcd, 0x69, 0x5d, 0xbf, 0xa7, 0x64, 0xd6, 0xc1, 0x1c, 0xc6, - 0x5c, 0x8b, 0xde, 0xe8, 0x98, 0x27, 0x10, 0xbd, 0xf7, 0x8b, 0x01, 0x70, 0x0f, 0xa7, 0x58, 0x60, - 0xd9, 0xc0, 0xb7, 0x40, 0x8b, 0x28, 0x20, 0x31, 0x97, 0xc9, 0xdb, 0xeb, 0x97, 0xe6, 0xc5, 0x30, - 0x8c, 0xb9, 0x6f, 0x29, 0x68, 0x79, 0xe6, 0x2d, 0xd0, 0xc5, 0x92, 0x7e, 0x8b, 0xc7, 0xf8, 0x29, - 0x68, 0xe9, 0xf7, 0x29, 0x58, 0x93, 0x2b, 0x81, 0x4b, 0x9e, 0xde, 0xe2, 0xb6, 0x9c, 0xa8, 0x0b, - 0x82, 0x7b, 0xaf, 0x0d, 0xb8, 0xf8, 0x90, 0x24, 0x0c, 0x95, 0xf5, 0xa8, 0x3c, 0x19, 0xd6, 0xc0, - 0xe2, 0x2c, 0xd2, 0x4f, 0x24, 0x43, 0xde, 0x30, 0x4b, 0x9c, 0x45, 0xf2, 0x79, 0x34, 0x04, 0xaf, - 0xdc, 0x3b, 0xe6, 0x89, 0xb4, 0x28, 0x9d, 0xae, 0x72, 0x16, 0x3d, 0x38, 0xfa, 0x95, 0xb4, 0x06, - 0x56, 0xcc, 0x85, 0x3e, 0xc6, 0x54, 0xc7, 0xc4, 0x5c, 0xc8, 0x63, 0x3e, 0x03, 0xeb, 0x80, 0xc0, - 0x93, 0x0c, 0x9e, 0xe5, 0x09, 0x87, 0x83, 0xe1, 0xcb, 0xbd, 0x96, 0xf1, 0x6a, 0xaf, 0x65, 0xfc, - 0xbd, 0xd7, 0x32, 0x7e, 0xde, 0x6f, 0x2d, 0xbc, 0xda, 0x6f, 0x2d, 0xfc, 0xb9, 0xdf, 0x5a, 0xf8, - 0xa1, 0x9f, 0x10, 0xb1, 0x55, 0x84, 0xbd, 0x88, 0x66, 0xfd, 0x30, 0x0f, 0xaf, 0x47, 0x5b, 0x88, - 0xe4, 0xfd, 0xca, 0x2b, 0x7d, 0xe7, 0xf0, 0xff, 0x8e, 0xf0, 0x9c, 0x7c, 0xa7, 0xdf, 0xfc, 0x2f, - 0x00, 0x00, 0xff, 0xff, 0xe9, 0x7b, 0x5b, 0x1a, 0x9a, 0x0c, 0x00, 0x00, + // 1166 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcf, 0x6e, 0xdb, 0xc6, + 0x13, 0x36, 0x4d, 0x29, 0x36, 0x47, 0x96, 0xf3, 0x0b, 0x23, 0xfc, 0xc2, 0x38, 0x88, 0xa4, 0x10, + 0x68, 0x21, 0xb4, 0xb5, 0x84, 0x38, 0x45, 0x50, 0x14, 0x01, 0x02, 0xab, 0x49, 0x03, 0xa1, 0x4d, + 0x8b, 0xd2, 0x4e, 0x0a, 0xf4, 0x42, 0x2c, 0xc9, 0x35, 0xbd, 0x0d, 0xc9, 0x55, 0x77, 0x97, 0x8e, + 0x95, 0xa7, 0xe8, 0x63, 0xf4, 0x5c, 0xe4, 0x05, 0x7a, 0x0b, 0x0a, 0x14, 0x08, 0x7c, 0x2a, 0x7a, + 0x30, 0x0a, 0xfb, 0x0d, 0x7a, 0xe8, 0xb9, 0xe0, 0xee, 0xca, 0xa1, 0x25, 0x39, 0xfe, 0x83, 0xe4, + 0xa6, 0x9d, 0xfd, 0x86, 0x3b, 0xf3, 0xcd, 0x37, 0xb3, 0x2b, 0x68, 0xc6, 0x0c, 0xe3, 0x6c, 0x8b, + 0xe0, 0x24, 0xea, 0x71, 0x41, 0x19, 0x8a, 0x71, 0x4f, 0x8c, 0x86, 0x98, 0x77, 0x87, 0x8c, 0x0a, + 0x6a, 0xdb, 0x6f, 0xf6, 0xbb, 0x7a, 0x7f, 0xa5, 0x19, 0x52, 0x9e, 0x52, 0xde, 0x0b, 0x10, 0xc7, + 0xbd, 0x9d, 0xdb, 0x01, 0x16, 0xe8, 0x76, 0x2f, 0xa4, 0x24, 0x53, 0x3e, 0x2b, 0xd7, 0xd5, 0xbe, + 0x2f, 0x57, 0x3d, 0xb5, 0xd0, 0x5b, 0x8d, 0x98, 0xc6, 0x54, 0xd9, 0x8b, 0x5f, 0xda, 0x7a, 0xab, + 0x14, 0xc4, 0x10, 0x8d, 0x52, 0x9c, 0x89, 0x1e, 0xcd, 0x85, 0xbf, 0x95, 0xd0, 0xe7, 0x1a, 0xf2, + 0xe1, 0x0c, 0x08, 0x17, 0x0c, 0xa3, 0xd4, 0x67, 0x38, 0xa4, 0x2c, 0xd2, 0xb8, 0xd6, 0x8c, 0x7c, + 0x42, 0x9a, 0xa6, 0x54, 0x07, 0xe7, 0xfe, 0x52, 0x01, 0xe8, 0xe7, 0xe1, 0x33, 0x2c, 0x06, 0xd9, + 0x16, 0xb5, 0xbb, 0x50, 0xa5, 0xcf, 0x33, 0xcc, 0x1c, 0xa3, 0x6d, 0x74, 0xac, 0xbe, 0xb3, 0xf7, + 0x72, 0xb5, 0xa1, 0x23, 0x5e, 0x8f, 0x22, 0x86, 0x39, 0xdf, 0x10, 0x8c, 0x64, 0xb1, 0xa7, 0x60, + 0x76, 0x0b, 0x6a, 0x81, 0xf4, 0xf6, 0x33, 0x94, 0x62, 0x67, 0xbe, 0xf0, 0xf2, 0x40, 0x99, 0xbe, + 0x41, 0x29, 0xb6, 0xfb, 0x00, 0x3b, 0x84, 0x93, 0x80, 0x24, 0x44, 0x8c, 0x1c, 0xb3, 0x6d, 0x74, + 0x96, 0xd7, 0xdc, 0xee, 0x34, 0x8b, 0xdd, 0xa7, 0x47, 0xa8, 0xcd, 0xd1, 0x10, 0x7b, 0x25, 0x2f, + 0xfb, 0x63, 0x98, 0x27, 0x91, 0x53, 0x91, 0x11, 0xdd, 0x78, 0xb5, 0xdf, 0x9a, 0xfb, 0x6b, 0xbf, + 0x55, 0x79, 0x42, 0x32, 0xb1, 0xf7, 0x72, 0xb5, 0xa6, 0xa3, 0x2b, 0x96, 0xde, 0x3c, 0x89, 0xec, + 0xfb, 0x50, 0xe3, 0x34, 0x67, 0x21, 0xf6, 0x8b, 0xba, 0x39, 0x55, 0x79, 0x62, 0x73, 0xd6, 0x89, + 0x1b, 0x12, 0xa6, 0x4e, 0xe3, 0x47, 0xbf, 0xed, 0x1b, 0x60, 0x85, 0x0c, 0x23, 0x81, 0x7d, 0x24, + 0x9c, 0x4b, 0x6d, 0xa3, 0x63, 0x7a, 0x8b, 0xca, 0xb0, 0x2e, 0xec, 0x75, 0xb8, 0xac, 0xe9, 0xf6, + 0x91, 0xe2, 0xc3, 0x59, 0x38, 0x85, 0xa9, 0x65, 0xed, 0xa0, 0xad, 0x76, 0x1f, 0x9a, 0x71, 0x42, + 0x03, 0x94, 0xf8, 0x3b, 0x84, 0x89, 0x1c, 0x25, 0x7e, 0xcc, 0x68, 0x3e, 0xf4, 0xb7, 0x50, 0x4a, + 0x92, 0x91, 0x4f, 0x22, 0x67, 0xb1, 0x6d, 0x74, 0xea, 0xde, 0x8a, 0x42, 0x3d, 0x55, 0xa0, 0x47, + 0x05, 0xe6, 0x4b, 0x09, 0x19, 0x44, 0xf6, 0x27, 0x60, 0x87, 0xdb, 0x88, 0xc5, 0x38, 0xf2, 0x19, + 0x46, 0x91, 0xff, 0x53, 0x4e, 0x05, 0x72, 0xac, 0xb6, 0xd1, 0xa9, 0x78, 0xff, 0xd3, 0x3b, 0x1e, + 0x46, 0xd1, 0x77, 0x85, 0xdd, 0x7e, 0x08, 0x75, 0x5d, 0x24, 0x2e, 0x90, 0xc8, 0xb9, 0x03, 0x92, + 0x94, 0xf6, 0x2c, 0x52, 0x94, 0x16, 0x36, 0x24, 0xce, 0x5b, 0x0a, 0x4a, 0x2b, 0xf7, 0x5f, 0x03, + 0xec, 0x41, 0x26, 0x30, 0xcb, 0x50, 0x52, 0x92, 0xcc, 0x4d, 0x80, 0x21, 0x23, 0x05, 0xdf, 0x24, + 0xc5, 0x52, 0x37, 0xa6, 0x67, 0x49, 0xcb, 0x26, 0x49, 0xb1, 0xfd, 0x11, 0x5c, 0x11, 0x54, 0xa0, + 0xc4, 0x57, 0x61, 0xf9, 0x9c, 0xbc, 0x50, 0x3a, 0xa9, 0x78, 0x97, 0xe5, 0xc6, 0x17, 0xd2, 0xbe, + 0x41, 0x5e, 0x60, 0xfb, 0x7b, 0x68, 0x24, 0x34, 0x9c, 0x64, 0x86, 0x3b, 0x66, 0xdb, 0xec, 0xd4, + 0xd6, 0x3e, 0x98, 0x15, 0xef, 0xd7, 0x05, 0xbe, 0xcc, 0x91, 0x67, 0x27, 0x93, 0x26, 0x6e, 0xdf, + 0x83, 0x1b, 0x19, 0xde, 0x15, 0xfe, 0x8c, 0xaf, 0xfb, 0x5a, 0x5a, 0x75, 0xef, 0x5a, 0x01, 0x99, + 0xfa, 0xde, 0x20, 0x72, 0x7f, 0xab, 0x02, 0x7c, 0x1b, 0xfc, 0x88, 0xc3, 0x8b, 0xf5, 0xc8, 0x1a, + 0x2c, 0x48, 0xfd, 0x50, 0xa6, 0xfa, 0xe3, 0x2d, 0x1e, 0x63, 0xe0, 0x64, 0x5f, 0x99, 0x53, 0x7d, + 0xd5, 0x82, 0x1a, 0x95, 0x21, 0x29, 0x40, 0x45, 0x01, 0x94, 0x49, 0x02, 0x54, 0xd3, 0x54, 0xcf, + 0xd6, 0x34, 0x77, 0xe0, 0xff, 0x27, 0x50, 0x73, 0x49, 0x52, 0x73, 0x35, 0x99, 0xa6, 0xc5, 0xbe, + 0x05, 0x4b, 0x43, 0x34, 0x4a, 0x28, 0x8a, 0x54, 0x51, 0x17, 0x64, 0x51, 0x6b, 0xda, 0x26, 0x0b, + 0x7a, 0xbc, 0xfb, 0x17, 0x2f, 0xd4, 0xfd, 0xb7, 0x60, 0x29, 0xa4, 0x99, 0x28, 0x5a, 0x4e, 0x76, + 0xb4, 0x25, 0x53, 0xad, 0x69, 0xdb, 0x74, 0xcb, 0xc2, 0x44, 0xcb, 0x3e, 0x84, 0xba, 0x66, 0x4a, + 0xab, 0xbf, 0x76, 0xb2, 0xfa, 0x55, 0x95, 0xc7, 0xea, 0xa7, 0xa5, 0x95, 0xfd, 0x15, 0x5c, 0x66, + 0x38, 0xca, 0xb3, 0x08, 0x65, 0xe1, 0x48, 0x45, 0xb2, 0x74, 0x72, 0x3e, 0xde, 0x11, 0x54, 0xe6, + 0xb3, 0xcc, 0x8e, 0xad, 0x27, 0x87, 0x54, 0xfd, 0xdc, 0x43, 0xaa, 0x07, 0x56, 0xb8, 0x8d, 0xc3, + 0x67, 0x3c, 0x4f, 0xb9, 0xb3, 0xdc, 0x36, 0x3b, 0x4b, 0xfd, 0x2b, 0xff, 0xec, 0xb7, 0xea, 0x82, + 0x21, 0x22, 0xf8, 0xe7, 0x2e, 0x4d, 0x89, 0x70, 0xbd, 0x37, 0x18, 0x77, 0xdf, 0x00, 0x4b, 0x15, + 0xee, 0x22, 0x12, 0xbe, 0x09, 0xa0, 0x14, 0x51, 0x9a, 0xf2, 0x96, 0xb4, 0x48, 0xad, 0x4d, 0xa4, + 0x63, 0x9e, 0x3b, 0x9d, 0x73, 0x4d, 0xf8, 0x06, 0x54, 0xf1, 0xae, 0x60, 0x48, 0x89, 0xdb, 0x53, + 0x0b, 0xf7, 0x1e, 0x54, 0x37, 0x8b, 0xe4, 0x8b, 0x58, 0x25, 0x0b, 0x2a, 0x16, 0x43, 0xc5, 0x2a, + 0x2d, 0xf2, 0xa8, 0x06, 0x54, 0x77, 0x50, 0x92, 0x8f, 0xb3, 0x50, 0x0b, 0xf7, 0x0f, 0x03, 0x96, + 0xd5, 0x4c, 0x7b, 0x8c, 0x05, 0x7a, 0x80, 0x04, 0xb2, 0xdb, 0x50, 0x8b, 0x30, 0x0f, 0x19, 0x19, + 0x0a, 0x42, 0x33, 0xfd, 0xa1, 0xb2, 0xa9, 0x50, 0x26, 0xde, 0x55, 0xf3, 0xd0, 0xcf, 0x59, 0xa2, + 0xbf, 0x58, 0x1b, 0xdb, 0x9e, 0xb0, 0xe4, 0xf4, 0x3e, 0x6e, 0x40, 0x95, 0xa4, 0x28, 0x1e, 0x77, + 0xb0, 0x5a, 0xd8, 0xf7, 0x01, 0x90, 0x10, 0x8c, 0x04, 0xb9, 0xc0, 0xdc, 0xa9, 0xca, 0xf1, 0x77, + 0x7d, 0x16, 0x9f, 0x32, 0xe5, 0x7e, 0xa5, 0xa0, 0xcc, 0x2b, 0xb9, 0xc8, 0x7c, 0x94, 0x98, 0xdf, + 0x79, 0x3e, 0xe5, 0xb1, 0x63, 0x4e, 0x8d, 0x9d, 0xf7, 0x94, 0xcf, 0xef, 0x06, 0xd4, 0xa5, 0x7c, + 0xdf, 0x6d, 0x3a, 0xc7, 0x75, 0x6d, 0x4e, 0xea, 0xfa, 0x3d, 0x25, 0xb3, 0x06, 0xe6, 0x20, 0xe2, + 0x5a, 0xf4, 0x46, 0xdb, 0x3c, 0x83, 0xe8, 0xdd, 0x5f, 0x0d, 0x80, 0x07, 0x38, 0xc1, 0x02, 0xcb, + 0x06, 0xbe, 0x0b, 0x5a, 0x44, 0x3e, 0x89, 0xb8, 0x4c, 0xbe, 0xb6, 0x76, 0x6d, 0x56, 0x0c, 0x83, + 0x88, 0x7b, 0x96, 0x82, 0x16, 0x67, 0xde, 0x05, 0x5d, 0x2c, 0xe9, 0x37, 0x7f, 0x8a, 0x9f, 0x82, + 0x16, 0x7e, 0x9f, 0x82, 0x35, 0xbe, 0x12, 0xb8, 0xe4, 0xe9, 0x2d, 0x6e, 0x8b, 0xb1, 0xba, 0x20, + 0xb8, 0xbb, 0x67, 0xc0, 0xd5, 0xc7, 0x24, 0x66, 0xa8, 0xa8, 0x47, 0xe9, 0xc9, 0xb0, 0x02, 0x16, + 0x67, 0xa1, 0xcf, 0xe5, 0x0d, 0x63, 0xc8, 0x1b, 0x66, 0x81, 0xb3, 0x70, 0xa3, 0xb8, 0x55, 0x06, + 0xe0, 0x16, 0x7b, 0xa7, 0x3c, 0x91, 0xe6, 0xa5, 0xd3, 0x4d, 0xce, 0xc2, 0x47, 0x27, 0xbf, 0x92, + 0x56, 0xc0, 0x8a, 0xb8, 0xd0, 0xc7, 0x98, 0xea, 0x98, 0x88, 0x0b, 0x79, 0xcc, 0x67, 0x60, 0x1d, + 0x11, 0x78, 0x96, 0xc1, 0xb3, 0x38, 0xe6, 0xb0, 0x3f, 0x78, 0x75, 0xd0, 0x34, 0x5e, 0x1f, 0x34, + 0x8d, 0xbf, 0x0f, 0x9a, 0xc6, 0xcf, 0x87, 0xcd, 0xb9, 0xd7, 0x87, 0xcd, 0xb9, 0x3f, 0x0f, 0x9b, + 0x73, 0x3f, 0xf4, 0x62, 0x22, 0xb6, 0xf3, 0xa0, 0x1b, 0xd2, 0xb4, 0x17, 0x64, 0xc1, 0x6a, 0xb8, + 0x8d, 0x48, 0xd6, 0x2b, 0xbd, 0xc0, 0x77, 0x8f, 0xff, 0xa7, 0x08, 0x2e, 0xc9, 0x37, 0xf8, 0x9d, + 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x44, 0x17, 0xd2, 0x5c, 0x76, 0x0c, 0x00, 0x00, } func (m *BucketInfo) Marshal() (dAtA []byte, err error) { @@ -1030,21 +1019,16 @@ func (m *BucketInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.BucketStatus != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.BucketStatus)) i-- - dAtA[i] = 0x58 + dAtA[i] = 0x50 } if m.ChargedReadQuota != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.ChargedReadQuota)) i-- - dAtA[i] = 0x50 + dAtA[i] = 0x48 } if m.GlobalVirtualGroupFamilyId != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.GlobalVirtualGroupFamilyId)) i-- - dAtA[i] = 0x48 - } - if m.PrimarySpId != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.PrimarySpId)) - i-- dAtA[i] = 0x40 } if len(m.PaymentAddress) > 0 { @@ -1735,9 +1719,6 @@ func (m *BucketInfo) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - if m.PrimarySpId != 0 { - n += 1 + sovTypes(uint64(m.PrimarySpId)) - } if m.GlobalVirtualGroupFamilyId != 0 { n += 1 + sovTypes(uint64(m.GlobalVirtualGroupFamilyId)) } @@ -2247,25 +2228,6 @@ func (m *BucketInfo) Unmarshal(dAtA []byte) error { m.PaymentAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) - } - m.PrimarySpId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.PrimarySpId |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilyId", wireType) } @@ -2284,7 +2246,7 @@ func (m *BucketInfo) Unmarshal(dAtA []byte) error { break } } - case 10: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ChargedReadQuota", wireType) } @@ -2303,7 +2265,7 @@ func (m *BucketInfo) Unmarshal(dAtA []byte) error { break } } - case 11: + case 10: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field BucketStatus", wireType) } diff --git a/x/virtualgroup/client/cli/query.go b/x/virtualgroup/client/cli/query.go index 0792156ff..0ca76153b 100644 --- a/x/virtualgroup/client/cli/query.go +++ b/x/virtualgroup/client/cli/query.go @@ -1,9 +1,11 @@ package cli import ( + "context" "fmt" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" "github.com/bnb-chain/greenfield/x/virtualgroup/types" @@ -22,10 +24,35 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdGlobalVirtualGroup()) cmd.AddCommand(CmdGlobalVirtualGroupByFamilyID()) - cmd.AddCommand(CmdGlobalVirtualGroupFamilies()) cmd.AddCommand(CmdGlobalVirtualGroupFamily()) + cmd.AddCommand(CmdGlobalVirtualGroupFamilies()) + cmd.AddCommand(CmdQueryParams()) // this line is used by starport scaffolding # 1 return cmd } + +func CmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the parameters of the virtual group module", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/virtualgroup/client/cli/query_global_virtual_group_families.go b/x/virtualgroup/client/cli/query_global_virtual_group_families.go index 29415162b..6714a67dd 100644 --- a/x/virtualgroup/client/cli/query_global_virtual_group_families.go +++ b/x/virtualgroup/client/cli/query_global_virtual_group_families.go @@ -16,14 +16,10 @@ var _ = strconv.Itoa(0) func CmdGlobalVirtualGroupFamilies() *cobra.Command { cmd := &cobra.Command{ - Use: "global-virtual-group-families [sp-id] [limit]", + Use: "global-virtual-group-families [limit]", Short: "query all global virtual groups families of the storage provider.", - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { - spID, err := strconv.ParseInt(args[0], 10, 32) - if err != nil || spID <= 0 { - return fmt.Errorf("invalid GVG id %s", args[1]) - } limit, err := strconv.ParseInt(args[1], 10, 32) if err != nil || limit <= 0 { @@ -38,8 +34,7 @@ func CmdGlobalVirtualGroupFamilies() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) params := &types.QueryGlobalVirtualGroupFamiliesRequest{ - StorageProviderId: uint32(spID), - Pagination: &query.PageRequest{Limit: uint64(limit)}, + Pagination: &query.PageRequest{Limit: uint64(limit)}, } res, err := queryClient.GlobalVirtualGroupFamilies(cmd.Context(), params) diff --git a/x/virtualgroup/client/cli/query_global_virtual_group_family.go b/x/virtualgroup/client/cli/query_global_virtual_group_family.go index 3ac267526..aba64f63b 100644 --- a/x/virtualgroup/client/cli/query_global_virtual_group_family.go +++ b/x/virtualgroup/client/cli/query_global_virtual_group_family.go @@ -15,16 +15,11 @@ var _ = strconv.Itoa(0) func CmdGlobalVirtualGroupFamily() *cobra.Command { cmd := &cobra.Command{ - Use: "global-virtual-group-family [sp-id] [family-id]", - Short: "query global virtual group family by its id.", - Args: cobra.ExactArgs(2), + Use: "global-virtual-group-family [family-id]", + Short: "query global virtual group family.", + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { - spID, err := strconv.ParseInt(args[0], 10, 32) - if err != nil || spID <= 0 { - return fmt.Errorf("invalid GVG id %s", args[1]) - } - - familyID, err := strconv.ParseInt(args[1], 10, 32) + familyID, err := strconv.ParseInt(args[0], 10, 32) if err != nil || familyID <= 0 { return fmt.Errorf("invalid GVG id %s", args[1]) } @@ -36,8 +31,7 @@ func CmdGlobalVirtualGroupFamily() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) params := &types.QueryGlobalVirtualGroupFamilyRequest{ - StorageProviderId: uint32(spID), - FamilyId: uint32(familyID), + FamilyId: uint32(familyID), } res, err := queryClient.GlobalVirtualGroupFamily(cmd.Context(), params) diff --git a/x/virtualgroup/keeper/grpc_query.go b/x/virtualgroup/keeper/grpc_query.go index b5a84ef3a..568f8614f 100644 --- a/x/virtualgroup/keeper/grpc_query.go +++ b/x/virtualgroup/keeper/grpc_query.go @@ -2,15 +2,14 @@ package keeper import ( "context" + "math" + "github.com/bnb-chain/greenfield/x/virtualgroup/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - - "github.com/bnb-chain/greenfield/internal/sequence" - "github.com/bnb-chain/greenfield/x/virtualgroup/types" ) func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { @@ -52,7 +51,7 @@ func (k Keeper) GlobalVirtualGroupByFamilyID(goCtx context.Context, req *types.Q return nil, status.Error(codes.InvalidArgument, "invalid request") } - gvgFamily, found := k.GetGVGFamily(ctx, req.StorageProviderId, req.GlobalVirtualGroupFamilyId) + gvgFamily, found := k.GetGVGFamily(ctx, req.GlobalVirtualGroupFamilyId) if !found { return nil, types.ErrGVGFamilyNotExist } @@ -68,7 +67,7 @@ func (k Keeper) GlobalVirtualGroupByFamilyID(goCtx context.Context, req *types.Q return &types.QueryGlobalVirtualGroupByFamilyIDResponse{GlobalVirtualGroups: gvgs}, nil } -func (k Keeper) GlobalVirtualGroupFamilies(goCtx context.Context, req *types.QueryGlobalVirtualGroupFamiliesRequest) (*types.QueryGlobalVirtualGroupFamiliesResponse, error) { +func (k Keeper) GlobalVirtualGroupFamily(goCtx context.Context, req *types.QueryGlobalVirtualGroupFamilyRequest) (*types.QueryGlobalVirtualGroupFamilyResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -79,38 +78,55 @@ func (k Keeper) GlobalVirtualGroupFamilies(goCtx context.Context, req *types.Que return nil, status.Error(codes.InvalidArgument, "invalid request") } + gvgFamily, found := k.GetGVGFamily(ctx, req.FamilyId) + if !found { + return nil, types.ErrGVGFamilyNotExist + } + + return &types.QueryGlobalVirtualGroupFamilyResponse{GlobalVirtualGroupFamily: gvgFamily}, nil +} + +func (k Keeper) GlobalVirtualGroupFamilies(goCtx context.Context, req *types.QueryGlobalVirtualGroupFamiliesRequest) (*types.QueryGlobalVirtualGroupFamiliesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + var gvgFamilies []*types.GlobalVirtualGroupFamily store := ctx.KVStore(k.storeKey) - var uint32Sequence sequence.Sequence[uint32] - gvgFamiliesStore := prefix.NewStore(store, append(types.GVGFamilyKey, uint32Sequence.EncodeSequence(req.StorageProviderId)...)) - var gvgFamiles []*types.GlobalVirtualGroupFamily - pageRes, err := query.Paginate(gvgFamiliesStore, req.Pagination, func(key []byte, value []byte) error { + gvgFamilyStore := prefix.NewStore(store, types.GVGFamilyKey) + + pageRes, err := query.Paginate(gvgFamilyStore, req.Pagination, func(key []byte, value []byte) error { var gvgFamily types.GlobalVirtualGroupFamily k.cdc.MustUnmarshal(value, &gvgFamily) - gvgFamiles = append(gvgFamiles, &gvgFamily) + gvgFamilies = append(gvgFamilies, &gvgFamily) return nil }) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - - return &types.QueryGlobalVirtualGroupFamiliesResponse{GlobalVirtualGroupFamilies: gvgFamiles, Pagination: pageRes}, nil + return &types.QueryGlobalVirtualGroupFamiliesResponse{GvgFamilies: gvgFamilies, Pagination: pageRes}, nil } -func (k Keeper) GlobalVirtualGroupFamily(goCtx context.Context, req *types.QueryGlobalVirtualGroupFamilyRequest) (*types.QueryGlobalVirtualGroupFamilyResponse, error) { +func (k Keeper) AvailableGlobalVirtualGroupFamilies(goCtx context.Context, req *types.AvailableGlobalVirtualGroupFamiliesRequest) (*types.AvailableGlobalVirtualGroupFamiliesResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - ctx := sdk.UnwrapSDKContext(goCtx) - - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") - } - - gvgFamily, found := k.GetGVGFamily(ctx, req.StorageProviderId, req.FamilyId) - if !found { - return nil, types.ErrGVGNotExist + availableFamilyIds := make([]uint32, 0) + for _, gvgfID := range req.GlobalVirtualGroupFamilyIds { + gvgFamily, found := k.GetGVGFamily(ctx, gvgfID) + if !found { + return nil, types.ErrGVGFamilyNotExist + } + totalStakingSize, stored, err := k.GetGlobalVirtualFamilyTotalStakingAndStoredSize(ctx, gvgFamily) + if err != nil { + return nil, err + } + if float64(stored) < math.Min(float64(totalStakingSize), float64(k.MaxStoreSizePerFamily(ctx))) && uint32(len(gvgFamily.GlobalVirtualGroupIds)) < k.MaxGlobalVirtualGroupNumPerFamily(ctx) { + availableFamilyIds = append(availableFamilyIds, gvgfID) + } } - - return &types.QueryGlobalVirtualGroupFamilyResponse{GlobalVirtualGroupFamily: gvgFamily}, nil + return &types.AvailableGlobalVirtualGroupFamiliesResponse{GlobalVirtualGroupFamilyIds: availableFamilyIds}, nil } diff --git a/x/virtualgroup/keeper/keeper.go b/x/virtualgroup/keeper/keeper.go index e4edf370d..d60353b2f 100644 --- a/x/virtualgroup/keeper/keeper.go +++ b/x/virtualgroup/keeper/keeper.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" @@ -93,8 +92,21 @@ func (k Keeper) SetGVG(ctx sdk.Context, gvg *types.GlobalVirtualGroup) { store.Set(types.GetGVGKey(gvg.Id), bz) } -func (k Keeper) DeleteGVG(ctx sdk.Context, primarySp *sptypes.StorageProvider, gvgID uint32) error { +func (k Keeper) SetGVGAndEmitUpdateEvent(ctx sdk.Context, gvg *types.GlobalVirtualGroup) error { + k.SetGVG(ctx, gvg) + if err := ctx.EventManager().EmitTypedEvents(&types.EventUpdateGlobalVirtualGroup{ + Id: gvg.Id, + PrimarySpId: gvg.PrimarySpId, + StoreSize: gvg.StoredSize, + TotalDeposit: gvg.TotalDeposit, + SecondarySpIds: gvg.SecondarySpIds, + }); err != nil { + return err + } + return nil +} +func (k Keeper) DeleteGVG(ctx sdk.Context, primarySp *sptypes.StorageProvider, gvgID uint32) error { store := ctx.KVStore(k.storeKey) gvg, found := k.GetGVG(ctx, gvgID) @@ -119,13 +131,18 @@ func (k Keeper) DeleteGVG(ctx sdk.Context, primarySp *sptypes.StorageProvider, g } } - gvgFamily, found := k.GetGVGFamily(ctx, primarySp.Id, gvg.FamilyId) + gvgFamily, found := k.GetGVGFamily(ctx, gvg.FamilyId) if !found { panic("not found gvg family when delete gvg") } gvgFamily.MustRemoveGVG(gvg.Id) + // update stat + stat := k.MustGetGVGStatisticsWithinSP(ctx, gvgFamily.PrimarySpId) + stat.PrimaryCount-- + k.SetGVGStatisticsWithSP(ctx, stat) + for _, secondarySPID := range gvg.SecondarySpIds { gvgStatisticsWithinSP := k.MustGetGVGStatisticsWithinSP(ctx, secondarySPID) gvgStatisticsWithinSP.SecondaryCount-- @@ -133,11 +150,25 @@ func (k Keeper) DeleteGVG(ctx sdk.Context, primarySp *sptypes.StorageProvider, g } store.Delete(types.GetGVGKey(gvg.Id)) + if err := ctx.EventManager().EmitTypedEvents(&types.EventDeleteGlobalVirtualGroup{ + Id: gvg.Id, + PrimarySpId: gvg.PrimarySpId, + }); err != nil { + return err + } if k.paymentKeeper.IsEmptyNetFlow(ctx, sdk.MustAccAddressFromHex(gvgFamily.VirtualPaymentAddress)) { - store.Delete(types.GetGVGFamilyKey(primarySp.Id, gvg.FamilyId)) + store.Delete(types.GetGVGFamilyKey(gvg.FamilyId)) + if err := ctx.EventManager().EmitTypedEvents(&types.EventDeleteGlobalVirtualGroupFamily{ + Id: gvgFamily.Id, + PrimarySpId: gvgFamily.PrimarySpId, + }); err != nil { + return err + } } else { - k.SetGVGFamily(ctx, gvg.PrimarySpId, gvgFamily) + if err := k.SetGVGFamilyAndEmitUpdateEvent(ctx, gvgFamily); err != nil { + return err + } } return nil } @@ -155,19 +186,30 @@ func (k Keeper) GetGVG(ctx sdk.Context, gvgID uint32) (*types.GlobalVirtualGroup return &gvg, true } -func (k Keeper) SetGVGFamily(ctx sdk.Context, primarySpID uint32, gvgFamily *types.GlobalVirtualGroupFamily) { +func (k Keeper) SetGVGFamilyAndEmitUpdateEvent(ctx sdk.Context, gvgFamily *types.GlobalVirtualGroupFamily) error { + k.SetGVGFamily(ctx, gvgFamily) + if err := ctx.EventManager().EmitTypedEvents(&types.EventUpdateGlobalVirtualGroupFamily{ + Id: gvgFamily.Id, + PrimarySpId: gvgFamily.PrimarySpId, + GlobalVirtualGroupIds: gvgFamily.GlobalVirtualGroupIds, + }); err != nil { + return err + } + return nil +} +func (k Keeper) SetGVGFamily(ctx sdk.Context, gvgFamily *types.GlobalVirtualGroupFamily) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(gvgFamily) - store.Set(types.GetGVGFamilyKey(primarySpID, gvgFamily.Id), bz) + store.Set(types.GetGVGFamilyKey(gvgFamily.Id), bz) } -func (k Keeper) GetGVGFamily(ctx sdk.Context, spID, familyID uint32) (*types.GlobalVirtualGroupFamily, bool) { +func (k Keeper) GetGVGFamily(ctx sdk.Context, familyID uint32) (*types.GlobalVirtualGroupFamily, bool) { store := ctx.KVStore(k.storeKey) var gvgFamily types.GlobalVirtualGroupFamily - bz := store.Get(types.GetGVGFamilyKey(spID, familyID)) + bz := store.Get(types.GetGVGFamilyKey(familyID)) if bz == nil { return nil, false } @@ -175,8 +217,8 @@ func (k Keeper) GetGVGFamily(ctx sdk.Context, spID, familyID uint32) (*types.Glo return &gvgFamily, true } -func (k Keeper) GetAndCheckGVGFamilyAvailableForNewBucket(ctx sdk.Context, spID, familyID uint32) (*types.GlobalVirtualGroupFamily, error) { - gvgFamily, found := k.GetGVGFamily(ctx, spID, familyID) +func (k Keeper) GetAndCheckGVGFamilyAvailableForNewBucket(ctx sdk.Context, familyID uint32) (*types.GlobalVirtualGroupFamily, error) { + gvgFamily, found := k.GetGVGFamily(ctx, familyID) if !found { return nil, types.ErrGVGFamilyNotExist } @@ -190,7 +232,7 @@ func (k Keeper) GetAndCheckGVGFamilyAvailableForNewBucket(ctx sdk.Context, spID, return gvgFamily, nil } -func (k Keeper) GetOrCreateEmptyGVGFamily(ctx sdk.Context, familyID uint32, spID uint32) (*types.GlobalVirtualGroupFamily, error) { +func (k Keeper) GetOrCreateEmptyGVGFamily(ctx sdk.Context, familyID uint32, primarySPID uint32) (*types.GlobalVirtualGroupFamily, error) { store := ctx.KVStore(k.storeKey) var gvgFamily types.GlobalVirtualGroupFamily // If familyID is not specified, a new family needs to be created @@ -198,11 +240,12 @@ func (k Keeper) GetOrCreateEmptyGVGFamily(ctx sdk.Context, familyID uint32, spID id := k.GenNextGVGFamilyID(ctx) gvgFamily = types.GlobalVirtualGroupFamily{ Id: id, + PrimarySpId: primarySPID, VirtualPaymentAddress: k.DeriveVirtualPaymentAccount(types.GVGFamilyName, id).String(), } return &gvgFamily, nil } else { - bz := store.Get(types.GetGVGFamilyKey(spID, familyID)) + bz := store.Get(types.GetGVGFamilyKey(familyID)) if bz == nil { return nil, types.ErrGVGFamilyNotExist } @@ -228,12 +271,18 @@ func (k Keeper) GetAvailableStakingTokens(ctx sdk.Context, gvg *types.GlobalVirt } func (k Keeper) SwapOutAsPrimarySP(ctx sdk.Context, primarySP, successorSP *sptypes.StorageProvider, familyID uint32) error { - store := ctx.KVStore(k.storeKey) - family, found := k.GetGVGFamily(ctx, primarySP.Id, familyID) + family, found := k.GetGVGFamily(ctx, familyID) if !found { return types.ErrGVGFamilyNotExist } + if family.PrimarySpId != primarySP.Id { + return types.ErrSwapOutFailed.Wrapf("the family(ID: %d) is not owned by primary sp(ID: %d)", family.Id, primarySP.Id) + } + + srcStat := k.MustGetGVGStatisticsWithinSP(ctx, primarySP.Id) + dstStat := k.GetOrCreateGVGStatisticsWithinSP(ctx, successorSP.Id) + var gvgs []*types.GlobalVirtualGroup for _, gvgID := range family.GlobalVirtualGroupIds { gvg, found := k.GetGVG(ctx, gvgID) @@ -261,19 +310,30 @@ func (k Keeper) SwapOutAsPrimarySP(ctx sdk.Context, primarySP, successorSP *spty gvg.PrimarySpId = successorSP.Id gvgs = append(gvgs, gvg) + srcStat.PrimaryCount-- + dstStat.PrimaryCount++ } + family.PrimarySpId = successorSP.Id + // settlement err := k.SettleAndDistributeGVGFamily(ctx, primarySP, family) if err != nil { return types.ErrSwapOutFailed.Wrapf("fail to settle GVG family %d", familyID) } - k.SetGVGFamily(ctx, successorSP.Id, family) + if err := k.SetGVGFamilyAndEmitUpdateEvent(ctx, family); err != nil { + return types.ErrSwapOutFailed.Wrapf("failed to set gvg family and emit update event, err: %s", err) + } + for _, gvg := range gvgs { - k.SetGVG(ctx, gvg) + if err := k.SetGVGAndEmitUpdateEvent(ctx, gvg); err != nil { + return types.ErrSwapOutFailed.Wrapf("failed to set gvg and emit update event, err: %s", err) + } } - store.Delete(types.GetGVGFamilyKey(primarySP.Id, familyID)) + k.SetGVGStatisticsWithSP(ctx, srcStat) + k.SetGVGStatisticsWithSP(ctx, dstStat) + return nil } @@ -318,7 +378,11 @@ func (k Keeper) SwapOutAsSecondarySP(ctx sdk.Context, secondarySP, successorSP * successor.SecondaryCount++ k.SetGVGStatisticsWithSP(ctx, origin) k.SetGVGStatisticsWithSP(ctx, successor) - k.SetGVG(ctx, gvg) + + if err := k.SetGVGAndEmitUpdateEvent(ctx, gvg); err != nil { + return err + } + return nil } @@ -379,19 +443,15 @@ func (k Keeper) BatchSetGVGStatisticsWithinSP(ctx sdk.Context, gvgsStatisticsWit } func (k Keeper) StorageProviderExitable(ctx sdk.Context, spID uint32) error { - store := ctx.KVStore(k.storeKey) - - prefixStore := prefix.NewStore(store, types.GetGVGFamilyPrefixKey(spID)) - iter := prefixStore.Iterator(nil, nil) - if iter.Valid() { - var family types.GlobalVirtualGroupFamily - k.cdc.MustUnmarshal(iter.Value(), &family) - return types.ErrSPCanNotExit.Wrapf("not swap out from all the family, key: %s", family.String()) - } + stat, found := k.GetGVGStatisticsWithinSP(ctx, spID) + if found { + if stat.PrimaryCount != 0 { + return types.ErrSPCanNotExit.Wrapf("not swap out from all the family, stat: %s", stat.String()) + } - gvgStat, found := k.GetGVGStatisticsWithinSP(ctx, spID) - if found && gvgStat.SecondaryCount != 0 { - return types.ErrSPCanNotExit.Wrapf("not swap out from all the gvgs, remain: %d", gvgStat.SecondaryCount) + if stat.SecondaryCount != 0 { + return types.ErrSPCanNotExit.Wrapf("not swap out from all the gvgs, stat: %s", stat.String()) + } } return nil } @@ -420,6 +480,20 @@ func (k Keeper) GetTotalStakingStoreSize(ctx sdk.Context, gvg *types.GlobalVirtu } } +func (k Keeper) GetGlobalVirtualFamilyTotalStakingAndStoredSize(ctx sdk.Context, gvgFamily *types.GlobalVirtualGroupFamily) (uint64, uint64, error) { + var familyTotalStakingSize uint64 + var familyStoredSize uint64 + for _, gvgID := range gvgFamily.GlobalVirtualGroupIds { + gvg, found := k.GetGVG(ctx, gvgID) + if !found { + return 0, 0, types.ErrGVGNotExist + } + familyTotalStakingSize += k.GetTotalStakingStoreSize(ctx, gvg) + familyStoredSize += gvg.GetStoredSize() + } + return familyTotalStakingSize, familyStoredSize, nil +} + func (k Keeper) GetGlobalVirtualGroupIfAvailable(ctx sdk.Context, gvgID uint32, expectedStoreSize uint64) (*types.GlobalVirtualGroup, error) { gvg, found := k.GetGVG(ctx, gvgID) if !found { diff --git a/x/virtualgroup/keeper/msg_server.go b/x/virtualgroup/keeper/msg_server.go index 4a11bf00f..4ee5e956f 100644 --- a/x/virtualgroup/keeper/msg_server.go +++ b/x/virtualgroup/keeper/msg_server.go @@ -34,8 +34,8 @@ func (k msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParam // Some parameters cannot be modified originParams := k.GetParams(ctx) - if req.Params.GvgStakingPerBytes != originParams.GvgStakingPerBytes || req.Params.DepositDenom != originParams.DepositDenom { - return nil, errors.ErrInvalidParameter.Wrap("GvgStakingPerBytes and depositDenom are not allow to update") + if !req.Params.GvgStakingPerBytes.Equal(originParams.GvgStakingPerBytes) || req.Params.DepositDenom != originParams.DepositDenom { + return nil, errors.ErrInvalidParameter.Wrapf("GvgStakingPerBytes and depositDenom are not allow to update, current: %v, %v, got: %v, %v", originParams.GvgStakingPerBytes, originParams.DepositDenom, req.Params.GvgStakingPerBytes, req.Params.DepositDenom) } if err := k.SetParams(ctx, req.Params); err != nil { @@ -55,6 +55,11 @@ func (k msgServer) CreateGlobalVirtualGroup(goCtx context.Context, req *types.Ms if !found { return nil, sptypes.ErrStorageProviderNotFound.Wrapf("The address must be operator address of sp.") } + + stat := k.GetOrCreateGVGStatisticsWithinSP(ctx, sp.Id) + stat.PrimaryCount++ + gvgStatisticsWithinSPs = append(gvgStatisticsWithinSPs, stat) + var secondarySpIds []uint32 for _, id := range req.SecondarySpIds { ssp, found := k.spKeeper.GetStorageProvider(ctx, id) @@ -98,7 +103,7 @@ func (k msgServer) CreateGlobalVirtualGroup(goCtx context.Context, req *types.Ms gvgFamily.AppendGVG(gvg.Id) k.SetGVG(ctx, gvg) - k.SetGVGFamily(ctx, gvg.PrimarySpId, gvgFamily) + k.SetGVGFamily(ctx, gvgFamily) k.BatchSetGVGStatisticsWithinSP(ctx, gvgStatisticsWithinSPs) if err := ctx.EventManager().EmitTypedEvents(&types.EventCreateGlobalVirtualGroup{ @@ -114,7 +119,8 @@ func (k msgServer) CreateGlobalVirtualGroup(goCtx context.Context, req *types.Ms } if req.FamilyId == types.NoSpecifiedFamilyId { if err := ctx.EventManager().EmitTypedEvents(&types.EventCreateGlobalVirtualGroupFamily{ - Id: gvg.Id, + Id: gvgFamily.Id, + PrimarySpId: gvgFamily.PrimarySpId, VirtualPaymentAddress: gvgFamily.VirtualPaymentAddress, }); err != nil { return nil, err @@ -139,7 +145,8 @@ func (k msgServer) DeleteGlobalVirtualGroup(goCtx context.Context, req *types.Ms } if err = ctx.EventManager().EmitTypedEvents(&types.EventDeleteGlobalVirtualGroup{ - Id: req.GlobalVirtualGroupId, + Id: req.GlobalVirtualGroupId, + PrimarySpId: sp.Id, }); err != nil { return nil, err } @@ -181,9 +188,11 @@ func (k msgServer) Deposit(goCtx context.Context, req *types.MsgDeposit) (*types k.SetGVG(ctx, gvg) if err := ctx.EventManager().EmitTypedEvents(&types.EventUpdateGlobalVirtualGroup{ - Id: req.GlobalVirtualGroupId, - StoreSize: gvg.StoredSize, - TotalDeposit: gvg.TotalDeposit, + Id: gvg.Id, + PrimarySpId: gvg.PrimarySpId, + StoreSize: gvg.StoredSize, + TotalDeposit: gvg.TotalDeposit, + SecondarySpIds: gvg.SecondarySpIds, }); err != nil { return nil, err } @@ -334,7 +343,7 @@ func (k msgServer) Settle(goCtx context.Context, req *types.MsgSettle) (*types.M } if req.GlobalVirtualGroupFamilyId != types.NoSpecifiedFamilyId { - family, found := k.GetGVGFamily(ctx, sp.Id, req.GlobalVirtualGroupFamilyId) + family, found := k.GetGVGFamily(ctx, req.GlobalVirtualGroupFamilyId) if !found { return nil, types.ErrGVGFamilyNotExist } diff --git a/x/virtualgroup/keeper/payment_test.go b/x/virtualgroup/keeper/payment_test.go new file mode 100644 index 000000000..a8acb37f7 --- /dev/null +++ b/x/virtualgroup/keeper/payment_test.go @@ -0,0 +1,125 @@ +package keeper_test + +import ( + "errors" + "testing" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/bnb-chain/greenfield/testutil/sample" + "github.com/bnb-chain/greenfield/x/challenge" + sptypes "github.com/bnb-chain/greenfield/x/sp/types" + "github.com/bnb-chain/greenfield/x/virtualgroup/keeper" + "github.com/bnb-chain/greenfield/x/virtualgroup/types" +) + +type TestSuite struct { + suite.Suite + + cdc codec.Codec + virtualgroupKeeper *keeper.Keeper + + bankKeeper *types.MockBankKeeper + accountKeeper *types.MockAccountKeeper + spKeeper *types.MockSpKeeper + paymentKeeper *types.MockPaymentKeeper + + ctx sdk.Context +} + +func (s *TestSuite) SetupTest() { + encCfg := moduletestutil.MakeTestEncodingConfig(challenge.AppModuleBasic{}) + key := storetypes.NewKVStoreKey(types.StoreKey) + testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test")) + + ctrl := gomock.NewController(s.T()) + + bankKeeper := types.NewMockBankKeeper(ctrl) + accountKeeper := types.NewMockAccountKeeper(ctrl) + spKeeper := types.NewMockSpKeeper(ctrl) + paymentKeeper := types.NewMockPaymentKeeper(ctrl) + + s.ctx = testCtx.Ctx + s.virtualgroupKeeper = keeper.NewKeeper( + encCfg.Codec, + key, + key, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + spKeeper, + accountKeeper, + bankKeeper, + paymentKeeper, + ) + + s.cdc = encCfg.Codec + s.bankKeeper = bankKeeper + s.accountKeeper = accountKeeper + s.spKeeper = spKeeper + s.paymentKeeper = paymentKeeper + + err := s.virtualgroupKeeper.SetParams(s.ctx, types.DefaultParams()) + s.Require().NoError(err) +} + +func TestTestSuite(t *testing.T) { + suite.Run(t, new(TestSuite)) +} + +func (s *TestSuite) TestSettleAndDistributeGVGFamily() { + sp := &sptypes.StorageProvider{Id: 1, FundingAddress: sample.RandAccAddress().String()} + family := &types.GlobalVirtualGroupFamily{Id: 1, VirtualPaymentAddress: sample.RandAccAddress().String()} + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.ZeroInt(), nil) + err := s.virtualgroupKeeper.SettleAndDistributeGVGFamily(s.ctx, sp, family) + require.NoError(s.T(), err) + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.ZeroInt(), errors.New("error")) + err = s.virtualgroupKeeper.SettleAndDistributeGVGFamily(s.ctx, sp, family) + require.Error(s.T(), err) + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.NewInt(1024), nil) + s.paymentKeeper.EXPECT().Withdraw(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + err = s.virtualgroupKeeper.SettleAndDistributeGVGFamily(s.ctx, sp, family) + require.NoError(s.T(), err) +} + +func (s *TestSuite) TestSettleAndDistributeGVG() { + gvg := &types.GlobalVirtualGroup{Id: 1, + VirtualPaymentAddress: sample.RandAccAddress().String(), + SecondarySpIds: []uint32{3, 6, 9}} + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.ZeroInt(), nil) + err := s.virtualgroupKeeper.SettleAndDistributeGVG(s.ctx, gvg) + require.NoError(s.T(), err) + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.ZeroInt(), errors.New("error")) + err = s.virtualgroupKeeper.SettleAndDistributeGVG(s.ctx, gvg) + require.Error(s.T(), err) + + s.paymentKeeper.EXPECT().QueryDynamicBalance(gomock.Any(), gomock.Any()). + Return(math.NewInt(1024), nil).AnyTimes() + s.paymentKeeper.EXPECT().Withdraw(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil).AnyTimes() + + sp := &sptypes.StorageProvider{Id: 1, FundingAddress: sample.RandAccAddress().String()} + s.spKeeper.EXPECT().GetStorageProvider(gomock.Any(), gomock.Any()). + Return(sp, true).AnyTimes() + err = s.virtualgroupKeeper.SettleAndDistributeGVG(s.ctx, gvg) + require.NoError(s.T(), err) +} diff --git a/x/virtualgroup/types/events.pb.go b/x/virtualgroup/types/events.pb.go index 9d55414d1..8c1c0afca 100644 --- a/x/virtualgroup/types/events.pb.go +++ b/x/virtualgroup/types/events.pb.go @@ -118,19 +118,151 @@ func (m *EventCreateGlobalVirtualGroup) GetVirtualPaymentAddress() string { return "" } +type EventUpdateGlobalVirtualGroup struct { + // The id of global virtual group, which has been updated + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The store size of all the objects stores in this global virtual group + StoreSize uint64 `protobuf:"varint,2,opt,name=store_size,json=storeSize,proto3" json:"store_size,omitempty"` + // The total amount of the staking for this global virtual group + TotalDeposit github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=total_deposit,json=totalDeposit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_deposit"` + // Primary SP ID represents the unique id of the primary storage provider in the group. + PrimarySpId uint32 `protobuf:"varint,4,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` + // Secondary SP IDs represents the list of unique identifiers of the secondary storage providers in the group. + SecondarySpIds []uint32 `protobuf:"varint,5,rep,packed,name=secondary_sp_ids,json=secondarySpIds,proto3" json:"secondary_sp_ids,omitempty"` +} + +func (m *EventUpdateGlobalVirtualGroup) Reset() { *m = EventUpdateGlobalVirtualGroup{} } +func (m *EventUpdateGlobalVirtualGroup) String() string { return proto.CompactTextString(m) } +func (*EventUpdateGlobalVirtualGroup) ProtoMessage() {} +func (*EventUpdateGlobalVirtualGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_ece39ea12016bd5b, []int{1} +} +func (m *EventUpdateGlobalVirtualGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventUpdateGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventUpdateGlobalVirtualGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventUpdateGlobalVirtualGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventUpdateGlobalVirtualGroup.Merge(m, src) +} +func (m *EventUpdateGlobalVirtualGroup) XXX_Size() int { + return m.Size() +} +func (m *EventUpdateGlobalVirtualGroup) XXX_DiscardUnknown() { + xxx_messageInfo_EventUpdateGlobalVirtualGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_EventUpdateGlobalVirtualGroup proto.InternalMessageInfo + +func (m *EventUpdateGlobalVirtualGroup) GetId() uint32 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *EventUpdateGlobalVirtualGroup) GetStoreSize() uint64 { + if m != nil { + return m.StoreSize + } + return 0 +} + +func (m *EventUpdateGlobalVirtualGroup) GetPrimarySpId() uint32 { + if m != nil { + return m.PrimarySpId + } + return 0 +} + +func (m *EventUpdateGlobalVirtualGroup) GetSecondarySpIds() []uint32 { + if m != nil { + return m.SecondarySpIds + } + return nil +} + +type EventDeleteGlobalVirtualGroup struct { + // The id of global virtual group, which has been deleted + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The id of the primary sp who create this global virtual group family + PrimarySpId uint32 `protobuf:"varint,2,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` +} + +func (m *EventDeleteGlobalVirtualGroup) Reset() { *m = EventDeleteGlobalVirtualGroup{} } +func (m *EventDeleteGlobalVirtualGroup) String() string { return proto.CompactTextString(m) } +func (*EventDeleteGlobalVirtualGroup) ProtoMessage() {} +func (*EventDeleteGlobalVirtualGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_ece39ea12016bd5b, []int{2} +} +func (m *EventDeleteGlobalVirtualGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventDeleteGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventDeleteGlobalVirtualGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventDeleteGlobalVirtualGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventDeleteGlobalVirtualGroup.Merge(m, src) +} +func (m *EventDeleteGlobalVirtualGroup) XXX_Size() int { + return m.Size() +} +func (m *EventDeleteGlobalVirtualGroup) XXX_DiscardUnknown() { + xxx_messageInfo_EventDeleteGlobalVirtualGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_EventDeleteGlobalVirtualGroup proto.InternalMessageInfo + +func (m *EventDeleteGlobalVirtualGroup) GetId() uint32 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *EventDeleteGlobalVirtualGroup) GetPrimarySpId() uint32 { + if m != nil { + return m.PrimarySpId + } + return 0 +} + type EventCreateGlobalVirtualGroupFamily struct { // The id of global virtual group family, which is auto generated by blockchain Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The id of the primary sp who create this global virtual group family + PrimarySpId uint32 `protobuf:"varint,2,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` // The virtual payment address of this global virtual group family, which is auto generated by blockcahin // all users' read quota payment flows will flow to this account. - VirtualPaymentAddress string `protobuf:"bytes,2,opt,name=virtual_payment_address,json=virtualPaymentAddress,proto3" json:"virtual_payment_address,omitempty"` + VirtualPaymentAddress string `protobuf:"bytes,3,opt,name=virtual_payment_address,json=virtualPaymentAddress,proto3" json:"virtual_payment_address,omitempty"` + // global_virtual_group_ids are the ids of gvgs in this family + GlobalVirtualGroupIds []uint32 `protobuf:"varint,4,rep,packed,name=global_virtual_group_ids,json=globalVirtualGroupIds,proto3" json:"global_virtual_group_ids,omitempty"` } func (m *EventCreateGlobalVirtualGroupFamily) Reset() { *m = EventCreateGlobalVirtualGroupFamily{} } func (m *EventCreateGlobalVirtualGroupFamily) String() string { return proto.CompactTextString(m) } func (*EventCreateGlobalVirtualGroupFamily) ProtoMessage() {} func (*EventCreateGlobalVirtualGroupFamily) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{1} + return fileDescriptor_ece39ea12016bd5b, []int{3} } func (m *EventCreateGlobalVirtualGroupFamily) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -166,6 +298,13 @@ func (m *EventCreateGlobalVirtualGroupFamily) GetId() uint32 { return 0 } +func (m *EventCreateGlobalVirtualGroupFamily) GetPrimarySpId() uint32 { + if m != nil { + return m.PrimarySpId + } + return 0 +} + func (m *EventCreateGlobalVirtualGroupFamily) GetVirtualPaymentAddress() string { if m != nil { return m.VirtualPaymentAddress @@ -173,23 +312,34 @@ func (m *EventCreateGlobalVirtualGroupFamily) GetVirtualPaymentAddress() string return "" } -type EventDeleteGlobalVirtualGroup struct { - // The id of global virtual group, which has been deleted +func (m *EventCreateGlobalVirtualGroupFamily) GetGlobalVirtualGroupIds() []uint32 { + if m != nil { + return m.GlobalVirtualGroupIds + } + return nil +} + +type EventUpdateGlobalVirtualGroupFamily struct { + // The id of global virtual group family, which is auto generated by blockchain Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The id of the primary sp who create this global virtual group family + PrimarySpId uint32 `protobuf:"varint,2,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` + // global_virtual_group_ids are the ids of gvgs in this family + GlobalVirtualGroupIds []uint32 `protobuf:"varint,3,rep,packed,name=global_virtual_group_ids,json=globalVirtualGroupIds,proto3" json:"global_virtual_group_ids,omitempty"` } -func (m *EventDeleteGlobalVirtualGroup) Reset() { *m = EventDeleteGlobalVirtualGroup{} } -func (m *EventDeleteGlobalVirtualGroup) String() string { return proto.CompactTextString(m) } -func (*EventDeleteGlobalVirtualGroup) ProtoMessage() {} -func (*EventDeleteGlobalVirtualGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{2} +func (m *EventUpdateGlobalVirtualGroupFamily) Reset() { *m = EventUpdateGlobalVirtualGroupFamily{} } +func (m *EventUpdateGlobalVirtualGroupFamily) String() string { return proto.CompactTextString(m) } +func (*EventUpdateGlobalVirtualGroupFamily) ProtoMessage() {} +func (*EventUpdateGlobalVirtualGroupFamily) Descriptor() ([]byte, []int) { + return fileDescriptor_ece39ea12016bd5b, []int{4} } -func (m *EventDeleteGlobalVirtualGroup) XXX_Unmarshal(b []byte) error { +func (m *EventUpdateGlobalVirtualGroupFamily) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *EventDeleteGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *EventUpdateGlobalVirtualGroupFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_EventDeleteGlobalVirtualGroup.Marshal(b, m, deterministic) + return xxx_messageInfo_EventUpdateGlobalVirtualGroupFamily.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -199,46 +349,58 @@ func (m *EventDeleteGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool return b[:n], nil } } -func (m *EventDeleteGlobalVirtualGroup) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventDeleteGlobalVirtualGroup.Merge(m, src) +func (m *EventUpdateGlobalVirtualGroupFamily) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventUpdateGlobalVirtualGroupFamily.Merge(m, src) } -func (m *EventDeleteGlobalVirtualGroup) XXX_Size() int { +func (m *EventUpdateGlobalVirtualGroupFamily) XXX_Size() int { return m.Size() } -func (m *EventDeleteGlobalVirtualGroup) XXX_DiscardUnknown() { - xxx_messageInfo_EventDeleteGlobalVirtualGroup.DiscardUnknown(m) +func (m *EventUpdateGlobalVirtualGroupFamily) XXX_DiscardUnknown() { + xxx_messageInfo_EventUpdateGlobalVirtualGroupFamily.DiscardUnknown(m) } -var xxx_messageInfo_EventDeleteGlobalVirtualGroup proto.InternalMessageInfo +var xxx_messageInfo_EventUpdateGlobalVirtualGroupFamily proto.InternalMessageInfo -func (m *EventDeleteGlobalVirtualGroup) GetId() uint32 { +func (m *EventUpdateGlobalVirtualGroupFamily) GetId() uint32 { if m != nil { return m.Id } return 0 } -type EventUpdateGlobalVirtualGroup struct { - // The id of global virtual group, which has been updated +func (m *EventUpdateGlobalVirtualGroupFamily) GetPrimarySpId() uint32 { + if m != nil { + return m.PrimarySpId + } + return 0 +} + +func (m *EventUpdateGlobalVirtualGroupFamily) GetGlobalVirtualGroupIds() []uint32 { + if m != nil { + return m.GlobalVirtualGroupIds + } + return nil +} + +type EventDeleteGlobalVirtualGroupFamily struct { + // The id of global virtual group family, which is auto generated by blockchain Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - // The store size of all the objects stores in this global virtual group - StoreSize uint64 `protobuf:"varint,2,opt,name=store_size,json=storeSize,proto3" json:"store_size,omitempty"` - // The total amount of the staking for this global virtual group - TotalDeposit github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=total_deposit,json=totalDeposit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_deposit"` + // The id of the primary sp who create this global virtual group family + PrimarySpId uint32 `protobuf:"varint,2,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` } -func (m *EventUpdateGlobalVirtualGroup) Reset() { *m = EventUpdateGlobalVirtualGroup{} } -func (m *EventUpdateGlobalVirtualGroup) String() string { return proto.CompactTextString(m) } -func (*EventUpdateGlobalVirtualGroup) ProtoMessage() {} -func (*EventUpdateGlobalVirtualGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{3} +func (m *EventDeleteGlobalVirtualGroupFamily) Reset() { *m = EventDeleteGlobalVirtualGroupFamily{} } +func (m *EventDeleteGlobalVirtualGroupFamily) String() string { return proto.CompactTextString(m) } +func (*EventDeleteGlobalVirtualGroupFamily) ProtoMessage() {} +func (*EventDeleteGlobalVirtualGroupFamily) Descriptor() ([]byte, []int) { + return fileDescriptor_ece39ea12016bd5b, []int{5} } -func (m *EventUpdateGlobalVirtualGroup) XXX_Unmarshal(b []byte) error { +func (m *EventDeleteGlobalVirtualGroupFamily) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *EventUpdateGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *EventDeleteGlobalVirtualGroupFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_EventUpdateGlobalVirtualGroup.Marshal(b, m, deterministic) + return xxx_messageInfo_EventDeleteGlobalVirtualGroupFamily.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -248,28 +410,28 @@ func (m *EventUpdateGlobalVirtualGroup) XXX_Marshal(b []byte, deterministic bool return b[:n], nil } } -func (m *EventUpdateGlobalVirtualGroup) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventUpdateGlobalVirtualGroup.Merge(m, src) +func (m *EventDeleteGlobalVirtualGroupFamily) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventDeleteGlobalVirtualGroupFamily.Merge(m, src) } -func (m *EventUpdateGlobalVirtualGroup) XXX_Size() int { +func (m *EventDeleteGlobalVirtualGroupFamily) XXX_Size() int { return m.Size() } -func (m *EventUpdateGlobalVirtualGroup) XXX_DiscardUnknown() { - xxx_messageInfo_EventUpdateGlobalVirtualGroup.DiscardUnknown(m) +func (m *EventDeleteGlobalVirtualGroupFamily) XXX_DiscardUnknown() { + xxx_messageInfo_EventDeleteGlobalVirtualGroupFamily.DiscardUnknown(m) } -var xxx_messageInfo_EventUpdateGlobalVirtualGroup proto.InternalMessageInfo +var xxx_messageInfo_EventDeleteGlobalVirtualGroupFamily proto.InternalMessageInfo -func (m *EventUpdateGlobalVirtualGroup) GetId() uint32 { +func (m *EventDeleteGlobalVirtualGroupFamily) GetId() uint32 { if m != nil { return m.Id } return 0 } -func (m *EventUpdateGlobalVirtualGroup) GetStoreSize() uint64 { +func (m *EventDeleteGlobalVirtualGroupFamily) GetPrimarySpId() uint32 { if m != nil { - return m.StoreSize + return m.PrimarySpId } return 0 } @@ -290,7 +452,7 @@ func (m *EventCreateLocalVirtualGroup) Reset() { *m = EventCreateLocalVi func (m *EventCreateLocalVirtualGroup) String() string { return proto.CompactTextString(m) } func (*EventCreateLocalVirtualGroup) ProtoMessage() {} func (*EventCreateLocalVirtualGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{4} + return fileDescriptor_ece39ea12016bd5b, []int{6} } func (m *EventCreateLocalVirtualGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -343,17 +505,19 @@ func (m *EventCreateLocalVirtualGroup) GetStoredSize() uint64 { type EventUpdateLocalVirtualGroup struct { // The id of the local virtual group Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - // The id of the global virtual group - GlobalVirtualGroupId uint32 `protobuf:"varint,2,opt,name=global_virtual_group_id,json=globalVirtualGroupId,proto3" json:"global_virtual_group_id,omitempty"` + // The id of the bucket + BucketId Uint `protobuf:"bytes,2,opt,name=bucket_id,json=bucketId,proto3,customtype=Uint" json:"bucket_id"` + // The global_virtual_group_id is gvgid of lvg after migrate + GlobalVirtualGroupId uint32 `protobuf:"varint,3,opt,name=global_virtual_group_id,json=globalVirtualGroupId,proto3" json:"global_virtual_group_id,omitempty"` // The stored size of all the objects stores in this lvg - StoredSize uint64 `protobuf:"varint,3,opt,name=stored_size,json=storedSize,proto3" json:"stored_size,omitempty"` + StoredSize uint64 `protobuf:"varint,4,opt,name=stored_size,json=storedSize,proto3" json:"stored_size,omitempty"` } func (m *EventUpdateLocalVirtualGroup) Reset() { *m = EventUpdateLocalVirtualGroup{} } func (m *EventUpdateLocalVirtualGroup) String() string { return proto.CompactTextString(m) } func (*EventUpdateLocalVirtualGroup) ProtoMessage() {} func (*EventUpdateLocalVirtualGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{5} + return fileDescriptor_ece39ea12016bd5b, []int{7} } func (m *EventUpdateLocalVirtualGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -403,6 +567,53 @@ func (m *EventUpdateLocalVirtualGroup) GetStoredSize() uint64 { return 0 } +type EventDeleteLocalVirtualGroup struct { + // The id of the local virtual group + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The id of the bucket + BucketId Uint `protobuf:"bytes,2,opt,name=bucket_id,json=bucketId,proto3,customtype=Uint" json:"bucket_id"` +} + +func (m *EventDeleteLocalVirtualGroup) Reset() { *m = EventDeleteLocalVirtualGroup{} } +func (m *EventDeleteLocalVirtualGroup) String() string { return proto.CompactTextString(m) } +func (*EventDeleteLocalVirtualGroup) ProtoMessage() {} +func (*EventDeleteLocalVirtualGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_ece39ea12016bd5b, []int{8} +} +func (m *EventDeleteLocalVirtualGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventDeleteLocalVirtualGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventDeleteLocalVirtualGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventDeleteLocalVirtualGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventDeleteLocalVirtualGroup.Merge(m, src) +} +func (m *EventDeleteLocalVirtualGroup) XXX_Size() int { + return m.Size() +} +func (m *EventDeleteLocalVirtualGroup) XXX_DiscardUnknown() { + xxx_messageInfo_EventDeleteLocalVirtualGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_EventDeleteLocalVirtualGroup proto.InternalMessageInfo + +func (m *EventDeleteLocalVirtualGroup) GetId() uint32 { + if m != nil { + return m.Id + } + return 0 +} + type EventSwapOut struct { // The id of the storage provider who wants to swap out StorageProviderId uint32 `protobuf:"varint,1,opt,name=storage_provider_id,json=storageProviderId,proto3" json:"storage_provider_id,omitempty"` @@ -418,7 +629,7 @@ func (m *EventSwapOut) Reset() { *m = EventSwapOut{} } func (m *EventSwapOut) String() string { return proto.CompactTextString(m) } func (*EventSwapOut) ProtoMessage() {} func (*EventSwapOut) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{6} + return fileDescriptor_ece39ea12016bd5b, []int{9} } func (m *EventSwapOut) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -490,7 +701,7 @@ func (m *EventCompleteSwapOut) Reset() { *m = EventCompleteSwapOut{} } func (m *EventCompleteSwapOut) String() string { return proto.CompactTextString(m) } func (*EventCompleteSwapOut) ProtoMessage() {} func (*EventCompleteSwapOut) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{7} + return fileDescriptor_ece39ea12016bd5b, []int{10} } func (m *EventCompleteSwapOut) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -562,7 +773,7 @@ func (m *EventCancelSwapOut) Reset() { *m = EventCancelSwapOut{} } func (m *EventCancelSwapOut) String() string { return proto.CompactTextString(m) } func (*EventCancelSwapOut) ProtoMessage() {} func (*EventCancelSwapOut) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{8} + return fileDescriptor_ece39ea12016bd5b, []int{11} } func (m *EventCancelSwapOut) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -630,7 +841,7 @@ func (m *EventStorageProviderExit) Reset() { *m = EventStorageProviderEx func (m *EventStorageProviderExit) String() string { return proto.CompactTextString(m) } func (*EventStorageProviderExit) ProtoMessage() {} func (*EventStorageProviderExit) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{9} + return fileDescriptor_ece39ea12016bd5b, []int{12} } func (m *EventStorageProviderExit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -686,7 +897,7 @@ func (m *EventCompleteStorageProviderExit) Reset() { *m = EventCompleteS func (m *EventCompleteStorageProviderExit) String() string { return proto.CompactTextString(m) } func (*EventCompleteStorageProviderExit) ProtoMessage() {} func (*EventCompleteStorageProviderExit) Descriptor() ([]byte, []int) { - return fileDescriptor_ece39ea12016bd5b, []int{10} + return fileDescriptor_ece39ea12016bd5b, []int{13} } func (m *EventCompleteStorageProviderExit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -731,11 +942,14 @@ func (m *EventCompleteStorageProviderExit) GetOperatorAddress() string { func init() { proto.RegisterType((*EventCreateGlobalVirtualGroup)(nil), "greenfield.virtualgroup.EventCreateGlobalVirtualGroup") - proto.RegisterType((*EventCreateGlobalVirtualGroupFamily)(nil), "greenfield.virtualgroup.EventCreateGlobalVirtualGroupFamily") - proto.RegisterType((*EventDeleteGlobalVirtualGroup)(nil), "greenfield.virtualgroup.EventDeleteGlobalVirtualGroup") proto.RegisterType((*EventUpdateGlobalVirtualGroup)(nil), "greenfield.virtualgroup.EventUpdateGlobalVirtualGroup") + proto.RegisterType((*EventDeleteGlobalVirtualGroup)(nil), "greenfield.virtualgroup.EventDeleteGlobalVirtualGroup") + proto.RegisterType((*EventCreateGlobalVirtualGroupFamily)(nil), "greenfield.virtualgroup.EventCreateGlobalVirtualGroupFamily") + proto.RegisterType((*EventUpdateGlobalVirtualGroupFamily)(nil), "greenfield.virtualgroup.EventUpdateGlobalVirtualGroupFamily") + proto.RegisterType((*EventDeleteGlobalVirtualGroupFamily)(nil), "greenfield.virtualgroup.EventDeleteGlobalVirtualGroupFamily") proto.RegisterType((*EventCreateLocalVirtualGroup)(nil), "greenfield.virtualgroup.EventCreateLocalVirtualGroup") proto.RegisterType((*EventUpdateLocalVirtualGroup)(nil), "greenfield.virtualgroup.EventUpdateLocalVirtualGroup") + proto.RegisterType((*EventDeleteLocalVirtualGroup)(nil), "greenfield.virtualgroup.EventDeleteLocalVirtualGroup") proto.RegisterType((*EventSwapOut)(nil), "greenfield.virtualgroup.EventSwapOut") proto.RegisterType((*EventCompleteSwapOut)(nil), "greenfield.virtualgroup.EventCompleteSwapOut") proto.RegisterType((*EventCancelSwapOut)(nil), "greenfield.virtualgroup.EventCancelSwapOut") @@ -748,54 +962,56 @@ func init() { } var fileDescriptor_ece39ea12016bd5b = []byte{ - // 747 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x3f, 0x4f, 0x1b, 0x49, - 0x14, 0xf7, 0xd8, 0x3e, 0x0e, 0x0f, 0x18, 0xb8, 0x3d, 0x23, 0xef, 0xc1, 0x61, 0xac, 0xbd, 0x13, - 0x72, 0x63, 0xbb, 0xb8, 0x43, 0x77, 0xc5, 0x35, 0x67, 0x20, 0x68, 0xa5, 0x28, 0x41, 0xb6, 0x48, - 0x91, 0x66, 0xb5, 0xde, 0x19, 0x96, 0x11, 0xeb, 0x9d, 0xd5, 0xcc, 0x98, 0x60, 0x3e, 0x40, 0x52, - 0x26, 0x5f, 0x25, 0x12, 0x1f, 0x20, 0x25, 0x25, 0xa2, 0x8a, 0x52, 0xa0, 0x08, 0x57, 0xe9, 0x52, - 0x53, 0x45, 0x3b, 0x33, 0x36, 0x06, 0x83, 0x71, 0x48, 0x14, 0x45, 0xa9, 0xec, 0x7d, 0xf3, 0xfe, - 0xfc, 0x7e, 0xbf, 0xf7, 0xe6, 0x69, 0xe0, 0x9f, 0x3e, 0xc3, 0x38, 0xdc, 0x21, 0x38, 0x40, 0xd5, - 0x7d, 0xc2, 0x44, 0xdb, 0x0d, 0x7c, 0x46, 0xdb, 0x51, 0x15, 0xef, 0xe3, 0x50, 0xf0, 0x4a, 0xc4, - 0xa8, 0xa0, 0x46, 0xfe, 0xd2, 0xab, 0x32, 0xe8, 0xb5, 0xf0, 0x9b, 0x47, 0x79, 0x8b, 0x72, 0x47, - 0xba, 0x55, 0xd5, 0x87, 0x8a, 0x59, 0xc8, 0xf9, 0xd4, 0xa7, 0xca, 0x1e, 0xff, 0x53, 0x56, 0xeb, - 0x63, 0x12, 0x2e, 0x6d, 0xc4, 0xa9, 0xd7, 0x18, 0x76, 0x05, 0xde, 0x0c, 0x68, 0xd3, 0x0d, 0x9e, - 0xa8, 0x94, 0x9b, 0x71, 0x4a, 0x63, 0x06, 0x26, 0x09, 0x32, 0x41, 0x11, 0x94, 0xb2, 0xf5, 0x24, - 0x41, 0xc6, 0x22, 0xcc, 0xec, 0xb8, 0x2d, 0x12, 0x74, 0x1c, 0x82, 0xcc, 0xa4, 0x34, 0x4f, 0x2a, - 0x83, 0x8d, 0x0c, 0x0b, 0x66, 0x23, 0x46, 0x5a, 0x2e, 0xeb, 0x38, 0x3c, 0x8a, 0x1d, 0x52, 0xd2, - 0x61, 0x4a, 0x1b, 0x1b, 0x91, 0x8d, 0x8c, 0x12, 0x9c, 0xe3, 0xd8, 0xa3, 0x21, 0xea, 0x7b, 0x71, - 0x33, 0x5d, 0x4c, 0x95, 0xb2, 0xf5, 0x99, 0xbe, 0x3d, 0x76, 0xe4, 0xc6, 0x32, 0x9c, 0xe2, 0x82, - 0x32, 0x8c, 0x1c, 0x4e, 0x0e, 0xb1, 0xf9, 0x53, 0x11, 0x94, 0xd2, 0x75, 0xa8, 0x4c, 0x0d, 0x72, - 0x88, 0x8d, 0x2d, 0x98, 0xd7, 0xf4, 0x9d, 0xc8, 0xed, 0xb4, 0x70, 0x28, 0x1c, 0x17, 0x21, 0x86, - 0x39, 0x37, 0x27, 0x8a, 0xa0, 0x94, 0xa9, 0x99, 0xa7, 0x47, 0xe5, 0x9c, 0x96, 0xe1, 0x7f, 0x75, - 0xd2, 0x10, 0x8c, 0x84, 0x7e, 0x7d, 0x5e, 0x07, 0x6e, 0xa9, 0x38, 0x7d, 0x68, 0xb8, 0x30, 0x2b, - 0xa8, 0x70, 0x03, 0x07, 0xe1, 0x88, 0x72, 0x22, 0xcc, 0x9f, 0x65, 0x9e, 0xff, 0x8e, 0xcf, 0x96, - 0x13, 0xef, 0xce, 0x96, 0x57, 0x7c, 0x22, 0x76, 0xdb, 0xcd, 0x8a, 0x47, 0x5b, 0x5a, 0x5d, 0xfd, - 0x53, 0xe6, 0x68, 0xaf, 0x2a, 0x3a, 0x11, 0xe6, 0x15, 0x3b, 0x14, 0xa7, 0x47, 0x65, 0xa8, 0xab, - 0xda, 0xa1, 0xa8, 0x4f, 0xcb, 0x94, 0xeb, 0x2a, 0xa3, 0xf5, 0x02, 0xc0, 0x3f, 0x46, 0x4a, 0xfe, - 0x40, 0xaa, 0x39, 0x24, 0xfc, 0x08, 0xb2, 0xc9, 0x7b, 0x91, 0xb5, 0xaa, 0xba, 0xf7, 0xeb, 0x38, - 0xc0, 0xe3, 0xf4, 0xde, 0x7a, 0x0d, 0x74, 0xc4, 0x76, 0x84, 0xc6, 0x9b, 0x96, 0x25, 0xa8, 0xfa, - 0xa5, 0x3a, 0x98, 0x94, 0x1d, 0xcc, 0x48, 0x8b, 0x6c, 0xe0, 0x90, 0xdc, 0xa9, 0xaf, 0x2e, 0xf7, - 0x1b, 0x00, 0x7f, 0x1f, 0x90, 0xfb, 0x21, 0xf5, 0xee, 0x80, 0xfc, 0x2f, 0xcc, 0x34, 0xdb, 0xde, - 0x1e, 0x16, 0xbd, 0x01, 0xcf, 0xd4, 0x16, 0x35, 0x9e, 0xf4, 0x36, 0x91, 0xd5, 0xa6, 0x74, 0xb5, - 0xf8, 0xb3, 0x3e, 0xa9, 0xbc, 0x6d, 0x64, 0xac, 0xc2, 0xbc, 0x2f, 0x25, 0x71, 0x7a, 0x8d, 0x92, - 0xb7, 0xf2, 0xf2, 0x1e, 0xe4, 0xfc, 0x21, 0xc5, 0x6c, 0x74, 0x7d, 0xcc, 0xd3, 0xd7, 0xc7, 0xdc, - 0x7a, 0xde, 0xa3, 0xa0, 0x64, 0xbf, 0x9b, 0xc2, 0x08, 0x20, 0xc9, 0xf1, 0x81, 0xa4, 0x86, 0x80, - 0x74, 0x01, 0x9c, 0x96, 0x40, 0x1a, 0xcf, 0xdc, 0xe8, 0x71, 0x5b, 0x18, 0x15, 0xf8, 0x6b, 0x7c, - 0xec, 0xfa, 0x38, 0x5e, 0x39, 0xfb, 0x04, 0x61, 0xe6, 0xf4, 0x91, 0xfc, 0xa2, 0x8f, 0xb6, 0xf4, - 0x89, 0x8d, 0x8c, 0x1a, 0x2c, 0xdc, 0x08, 0xec, 0xfa, 0x46, 0x59, 0xf0, 0x6f, 0xb9, 0x15, 0x36, - 0x32, 0xfe, 0x81, 0xe6, 0x2d, 0xe4, 0xb8, 0x99, 0x92, 0x7b, 0x64, 0xfe, 0x26, 0x76, 0xdc, 0x58, - 0x81, 0xb3, 0xbc, 0xed, 0x79, 0x98, 0x73, 0xca, 0xf4, 0x7a, 0x4a, 0xcb, 0x6a, 0xd9, 0xbe, 0x39, - 0xde, 0x3b, 0xd6, 0x05, 0x80, 0x39, 0x35, 0x31, 0xb4, 0x15, 0xc5, 0x37, 0xe3, 0xbe, 0x6c, 0x57, - 0x61, 0x9e, 0x33, 0xcf, 0xb9, 0x29, 0x46, 0xb7, 0x81, 0x33, 0xaf, 0x71, 0x0f, 0x91, 0x52, 0x5f, - 0x24, 0x52, 0x7a, 0x84, 0x48, 0xd6, 0x07, 0x00, 0x0d, 0x45, 0xde, 0x0d, 0x3d, 0x1c, 0xfc, 0xd0, - 0x8d, 0x7e, 0x09, 0xa0, 0xa9, 0xc6, 0xf9, 0x2a, 0xfe, 0x8d, 0x03, 0xf2, 0xf9, 0x8c, 0xd7, 0xe0, - 0x1c, 0x8d, 0x30, 0x73, 0x05, 0x65, 0x63, 0xef, 0xe5, 0xd9, 0x5e, 0x44, 0x6f, 0x23, 0x5f, 0x00, - 0x58, 0xbc, 0x3a, 0x7a, 0xdf, 0x09, 0xb2, 0x6f, 0xb0, 0xa9, 0x6b, 0x8f, 0x8e, 0xcf, 0x0b, 0xe0, - 0xe4, 0xbc, 0x00, 0xde, 0x9f, 0x17, 0xc0, 0xab, 0x6e, 0x21, 0x71, 0xd2, 0x2d, 0x24, 0xde, 0x76, - 0x0b, 0x89, 0xa7, 0x7f, 0x0f, 0x64, 0x6f, 0x86, 0xcd, 0xb2, 0xb7, 0xeb, 0x92, 0xb0, 0x3a, 0xf0, - 0x54, 0x3a, 0xb8, 0xfa, 0x58, 0x92, 0xf5, 0x9a, 0x13, 0xf2, 0x89, 0xf3, 0xd7, 0xa7, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x89, 0x1e, 0x45, 0x35, 0x54, 0x09, 0x00, 0x00, + // 778 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0xcf, 0x4f, 0x13, 0x4f, + 0x14, 0xef, 0xb6, 0x85, 0x2f, 0x1d, 0x28, 0xf0, 0x5d, 0x4b, 0xba, 0x82, 0x94, 0xa6, 0x1a, 0xd2, + 0x4b, 0xdb, 0x83, 0x12, 0x3d, 0x78, 0xb1, 0x80, 0xa4, 0x89, 0x51, 0xd2, 0x06, 0x13, 0xbd, 0x6c, + 0xb6, 0x3b, 0xc3, 0x32, 0x61, 0xbb, 0xb3, 0x99, 0x99, 0x22, 0xe5, 0x9f, 0xd0, 0xf8, 0xb7, 0xf0, + 0x07, 0x78, 0xe4, 0x48, 0x38, 0x19, 0x0f, 0xc4, 0x50, 0x2f, 0xde, 0x3c, 0x7b, 0xd1, 0xec, 0xcc, + 0xb4, 0xb4, 0xf4, 0x07, 0x58, 0xd4, 0xa8, 0xa7, 0x76, 0xdf, 0xbc, 0x79, 0xef, 0x7d, 0x3e, 0xef, + 0x33, 0x6f, 0x06, 0xdc, 0x71, 0x28, 0x42, 0xde, 0x36, 0x46, 0x2e, 0x2c, 0xec, 0x61, 0xca, 0xeb, + 0x96, 0xeb, 0x50, 0x52, 0xf7, 0x0b, 0x68, 0x0f, 0x79, 0x9c, 0xe5, 0x7d, 0x4a, 0x38, 0xd1, 0x93, + 0xe7, 0x5e, 0xf9, 0x4e, 0xaf, 0xf9, 0x9b, 0x36, 0x61, 0x35, 0xc2, 0x4c, 0xe1, 0x56, 0x90, 0x1f, + 0x72, 0xcf, 0x7c, 0xc2, 0x21, 0x0e, 0x91, 0xf6, 0xe0, 0x9f, 0xb4, 0x66, 0xbe, 0x84, 0xc1, 0xe2, + 0x7a, 0x10, 0x7a, 0x95, 0x22, 0x8b, 0xa3, 0x0d, 0x97, 0x54, 0x2d, 0xf7, 0xb9, 0x0c, 0xb9, 0x11, + 0x84, 0xd4, 0xa7, 0x41, 0x18, 0x43, 0x43, 0x4b, 0x6b, 0xd9, 0x78, 0x39, 0x8c, 0xa1, 0xbe, 0x00, + 0x62, 0xdb, 0x56, 0x0d, 0xbb, 0x0d, 0x13, 0x43, 0x23, 0x2c, 0xcc, 0x13, 0xd2, 0x50, 0x82, 0x7a, + 0x06, 0xc4, 0x7d, 0x8a, 0x6b, 0x16, 0x6d, 0x98, 0xcc, 0x0f, 0x1c, 0x22, 0xc2, 0x61, 0x52, 0x19, + 0x2b, 0x7e, 0x09, 0xea, 0x59, 0x30, 0xcb, 0x90, 0x4d, 0x3c, 0xd8, 0xf6, 0x62, 0x46, 0x34, 0x1d, + 0xc9, 0xc6, 0xcb, 0xd3, 0x6d, 0x7b, 0xe0, 0xc8, 0xf4, 0x25, 0x30, 0xc9, 0x38, 0xa1, 0x08, 0x9a, + 0x0c, 0x1f, 0x20, 0x63, 0x2c, 0xad, 0x65, 0xa3, 0x65, 0x20, 0x4d, 0x15, 0x7c, 0x80, 0xf4, 0x4d, + 0x90, 0x54, 0xf0, 0x4d, 0xdf, 0x6a, 0xd4, 0x90, 0xc7, 0x4d, 0x0b, 0x42, 0x8a, 0x18, 0x33, 0xc6, + 0xd3, 0x5a, 0x36, 0x56, 0x34, 0x4e, 0x0e, 0x73, 0x09, 0x45, 0xc3, 0x23, 0xb9, 0x52, 0xe1, 0x14, + 0x7b, 0x4e, 0x79, 0x4e, 0x6d, 0xdc, 0x94, 0xfb, 0xd4, 0xa2, 0x6e, 0x81, 0x38, 0x27, 0xdc, 0x72, + 0x4d, 0x88, 0x7c, 0xc2, 0x30, 0x37, 0xfe, 0x13, 0x71, 0x1e, 0x1e, 0x9d, 0x2e, 0x85, 0x3e, 0x9c, + 0x2e, 0x2d, 0x3b, 0x98, 0xef, 0xd4, 0xab, 0x79, 0x9b, 0xd4, 0x14, 0xbb, 0xea, 0x27, 0xc7, 0xe0, + 0x6e, 0x81, 0x37, 0x7c, 0xc4, 0xf2, 0x25, 0x8f, 0x9f, 0x1c, 0xe6, 0x80, 0xca, 0x5a, 0xf2, 0x78, + 0x79, 0x4a, 0x84, 0x5c, 0x93, 0x11, 0x33, 0xdf, 0x34, 0x45, 0xf9, 0x96, 0x0f, 0xaf, 0x46, 0xf9, + 0x22, 0x90, 0xa0, 0x25, 0x0d, 0x61, 0x41, 0x43, 0x4c, 0x58, 0x04, 0x0b, 0x3d, 0x35, 0x47, 0x7e, + 0x76, 0xcd, 0xbd, 0x7d, 0x8d, 0x5e, 0xad, 0xaf, 0x63, 0xfd, 0xfa, 0x9a, 0xa9, 0x28, 0x02, 0xd6, + 0x90, 0x8b, 0xae, 0x44, 0x40, 0x4f, 0xfa, 0x70, 0x4f, 0xfa, 0xcc, 0x27, 0x0d, 0xdc, 0x1e, 0xaa, + 0xe4, 0xc7, 0x42, 0xa4, 0xa3, 0xc4, 0x1e, 0xa6, 0xb3, 0xc8, 0x68, 0x3a, 0xbb, 0x0f, 0x0c, 0x47, + 0x54, 0x68, 0xb6, 0x02, 0x8b, 0x03, 0xdc, 0x71, 0x18, 0xe6, 0x9c, 0x1e, 0x04, 0x01, 0x77, 0x6f, + 0x5b, 0x30, 0x07, 0xa9, 0xe7, 0x1a, 0x30, 0x87, 0x15, 0x15, 0x19, 0x56, 0xd4, 0x0b, 0x55, 0xd3, + 0xa0, 0x86, 0x8e, 0x5e, 0x53, 0xe6, 0x9d, 0x06, 0x6e, 0x75, 0xb4, 0xf5, 0x09, 0xb1, 0x2f, 0xd1, + 0xca, 0x03, 0x10, 0xab, 0xd6, 0xed, 0x5d, 0xc4, 0x5b, 0x01, 0x63, 0xc5, 0x05, 0x75, 0x12, 0xa2, + 0x5b, 0x58, 0xe8, 0x7c, 0x52, 0x75, 0x2a, 0xf8, 0x2c, 0x4f, 0x48, 0xef, 0x12, 0xd4, 0x57, 0x40, + 0x72, 0x00, 0x7c, 0x35, 0xc6, 0x12, 0xfd, 0xd0, 0x5f, 0x9c, 0x52, 0xd1, 0x8b, 0x53, 0xea, 0x1c, + 0x82, 0x6c, 0xd9, 0xdf, 0x08, 0x61, 0x47, 0x21, 0x90, 0x0d, 0xfe, 0x85, 0x08, 0x32, 0x4d, 0x0d, + 0x4c, 0x89, 0x54, 0x95, 0x57, 0x96, 0xff, 0xac, 0xce, 0xf5, 0x3c, 0xb8, 0x11, 0x14, 0x62, 0x39, + 0x28, 0xb8, 0xd5, 0xf6, 0x30, 0x44, 0xd4, 0x6c, 0xe7, 0xfa, 0x5f, 0x2d, 0x6d, 0xaa, 0x95, 0x12, + 0xd4, 0x8b, 0x20, 0xd5, 0x97, 0x82, 0x8b, 0x97, 0xd6, 0xbc, 0x33, 0x40, 0xa6, 0xd7, 0x38, 0x08, + 0xfa, 0x32, 0x98, 0x61, 0x75, 0xdb, 0x46, 0x8c, 0x11, 0xda, 0x35, 0x29, 0xe3, 0x6d, 0xb3, 0x50, + 0xf5, 0x57, 0x0d, 0x24, 0xa4, 0xaa, 0x49, 0xcd, 0x0f, 0x28, 0x1d, 0x15, 0xed, 0x0a, 0x48, 0x32, + 0x6a, 0x9b, 0xfd, 0xf6, 0x48, 0x98, 0x09, 0x46, 0xed, 0xca, 0x08, 0x24, 0x45, 0xae, 0x45, 0xd2, + 0xd0, 0x11, 0xf6, 0x59, 0x03, 0xba, 0x04, 0x6f, 0x79, 0x36, 0x72, 0xff, 0xe9, 0x46, 0xbf, 0xd6, + 0x80, 0x21, 0xe5, 0xdc, 0x5d, 0xff, 0xfa, 0x3e, 0xfe, 0x71, 0xc4, 0xab, 0x60, 0x96, 0xf8, 0x88, + 0x5a, 0x9c, 0xd0, 0xf6, 0xfd, 0x13, 0xbe, 0xe4, 0xfe, 0x99, 0x69, 0xed, 0x50, 0xe6, 0x40, 0x7a, + 0xe9, 0x6e, 0xe9, 0xfd, 0x21, 0x95, 0xfd, 0x86, 0x77, 0x4c, 0xf1, 0xe9, 0xd1, 0x59, 0x4a, 0x3b, + 0x3e, 0x4b, 0x69, 0x1f, 0xcf, 0x52, 0xda, 0x9b, 0x66, 0x2a, 0x74, 0xdc, 0x4c, 0x85, 0xde, 0x37, + 0x53, 0xa1, 0x97, 0xf7, 0x3a, 0xa2, 0x57, 0xbd, 0x6a, 0xce, 0xde, 0xb1, 0xb0, 0x57, 0xe8, 0x78, + 0x8d, 0xef, 0x77, 0xbf, 0xc7, 0x45, 0xbe, 0xea, 0xb8, 0x78, 0x45, 0xdf, 0xfd, 0x1e, 0x00, 0x00, + 0xff, 0xff, 0x21, 0xa5, 0x62, 0x6c, 0xb7, 0x0b, 0x00, 0x00, } func (m *EventCreateGlobalVirtualGroup) Marshal() (dAtA []byte, err error) { @@ -876,7 +1092,7 @@ func (m *EventCreateGlobalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *EventCreateGlobalVirtualGroupFamily) Marshal() (dAtA []byte, err error) { +func (m *EventUpdateGlobalVirtualGroup) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -886,22 +1102,53 @@ func (m *EventCreateGlobalVirtualGroupFamily) Marshal() (dAtA []byte, err error) return dAtA[:n], nil } -func (m *EventCreateGlobalVirtualGroupFamily) MarshalTo(dAtA []byte) (int, error) { +func (m *EventUpdateGlobalVirtualGroup) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *EventCreateGlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *EventUpdateGlobalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.VirtualPaymentAddress) > 0 { - i -= len(m.VirtualPaymentAddress) - copy(dAtA[i:], m.VirtualPaymentAddress) - i = encodeVarintEvents(dAtA, i, uint64(len(m.VirtualPaymentAddress))) - i-- - dAtA[i] = 0x12 + if len(m.SecondarySpIds) > 0 { + dAtA4 := make([]byte, len(m.SecondarySpIds)*10) + var j3 int + for _, num := range m.SecondarySpIds { + for num >= 1<<7 { + dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j3++ + } + dAtA4[j3] = uint8(num) + j3++ + } + i -= j3 + copy(dAtA[i:], dAtA4[:j3]) + i = encodeVarintEvents(dAtA, i, uint64(j3)) + i-- + dAtA[i] = 0x2a + } + if m.PrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) + i-- + dAtA[i] = 0x20 + } + { + size := m.TotalDeposit.Size() + i -= size + if _, err := m.TotalDeposit.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if m.StoreSize != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.StoreSize)) + i-- + dAtA[i] = 0x10 } if m.Id != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.Id)) @@ -931,6 +1178,11 @@ func (m *EventDeleteGlobalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if m.PrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) + i-- + dAtA[i] = 0x10 + } if m.Id != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.Id)) i-- @@ -939,7 +1191,7 @@ func (m *EventDeleteGlobalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *EventUpdateGlobalVirtualGroup) Marshal() (dAtA []byte, err error) { +func (m *EventCreateGlobalVirtualGroupFamily) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -949,28 +1201,127 @@ func (m *EventUpdateGlobalVirtualGroup) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *EventUpdateGlobalVirtualGroup) MarshalTo(dAtA []byte) (int, error) { +func (m *EventCreateGlobalVirtualGroupFamily) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *EventUpdateGlobalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *EventCreateGlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size := m.TotalDeposit.Size() - i -= size - if _, err := m.TotalDeposit.MarshalTo(dAtA[i:]); err != nil { - return 0, err + if len(m.GlobalVirtualGroupIds) > 0 { + dAtA6 := make([]byte, len(m.GlobalVirtualGroupIds)*10) + var j5 int + for _, num := range m.GlobalVirtualGroupIds { + for num >= 1<<7 { + dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j5++ + } + dAtA6[j5] = uint8(num) + j5++ } - i = encodeVarintEvents(dAtA, i, uint64(size)) + i -= j5 + copy(dAtA[i:], dAtA6[:j5]) + i = encodeVarintEvents(dAtA, i, uint64(j5)) + i-- + dAtA[i] = 0x22 } - i-- - dAtA[i] = 0x1a - if m.StoreSize != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.StoreSize)) + if len(m.VirtualPaymentAddress) > 0 { + i -= len(m.VirtualPaymentAddress) + copy(dAtA[i:], m.VirtualPaymentAddress) + i = encodeVarintEvents(dAtA, i, uint64(len(m.VirtualPaymentAddress))) + i-- + dAtA[i] = 0x1a + } + if m.PrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EventUpdateGlobalVirtualGroupFamily) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventUpdateGlobalVirtualGroupFamily) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventUpdateGlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.GlobalVirtualGroupIds) > 0 { + dAtA8 := make([]byte, len(m.GlobalVirtualGroupIds)*10) + var j7 int + for _, num := range m.GlobalVirtualGroupIds { + for num >= 1<<7 { + dAtA8[j7] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j7++ + } + dAtA8[j7] = uint8(num) + j7++ + } + i -= j7 + copy(dAtA[i:], dAtA8[:j7]) + i = encodeVarintEvents(dAtA, i, uint64(j7)) + i-- + dAtA[i] = 0x1a + } + if m.PrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EventDeleteGlobalVirtualGroupFamily) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventDeleteGlobalVirtualGroupFamily) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventDeleteGlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PrimarySpId != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.PrimarySpId)) i-- dAtA[i] = 0x10 } @@ -1053,13 +1404,61 @@ func (m *EventUpdateLocalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, e if m.StoredSize != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.StoredSize)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x20 } if m.GlobalVirtualGroupId != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.GlobalVirtualGroupId)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x18 + } + { + size := m.BucketId.Size() + i -= size + if _, err := m.BucketId.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.Id != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EventDeleteLocalVirtualGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventDeleteLocalVirtualGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventDeleteLocalVirtualGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.BucketId.Size() + i -= size + if _, err := m.BucketId.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvents(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 if m.Id != 0 { i = encodeVarintEvents(dAtA, i, uint64(m.Id)) i-- @@ -1094,20 +1493,20 @@ func (m *EventSwapOut) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x20 } if len(m.GlobalVirtualGroupIds) > 0 { - dAtA4 := make([]byte, len(m.GlobalVirtualGroupIds)*10) - var j3 int + dAtA10 := make([]byte, len(m.GlobalVirtualGroupIds)*10) + var j9 int for _, num := range m.GlobalVirtualGroupIds { for num >= 1<<7 { - dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80) + dAtA10[j9] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j3++ + j9++ } - dAtA4[j3] = uint8(num) - j3++ + dAtA10[j9] = uint8(num) + j9++ } - i -= j3 - copy(dAtA[i:], dAtA4[:j3]) - i = encodeVarintEvents(dAtA, i, uint64(j3)) + i -= j9 + copy(dAtA[i:], dAtA10[:j9]) + i = encodeVarintEvents(dAtA, i, uint64(j9)) i-- dAtA[i] = 0x1a } @@ -1145,20 +1544,20 @@ func (m *EventCompleteSwapOut) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if len(m.GlobalVirtualGroupIds) > 0 { - dAtA6 := make([]byte, len(m.GlobalVirtualGroupIds)*10) - var j5 int + dAtA12 := make([]byte, len(m.GlobalVirtualGroupIds)*10) + var j11 int for _, num := range m.GlobalVirtualGroupIds { for num >= 1<<7 { - dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) + dAtA12[j11] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j5++ + j11++ } - dAtA6[j5] = uint8(num) - j5++ + dAtA12[j11] = uint8(num) + j11++ } - i -= j5 - copy(dAtA[i:], dAtA6[:j5]) - i = encodeVarintEvents(dAtA, i, uint64(j5)) + i -= j11 + copy(dAtA[i:], dAtA12[:j11]) + i = encodeVarintEvents(dAtA, i, uint64(j11)) i-- dAtA[i] = 0x22 } @@ -1206,20 +1605,20 @@ func (m *EventCancelSwapOut) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x20 } if len(m.GlobalVirtualGroupIds) > 0 { - dAtA8 := make([]byte, len(m.GlobalVirtualGroupIds)*10) - var j7 int + dAtA14 := make([]byte, len(m.GlobalVirtualGroupIds)*10) + var j13 int for _, num := range m.GlobalVirtualGroupIds { for num >= 1<<7 { - dAtA8[j7] = uint8(uint64(num)&0x7f | 0x80) + dAtA14[j13] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j7++ + j13++ } - dAtA8[j7] = uint8(num) - j7++ + dAtA14[j13] = uint8(num) + j13++ } - i -= j7 - copy(dAtA[i:], dAtA8[:j7]) - i = encodeVarintEvents(dAtA, i, uint64(j7)) + i -= j13 + copy(dAtA[i:], dAtA14[:j13]) + i = encodeVarintEvents(dAtA, i, uint64(j13)) i-- dAtA[i] = 0x1a } @@ -1361,7 +1760,7 @@ func (m *EventCreateGlobalVirtualGroup) Size() (n int) { return n } -func (m *EventCreateGlobalVirtualGroupFamily) Size() (n int) { +func (m *EventUpdateGlobalVirtualGroup) Size() (n int) { if m == nil { return 0 } @@ -1370,9 +1769,20 @@ func (m *EventCreateGlobalVirtualGroupFamily) Size() (n int) { if m.Id != 0 { n += 1 + sovEvents(uint64(m.Id)) } - l = len(m.VirtualPaymentAddress) - if l > 0 { - n += 1 + l + sovEvents(uint64(l)) + if m.StoreSize != 0 { + n += 1 + sovEvents(uint64(m.StoreSize)) + } + l = m.TotalDeposit.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.PrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.PrimarySpId)) + } + if len(m.SecondarySpIds) > 0 { + l = 0 + for _, e := range m.SecondarySpIds { + l += sovEvents(uint64(e)) + } + n += 1 + sovEvents(uint64(l)) + l } return n } @@ -1386,10 +1796,13 @@ func (m *EventDeleteGlobalVirtualGroup) Size() (n int) { if m.Id != 0 { n += 1 + sovEvents(uint64(m.Id)) } + if m.PrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.PrimarySpId)) + } return n } -func (m *EventUpdateGlobalVirtualGroup) Size() (n int) { +func (m *EventCreateGlobalVirtualGroupFamily) Size() (n int) { if m == nil { return 0 } @@ -1398,11 +1811,57 @@ func (m *EventUpdateGlobalVirtualGroup) Size() (n int) { if m.Id != 0 { n += 1 + sovEvents(uint64(m.Id)) } - if m.StoreSize != 0 { - n += 1 + sovEvents(uint64(m.StoreSize)) + if m.PrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.PrimarySpId)) + } + l = len(m.VirtualPaymentAddress) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + if len(m.GlobalVirtualGroupIds) > 0 { + l = 0 + for _, e := range m.GlobalVirtualGroupIds { + l += sovEvents(uint64(e)) + } + n += 1 + sovEvents(uint64(l)) + l + } + return n +} + +func (m *EventUpdateGlobalVirtualGroupFamily) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovEvents(uint64(m.Id)) + } + if m.PrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.PrimarySpId)) + } + if len(m.GlobalVirtualGroupIds) > 0 { + l = 0 + for _, e := range m.GlobalVirtualGroupIds { + l += sovEvents(uint64(e)) + } + n += 1 + sovEvents(uint64(l)) + l + } + return n +} + +func (m *EventDeleteGlobalVirtualGroupFamily) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovEvents(uint64(m.Id)) + } + if m.PrimarySpId != 0 { + n += 1 + sovEvents(uint64(m.PrimarySpId)) } - l = m.TotalDeposit.Size() - n += 1 + l + sovEvents(uint64(l)) return n } @@ -1435,6 +1894,8 @@ func (m *EventUpdateLocalVirtualGroup) Size() (n int) { if m.Id != 0 { n += 1 + sovEvents(uint64(m.Id)) } + l = m.BucketId.Size() + n += 1 + l + sovEvents(uint64(l)) if m.GlobalVirtualGroupId != 0 { n += 1 + sovEvents(uint64(m.GlobalVirtualGroupId)) } @@ -1444,6 +1905,20 @@ func (m *EventUpdateLocalVirtualGroup) Size() (n int) { return n } +func (m *EventDeleteLocalVirtualGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovEvents(uint64(m.Id)) + } + l = m.BucketId.Size() + n += 1 + l + sovEvents(uint64(l)) + return n +} + func (m *EventSwapOut) Size() (n int) { if m == nil { return 0 @@ -1791,21 +2266,522 @@ func (m *EventCreateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TotalDeposit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalDeposit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventUpdateGlobalVirtualGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventUpdateGlobalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StoreSize", wireType) + } + m.StoreSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StoreSize |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalDeposit", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalDeposit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + } + m.PrimarySpId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimarySpId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType == 0 { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SecondarySpIds = append(m.SecondarySpIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.SecondarySpIds) == 0 { + m.SecondarySpIds = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SecondarySpIds = append(m.SecondarySpIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field SecondarySpIds", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventDeleteGlobalVirtualGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventDeleteGlobalVirtualGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventDeleteGlobalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + } + m.PrimarySpId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimarySpId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventCreateGlobalVirtualGroupFamily: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventCreateGlobalVirtualGroupFamily: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + } + m.PrimarySpId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimarySpId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VirtualPaymentAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VirtualPaymentAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType == 0 { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupIds = append(m.GlobalVirtualGroupIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.GlobalVirtualGroupIds) == 0 { + m.GlobalVirtualGroupIds = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupIds = append(m.GlobalVirtualGroupIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupIds", wireType) + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -1827,7 +2803,7 @@ func (m *EventCreateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { +func (m *EventUpdateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1850,10 +2826,10 @@ func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventCreateGlobalVirtualGroupFamily: wiretype end group for non-group") + return fmt.Errorf("proto: EventUpdateGlobalVirtualGroupFamily: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventCreateGlobalVirtualGroupFamily: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventUpdateGlobalVirtualGroupFamily: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1876,10 +2852,10 @@ func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VirtualPaymentAddress", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) } - var stringLen uint64 + m.PrimarySpId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -1889,24 +2865,87 @@ func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.PrimarySpId |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF + case 3: + if wireType == 0 { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupIds = append(m.GlobalVirtualGroupIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.GlobalVirtualGroupIds) == 0 { + m.GlobalVirtualGroupIds = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupIds = append(m.GlobalVirtualGroupIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupIds", wireType) } - m.VirtualPaymentAddress = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -1928,7 +2967,7 @@ func (m *EventCreateGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventDeleteGlobalVirtualGroup) Unmarshal(dAtA []byte) error { +func (m *EventDeleteGlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1951,10 +2990,10 @@ func (m *EventDeleteGlobalVirtualGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventDeleteGlobalVirtualGroup: wiretype end group for non-group") + return fmt.Errorf("proto: EventDeleteGlobalVirtualGroupFamily: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventDeleteGlobalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventDeleteGlobalVirtualGroupFamily: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1976,6 +3015,25 @@ func (m *EventDeleteGlobalVirtualGroup) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + } + m.PrimarySpId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimarySpId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -1997,7 +3055,7 @@ func (m *EventDeleteGlobalVirtualGroup) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { +func (m *EventCreateLocalVirtualGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2020,10 +3078,10 @@ func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventUpdateGlobalVirtualGroup: wiretype end group for non-group") + return fmt.Errorf("proto: EventCreateLocalVirtualGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventUpdateGlobalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventCreateLocalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2046,27 +3104,8 @@ func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StoreSize", wireType) - } - m.StoreSize = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.StoreSize |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TotalDeposit", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BucketId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2094,10 +3133,48 @@ func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.TotalDeposit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.BucketId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupId", wireType) + } + m.GlobalVirtualGroupId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GlobalVirtualGroupId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StoredSize", wireType) + } + m.StoredSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StoredSize |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) @@ -2119,7 +3196,7 @@ func (m *EventUpdateGlobalVirtualGroup) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventCreateLocalVirtualGroup) Unmarshal(dAtA []byte) error { +func (m *EventUpdateLocalVirtualGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2142,10 +3219,10 @@ func (m *EventCreateLocalVirtualGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventCreateLocalVirtualGroup: wiretype end group for non-group") + return fmt.Errorf("proto: EventUpdateLocalVirtualGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventCreateLocalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventUpdateLocalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2260,7 +3337,7 @@ func (m *EventCreateLocalVirtualGroup) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventUpdateLocalVirtualGroup) Unmarshal(dAtA []byte) error { +func (m *EventDeleteLocalVirtualGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2283,10 +3360,10 @@ func (m *EventUpdateLocalVirtualGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventUpdateLocalVirtualGroup: wiretype end group for non-group") + return fmt.Errorf("proto: EventDeleteLocalVirtualGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventUpdateLocalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventDeleteLocalVirtualGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2309,10 +3386,10 @@ func (m *EventUpdateLocalVirtualGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupId", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BucketId", wireType) } - m.GlobalVirtualGroupId = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -2322,30 +3399,26 @@ func (m *EventUpdateLocalVirtualGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.GlobalVirtualGroupId |= uint32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StoredSize", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents } - m.StoredSize = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.StoredSize |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF } + if err := m.BucketId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/x/virtualgroup/types/keys.go b/x/virtualgroup/types/keys.go index 88272ece8..a0e92f211 100644 --- a/x/virtualgroup/types/keys.go +++ b/x/virtualgroup/types/keys.go @@ -50,9 +50,9 @@ func GetGVGKey(gvgID uint32) []byte { return append(GVGKey, uint32Seq.EncodeSequence(gvgID)...) } -func GetGVGFamilyKey(spID uint32, familyID uint32) []byte { +func GetGVGFamilyKey(familyID uint32) []byte { var uint32Seq sequence.Sequence[uint32] - return append(GVGFamilyKey, append(uint32Seq.EncodeSequence(spID), uint32Seq.EncodeSequence(familyID)...)...) + return append(GVGFamilyKey, uint32Seq.EncodeSequence(familyID)...) } func GetGVGFamilyPrefixKey(spID uint32) []byte { diff --git a/x/virtualgroup/types/query.pb.go b/x/virtualgroup/types/query.pb.go index 6f994875a..336ea65d8 100644 --- a/x/virtualgroup/types/query.pb.go +++ b/x/virtualgroup/types/query.pb.go @@ -303,9 +303,97 @@ func (m *QueryGlobalVirtualGroupByFamilyIDResponse) GetGlobalVirtualGroups() []* return nil } +type QueryGlobalVirtualGroupFamilyRequest struct { + FamilyId uint32 `protobuf:"varint,1,opt,name=family_id,json=familyId,proto3" json:"family_id,omitempty"` +} + +func (m *QueryGlobalVirtualGroupFamilyRequest) Reset() { *m = QueryGlobalVirtualGroupFamilyRequest{} } +func (m *QueryGlobalVirtualGroupFamilyRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGlobalVirtualGroupFamilyRequest) ProtoMessage() {} +func (*QueryGlobalVirtualGroupFamilyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_83cd53fc415e00e7, []int{6} +} +func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.Merge(m, src) +} +func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest proto.InternalMessageInfo + +func (m *QueryGlobalVirtualGroupFamilyRequest) GetFamilyId() uint32 { + if m != nil { + return m.FamilyId + } + return 0 +} + +type QueryGlobalVirtualGroupFamilyResponse struct { + GlobalVirtualGroupFamily *GlobalVirtualGroupFamily `protobuf:"bytes,1,opt,name=global_virtual_group_family,json=globalVirtualGroupFamily,proto3" json:"global_virtual_group_family,omitempty"` +} + +func (m *QueryGlobalVirtualGroupFamilyResponse) Reset() { *m = QueryGlobalVirtualGroupFamilyResponse{} } +func (m *QueryGlobalVirtualGroupFamilyResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGlobalVirtualGroupFamilyResponse) ProtoMessage() {} +func (*QueryGlobalVirtualGroupFamilyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_83cd53fc415e00e7, []int{7} +} +func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.Merge(m, src) +} +func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse proto.InternalMessageInfo + +func (m *QueryGlobalVirtualGroupFamilyResponse) GetGlobalVirtualGroupFamily() *GlobalVirtualGroupFamily { + if m != nil { + return m.GlobalVirtualGroupFamily + } + return nil +} + +// this line is used by starport scaffolding # 3 type QueryGlobalVirtualGroupFamiliesRequest struct { - StorageProviderId uint32 `protobuf:"varint,1,opt,name=storage_provider_id,json=storageProviderId,proto3" json:"storage_provider_id,omitempty"` - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryGlobalVirtualGroupFamiliesRequest) Reset() { @@ -314,7 +402,7 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) Reset() { func (m *QueryGlobalVirtualGroupFamiliesRequest) String() string { return proto.CompactTextString(m) } func (*QueryGlobalVirtualGroupFamiliesRequest) ProtoMessage() {} func (*QueryGlobalVirtualGroupFamiliesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_83cd53fc415e00e7, []int{6} + return fileDescriptor_83cd53fc415e00e7, []int{8} } func (m *QueryGlobalVirtualGroupFamiliesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -343,13 +431,6 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryGlobalVirtualGroupFamiliesRequest proto.InternalMessageInfo -func (m *QueryGlobalVirtualGroupFamiliesRequest) GetStorageProviderId() uint32 { - if m != nil { - return m.StorageProviderId - } - return 0 -} - func (m *QueryGlobalVirtualGroupFamiliesRequest) GetPagination() *query.PageRequest { if m != nil { return m.Pagination @@ -358,8 +439,8 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) GetPagination() *query.PageRequ } type QueryGlobalVirtualGroupFamiliesResponse struct { - GlobalVirtualGroupFamilies []*GlobalVirtualGroupFamily `protobuf:"bytes,1,rep,name=global_virtual_group_families,json=globalVirtualGroupFamilies,proto3" json:"global_virtual_group_families,omitempty"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + GvgFamilies []*GlobalVirtualGroupFamily `protobuf:"bytes,1,rep,name=gvg_families,json=gvgFamilies,proto3" json:"gvg_families,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryGlobalVirtualGroupFamiliesResponse) Reset() { @@ -368,7 +449,7 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Reset() { func (m *QueryGlobalVirtualGroupFamiliesResponse) String() string { return proto.CompactTextString(m) } func (*QueryGlobalVirtualGroupFamiliesResponse) ProtoMessage() {} func (*QueryGlobalVirtualGroupFamiliesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_83cd53fc415e00e7, []int{7} + return fileDescriptor_83cd53fc415e00e7, []int{9} } func (m *QueryGlobalVirtualGroupFamiliesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -397,9 +478,9 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryGlobalVirtualGroupFamiliesResponse proto.InternalMessageInfo -func (m *QueryGlobalVirtualGroupFamiliesResponse) GetGlobalVirtualGroupFamilies() []*GlobalVirtualGroupFamily { +func (m *QueryGlobalVirtualGroupFamiliesResponse) GetGvgFamilies() []*GlobalVirtualGroupFamily { if m != nil { - return m.GlobalVirtualGroupFamilies + return m.GvgFamilies } return nil } @@ -411,23 +492,26 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) GetPagination() *query.PageRes return nil } -type QueryGlobalVirtualGroupFamilyRequest struct { - StorageProviderId uint32 `protobuf:"varint,1,opt,name=storage_provider_id,json=storageProviderId,proto3" json:"storage_provider_id,omitempty"` - FamilyId uint32 `protobuf:"varint,2,opt,name=family_id,json=familyId,proto3" json:"family_id,omitempty"` +type AvailableGlobalVirtualGroupFamiliesRequest struct { + GlobalVirtualGroupFamilyIds []uint32 `protobuf:"varint,1,rep,packed,name=global_virtual_group_family_ids,json=globalVirtualGroupFamilyIds,proto3" json:"global_virtual_group_family_ids,omitempty"` } -func (m *QueryGlobalVirtualGroupFamilyRequest) Reset() { *m = QueryGlobalVirtualGroupFamilyRequest{} } -func (m *QueryGlobalVirtualGroupFamilyRequest) String() string { return proto.CompactTextString(m) } -func (*QueryGlobalVirtualGroupFamilyRequest) ProtoMessage() {} -func (*QueryGlobalVirtualGroupFamilyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_83cd53fc415e00e7, []int{8} +func (m *AvailableGlobalVirtualGroupFamiliesRequest) Reset() { + *m = AvailableGlobalVirtualGroupFamiliesRequest{} } -func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Unmarshal(b []byte) error { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) String() string { + return proto.CompactTextString(m) +} +func (*AvailableGlobalVirtualGroupFamiliesRequest) ProtoMessage() {} +func (*AvailableGlobalVirtualGroupFamiliesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_83cd53fc415e00e7, []int{10} +} +func (m *AvailableGlobalVirtualGroupFamiliesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -437,48 +521,45 @@ func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Marshal(b []byte, determinist return b[:n], nil } } -func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.Merge(m, src) +func (m *AvailableGlobalVirtualGroupFamiliesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesRequest.Merge(m, src) } -func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_Size() int { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) XXX_Size() int { return m.Size() } -func (m *QueryGlobalVirtualGroupFamilyRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest.DiscardUnknown(m) +func (m *AvailableGlobalVirtualGroupFamiliesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryGlobalVirtualGroupFamilyRequest proto.InternalMessageInfo +var xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesRequest proto.InternalMessageInfo -func (m *QueryGlobalVirtualGroupFamilyRequest) GetStorageProviderId() uint32 { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) GetGlobalVirtualGroupFamilyIds() []uint32 { if m != nil { - return m.StorageProviderId + return m.GlobalVirtualGroupFamilyIds } - return 0 + return nil } -func (m *QueryGlobalVirtualGroupFamilyRequest) GetFamilyId() uint32 { - if m != nil { - return m.FamilyId - } - return 0 +type AvailableGlobalVirtualGroupFamiliesResponse struct { + GlobalVirtualGroupFamilyIds []uint32 `protobuf:"varint,1,rep,packed,name=global_virtual_group_family_ids,json=globalVirtualGroupFamilyIds,proto3" json:"global_virtual_group_family_ids,omitempty"` } -type QueryGlobalVirtualGroupFamilyResponse struct { - GlobalVirtualGroupFamily *GlobalVirtualGroupFamily `protobuf:"bytes,1,opt,name=global_virtual_group_family,json=globalVirtualGroupFamily,proto3" json:"global_virtual_group_family,omitempty"` +func (m *AvailableGlobalVirtualGroupFamiliesResponse) Reset() { + *m = AvailableGlobalVirtualGroupFamiliesResponse{} } - -func (m *QueryGlobalVirtualGroupFamilyResponse) Reset() { *m = QueryGlobalVirtualGroupFamilyResponse{} } -func (m *QueryGlobalVirtualGroupFamilyResponse) String() string { return proto.CompactTextString(m) } -func (*QueryGlobalVirtualGroupFamilyResponse) ProtoMessage() {} -func (*QueryGlobalVirtualGroupFamilyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_83cd53fc415e00e7, []int{9} +func (m *AvailableGlobalVirtualGroupFamiliesResponse) String() string { + return proto.CompactTextString(m) } -func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Unmarshal(b []byte) error { +func (*AvailableGlobalVirtualGroupFamiliesResponse) ProtoMessage() {} +func (*AvailableGlobalVirtualGroupFamiliesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_83cd53fc415e00e7, []int{11} +} +func (m *AvailableGlobalVirtualGroupFamiliesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -488,21 +569,21 @@ func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Marshal(b []byte, determinis return b[:n], nil } } -func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.Merge(m, src) +func (m *AvailableGlobalVirtualGroupFamiliesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesResponse.Merge(m, src) } -func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_Size() int { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) XXX_Size() int { return m.Size() } -func (m *QueryGlobalVirtualGroupFamilyResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse.DiscardUnknown(m) +func (m *AvailableGlobalVirtualGroupFamiliesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryGlobalVirtualGroupFamilyResponse proto.InternalMessageInfo +var xxx_messageInfo_AvailableGlobalVirtualGroupFamiliesResponse proto.InternalMessageInfo -func (m *QueryGlobalVirtualGroupFamilyResponse) GetGlobalVirtualGroupFamily() *GlobalVirtualGroupFamily { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) GetGlobalVirtualGroupFamilyIds() []uint32 { if m != nil { - return m.GlobalVirtualGroupFamily + return m.GlobalVirtualGroupFamilyIds } return nil } @@ -514,10 +595,12 @@ func init() { proto.RegisterType((*QueryGlobalVirtualGroupResponse)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupResponse") proto.RegisterType((*QueryGlobalVirtualGroupByFamilyIDRequest)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupByFamilyIDRequest") proto.RegisterType((*QueryGlobalVirtualGroupByFamilyIDResponse)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupByFamilyIDResponse") - proto.RegisterType((*QueryGlobalVirtualGroupFamiliesRequest)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamiliesRequest") - proto.RegisterType((*QueryGlobalVirtualGroupFamiliesResponse)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamiliesResponse") proto.RegisterType((*QueryGlobalVirtualGroupFamilyRequest)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamilyRequest") proto.RegisterType((*QueryGlobalVirtualGroupFamilyResponse)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamilyResponse") + proto.RegisterType((*QueryGlobalVirtualGroupFamiliesRequest)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamiliesRequest") + proto.RegisterType((*QueryGlobalVirtualGroupFamiliesResponse)(nil), "greenfield.virtualgroup.QueryGlobalVirtualGroupFamiliesResponse") + proto.RegisterType((*AvailableGlobalVirtualGroupFamiliesRequest)(nil), "greenfield.virtualgroup.AvailableGlobalVirtualGroupFamiliesRequest") + proto.RegisterType((*AvailableGlobalVirtualGroupFamiliesResponse)(nil), "greenfield.virtualgroup.AvailableGlobalVirtualGroupFamiliesResponse") } func init() { @@ -525,53 +608,57 @@ func init() { } var fileDescriptor_83cd53fc415e00e7 = []byte{ - // 726 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x4f, 0xd4, 0x4e, - 0x18, 0xde, 0xe1, 0xf7, 0x13, 0xf5, 0x25, 0x1e, 0x1c, 0xd6, 0x40, 0x0a, 0x76, 0xb5, 0x22, 0xe0, - 0x1f, 0xda, 0x80, 0x80, 0xc4, 0x00, 0xea, 0xc6, 0x40, 0xb8, 0x18, 0xdc, 0x18, 0x4d, 0x4c, 0xcc, - 0x66, 0xca, 0x0e, 0x65, 0x92, 0xdd, 0x4e, 0x69, 0xbb, 0xc4, 0xde, 0x8c, 0x67, 0x0e, 0x26, 0x9e, - 0xbc, 0x18, 0x3f, 0x89, 0x67, 0x8e, 0x24, 0x1e, 0xf4, 0xa4, 0x06, 0x3c, 0xe8, 0xa7, 0xd0, 0xec, - 0x74, 0x36, 0x0b, 0xb4, 0xb3, 0x4b, 0xeb, 0xad, 0xe9, 0xbc, 0x7f, 0x9e, 0xe7, 0x79, 0xe7, 0x7d, - 0x32, 0x70, 0xcd, 0xf1, 0x29, 0x75, 0x37, 0x19, 0xad, 0xd7, 0xac, 0x1d, 0xe6, 0x87, 0x4d, 0x52, - 0x77, 0x7c, 0xde, 0xf4, 0xac, 0xed, 0x26, 0xf5, 0x23, 0xd3, 0xf3, 0x79, 0xc8, 0xf1, 0x50, 0x27, - 0xc8, 0x3c, 0x1a, 0xa4, 0xdd, 0xdc, 0xe0, 0x41, 0x83, 0x07, 0x96, 0x4d, 0x02, 0x1a, 0x67, 0x58, - 0x3b, 0xd3, 0x36, 0x0d, 0xc9, 0xb4, 0xe5, 0x11, 0x87, 0xb9, 0x24, 0x64, 0xdc, 0x8d, 0x8b, 0x68, - 0x45, 0x87, 0x3b, 0x5c, 0x7c, 0x5a, 0xad, 0x2f, 0xf9, 0x77, 0xd4, 0xe1, 0xdc, 0xa9, 0x53, 0x8b, - 0x78, 0xcc, 0x22, 0xae, 0xcb, 0x43, 0x91, 0x12, 0xc8, 0xd3, 0x31, 0x15, 0x3a, 0x8f, 0xf8, 0xa4, - 0xd1, 0x8e, 0x52, 0x72, 0x08, 0x23, 0x8f, 0xca, 0x20, 0xa3, 0x08, 0xf8, 0x49, 0x0b, 0xe0, 0xba, - 0xc8, 0xac, 0xd0, 0xed, 0x26, 0x0d, 0x42, 0xe3, 0x29, 0x0c, 0x1e, 0xfb, 0x1b, 0x78, 0xdc, 0x0d, - 0x28, 0x5e, 0x82, 0xfe, 0xb8, 0xc3, 0x30, 0xba, 0x82, 0x26, 0x07, 0x66, 0x4a, 0xa6, 0x42, 0x01, - 0x33, 0x4e, 0x2c, 0xff, 0xbf, 0xf7, 0xad, 0x54, 0xa8, 0xc8, 0x24, 0xe3, 0x39, 0xe8, 0xa2, 0xea, - 0x6a, 0x9d, 0xdb, 0xa4, 0xfe, 0x2c, 0x8e, 0x5f, 0x6d, 0xc5, 0xcb, 0xbe, 0x78, 0x0e, 0x86, 0x1c, - 0x71, 0x58, 0x95, 0xd5, 0xaa, 0xa2, 0x5c, 0x95, 0xd5, 0x44, 0xc7, 0x0b, 0x95, 0xa2, 0x93, 0xc8, - 0x5d, 0xab, 0x19, 0xaf, 0x11, 0x94, 0x94, 0x95, 0x25, 0xf6, 0x97, 0x50, 0x4c, 0x2b, 0x2d, 0x99, - 0xdc, 0x52, 0x32, 0x49, 0x29, 0x89, 0x93, 0x20, 0x8c, 0x0f, 0x08, 0x26, 0x15, 0x10, 0xca, 0xd1, - 0x0a, 0x69, 0xb0, 0x7a, 0xb4, 0xf6, 0xa8, 0x4d, 0xd3, 0x84, 0xc1, 0x20, 0xe4, 0x3e, 0x71, 0x68, - 0xd5, 0xf3, 0xf9, 0x0e, 0xab, 0x51, 0xbf, 0x43, 0xf1, 0xa2, 0x3c, 0x5a, 0x97, 0x27, 0x6b, 0x35, - 0x5c, 0x06, 0x3d, 0x55, 0x96, 0x4d, 0x51, 0xb7, 0x95, 0xda, 0x27, 0x52, 0xb5, 0x24, 0x30, 0xd9, - 0xba, 0x66, 0xec, 0x22, 0xb8, 0x71, 0x0a, 0x80, 0x52, 0xad, 0x2a, 0x5c, 0x4a, 0xeb, 0xd8, 0x1a, - 0xfc, 0x7f, 0x59, 0xe5, 0x1a, 0x4c, 0xa2, 0x0a, 0x8c, 0x8f, 0x08, 0xc6, 0x15, 0x70, 0x04, 0x18, - 0x46, 0x83, 0xbc, 0x6a, 0xad, 0x00, 0x74, 0xb6, 0x4c, 0x28, 0x33, 0x30, 0x33, 0x6e, 0xc6, 0x2b, - 0x69, 0xb6, 0x56, 0xd2, 0x8c, 0x97, 0x58, 0xae, 0xa4, 0xb9, 0x4e, 0x1c, 0x2a, 0x7b, 0x55, 0x8e, - 0x64, 0x1a, 0xbf, 0x10, 0x4c, 0xf4, 0x84, 0x28, 0xf5, 0x0a, 0xe1, 0xb2, 0x7a, 0x42, 0x8c, 0xb6, - 0x75, 0x9b, 0xce, 0xa0, 0x5b, 0x3c, 0x13, 0xe5, 0x4c, 0x19, 0x0d, 0xf0, 0x6a, 0x0a, 0xd3, 0x89, - 0x9e, 0x4c, 0x63, 0xc8, 0xc7, 0xa8, 0x06, 0x30, 0xd6, 0x8d, 0x69, 0x94, 0x77, 0x14, 0x23, 0x70, - 0xfe, 0xe4, 0x1d, 0x3d, 0xb7, 0xd9, 0xbe, 0x91, 0xef, 0x11, 0x5c, 0xef, 0xd1, 0x55, 0xaa, 0xeb, - 0xc1, 0x48, 0x97, 0xfb, 0x2f, 0x57, 0x38, 0x87, 0xb6, 0xc3, 0xaa, 0x7d, 0x99, 0xf9, 0x73, 0x16, - 0xce, 0x08, 0x6c, 0x78, 0x17, 0x41, 0x7f, 0xec, 0x66, 0x58, 0x7d, 0xeb, 0x93, 0x16, 0xaa, 0xdd, - 0x3e, 0x5d, 0x70, 0xcc, 0xd0, 0x98, 0x78, 0xf3, 0xf9, 0xe7, 0xbb, 0xbe, 0xab, 0xb8, 0x64, 0x75, - 0xb7, 0x76, 0xfc, 0x09, 0x01, 0x4e, 0xf2, 0xc1, 0x77, 0xbb, 0x77, 0x53, 0x3a, 0xae, 0xb6, 0x90, - 0x3d, 0x51, 0x42, 0x9e, 0x13, 0x90, 0x2d, 0x3c, 0xa5, 0x84, 0x9c, 0x36, 0x33, 0xfc, 0x1b, 0xc1, - 0x68, 0x37, 0x0b, 0xc2, 0x0f, 0xb3, 0x22, 0x4a, 0xf8, 0xab, 0x56, 0xfe, 0x97, 0x12, 0x92, 0x5e, - 0x59, 0xd0, 0x5b, 0xc4, 0xf7, 0x32, 0xd1, 0xab, 0xda, 0x51, 0xc7, 0x95, 0xf1, 0x77, 0x04, 0x9a, - 0xda, 0x3c, 0xf0, 0xfd, 0xac, 0x30, 0x4f, 0x38, 0xa3, 0xf6, 0x20, 0x7f, 0x01, 0xc9, 0x72, 0x59, - 0xb0, 0x5c, 0xc0, 0xf3, 0xd9, 0x58, 0xb6, 0x6d, 0x0d, 0x7f, 0x41, 0x30, 0xac, 0x5a, 0x2f, 0xbc, - 0x94, 0x0b, 0x5e, 0xdb, 0x6c, 0xb4, 0xe5, 0xbc, 0xe9, 0x92, 0xdb, 0xa2, 0xe0, 0x36, 0x8f, 0x67, - 0x73, 0x70, 0x8b, 0xca, 0x8f, 0xf7, 0x0e, 0x74, 0xb4, 0x7f, 0xa0, 0xa3, 0x1f, 0x07, 0x3a, 0x7a, - 0x7b, 0xa8, 0x17, 0xf6, 0x0f, 0xf5, 0xc2, 0xd7, 0x43, 0xbd, 0xf0, 0x62, 0xd6, 0x61, 0xe1, 0x56, - 0xd3, 0x36, 0x37, 0x78, 0xc3, 0xb2, 0x5d, 0x7b, 0x6a, 0x63, 0x8b, 0x30, 0xf7, 0x68, 0x8f, 0x57, - 0x29, 0xcf, 0x2d, 0xbb, 0x5f, 0xbc, 0xb7, 0xee, 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x02, 0x72, - 0x7e, 0x9e, 0x5a, 0x0a, 0x00, 0x00, + // 800 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x4f, 0x4f, 0xdb, 0x48, + 0x18, 0xc6, 0x33, 0xec, 0x2e, 0x5a, 0x5e, 0x96, 0xc3, 0x0e, 0x59, 0x81, 0x0c, 0x72, 0x76, 0x0d, + 0x0b, 0x14, 0x8a, 0x2d, 0x28, 0x50, 0x54, 0x01, 0x85, 0x80, 0xa0, 0x5c, 0x2a, 0x1a, 0xa1, 0x56, + 0xaa, 0x54, 0x45, 0x63, 0x32, 0x0c, 0x96, 0x1c, 0x8f, 0xb1, 0x9d, 0xa8, 0xb9, 0x55, 0x3d, 0x73, + 0xa8, 0xd4, 0x53, 0x2f, 0xfd, 0x28, 0x3d, 0x73, 0x44, 0xea, 0xa1, 0x3d, 0xb5, 0x15, 0xf4, 0xd2, + 0xaf, 0x50, 0xf5, 0x50, 0x65, 0x3c, 0x56, 0x88, 0x92, 0xc9, 0x3f, 0x7a, 0x8b, 0x3c, 0xf3, 0x3e, + 0xef, 0xf3, 0x7b, 0xc7, 0xf3, 0xc4, 0x30, 0xc1, 0x02, 0x4a, 0xbd, 0x63, 0x87, 0xba, 0x05, 0xab, + 0xec, 0x04, 0x51, 0x89, 0xb8, 0x2c, 0xe0, 0x25, 0xdf, 0x3a, 0x2d, 0xd1, 0xa0, 0x62, 0xfa, 0x01, + 0x8f, 0x38, 0x1e, 0xa9, 0x6d, 0x32, 0xaf, 0x6f, 0xd2, 0x66, 0x8f, 0x78, 0x58, 0xe4, 0xa1, 0x65, + 0x93, 0x90, 0xc6, 0x15, 0x56, 0x79, 0xc1, 0xa6, 0x11, 0x59, 0xb0, 0x7c, 0xc2, 0x1c, 0x8f, 0x44, + 0x0e, 0xf7, 0x62, 0x11, 0x2d, 0xcd, 0x38, 0xe3, 0xe2, 0xa7, 0x55, 0xfd, 0x25, 0x9f, 0x8e, 0x33, + 0xce, 0x99, 0x4b, 0x2d, 0xe2, 0x3b, 0x16, 0xf1, 0x3c, 0x1e, 0x89, 0x92, 0x50, 0xae, 0x4e, 0xaa, + 0xdc, 0xf9, 0x24, 0x20, 0xc5, 0x64, 0x97, 0x92, 0x21, 0xaa, 0xf8, 0x54, 0x6e, 0x32, 0xd2, 0x80, + 0x1f, 0x55, 0x0d, 0x1e, 0x88, 0xca, 0x1c, 0x3d, 0x2d, 0xd1, 0x30, 0x32, 0x0e, 0x61, 0xb8, 0xee, + 0x69, 0xe8, 0x73, 0x2f, 0xa4, 0x78, 0x1d, 0xfa, 0xe3, 0x0e, 0xa3, 0xe8, 0x5f, 0x34, 0x33, 0xb8, + 0x98, 0x31, 0x15, 0x13, 0x30, 0xe3, 0xc2, 0xec, 0xef, 0xe7, 0x9f, 0x32, 0xa9, 0x9c, 0x2c, 0x32, + 0x9e, 0x80, 0x2e, 0x54, 0xf7, 0x5c, 0x6e, 0x13, 0xf7, 0x71, 0xbc, 0x7f, 0xaf, 0xba, 0x5f, 0xf6, + 0xc5, 0xcb, 0x30, 0xc2, 0xc4, 0x62, 0x5e, 0xaa, 0xe5, 0x85, 0x5c, 0xde, 0x29, 0x88, 0x8e, 0x43, + 0xb9, 0x34, 0x6b, 0xa8, 0xdd, 0x2f, 0x18, 0x2f, 0x10, 0x64, 0x94, 0xca, 0xd2, 0xfb, 0x33, 0x48, + 0x37, 0x93, 0x96, 0x24, 0x73, 0x4a, 0x92, 0x26, 0x92, 0xb8, 0xd1, 0x84, 0xf1, 0x16, 0xc1, 0x8c, + 0xc2, 0x42, 0xb6, 0xb2, 0x4b, 0x8a, 0x8e, 0x5b, 0xd9, 0xdf, 0x49, 0x30, 0x4d, 0x18, 0x0e, 0x23, + 0x1e, 0x10, 0x46, 0xf3, 0x7e, 0xc0, 0xcb, 0x4e, 0x81, 0x06, 0x35, 0xc4, 0xbf, 0xe5, 0xd2, 0x81, + 0x5c, 0xd9, 0x2f, 0xe0, 0x2c, 0xe8, 0x4d, 0xc7, 0x72, 0x2c, 0x74, 0xab, 0xa5, 0x7d, 0xa2, 0x54, + 0x6b, 0x34, 0x26, 0x5b, 0x17, 0x8c, 0x33, 0x04, 0xb7, 0x3a, 0x30, 0x28, 0xa7, 0x95, 0x87, 0x7f, + 0x9a, 0x75, 0xac, 0x1e, 0xfc, 0x6f, 0xdd, 0x8e, 0x6b, 0xb8, 0xd1, 0x55, 0x68, 0x6c, 0xc3, 0xa4, + 0xc2, 0x4d, 0xec, 0x25, 0x19, 0xd5, 0x18, 0x0c, 0xd4, 0x28, 0xe3, 0x01, 0xfd, 0x79, 0x9c, 0x30, + 0xbd, 0x41, 0xf0, 0x7f, 0x1b, 0x15, 0xc9, 0xe3, 0xc3, 0x58, 0x8b, 0x09, 0xca, 0x97, 0x60, 0xa1, + 0x0b, 0x2a, 0xa9, 0x3f, 0xaa, 0x9a, 0xb8, 0xe1, 0xc3, 0x54, 0x2b, 0x6b, 0x0e, 0x4d, 0x2e, 0x1b, + 0xde, 0x05, 0xa8, 0xa5, 0x82, 0xb4, 0x32, 0x65, 0xc6, 0x11, 0x62, 0x56, 0x23, 0xc4, 0x8c, 0x43, + 0x47, 0x46, 0x88, 0x79, 0x40, 0x18, 0x95, 0xb5, 0xb9, 0x6b, 0x95, 0xc6, 0x39, 0x82, 0xe9, 0xb6, + 0x2d, 0xe5, 0x3c, 0x0e, 0xe1, 0x2f, 0x56, 0x66, 0x31, 0xbe, 0x43, 0x93, 0x63, 0xed, 0x61, 0x00, + 0x83, 0xac, 0xcc, 0x12, 0x75, 0xbc, 0x57, 0x47, 0xd2, 0x27, 0x48, 0xa6, 0xdb, 0x92, 0xc4, 0x96, + 0xea, 0x50, 0x02, 0x98, 0xdd, 0x2a, 0x13, 0xc7, 0x25, 0xb6, 0x4b, 0xdb, 0x0f, 0x70, 0x07, 0x32, + 0xad, 0xaf, 0x47, 0xcc, 0x37, 0x94, 0x1b, 0x53, 0xdf, 0x8f, 0xd0, 0x08, 0x61, 0xae, 0xa3, 0x9e, + 0x72, 0x82, 0xbf, 0xa4, 0xe9, 0xe2, 0x8f, 0x01, 0xf8, 0x43, 0x9c, 0x19, 0x3e, 0x43, 0xd0, 0x1f, + 0xa7, 0x26, 0x56, 0xdf, 0xae, 0xc6, 0xa8, 0xd6, 0x6e, 0x77, 0xb6, 0x39, 0x76, 0x6d, 0x4c, 0xbf, + 0x7c, 0xff, 0xf5, 0x75, 0xdf, 0x7f, 0x38, 0x63, 0xb5, 0xfe, 0x0b, 0xc1, 0xef, 0x10, 0xe0, 0xc6, + 0x29, 0xe0, 0xbb, 0xad, 0xbb, 0x29, 0x93, 0x5d, 0x5b, 0xed, 0xbe, 0x50, 0x5a, 0x5e, 0x16, 0x96, + 0x2d, 0x3c, 0xaf, 0xb4, 0xdc, 0xec, 0x1c, 0xf0, 0x37, 0x04, 0xe3, 0xad, 0xa2, 0x0e, 0x6f, 0x75, + 0xeb, 0xa8, 0x21, 0xc7, 0xb5, 0xec, 0x4d, 0x24, 0x24, 0x5e, 0x56, 0xe0, 0xad, 0xe1, 0x7b, 0x5d, + 0xe1, 0xe5, 0xed, 0x4a, 0xed, 0x4d, 0xc3, 0x1f, 0x10, 0x8c, 0xaa, 0x6e, 0x28, 0x5e, 0xef, 0xd6, + 0x64, 0x5d, 0x00, 0x6b, 0x1b, 0xbd, 0x96, 0x4b, 0xbe, 0x35, 0xc1, 0xb7, 0x82, 0x97, 0xba, 0xe3, + 0x8b, 0xe1, 0xf0, 0x67, 0x04, 0x9a, 0xfa, 0x32, 0xe2, 0xfb, 0x3d, 0x99, 0xab, 0x45, 0x87, 0xb6, + 0xd9, 0xbb, 0x80, 0xe4, 0xdb, 0x10, 0x7c, 0xab, 0x78, 0xa5, 0x07, 0xbe, 0x2a, 0xc2, 0x77, 0x04, + 0x13, 0x1d, 0xe4, 0x0e, 0xde, 0x56, 0x3a, 0xed, 0x3c, 0x29, 0xb5, 0x9d, 0x9b, 0x89, 0x48, 0xe4, + 0x07, 0x02, 0x39, 0x8b, 0x37, 0x95, 0xc8, 0x24, 0x51, 0xcb, 0xb7, 0x84, 0xcf, 0x3e, 0x3c, 0xbf, + 0xd4, 0xd1, 0xc5, 0xa5, 0x8e, 0xbe, 0x5c, 0xea, 0xe8, 0xd5, 0x95, 0x9e, 0xba, 0xb8, 0xd2, 0x53, + 0x1f, 0xaf, 0xf4, 0xd4, 0xd3, 0x25, 0xe6, 0x44, 0x27, 0x25, 0xdb, 0x3c, 0xe2, 0x45, 0xcb, 0xf6, + 0xec, 0xf9, 0xa3, 0x13, 0xe2, 0x78, 0xd7, 0xfb, 0x3d, 0x6f, 0xf2, 0x4d, 0x6b, 0xf7, 0x8b, 0x8f, + 0xda, 0x3b, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xba, 0xb0, 0xee, 0x41, 0xbf, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -592,10 +679,12 @@ type QueryClient interface { GlobalVirtualGroup(ctx context.Context, in *QueryGlobalVirtualGroupRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupResponse, error) // Queries a list of global virtual groups by family id. GlobalVirtualGroupByFamilyID(ctx context.Context, in *QueryGlobalVirtualGroupByFamilyIDRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupByFamilyIDResponse, error) - // Queries a list of global virtual group families by storage provider id. - GlobalVirtualGroupFamilies(ctx context.Context, in *QueryGlobalVirtualGroupFamiliesRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamiliesResponse, error) // Queries a global virtual group family by its id. GlobalVirtualGroupFamily(ctx context.Context, in *QueryGlobalVirtualGroupFamilyRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamilyResponse, error) + // Queries a list of GlobalVirtualGroupFamilies items. + GlobalVirtualGroupFamilies(ctx context.Context, in *QueryGlobalVirtualGroupFamiliesRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamiliesResponse, error) + // AvailableGlobalVirtualGroupFamilies filters a list of GlobalVirtualGroupFamilies ID which are qualified to create bucket on + AvailableGlobalVirtualGroupFamilies(ctx context.Context, in *AvailableGlobalVirtualGroupFamiliesRequest, opts ...grpc.CallOption) (*AvailableGlobalVirtualGroupFamiliesResponse, error) } type queryClient struct { @@ -633,6 +722,15 @@ func (c *queryClient) GlobalVirtualGroupByFamilyID(ctx context.Context, in *Quer return out, nil } +func (c *queryClient) GlobalVirtualGroupFamily(ctx context.Context, in *QueryGlobalVirtualGroupFamilyRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamilyResponse, error) { + out := new(QueryGlobalVirtualGroupFamilyResponse) + err := c.cc.Invoke(ctx, "/greenfield.virtualgroup.Query/GlobalVirtualGroupFamily", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) GlobalVirtualGroupFamilies(ctx context.Context, in *QueryGlobalVirtualGroupFamiliesRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamiliesResponse, error) { out := new(QueryGlobalVirtualGroupFamiliesResponse) err := c.cc.Invoke(ctx, "/greenfield.virtualgroup.Query/GlobalVirtualGroupFamilies", in, out, opts...) @@ -642,9 +740,9 @@ func (c *queryClient) GlobalVirtualGroupFamilies(ctx context.Context, in *QueryG return out, nil } -func (c *queryClient) GlobalVirtualGroupFamily(ctx context.Context, in *QueryGlobalVirtualGroupFamilyRequest, opts ...grpc.CallOption) (*QueryGlobalVirtualGroupFamilyResponse, error) { - out := new(QueryGlobalVirtualGroupFamilyResponse) - err := c.cc.Invoke(ctx, "/greenfield.virtualgroup.Query/GlobalVirtualGroupFamily", in, out, opts...) +func (c *queryClient) AvailableGlobalVirtualGroupFamilies(ctx context.Context, in *AvailableGlobalVirtualGroupFamiliesRequest, opts ...grpc.CallOption) (*AvailableGlobalVirtualGroupFamiliesResponse, error) { + out := new(AvailableGlobalVirtualGroupFamiliesResponse) + err := c.cc.Invoke(ctx, "/greenfield.virtualgroup.Query/AvailableGlobalVirtualGroupFamilies", in, out, opts...) if err != nil { return nil, err } @@ -659,10 +757,12 @@ type QueryServer interface { GlobalVirtualGroup(context.Context, *QueryGlobalVirtualGroupRequest) (*QueryGlobalVirtualGroupResponse, error) // Queries a list of global virtual groups by family id. GlobalVirtualGroupByFamilyID(context.Context, *QueryGlobalVirtualGroupByFamilyIDRequest) (*QueryGlobalVirtualGroupByFamilyIDResponse, error) - // Queries a list of global virtual group families by storage provider id. - GlobalVirtualGroupFamilies(context.Context, *QueryGlobalVirtualGroupFamiliesRequest) (*QueryGlobalVirtualGroupFamiliesResponse, error) // Queries a global virtual group family by its id. GlobalVirtualGroupFamily(context.Context, *QueryGlobalVirtualGroupFamilyRequest) (*QueryGlobalVirtualGroupFamilyResponse, error) + // Queries a list of GlobalVirtualGroupFamilies items. + GlobalVirtualGroupFamilies(context.Context, *QueryGlobalVirtualGroupFamiliesRequest) (*QueryGlobalVirtualGroupFamiliesResponse, error) + // AvailableGlobalVirtualGroupFamilies filters a list of GlobalVirtualGroupFamilies ID which are qualified to create bucket on + AvailableGlobalVirtualGroupFamilies(context.Context, *AvailableGlobalVirtualGroupFamiliesRequest) (*AvailableGlobalVirtualGroupFamiliesResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -678,11 +778,14 @@ func (*UnimplementedQueryServer) GlobalVirtualGroup(ctx context.Context, req *Qu func (*UnimplementedQueryServer) GlobalVirtualGroupByFamilyID(ctx context.Context, req *QueryGlobalVirtualGroupByFamilyIDRequest) (*QueryGlobalVirtualGroupByFamilyIDResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GlobalVirtualGroupByFamilyID not implemented") } +func (*UnimplementedQueryServer) GlobalVirtualGroupFamily(ctx context.Context, req *QueryGlobalVirtualGroupFamilyRequest) (*QueryGlobalVirtualGroupFamilyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GlobalVirtualGroupFamily not implemented") +} func (*UnimplementedQueryServer) GlobalVirtualGroupFamilies(ctx context.Context, req *QueryGlobalVirtualGroupFamiliesRequest) (*QueryGlobalVirtualGroupFamiliesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GlobalVirtualGroupFamilies not implemented") } -func (*UnimplementedQueryServer) GlobalVirtualGroupFamily(ctx context.Context, req *QueryGlobalVirtualGroupFamilyRequest) (*QueryGlobalVirtualGroupFamilyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GlobalVirtualGroupFamily not implemented") +func (*UnimplementedQueryServer) AvailableGlobalVirtualGroupFamilies(ctx context.Context, req *AvailableGlobalVirtualGroupFamiliesRequest) (*AvailableGlobalVirtualGroupFamiliesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AvailableGlobalVirtualGroupFamilies not implemented") } func RegisterQueryServer(s grpc1.Server, srv QueryServer) { @@ -743,6 +846,24 @@ func _Query_GlobalVirtualGroupByFamilyID_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _Query_GlobalVirtualGroupFamily_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGlobalVirtualGroupFamilyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GlobalVirtualGroupFamily(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/greenfield.virtualgroup.Query/GlobalVirtualGroupFamily", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GlobalVirtualGroupFamily(ctx, req.(*QueryGlobalVirtualGroupFamilyRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_GlobalVirtualGroupFamilies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryGlobalVirtualGroupFamiliesRequest) if err := dec(in); err != nil { @@ -761,20 +882,20 @@ func _Query_GlobalVirtualGroupFamilies_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } -func _Query_GlobalVirtualGroupFamily_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryGlobalVirtualGroupFamilyRequest) +func _Query_AvailableGlobalVirtualGroupFamilies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AvailableGlobalVirtualGroupFamiliesRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).GlobalVirtualGroupFamily(ctx, in) + return srv.(QueryServer).AvailableGlobalVirtualGroupFamilies(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/greenfield.virtualgroup.Query/GlobalVirtualGroupFamily", + FullMethod: "/greenfield.virtualgroup.Query/AvailableGlobalVirtualGroupFamilies", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).GlobalVirtualGroupFamily(ctx, req.(*QueryGlobalVirtualGroupFamilyRequest)) + return srv.(QueryServer).AvailableGlobalVirtualGroupFamilies(ctx, req.(*AvailableGlobalVirtualGroupFamiliesRequest)) } return interceptor(ctx, in, info, handler) } @@ -795,13 +916,17 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "GlobalVirtualGroupByFamilyID", Handler: _Query_GlobalVirtualGroupByFamilyID_Handler, }, + { + MethodName: "GlobalVirtualGroupFamily", + Handler: _Query_GlobalVirtualGroupFamily_Handler, + }, { MethodName: "GlobalVirtualGroupFamilies", Handler: _Query_GlobalVirtualGroupFamilies_Handler, }, { - MethodName: "GlobalVirtualGroupFamily", - Handler: _Query_GlobalVirtualGroupFamily_Handler, + MethodName: "AvailableGlobalVirtualGroupFamilies", + Handler: _Query_AvailableGlobalVirtualGroupFamilies_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -997,6 +1122,69 @@ func (m *QueryGlobalVirtualGroupByFamilyIDResponse) MarshalToSizedBuffer(dAtA [] return len(dAtA) - i, nil } +func (m *QueryGlobalVirtualGroupFamilyRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGlobalVirtualGroupFamilyRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGlobalVirtualGroupFamilyRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.FamilyId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.FamilyId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryGlobalVirtualGroupFamilyResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGlobalVirtualGroupFamilyResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGlobalVirtualGroupFamilyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.GlobalVirtualGroupFamily != nil { + { + size, err := m.GlobalVirtualGroupFamily.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *QueryGlobalVirtualGroupFamiliesRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1027,12 +1215,7 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) MarshalToSizedBuffer(dAtA []byt i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 - } - if m.StorageProviderId != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.StorageProviderId)) - i-- - dAtA[i] = 0x8 + dAtA[i] = 0xa } return len(dAtA) - i, nil } @@ -1069,10 +1252,10 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) MarshalToSizedBuffer(dAtA []by i-- dAtA[i] = 0x12 } - if len(m.GlobalVirtualGroupFamilies) > 0 { - for iNdEx := len(m.GlobalVirtualGroupFamilies) - 1; iNdEx >= 0; iNdEx-- { + if len(m.GvgFamilies) > 0 { + for iNdEx := len(m.GvgFamilies) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.GlobalVirtualGroupFamilies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.GvgFamilies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1086,7 +1269,7 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) MarshalToSizedBuffer(dAtA []by return len(dAtA) - i, nil } -func (m *QueryGlobalVirtualGroupFamilyRequest) Marshal() (dAtA []byte, err error) { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1096,30 +1279,38 @@ func (m *QueryGlobalVirtualGroupFamilyRequest) Marshal() (dAtA []byte, err error return dAtA[:n], nil } -func (m *QueryGlobalVirtualGroupFamilyRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGlobalVirtualGroupFamilyRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.FamilyId != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.FamilyId)) - i-- - dAtA[i] = 0x10 - } - if m.StorageProviderId != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.StorageProviderId)) + if len(m.GlobalVirtualGroupFamilyIds) > 0 { + dAtA7 := make([]byte, len(m.GlobalVirtualGroupFamilyIds)*10) + var j6 int + for _, num := range m.GlobalVirtualGroupFamilyIds { + for num >= 1<<7 { + dAtA7[j6] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j6++ + } + dAtA7[j6] = uint8(num) + j6++ + } + i -= j6 + copy(dAtA[i:], dAtA7[:j6]) + i = encodeVarintQuery(dAtA, i, uint64(j6)) i-- - dAtA[i] = 0x8 + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *QueryGlobalVirtualGroupFamilyResponse) Marshal() (dAtA []byte, err error) { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1129,25 +1320,31 @@ func (m *QueryGlobalVirtualGroupFamilyResponse) Marshal() (dAtA []byte, err erro return dAtA[:n], nil } -func (m *QueryGlobalVirtualGroupFamilyResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGlobalVirtualGroupFamilyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.GlobalVirtualGroupFamily != nil { - { - size, err := m.GlobalVirtualGroupFamily.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) + if len(m.GlobalVirtualGroupFamilyIds) > 0 { + dAtA9 := make([]byte, len(m.GlobalVirtualGroupFamilyIds)*10) + var j8 int + for _, num := range m.GlobalVirtualGroupFamilyIds { + for num >= 1<<7 { + dAtA9[j8] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j8++ + } + dAtA9[j8] = uint8(num) + j8++ } + i -= j8 + copy(dAtA[i:], dAtA9[:j8]) + i = encodeVarintQuery(dAtA, i, uint64(j8)) i-- dAtA[i] = 0xa } @@ -1210,32 +1407,57 @@ func (m *QueryGlobalVirtualGroupResponse) Size() (n int) { return n } -func (m *QueryGlobalVirtualGroupByFamilyIDRequest) Size() (n int) { +func (m *QueryGlobalVirtualGroupByFamilyIDRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StorageProviderId != 0 { + n += 1 + sovQuery(uint64(m.StorageProviderId)) + } + if m.GlobalVirtualGroupFamilyId != 0 { + n += 1 + sovQuery(uint64(m.GlobalVirtualGroupFamilyId)) + } + return n +} + +func (m *QueryGlobalVirtualGroupByFamilyIDResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.GlobalVirtualGroups) > 0 { + for _, e := range m.GlobalVirtualGroups { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryGlobalVirtualGroupFamilyRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.StorageProviderId != 0 { - n += 1 + sovQuery(uint64(m.StorageProviderId)) - } - if m.GlobalVirtualGroupFamilyId != 0 { - n += 1 + sovQuery(uint64(m.GlobalVirtualGroupFamilyId)) + if m.FamilyId != 0 { + n += 1 + sovQuery(uint64(m.FamilyId)) } return n } -func (m *QueryGlobalVirtualGroupByFamilyIDResponse) Size() (n int) { +func (m *QueryGlobalVirtualGroupFamilyResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.GlobalVirtualGroups) > 0 { - for _, e := range m.GlobalVirtualGroups { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } + if m.GlobalVirtualGroupFamily != nil { + l = m.GlobalVirtualGroupFamily.Size() + n += 1 + l + sovQuery(uint64(l)) } return n } @@ -1246,9 +1468,6 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) Size() (n int) { } var l int _ = l - if m.StorageProviderId != 0 { - n += 1 + sovQuery(uint64(m.StorageProviderId)) - } if m.Pagination != nil { l = m.Pagination.Size() n += 1 + l + sovQuery(uint64(l)) @@ -1262,8 +1481,8 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Size() (n int) { } var l int _ = l - if len(m.GlobalVirtualGroupFamilies) > 0 { - for _, e := range m.GlobalVirtualGroupFamilies { + if len(m.GvgFamilies) > 0 { + for _, e := range m.GvgFamilies { l = e.Size() n += 1 + l + sovQuery(uint64(l)) } @@ -1275,30 +1494,34 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Size() (n int) { return n } -func (m *QueryGlobalVirtualGroupFamilyRequest) Size() (n int) { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.StorageProviderId != 0 { - n += 1 + sovQuery(uint64(m.StorageProviderId)) - } - if m.FamilyId != 0 { - n += 1 + sovQuery(uint64(m.FamilyId)) + if len(m.GlobalVirtualGroupFamilyIds) > 0 { + l = 0 + for _, e := range m.GlobalVirtualGroupFamilyIds { + l += sovQuery(uint64(e)) + } + n += 1 + sovQuery(uint64(l)) + l } return n } -func (m *QueryGlobalVirtualGroupFamilyResponse) Size() (n int) { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.GlobalVirtualGroupFamily != nil { - l = m.GlobalVirtualGroupFamily.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.GlobalVirtualGroupFamilyIds) > 0 { + l = 0 + for _, e := range m.GlobalVirtualGroupFamilyIds { + l += sovQuery(uint64(e)) + } + n += 1 + sovQuery(uint64(l)) + l } return n } @@ -1769,7 +1992,7 @@ func (m *QueryGlobalVirtualGroupByFamilyIDResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *QueryGlobalVirtualGroupFamiliesRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGlobalVirtualGroupFamilyRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1792,17 +2015,17 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamiliesRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamiliesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StorageProviderId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field FamilyId", wireType) } - m.StorageProviderId = 0 + m.FamilyId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -1812,12 +2035,148 @@ func (m *QueryGlobalVirtualGroupFamiliesRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.StorageProviderId |= uint32(b&0x7F) << shift + m.FamilyId |= uint32(b&0x7F) << shift if b < 0x80 { break } } - case 2: + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGlobalVirtualGroupFamilyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamily", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GlobalVirtualGroupFamily == nil { + m.GlobalVirtualGroupFamily = &GlobalVirtualGroupFamily{} + } + if err := m.GlobalVirtualGroupFamily.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGlobalVirtualGroupFamiliesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamiliesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGlobalVirtualGroupFamiliesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) } @@ -1905,7 +2264,7 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilies", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GvgFamilies", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1932,8 +2291,8 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GlobalVirtualGroupFamilies = append(m.GlobalVirtualGroupFamilies, &GlobalVirtualGroupFamily{}) - if err := m.GlobalVirtualGroupFamilies[len(m.GlobalVirtualGroupFamilies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.GvgFamilies = append(m.GvgFamilies, &GlobalVirtualGroupFamily{}) + if err := m.GvgFamilies[len(m.GvgFamilies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1994,7 +2353,7 @@ func (m *QueryGlobalVirtualGroupFamiliesResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGlobalVirtualGroupFamilyRequest) Unmarshal(dAtA []byte) error { +func (m *AvailableGlobalVirtualGroupFamiliesRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2017,49 +2376,87 @@ func (m *QueryGlobalVirtualGroupFamilyRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AvailableGlobalVirtualGroupFamiliesRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AvailableGlobalVirtualGroupFamiliesRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StorageProviderId", wireType) - } - m.StorageProviderId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery + if wireType == 0 { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { - return io.ErrUnexpectedEOF + m.GlobalVirtualGroupFamilyIds = append(m.GlobalVirtualGroupFamilyIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } } - b := dAtA[iNdEx] - iNdEx++ - m.StorageProviderId |= uint32(b&0x7F) << shift - if b < 0x80 { - break + if packedLen < 0 { + return ErrInvalidLengthQuery } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FamilyId", wireType) - } - m.FamilyId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthQuery } - if iNdEx >= l { + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - m.FamilyId |= uint32(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } } + elementCount = count + if elementCount != 0 && len(m.GlobalVirtualGroupFamilyIds) == 0 { + m.GlobalVirtualGroupFamilyIds = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupFamilyIds = append(m.GlobalVirtualGroupFamilyIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilyIds", wireType) } default: iNdEx = preIndex @@ -2082,7 +2479,7 @@ func (m *QueryGlobalVirtualGroupFamilyRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGlobalVirtualGroupFamilyResponse) Unmarshal(dAtA []byte) error { +func (m *AvailableGlobalVirtualGroupFamiliesResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2105,48 +2502,88 @@ func (m *QueryGlobalVirtualGroupFamilyResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AvailableGlobalVirtualGroupFamiliesResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGlobalVirtualGroupFamilyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AvailableGlobalVirtualGroupFamiliesResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamily", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery + if wireType == 0 { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.GlobalVirtualGroupFamilyIds = append(m.GlobalVirtualGroupFamilyIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } } + elementCount = count + if elementCount != 0 && len(m.GlobalVirtualGroupFamilyIds) == 0 { + m.GlobalVirtualGroupFamilyIds = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GlobalVirtualGroupFamilyIds = append(m.GlobalVirtualGroupFamilyIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupFamilyIds", wireType) } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.GlobalVirtualGroupFamily == nil { - m.GlobalVirtualGroupFamily = &GlobalVirtualGroupFamily{} - } - if err := m.GlobalVirtualGroupFamily.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/virtualgroup/types/query.pb.gw.go b/x/virtualgroup/types/query.pb.gw.go index fd72384b0..6cad96d24 100644 --- a/x/virtualgroup/types/query.pb.gw.go +++ b/x/virtualgroup/types/query.pb.gw.go @@ -123,6 +123,42 @@ func local_request_Query_GlobalVirtualGroupByFamilyID_0(ctx context.Context, mar } +var ( + filter_Query_GlobalVirtualGroupFamily_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_GlobalVirtualGroupFamily_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGlobalVirtualGroupFamilyRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GlobalVirtualGroupFamily_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GlobalVirtualGroupFamily(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GlobalVirtualGroupFamily_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGlobalVirtualGroupFamilyRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GlobalVirtualGroupFamily_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GlobalVirtualGroupFamily(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_GlobalVirtualGroupFamilies_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -160,37 +196,37 @@ func local_request_Query_GlobalVirtualGroupFamilies_0(ctx context.Context, marsh } var ( - filter_Query_GlobalVirtualGroupFamily_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + filter_Query_AvailableGlobalVirtualGroupFamilies_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) -func request_Query_GlobalVirtualGroupFamily_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGlobalVirtualGroupFamilyRequest +func request_Query_AvailableGlobalVirtualGroupFamilies_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AvailableGlobalVirtualGroupFamiliesRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GlobalVirtualGroupFamily_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AvailableGlobalVirtualGroupFamilies_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.GlobalVirtualGroupFamily(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.AvailableGlobalVirtualGroupFamilies(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_GlobalVirtualGroupFamily_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGlobalVirtualGroupFamilyRequest +func local_request_Query_AvailableGlobalVirtualGroupFamilies_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AvailableGlobalVirtualGroupFamiliesRequest var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GlobalVirtualGroupFamily_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AvailableGlobalVirtualGroupFamilies_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.GlobalVirtualGroupFamily(ctx, &protoReq) + msg, err := server.AvailableGlobalVirtualGroupFamilies(ctx, &protoReq) return msg, metadata, err } @@ -270,6 +306,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamily_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GlobalVirtualGroupFamily_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GlobalVirtualGroupFamily_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamilies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -293,7 +352,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamily_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_AvailableGlobalVirtualGroupFamilies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -304,7 +363,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_GlobalVirtualGroupFamily_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_AvailableGlobalVirtualGroupFamilies_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -312,7 +371,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_GlobalVirtualGroupFamily_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_AvailableGlobalVirtualGroupFamilies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -417,6 +476,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamily_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GlobalVirtualGroupFamily_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GlobalVirtualGroupFamily_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamilies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -437,7 +516,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_GlobalVirtualGroupFamily_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_AvailableGlobalVirtualGroupFamilies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -446,14 +525,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_GlobalVirtualGroupFamily_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_AvailableGlobalVirtualGroupFamilies_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_GlobalVirtualGroupFamily_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_AvailableGlobalVirtualGroupFamilies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -467,9 +546,11 @@ var ( pattern_Query_GlobalVirtualGroupByFamilyID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "virtualgroup", "global_virtual_group_by_family_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GlobalVirtualGroupFamily_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "virtualgroup", "global_virtual_group_family"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GlobalVirtualGroupFamilies_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "virtualgroup", "global_virtual_group_families"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_GlobalVirtualGroupFamily_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "virtualgroup", "global_virtual_group_family"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_AvailableGlobalVirtualGroupFamilies_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"greenfield", "virtualgroup", "available_global_virtual_group_families"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -479,7 +560,9 @@ var ( forward_Query_GlobalVirtualGroupByFamilyID_0 = runtime.ForwardResponseMessage + forward_Query_GlobalVirtualGroupFamily_0 = runtime.ForwardResponseMessage + forward_Query_GlobalVirtualGroupFamilies_0 = runtime.ForwardResponseMessage - forward_Query_GlobalVirtualGroupFamily_0 = runtime.ForwardResponseMessage + forward_Query_AvailableGlobalVirtualGroupFamilies_0 = runtime.ForwardResponseMessage ) diff --git a/x/virtualgroup/types/types.pb.go b/x/virtualgroup/types/types.pb.go index 9cb8f886c..bb3ff54f1 100644 --- a/x/virtualgroup/types/types.pb.go +++ b/x/virtualgroup/types/types.pb.go @@ -125,10 +125,12 @@ func (m *GlobalVirtualGroup) GetVirtualPaymentAddress() string { type GlobalVirtualGroupFamily struct { // id is the identifier of the global virtual group family. Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // primary_sp_id + PrimarySpId uint32 `protobuf:"varint,2,opt,name=primary_sp_id,json=primarySpId,proto3" json:"primary_sp_id,omitempty"` // global_virtual_group_ids is a list of identifiers of the global virtual groups associated with the family. - GlobalVirtualGroupIds []uint32 `protobuf:"varint,2,rep,packed,name=global_virtual_group_ids,json=globalVirtualGroupIds,proto3" json:"global_virtual_group_ids,omitempty"` + GlobalVirtualGroupIds []uint32 `protobuf:"varint,3,rep,packed,name=global_virtual_group_ids,json=globalVirtualGroupIds,proto3" json:"global_virtual_group_ids,omitempty"` // virtual_payment_address is the payment address associated with the global virtual group family. - VirtualPaymentAddress string `protobuf:"bytes,3,opt,name=virtual_payment_address,json=virtualPaymentAddress,proto3" json:"virtual_payment_address,omitempty"` + VirtualPaymentAddress string `protobuf:"bytes,4,opt,name=virtual_payment_address,json=virtualPaymentAddress,proto3" json:"virtual_payment_address,omitempty"` } func (m *GlobalVirtualGroupFamily) Reset() { *m = GlobalVirtualGroupFamily{} } @@ -171,6 +173,13 @@ func (m *GlobalVirtualGroupFamily) GetId() uint32 { return 0 } +func (m *GlobalVirtualGroupFamily) GetPrimarySpId() uint32 { + if m != nil { + return m.PrimarySpId + } + return 0 +} + func (m *GlobalVirtualGroupFamily) GetGlobalVirtualGroupIds() []uint32 { if m != nil { return m.GlobalVirtualGroupIds @@ -244,6 +253,8 @@ func (m *GlobalVirtualGroupsBindingOnBucket) GetLocalVirtualGroupIds() []uint32 type GVGStatisticsWithinSP struct { // storage_provider_id defines the id of the sp which the statistics associated to StorageProviderId uint32 `protobuf:"varint,1,opt,name=storage_provider_id,json=storageProviderId,proto3" json:"storage_provider_id,omitempty"` + // primary_sp_family_count defines the number of the family which this sp serves as primary sp + PrimaryCount uint32 `protobuf:"varint,2,opt,name=primary_count,json=primaryCount,proto3" json:"primary_count,omitempty"` // secondary_count defines the number of global virtual groups (GVGs) in // which this storage provider serves as a secondary storage provider. SecondaryCount uint32 `protobuf:"varint,3,opt,name=secondary_count,json=secondaryCount,proto3" json:"secondary_count,omitempty"` @@ -289,6 +300,13 @@ func (m *GVGStatisticsWithinSP) GetStorageProviderId() uint32 { return 0 } +func (m *GVGStatisticsWithinSP) GetPrimaryCount() uint32 { + if m != nil { + return m.PrimaryCount + } + return 0 +} + func (m *GVGStatisticsWithinSP) GetSecondaryCount() uint32 { if m != nil { return m.SecondaryCount @@ -363,45 +381,47 @@ func init() { } var fileDescriptor_1fe6fc664532d0c3 = []byte{ - // 608 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x41, 0x6f, 0xd3, 0x3c, - 0x18, 0x6e, 0xda, 0x6e, 0xdf, 0xea, 0x7e, 0xdd, 0xc0, 0xdb, 0xb4, 0xb0, 0x49, 0x59, 0x15, 0xa4, - 0xd1, 0x4b, 0xdb, 0x03, 0x20, 0x38, 0x70, 0xa1, 0x20, 0xaa, 0x70, 0x60, 0x55, 0x22, 0x86, 0xc4, - 0x25, 0x72, 0x62, 0x2f, 0xb3, 0x96, 0xda, 0x51, 0xec, 0x0c, 0xba, 0x5f, 0xc1, 0x8f, 0x19, 0xff, - 0x61, 0x27, 0x34, 0xed, 0x84, 0x38, 0x4c, 0x68, 0x13, 0xff, 0x03, 0xc5, 0x36, 0x6d, 0x45, 0x27, - 0x0e, 0x70, 0x8a, 0xfd, 0xbc, 0xcf, 0xfb, 0x38, 0xef, 0xe3, 0xf7, 0x35, 0xb8, 0x9f, 0xe4, 0x84, - 0xb0, 0x43, 0x4a, 0x52, 0xdc, 0x3f, 0xa1, 0xb9, 0x2c, 0x50, 0x9a, 0xe4, 0xbc, 0xc8, 0xfa, 0x72, - 0x92, 0x11, 0xd1, 0xcb, 0x72, 0x2e, 0x39, 0xdc, 0x9a, 0x91, 0x7a, 0xf3, 0xa4, 0xed, 0x7b, 0x31, - 0x17, 0x63, 0x2e, 0x42, 0x45, 0xeb, 0xeb, 0x8d, 0xce, 0xd9, 0xde, 0x48, 0x78, 0xc2, 0x35, 0x5e, - 0xae, 0x34, 0xea, 0xfe, 0xa8, 0x02, 0x38, 0x4c, 0x79, 0x84, 0xd2, 0x03, 0xad, 0x33, 0x2c, 0x75, - 0xe0, 0x2a, 0xa8, 0x52, 0x6c, 0x5b, 0x6d, 0xab, 0xd3, 0xf2, 0xab, 0x14, 0xc3, 0x1d, 0xd0, 0x38, - 0x44, 0x63, 0x9a, 0x4e, 0x42, 0x8a, 0xed, 0xaa, 0x82, 0x57, 0x34, 0xe0, 0x61, 0xe8, 0x82, 0x56, - 0x96, 0xd3, 0x31, 0xca, 0x27, 0xa1, 0xc8, 0x4a, 0x42, 0x4d, 0x11, 0x9a, 0x06, 0x0c, 0x32, 0x0f, - 0xc3, 0x0e, 0xb8, 0x23, 0x48, 0xcc, 0x19, 0x9e, 0xb2, 0x84, 0x5d, 0x6f, 0xd7, 0x3a, 0x2d, 0x7f, - 0x75, 0x8a, 0x97, 0x44, 0x01, 0x77, 0x41, 0x53, 0x48, 0x9e, 0x13, 0x1c, 0x0a, 0x7a, 0x4a, 0xec, - 0xa5, 0xb6, 0xd5, 0xa9, 0xfb, 0x40, 0x43, 0x01, 0x3d, 0x25, 0x70, 0x04, 0xb6, 0x4c, 0xcd, 0x61, - 0x86, 0x26, 0x63, 0xc2, 0x64, 0x88, 0x30, 0xce, 0x89, 0x10, 0xf6, 0x72, 0xdb, 0xea, 0x34, 0x06, - 0xf6, 0xe5, 0x59, 0x77, 0xc3, 0xd4, 0xfe, 0x5c, 0x47, 0x02, 0x99, 0x53, 0x96, 0xf8, 0x9b, 0x26, - 0x71, 0xa4, 0xf3, 0x4c, 0x10, 0x22, 0xd0, 0x92, 0x5c, 0xa2, 0x34, 0xc4, 0x24, 0xe3, 0x82, 0x4a, - 0xfb, 0x3f, 0xa5, 0xf3, 0xec, 0xfc, 0x6a, 0xb7, 0xf2, 0xed, 0x6a, 0x77, 0x2f, 0xa1, 0xf2, 0xa8, - 0x88, 0x7a, 0x31, 0x1f, 0x1b, 0x4b, 0xcd, 0xa7, 0x2b, 0xf0, 0xb1, 0xb9, 0x17, 0x8f, 0xc9, 0xcb, - 0xb3, 0x2e, 0x30, 0xa7, 0x7a, 0x4c, 0xfa, 0xff, 0x2b, 0xc9, 0x97, 0x5a, 0xd1, 0xfd, 0x6c, 0x01, - 0x7b, 0xd1, 0xe7, 0x57, 0xca, 0xc2, 0x05, 0xb7, 0x9f, 0x00, 0x3b, 0x51, 0xdc, 0xf0, 0x57, 0xa1, - 0xea, 0x76, 0x95, 0x69, 0x55, 0x65, 0xda, 0x66, 0xb2, 0xa0, 0x55, 0x7a, 0xf7, 0x07, 0x6b, 0x6a, - 0x7f, 0x65, 0x8d, 0xfb, 0xc5, 0x02, 0xee, 0xe2, 0x7f, 0x8b, 0x01, 0x65, 0x98, 0xb2, 0x64, 0x9f, - 0x0d, 0x8a, 0xf8, 0x98, 0x48, 0xf8, 0x14, 0x34, 0x22, 0xb5, 0x0a, 0x4d, 0x21, 0x8d, 0xc1, 0x8e, - 0x71, 0xaf, 0xfe, 0x96, 0x2a, 0x6f, 0x9a, 0xe6, 0xd8, 0x72, 0xeb, 0xaf, 0x68, 0xb6, 0xf7, 0x0f, - 0xb5, 0x3e, 0x06, 0x5b, 0x29, 0x8f, 0x6f, 0xcd, 0xab, 0xa9, 0xbc, 0x0d, 0x15, 0xfe, 0x2d, 0xcd, - 0xcd, 0xc0, 0xe6, 0xf0, 0x60, 0x18, 0x48, 0x24, 0xa9, 0x90, 0x34, 0x16, 0xef, 0xa8, 0x3c, 0xa2, - 0x2c, 0x18, 0xc1, 0x1e, 0x58, 0x2f, 0x9b, 0x0c, 0x25, 0xa4, 0x9c, 0x9e, 0x13, 0x8a, 0x49, 0x1e, - 0x4e, 0x6f, 0xe5, 0xae, 0x09, 0x8d, 0x4c, 0xc4, 0xc3, 0xf0, 0x01, 0x58, 0x9b, 0x75, 0x74, 0xcc, - 0x0b, 0x26, 0x4d, 0xdf, 0xcf, 0x1a, 0xfa, 0x45, 0x89, 0xba, 0xaf, 0x41, 0x33, 0xf8, 0x80, 0xb2, - 0xfd, 0x42, 0x7a, 0xec, 0x90, 0xc3, 0x75, 0xb0, 0xa4, 0xa7, 0x44, 0x2b, 0xd7, 0x45, 0x39, 0x1e, - 0x7b, 0x60, 0x4d, 0x14, 0x71, 0x4c, 0x84, 0xe0, 0xb9, 0x19, 0x22, 0x3d, 0x65, 0xad, 0x29, 0x5c, - 0x4e, 0xc7, 0xe0, 0xcd, 0xf9, 0xb5, 0x63, 0x5d, 0x5c, 0x3b, 0xd6, 0xf7, 0x6b, 0xc7, 0xfa, 0x74, - 0xe3, 0x54, 0x2e, 0x6e, 0x9c, 0xca, 0xd7, 0x1b, 0xa7, 0xf2, 0xfe, 0xd1, 0x5c, 0x93, 0x46, 0x2c, - 0xea, 0xc6, 0x47, 0x88, 0xb2, 0xfe, 0xdc, 0x63, 0xf2, 0xf1, 0x96, 0xe7, 0x24, 0x5a, 0x56, 0xaf, - 0xc0, 0xc3, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x5c, 0xa3, 0x7d, 0x76, 0x04, 0x00, 0x00, + // 627 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x41, 0x6f, 0xd3, 0x3c, + 0x18, 0xc7, 0x9b, 0xae, 0xdb, 0xbb, 0xba, 0xeb, 0xf6, 0xe2, 0x6d, 0x5a, 0xd8, 0xa4, 0xae, 0xca, + 0xa4, 0xd1, 0x4b, 0xdb, 0x03, 0x20, 0x38, 0x70, 0xa1, 0x20, 0xaa, 0x70, 0x60, 0x55, 0x22, 0x86, + 0xc4, 0x25, 0x72, 0x62, 0x2f, 0xb3, 0x96, 0xda, 0x51, 0xec, 0x0c, 0xba, 0x4f, 0xc1, 0x85, 0x6f, + 0xb2, 0x0f, 0xb1, 0x13, 0x9a, 0x76, 0x02, 0x0e, 0x13, 0xda, 0xc4, 0xf7, 0x40, 0xb1, 0x4d, 0x3b, + 0x08, 0x1a, 0x12, 0xa7, 0xc4, 0xff, 0xe7, 0xef, 0xc7, 0x7a, 0x7e, 0x7e, 0x1e, 0x83, 0x9d, 0x38, + 0x23, 0x84, 0x1d, 0x50, 0x92, 0xe0, 0xfe, 0x31, 0xcd, 0x64, 0x8e, 0x92, 0x38, 0xe3, 0x79, 0xda, + 0x97, 0x93, 0x94, 0x88, 0x5e, 0x9a, 0x71, 0xc9, 0xe1, 0xc6, 0xcc, 0xd4, 0xbb, 0x69, 0xda, 0xbc, + 0x1b, 0x71, 0x31, 0xe6, 0x22, 0x50, 0xb6, 0xbe, 0x5e, 0xe8, 0x3d, 0x9b, 0x6b, 0x31, 0x8f, 0xb9, + 0xd6, 0x8b, 0x3f, 0xad, 0x3a, 0xdf, 0xab, 0x00, 0x0e, 0x13, 0x1e, 0xa2, 0x64, 0x5f, 0xe7, 0x19, + 0x16, 0x79, 0xe0, 0x32, 0xa8, 0x52, 0x6c, 0x5b, 0x6d, 0xab, 0xd3, 0xf4, 0xaa, 0x14, 0xc3, 0x2d, + 0x50, 0x3f, 0x40, 0x63, 0x9a, 0x4c, 0x02, 0x8a, 0xed, 0xaa, 0x92, 0x17, 0xb5, 0xe0, 0x62, 0xe8, + 0x80, 0x66, 0x9a, 0xd1, 0x31, 0xca, 0x26, 0x81, 0x48, 0x0b, 0xc3, 0x9c, 0x32, 0x34, 0x8c, 0xe8, + 0xa7, 0x2e, 0x86, 0x1d, 0xf0, 0xbf, 0x20, 0x11, 0x67, 0x78, 0xea, 0x12, 0x76, 0xad, 0x3d, 0xd7, + 0x69, 0x7a, 0xcb, 0x53, 0xbd, 0x30, 0x0a, 0xb8, 0x0d, 0x1a, 0x42, 0xf2, 0x8c, 0xe0, 0x40, 0xd0, + 0x13, 0x62, 0xcf, 0xb7, 0xad, 0x4e, 0xcd, 0x03, 0x5a, 0xf2, 0xe9, 0x09, 0x81, 0x23, 0xb0, 0x61, + 0x6a, 0x0e, 0x52, 0x34, 0x19, 0x13, 0x26, 0x03, 0x84, 0x71, 0x46, 0x84, 0xb0, 0x17, 0xda, 0x56, + 0xa7, 0x3e, 0xb0, 0x2f, 0x4e, 0xbb, 0x6b, 0xa6, 0xf6, 0xa7, 0x3a, 0xe2, 0xcb, 0x8c, 0xb2, 0xd8, + 0x5b, 0x37, 0x1b, 0x47, 0x7a, 0x9f, 0x09, 0x42, 0x04, 0x9a, 0x92, 0x4b, 0x94, 0x04, 0x98, 0xa4, + 0x5c, 0x50, 0x69, 0xff, 0xa7, 0xf2, 0x3c, 0x39, 0xbb, 0xdc, 0xae, 0x7c, 0xbd, 0xdc, 0xde, 0x8d, + 0xa9, 0x3c, 0xcc, 0xc3, 0x5e, 0xc4, 0xc7, 0x06, 0xa9, 0xf9, 0x74, 0x05, 0x3e, 0x32, 0xf7, 0xe2, + 0x32, 0x79, 0x71, 0xda, 0x05, 0xe6, 0x54, 0x97, 0x49, 0x6f, 0x49, 0xa5, 0x7c, 0xae, 0x33, 0x3a, + 0x5f, 0x2c, 0x60, 0x97, 0x39, 0xbf, 0x50, 0x08, 0x4b, 0xb4, 0x4b, 0x40, 0xab, 0x65, 0xa0, 0x8f, + 0x80, 0x1d, 0xab, 0x7c, 0xc1, 0x4f, 0x18, 0xaa, 0x03, 0x14, 0xd8, 0x39, 0x05, 0x76, 0x3d, 0x2e, + 0x9d, 0x57, 0xf0, 0xbd, 0x05, 0x5f, 0xed, 0x9f, 0xf0, 0x39, 0x9f, 0x2c, 0xe0, 0x94, 0x6b, 0x13, + 0x03, 0xca, 0x30, 0x65, 0xf1, 0x1e, 0x1b, 0xe4, 0xd1, 0x11, 0x91, 0xf0, 0x31, 0xa8, 0x87, 0xea, + 0x2f, 0x30, 0xc5, 0xd6, 0x07, 0x5b, 0x86, 0x70, 0xed, 0x35, 0x55, 0xfc, 0x1a, 0xe6, 0xd8, 0x62, + 0xe9, 0x2d, 0x6a, 0xf7, 0x5f, 0x6a, 0xad, 0xde, 0x56, 0xeb, 0x43, 0xb0, 0x91, 0xf0, 0xe8, 0x16, + 0x46, 0x6b, 0x2a, 0xfc, 0xdb, 0x36, 0xe7, 0xa3, 0x05, 0xd6, 0x87, 0xfb, 0x43, 0x5f, 0x22, 0x49, + 0x85, 0xa4, 0x91, 0x78, 0x43, 0xe5, 0x21, 0x65, 0xfe, 0x08, 0xf6, 0xc0, 0x6a, 0xd1, 0x89, 0x28, + 0x26, 0xc5, 0x88, 0x1d, 0x53, 0x4c, 0xb2, 0x60, 0x7a, 0x75, 0x77, 0x4c, 0x68, 0x64, 0x22, 0x2e, + 0x86, 0x3b, 0xb3, 0x9b, 0x8c, 0x78, 0xce, 0xa4, 0xb9, 0xc9, 0x25, 0x23, 0x3e, 0x2b, 0x34, 0x78, + 0x0f, 0xac, 0xcc, 0x66, 0x43, 0xdb, 0xf4, 0x04, 0xcd, 0x46, 0x43, 0x19, 0x9d, 0x97, 0xa0, 0xe1, + 0xbf, 0x43, 0xe9, 0x5e, 0x2e, 0x5d, 0x76, 0xc0, 0xe1, 0x2a, 0x98, 0xd7, 0xed, 0xa1, 0x8f, 0xaf, + 0x89, 0xa2, 0x2f, 0x76, 0xc1, 0x8a, 0xc8, 0xa3, 0x88, 0x08, 0xc1, 0xb3, 0x5f, 0xba, 0xa7, 0x39, + 0x95, 0x8b, 0xfe, 0x19, 0xbc, 0x3a, 0xbb, 0x6a, 0x59, 0xe7, 0x57, 0x2d, 0xeb, 0xdb, 0x55, 0xcb, + 0xfa, 0x70, 0xdd, 0xaa, 0x9c, 0x5f, 0xb7, 0x2a, 0x9f, 0xaf, 0x5b, 0x95, 0xb7, 0x0f, 0x6e, 0xb4, + 0x7b, 0xc8, 0xc2, 0x6e, 0x74, 0x88, 0x28, 0xeb, 0xdf, 0x78, 0x96, 0xde, 0xff, 0xe1, 0x61, 0x0a, + 0x17, 0xd4, 0x7b, 0x72, 0xff, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x83, 0x77, 0xa9, 0xc0, + 0x04, 0x00, 0x00, } func (m *GlobalVirtualGroup) Marshal() (dAtA []byte, err error) { @@ -507,7 +527,7 @@ func (m *GlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error copy(dAtA[i:], m.VirtualPaymentAddress) i = encodeVarintTypes(dAtA, i, uint64(len(m.VirtualPaymentAddress))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } if len(m.GlobalVirtualGroupIds) > 0 { dAtA4 := make([]byte, len(m.GlobalVirtualGroupIds)*10) @@ -525,7 +545,12 @@ func (m *GlobalVirtualGroupFamily) MarshalToSizedBuffer(dAtA []byte) (int, error copy(dAtA[i:], dAtA4[:j3]) i = encodeVarintTypes(dAtA, i, uint64(j3)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a + } + if m.PrimarySpId != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.PrimarySpId)) + i-- + dAtA[i] = 0x10 } if m.Id != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.Id)) @@ -629,6 +654,11 @@ func (m *GVGStatisticsWithinSP) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } + if m.PrimaryCount != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.PrimaryCount)) + i-- + dAtA[i] = 0x10 + } if m.StorageProviderId != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.StorageProviderId)) i-- @@ -724,6 +754,9 @@ func (m *GlobalVirtualGroupFamily) Size() (n int) { if m.Id != 0 { n += 1 + sovTypes(uint64(m.Id)) } + if m.PrimarySpId != 0 { + n += 1 + sovTypes(uint64(m.PrimarySpId)) + } if len(m.GlobalVirtualGroupIds) > 0 { l = 0 for _, e := range m.GlobalVirtualGroupIds { @@ -772,6 +805,9 @@ func (m *GVGStatisticsWithinSP) Size() (n int) { if m.StorageProviderId != 0 { n += 1 + sovTypes(uint64(m.StorageProviderId)) } + if m.PrimaryCount != 0 { + n += 1 + sovTypes(uint64(m.PrimaryCount)) + } if m.SecondaryCount != 0 { n += 1 + sovTypes(uint64(m.SecondaryCount)) } @@ -1116,6 +1152,25 @@ func (m *GlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { } } case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimarySpId", wireType) + } + m.PrimarySpId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimarySpId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType == 0 { var v uint32 for shift := uint(0); ; shift += 7 { @@ -1191,7 +1246,7 @@ func (m *GlobalVirtualGroupFamily) Unmarshal(dAtA []byte) error { } else { return fmt.Errorf("proto: wrong wireType = %d for field GlobalVirtualGroupIds", wireType) } - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field VirtualPaymentAddress", wireType) } @@ -1528,6 +1583,25 @@ func (m *GVGStatisticsWithinSP) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrimaryCount", wireType) + } + m.PrimaryCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PrimaryCount |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SecondaryCount", wireType)