Skip to content

Commit

Permalink
Merge pull request #593 from bnb-chain/develop
Browse files Browse the repository at this point in the history
release: prepare for release v1.6.0
  • Loading branch information
unclezoro authored Mar 15, 2024
2 parents b2ef76b + e4cc584 commit ad2660a
Show file tree
Hide file tree
Showing 49 changed files with 14,381 additions and 5,449 deletions.
23 changes: 23 additions & 0 deletions app/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func (app *App) RegisterUpgradeHandlers(chainID string, serverCfg *serverconfig.
app.registerHulunbeierPatchUpgradeHandler()
app.registerUralUpgradeHandler()
app.registerPawneeUpgradeHandler()
app.registerSerengetiUpgradeHandler()
// app.register...()
// ...
return nil
Expand Down Expand Up @@ -215,3 +216,25 @@ func (app *App) registerPawneeUpgradeHandler() {
return nil
})
}

func (app *App) registerSerengetiUpgradeHandler() {
// Register the upgrade handler
app.UpgradeKeeper.SetUpgradeHandler(upgradetypes.Serengeti,
func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
app.Logger().Info("upgrade to ", plan.Name)
app.VirtualgroupKeeper.MigrateGlobalVirtualGroupFamiliesForSP(ctx)
app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgToggleSPAsDelegatedAgent{}), 1.2e3))
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)
})

// Register the upgrade initializer
app.UpgradeKeeper.SetUpgradeInitializer(upgradetypes.Serengeti,
func() error {
app.Logger().Info("Init Serengeti upgrade")
return nil
})
}
1 change: 1 addition & 0 deletions deployment/localup/localup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ function generate_genesis() {
echo -e '[[upgrade]]\nname = "HulunbeierPatch"\nheight = 21\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
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
done

# enable swagger API for validator0
Expand Down
6 changes: 4 additions & 2 deletions e2e/tests/permission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,8 @@ func (s *StorageTestSuite) TestStalePermissionForAccountGC() {

// bucket and object dont exist after deletion
headObjectReq := storagetypes.QueryHeadObjectRequest{
BucketName: objectName,
BucketName: bucketName,
ObjectName: objectName,
}
_, err = s.Client.HeadObject(ctx, &headObjectReq)
s.Require().Error(err)
Expand Down Expand Up @@ -1331,7 +1332,8 @@ func (s *StorageTestSuite) TestStalePermissionForGroupGC() {

// bucket and object dont exist after deletion
headObjectReq := storagetypes.QueryHeadObjectRequest{
BucketName: objectName,
BucketName: bucketName,
ObjectName: objectName,
}
_, err = s.Client.HeadObject(ctx, &headObjectReq)
s.Require().Error(err)
Expand Down
406 changes: 406 additions & 0 deletions e2e/tests/storage_rate_limit_test.go

Large diffs are not rendered by default.

155 changes: 155 additions & 0 deletions e2e/tests/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2472,3 +2472,158 @@ func (s *StorageTestSuite) TestDisallowChangePaymentAccount() {
s.SendTxBlock(user, msgUpdateBucketInfo)
s.Require().NoError(err)
}

func (s *StorageTestSuite) TestToggleBucketSpAsDelegatedAgents() {
var err error
// CreateBucket
sp := s.BaseSuite.PickStorageProvider()
gvg, found := sp.GetFirstGlobalVirtualGroup()
s.Require().True(found)
user := s.GenAndChargeAccounts(1, 1000000)[0]
bucketName := storageutils.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)

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

MsgToggleSPAsDelegatedAgent := storagetypes.NewMsgToggleSPAsDelegatedAgent(
user.GetAddr(),
bucketName)
s.SendTxBlock(user, MsgToggleSPAsDelegatedAgent)

// HeadBucket
queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest)
s.Require().NoError(err)
s.Require().Equal(true, queryHeadBucketResponse.BucketInfo.SpAsDelegatedAgentDisabled)
}

func (s *StorageTestSuite) TestCreateObjectByDelegatedAgents() {
var err error
ctx := context.Background()

// CreateBucket
sp := s.BaseSuite.PickStorageProvider()
gvg, found := sp.GetFirstGlobalVirtualGroup()
s.Require().True(found)

bucketOwner := s.GenAndChargeAccounts(1, 1000000)[0]
bucketName := storageutils.GenRandomBucketName()
objectName := storageutils.GenRandomObjectName()

msgCreateBucket := storagetypes.NewMsgCreateBucket(
bucketOwner.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(bucketOwner, msgCreateBucket)

// HeadBucket
queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{
BucketName: bucketName,
}
queryHeadBucketResponse, err := s.Client.HeadBucket(ctx, &queryHeadBucketRequest)
s.Require().NoError(err)
s.Require().Equal(false, queryHeadBucketResponse.BucketInfo.SpAsDelegatedAgentDisabled)

// DelegateCreate for user2, who does not have permission
var buffer bytes.Buffer
// 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()
contextType := "text/event-stream"
msgDelegateCreateObject := storagetypes.NewMsgDelegateCreateObject(
sp.OperatorKey.GetAddr(),
bucketOwner.GetAddr(),
bucketName,
objectName,
uint64(payloadSize),
storagetypes.VISIBILITY_TYPE_PRIVATE,
nil,
contextType,
storagetypes.REDUNDANCY_EC_TYPE)
s.SendTxBlock(sp.OperatorKey, msgDelegateCreateObject)

headObjectReq := storagetypes.QueryHeadObjectRequest{
BucketName: bucketName,
ObjectName: objectName,
}
headObjectResp, err := s.Client.HeadObject(ctx, &headObjectReq)
s.Require().NoError(err)
s.Require().Equal(objectName, headObjectResp.ObjectInfo.ObjectName)
s.Require().Equal(bucketOwner.GetAddr().String(), headObjectResp.ObjectInfo.Owner)
s.Require().Equal(0, len(headObjectResp.ObjectInfo.Checksums))

// SP seal object, and update the object checksum
checksum := sdk.Keccak256(buffer.Bytes())
expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum}

gvgId := gvg.Id
msgSealObject := storagetypes.NewMsgSealObjectV2(sp.SealKey.GetAddr(), bucketName, objectName, gvg.Id, nil, expectChecksum)
secondarySigs := make([][]byte, 0)
secondarySPBlsPubKeys := make([]bls.PublicKey, 0)
blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, headObjectResp.ObjectInfo.Id, storagetypes.GenerateHash(expectChecksum[:])).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)

