Skip to content

Commit

Permalink
sync: sync master to develop and fix conflict (#604)
Browse files Browse the repository at this point in the history
* delete after harkfork (#592)

* fix: add upgrade check when deleting rate limit status

* add event (#596)

* feat: add bucketId in BucketFlowRateLimitStatus event

* feat: remove set bucket flow rate limit message

* comment related test cases

* fix: fix uncharge issue when force-deleting objects

* add test case

* create object with new gvg

* introduce erdos upgrade

* update gas price

* remove unused code

* update deps for v1.6.0 upgrade

---------

Co-authored-by: zjubfd <[email protected]>
Co-authored-by: yutianwu <[email protected]>
  • Loading branch information
3 people committed Apr 8, 2024
1 parent 0702cf0 commit ce7744b
Show file tree
Hide file tree
Showing 15 changed files with 793 additions and 168 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## V1.6.0
This release introduces the Serengeti upgrade.

Features:
* [#580](https://github.com/bnb-chain/greenfield/pull/580) feat: remove create object & bucket approval
* [#581](https://github.com/bnb-chain/greenfield/pull/581) feat: allow SP to create/update object for delegator


## v1.5.0
This release introduces the Pawnee upgrade to Testnet and Mainnet

Expand Down
1 change: 0 additions & 1 deletion app/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ func (app *App) registerSerengetiUpgradeHandler() {
app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgDelegateCreateObject{}), 1.2e3))
app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgDelegateUpdateObjectContent{}), 1.2e3))
app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSealObjectV2{}), 1.2e2))
app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e3))
return app.mm.RunMigrations(ctx, app.configurator, fromVM)
})

Expand Down
1 change: 1 addition & 0 deletions deployment/localup/localup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ function generate_genesis() {
echo -e '[[upgrade]]\nname = "Ural"\nheight = 22\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[[upgrade]]\nname = "Pawnee"\nheight = 23\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[[upgrade]]\nname = "Serengeti"\nheight = 24\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[[upgrade]]\nname = "Erdos"\nheight = 25\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
done

# enable swagger API for validator0
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/permission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func (s *StorageTestSuite) TestCreateObjectByOthersExpiration() {
s.Require().Equal(queryPolicyForAccountResp.Policy.ResourceType, resource.RESOURCE_TYPE_BUCKET)
s.Require().Equal(queryPolicyForAccountResp.Policy.ResourceId, queryHeadBucketResponse.BucketInfo.Id)

time.Sleep(5 * time.Second)
time.Sleep(6 * time.Second)
// CreateObject
objectName := storageutil.GenRandomObjectName()
// create test buffer
Expand Down
231 changes: 230 additions & 1 deletion e2e/tests/storage_rate_limit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,85 @@ import (
"context"
"fmt"
"math"
"strconv"
"time"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
gashubtypes "github.com/cosmos/cosmos-sdk/x/gashub/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/prysmaticlabs/prysm/crypto/bls"

"github.com/bnb-chain/greenfield/e2e/core"
"github.com/bnb-chain/greenfield/sdk/keys"
types2 "github.com/bnb-chain/greenfield/sdk/types"
storageutils "github.com/bnb-chain/greenfield/testutil/storage"
storagetypes "github.com/bnb-chain/greenfield/x/storage/types"
virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types"
)

func (s *StorageTestSuite) enableMessage() {
msgSetBucketFlowRateLimit := sdk.MsgTypeURL(&storagetypes.MsgSetBucketFlowRateLimit{})
msgMigrateBuketGasParams := gashubtypes.NewMsgGasParamsWithFixedGas(msgSetBucketFlowRateLimit, 1.2e3)

msgUpdateGasParams := gashubtypes.NewMsgSetMsgGasParams(authtypes.NewModuleAddress(govtypes.ModuleName).String(), []*gashubtypes.MsgGasParams{msgMigrateBuketGasParams}, nil)

var err error
validator := s.Validator.GetAddr()

ctx := context.Background()

msgProposal, err := govtypesv1.NewMsgSubmitProposal(
[]sdk.Msg{msgUpdateGasParams},
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)
}

func (s *StorageTestSuite) TestSetBucketRateLimitToZero() {
var err error
sp := s.BaseSuite.PickStorageProvider()
Expand Down Expand Up @@ -93,6 +164,8 @@ func (s *StorageTestSuite) TestSetBucketRateLimitToZero() {
// 6. the payment account set the rate limit to a positive number
// 7. user create an object in the bucket and it should pass
func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() {
s.enableMessage()

var err error
sp := s.BaseSuite.PickStorageProvider()
gvg, found := sp.GetFirstGlobalVirtualGroup()
Expand Down Expand Up @@ -185,6 +258,7 @@ func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() {
// 6. the payment account set the rate limit to a positive number
// 7. user update the read quota to a positive number and it should pass
func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() {
s.enableMessage()
var err error
sp := s.BaseSuite.PickStorageProvider()
gvg, found := sp.GetFirstGlobalVirtualGroup()
Expand Down Expand Up @@ -404,3 +478,158 @@ func (s *StorageTestSuite) TestQueryBucketRateLimit() {
s.Require().Equal(queryBucketRateLimitResponse.IsSet, true)
s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000))
}

func (s *StorageTestSuite) TestSetBucketFlowRateLimit_Discontinue() {
sp, user, bucketName, _, _, _ := s.createObjectWithNewGvg(storagetypes.VISIBILITY_TYPE_PRIVATE)

// SetBucketRateLimit
msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(user.GetAddr(), user.GetAddr(), user.GetAddr(), bucketName, sdkmath.NewInt(0))
s.SendTxBlock(user, msgSetBucketRateLimit)

queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{
BucketName: bucketName,
}
queryHeadBucketResponse, err := s.Client.HeadBucket(context.Background(), &queryHeadBucketRequest)
s.Require().NoError(err)

s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true)

msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test")
txRes1 := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket)
deleteAt1 := filterDiscontinueBucketEventFromTx(txRes1).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, deleteAt1)

if blockTime >= deleteAt1 {
break
}
}
}

func (s *StorageTestSuite) createObjectWithNewGvg(v storagetypes.VisibilityType) (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) {
var err error
// CreateBucket
sp := s.BaseSuite.PickStorageProvider()

_, secondarySps := s.GetSecondarySP(sp)
gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(sp, 0, secondarySps, 1)
gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{
GlobalVirtualGroupId: gvgID,
})
s.Require().NoError(err)
gvg := gvgResp.GlobalVirtualGroup

user := s.GenAndChargeAccounts(1, 1000000)[0]
bucketName := storageutils.GenRandomBucketName()
msgCreateBucket := storagetypes.NewMsgCreateBucket(
user.GetAddr(), bucketName, v, 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)

// HeadBucket
ctx := context.Background()
queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{
BucketName: bucketName,
}
queryHeadBucketResponse, err := s.Client.HeadBucket(ctx, &queryHeadBucketRequest)
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.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)

// CreateObject
objectName := storageutils.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), v, 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(ctx, &queryHeadObjectRequest)
s.Require().NoError(err)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectName, objectName)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.PayloadSize, uint64(payloadSize))
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Visibility, v)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Owner, user.GetAddr().String())
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Checksums, expectChecksum)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.RedundancyType, storagetypes.REDUNDANCY_EC_TYPE)
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ContentType, contextType)

// SealObject
gvgId := gvg.Id
msgSealObject := storagetypes.NewMsgSealObject(sp.SealKey.GetAddr(), bucketName, objectName, gvgId, nil)

secondarySigs := make([][]byte, 0)
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 _, 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)

// ListBuckets
queryListBucketsRequest := storagetypes.QueryListBucketsRequest{}
queryListBucketResponse, err := s.Client.ListBuckets(ctx, &queryListBucketsRequest)
s.Require().NoError(err)
s.Require().Greater(len(queryListBucketResponse.BucketInfos), 0)