headObjectResp, err = s.Client.HeadObject(ctx, &headObjectReq)
s.Require().NoError(err)
s.Require().Equal(objectName, headObjectResp.ObjectInfo.ObjectName)
s.Require().Equal(bucketOwner.GetAddr().String(), headObjectResp.ObjectInfo.Owner)
s.Require().Equal(expectChecksum, headObjectResp.ObjectInfo.Checksums)

// delegate update
var newBuffer bytes.Buffer
for i := 0; i < 2048; i++ {
newBuffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line))
}
newPayloadSize := uint64(newBuffer.Len())
newChecksum := sdk.Keccak256(newBuffer.Bytes())
newExpectChecksum := [][]byte{newChecksum, newChecksum, newChecksum, newChecksum, newChecksum, newChecksum, newChecksum}

msgUpdateObject := storagetypes.NewMsgDelegateUpdateObjectContent(sp.OperatorKey.GetAddr(),
bucketOwner.GetAddr(), bucketName, objectName, newPayloadSize, nil)
s.SendTxBlock(sp.OperatorKey, msgUpdateObject)
s.T().Logf("msgUpdateObject %s", msgUpdateObject.String())

// every secondary sp signs the checksums
newSecondarySigs := make([][]byte, 0)
newBlsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, headObjectResp.ObjectInfo.Id, storagetypes.GenerateHash(newExpectChecksum[:])).GetBlsSignHash()
for _, spID := range gvg.SecondarySpIds {
sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], newBlsSignHash)
s.Require().NoError(err)
newSecondarySigs = append(newSecondarySigs, sig)
}
aggBlsSig, err = core.BlsAggregateAndVerify(secondarySPBlsPubKeys, newBlsSignHash, newSecondarySigs)
s.Require().NoError(err)
msgSealObject = storagetypes.NewMsgSealObjectV2(sp.SealKey.GetAddr(), bucketName, objectName, gvg.Id, nil, newExpectChecksum)
msgSealObject.SecondarySpBlsAggSignatures = aggBlsSig
s.T().Logf("msgSealObject %s", msgSealObject.String())
s.SendTxBlock(sp.SealKey, msgSealObject)
}
26 changes: 26 additions & 0 deletions e2e/tests/virtualgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ func (s *VirtualGroupTestSuite) queryGlobalVirtualGroupsByFamily(familyID uint32
return resp.GlobalVirtualGroups
}

func (s *VirtualGroupTestSuite) querySpAvailableGlobalVirtualGroupFamilies(spId uint32) []uint32 {
resp, err := s.Client.QuerySpAvailableGlobalVirtualGroupFamilies(
context.Background(),
&virtualgroupmoduletypes.QuerySPAvailableGlobalVirtualGroupFamiliesRequest{
SpId: spId,
})
s.Require().NoError(err)
return resp.GlobalVirtualGroupFamilyIds
}

func (s *VirtualGroupTestSuite) querySpOptimalGlobalVirtualGroupFamily(spId uint32, strategy virtualgroupmoduletypes.PickVGFStrategy) uint32 {
resp, err := s.Client.QuerySpOptimalGlobalVirtualGroupFamily(
context.Background(),
&virtualgroupmoduletypes.QuerySpOptimalGlobalVirtualGroupFamilyRequest{
SpId: spId,
PickVgfStrategy: strategy,
})
s.Require().NoError(err)
return resp.GlobalVirtualGroupFamilyId
}