// ListObject
queryListObjectsRequest := storagetypes.QueryListObjectsRequest{
BucketName: bucketName,
}
queryListObjectsResponse, err := s.Client.ListObjects(ctx, &queryListObjectsRequest)
s.Require().NoError(err)
s.Require().Equal(len(queryListObjectsResponse.ObjectInfos), 1)
s.Require().Equal(queryListObjectsResponse.ObjectInfos[0].ObjectName, objectName)
return sp, user, bucketName, queryHeadBucketResponse.BucketInfo.Id, objectName, queryListObjectsResponse.ObjectInfos[0].Id
}
23 changes: 23 additions & 0 deletions e2e/tests/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,29 @@ func (s *StorageTestSuite) TestDiscontinueBucket_UserDeleted() {
s.Require().True(statusRes.SyncInfo.LatestBlockHeight > heightAfter)
}

func (s *StorageTestSuite) 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
}

// createObject with default VISIBILITY_TYPE_PRIVATE
func (s *StorageTestSuite) createObject() (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) {
return s.createObjectWithVisibility(storagetypes.VISIBILITY_TYPE_PRIVATE)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ replace (
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.0-20240402065323-40677309d454
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 v1.5.1-0.20240402084406-e0a150a3560b
github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.6.1-0.20240408055344-9b8b942c1b1a
github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/wercker/journalhook => github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ github.com/bnb-chain/greenfield-cometbft v0.0.0-20240402065323-40677309d454 h1:m
github.com/bnb-chain/greenfield-cometbft v0.0.0-20240402065323-40677309d454/go.mod h1:q9/nqW19iXvxyma5XgcZfxL/OkWI9s5e7yX9ecePz8A=
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 v1.5.1-0.20240402084406-e0a150a3560b h1:z396+z91HVC26OXxeuwtgBKM940dKMmiSxhJPOo4sDk=
github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240402084406-e0a150a3560b/go.mod h1:Vr1w2wnY2BZu8+61/tApisJounytBGxi8Jhp515oZB8=
github.com/bnb-chain/greenfield-cosmos-sdk v1.6.1-0.20240408055344-9b8b942c1b1a h1:/gZArTCLMgoS/QZGiaDWDOJ7Zal0V0+NbJt/VtH+E78=
github.com/bnb-chain/greenfield-cosmos-sdk v1.6.1-0.20240408055344-9b8b942c1b1a/go.mod h1:Vr1w2wnY2BZu8+61/tApisJounytBGxi8Jhp515oZB8=
github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210 h1:GHPbV2bC+gmuO6/sG0Tm8oGal3KKSRlyE+zPscDjlA8=
github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210/go.mod h1:vhsZxXE9tYJeYB5JR4hPhd6Pc/uPf7j1T8IJ7p9FdeM=
github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210 h1:FLVOn4+OVbsKi2+YJX5kmD27/4dRu4FW7xCXFhzDO5s=
Expand Down
19 changes: 19 additions & 0 deletions proto/greenfield/storage/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -654,4 +654,23 @@ message EventBucketFlowRateLimitStatus {
string bucket_name = 1;
// is_limited define the status of the bucket flow rate limit
bool is_limited = 2;
// bucket_id is the unique u256 for bucket. Not global, only unique in buckets.
string bucket_id = 3 [
(cosmos_proto.scalar) = "cosmos.Uint",
(gogoproto.customtype) = "Uint",
(gogoproto.nullable) = false
];
}

message EventToggleSPAsDelegatedAgent {
// bucket_name define the name of the bucket
string bucket_name = 1;
// bucket_id is the unique u256 for bucket. Not global, only unique in buckets.
string bucket_id = 2 [
(cosmos_proto.scalar) = "cosmos.Uint",
(gogoproto.customtype) = "Uint",
(gogoproto.nullable) = false
];
// sp_as_delegated_agent_disabled indicates that whether bucket owner disable SP as the upload agent.
bool sp_as_delegated_agent_disabled = 3;
}
Loading

0 comments on commit ce7744b

Please sign in to comment.