func (s *VirtualGroupTestSuite) queryAvailableGlobalVirtualGroupFamilies(familyIds []uint32) []uint32 {
resp, err := s.Client.AvailableGlobalVirtualGroupFamilies(
context.Background(),
Expand Down Expand Up @@ -111,6 +132,11 @@ func (s *VirtualGroupTestSuite) TestBasic() {

availableGvgFamilyIds := s.queryAvailableGlobalVirtualGroupFamilies([]uint32{gvg.FamilyId})
s.Require().Equal(availableGvgFamilyIds[0], gvg.FamilyId)
spAvailableGvgFamilyIds := s.querySpAvailableGlobalVirtualGroupFamilies(primarySP.Info.Id)
s.Require().Contains(spAvailableGvgFamilyIds, gvg.FamilyId)

spOptimalGvgFamilyId := s.querySpOptimalGlobalVirtualGroupFamily(primarySP.Info.Id, virtualgroupmoduletypes.Strategy_Maximize_Free_Store_Size)
s.Require().Equal(spOptimalGvgFamilyId, gvg.FamilyId)

srcGVGs := s.queryGlobalVirtualGroupsByFamily(gvg.FamilyId)

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ replace (
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.2.0
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.0
github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430
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 v1.2.0 h1:LTStppZS9WkVj0TfEYKkk5OAQDGfY
github.com/bnb-chain/greenfield-cometbft v1.2.0/go.mod h1:WVOEZ59UYM2XePQH47/IQfcInspDn8wbRXhFSJrbU1c=
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.0 h1:6HjAJpGEIqKmJ24pgkNPhbMKDtRYZQDeOjf0DZhOiA0=
github.com/bnb-chain/greenfield-cosmos-sdk v1.5.0/go.mod h1:XF8U3VN1euzLkIR5xiSNyQSnBabvnD86oz6fgdrpteQ=
github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430 h1:Lerm4iJITbmJBOqRj/IPQhS8cvjTKOfuq3XOoDgjAtM=
github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430/go.mod h1:XF8U3VN1euzLkIR5xiSNyQSnBabvnD86oz6fgdrpteQ=
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
16 changes: 16 additions & 0 deletions proto/greenfield/storage/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,19 @@ message LocalVirtualGroup {
// Notice that the minimum unit of charge is 128K
uint64 total_charge_size = 4;
}

message BucketFlowRateLimit {
// flow_rate_limit defines the flow rate limit of the bucket
string flow_rate_limit = 1 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

message BucketFlowRateLimitStatus {
// is_bucket_limited defines the flow rate limit status of the bucket, true means limited and the bucket is uncharged
bool is_bucket_limited = 1;
// payment_address is the payment address of the bucket which limited the flow rate
string payment_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
28 changes: 28 additions & 0 deletions proto/greenfield/storage/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ message EventSealObject {
uint32 global_virtual_group_id = 7;
// local_virtual_group_id defines the unique id of lvg which the object stored
uint32 local_virtual_group_id = 8;
// checksums define the total checksums of the object which generated by redundancy
// SP might set the checksum of object if it was delegated created by SP, which checksum
// will not be available until sealing object.
repeated bytes checksums = 9;
}

// EventCopyObject is emitted on MsgCopyObject
Expand Down Expand Up @@ -627,3 +631,27 @@ message EventCancelUpdateObjectContent {
(gogoproto.nullable) = false
];
}

message EventSetBucketFlowRateLimit {
// operator define the account address of operator who set the bucket flow rate limit
string operator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// bucket_name define the name of the bucket
string bucket_name = 2;
// payment_address define the payment address for the bucket
string payment_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// bucket_owner define the intended owner of the bucket
string bucket_owner = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// flow_rate_limit define the flow rate limit of the bucket
string flow_rate_limit = 5 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

message EventBucketFlowRateLimitStatus {
// bucket_name define the name of the bucket
string bucket_name = 1;
// is_limited define the status of the bucket flow rate limit
bool is_limited = 2;
}
21 changes: 21 additions & 0 deletions proto/greenfield/storage/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ service Query {
rpc QueryGroupsExistById(QueryGroupsExistByIdRequest) returns (QueryGroupsExistResponse) {
option (google.api.http).get = "/greenfield/storage/groups_exist_by_id/{group_ids}";
}

// Queries the flow rate limit of a bucket for a payment account
rpc QueryPaymentAccountBucketFlowRateLimit(QueryPaymentAccountBucketFlowRateLimitRequest) returns (QueryPaymentAccountBucketFlowRateLimitResponse) {
option (google.api.http).get = "/greenfield/storage/payment_account_bucket_flow_rate_limit/{payment_account}/{bucket_name}";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand Down Expand Up @@ -183,6 +188,7 @@ message QueryHeadBucketByIdRequest {

message QueryHeadBucketResponse {
BucketInfo bucket_info = 1;
BucketExtraInfo extra_info = 2;
}

message QueryHeadObjectRequest {
Expand Down Expand Up @@ -416,3 +422,18 @@ message QueryGroupsExistByIdRequest {
message QueryGroupsExistResponse {
map<string, bool> exists = 1;
}

message QueryPaymentAccountBucketFlowRateLimitRequest {
string payment_account = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string bucket_owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string bucket_name = 3;
}

message QueryPaymentAccountBucketFlowRateLimitResponse {
bool is_set = 1;
string flow_rate_limit = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
Loading

0 comments on commit ad2660a

Please sign in to comment.