Skip to content

Commit

Permalink
feat: remove bucket get approval
Browse files Browse the repository at this point in the history
  • Loading branch information
BarryTong65 committed Feb 29, 2024
1 parent a6c913a commit 3815ffd
Show file tree
Hide file tree
Showing 12 changed files with 1,731 additions and 254 deletions.
26 changes: 26 additions & 0 deletions proto/greenfield/virtualgroup/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ service Query {
rpc GVGStatistics(QuerySPGVGStatisticsRequest) returns (QuerySPGVGStatisticsResponse) {
option (google.api.http).get = "/greenfield/virtualgroup/sp_gvg_statistics";
}

// QuerySpAvailableGlobalVirtualGroupFamilies filters a list of GlobalVirtualGroupFamilies IDs under a certain SP that are qualified to create a bucket on
rpc QuerySpAvailableGlobalVirtualGroupFamilies(QuerySPAvailableGlobalVirtualGroupFamiliesRequest) returns (QuerySPAvailableGlobalVirtualGroupFamiliesResponse) {
option (google.api.http).get = "/greenfield/virtualgroup/sp_available_global_virtual_group_families";
}

// QuerySpOptimalGlobalVirtualGroupFamily filters the optimal GlobalVirtualGroupFamily under a certain SP that is qualified to create a bucket on
rpc QuerySpOptimalGlobalVirtualGroupFamily(QuerySpOptimalGlobalVirtualGroupFamilyRequest) returns (QuerySpOptimalGlobalVirtualGroupFamilyResponse) {
option (google.api.http).get = "/greenfield/virtualgroup/sp_optimal_global_virtual_group_family";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand Down Expand Up @@ -119,3 +129,19 @@ message QuerySPGVGStatisticsRequest {
message QuerySPGVGStatisticsResponse {
GVGStatisticsWithinSP gvg_stats = 1;
}

message QuerySPAvailableGlobalVirtualGroupFamiliesRequest {
uint32 sp_id = 1;
}

message QuerySPAvailableGlobalVirtualGroupFamiliesResponse {
repeated uint32 global_virtual_group_family_ids = 1;
}

message QuerySpOptimalGlobalVirtualGroupFamilyRequest {
uint32 sp_id = 1;
}

message QuerySpOptimalGlobalVirtualGroupFamilyResponse {
uint32 global_virtual_group_family_id = 1;
}
7 changes: 7 additions & 0 deletions proto/greenfield/virtualgroup/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ message GVGStatisticsWithinSP {
uint32 break_redundancy_reqmt_gvg_count = 4;
}

message GVGFamilyStatisticsWithinSP {
// storage_provider_id defines the id of the sp which the statistics associated to
uint32 storage_provider_id = 1;
// global_virtual_group_family_ids is a list of identifiers of the global virtual group family associated with the SP.
repeated uint32 global_virtual_group_family_ids = 2;
}

message SwapOutInfo {
// sp_id is the unique id of the storage provider who want to swap out.
uint32 sp_id = 1;
Expand Down
108 changes: 108 additions & 0 deletions swagger/static/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6310,6 +6310,54 @@ paths:
format: byte
tags:
- Query
/greenfield/virtualgroup/sp_available_global_virtual_group_families:
get:
summary: >-
QuerySpAvailableGlobalVirtualGroupFamilies filters a list of
GlobalVirtualGroupFamilies IDs under a certain SP that are qualified to
create a bucket on
operationId: QuerySpAvailableGlobalVirtualGroupFamilies
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: sp_id
in: query
required: false
type: integer
format: int64
tags:
- Query
/greenfield/virtualgroup/sp_gvg_statistics:
get:
summary: GVGStatistics gets gvg statistics for a SP
Expand Down Expand Up @@ -6394,6 +6442,52 @@ paths:
format: int64
tags:
- Query
/greenfield/virtualgroup/sp_optimal_global_virtual_group_family:
get:
summary: >-
QuerySpOptimalGlobalVirtualGroupFamily filters the optimal
GlobalVirtualGroupFamily under a certain SP that is qualified to create
a bucket on
operationId: QuerySpOptimalGlobalVirtualGroupFamily
responses:
'200':
description: A successful response.
schema:
type: object
properties:
global_virtual_group_family_id:
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: sp_id
in: query
required: false
type: integer
format: int64
tags:
- Query
/greenfield/virtualgroup/swap_in_info:
get:
summary: >-
Expand Down Expand Up @@ -37376,6 +37470,14 @@ definitions:
type: string
description: the the number of sp allowed to exit concurrently.
description: QueryParamsResponse is response type for the Query/Params RPC method.
greenfield.virtualgroup.QuerySPAvailableGlobalVirtualGroupFamiliesResponse:
type: object
properties:
global_virtual_group_family_ids:
type: array
items:
type: integer
format: int64
greenfield.virtualgroup.QuerySPGVGStatisticsResponse:
type: object
properties:
Expand Down Expand Up @@ -37421,6 +37523,12 @@ definitions:
unique to all other SP. So this will not be used for

swapIn individual GVG as secondary
greenfield.virtualgroup.QuerySpOptimalGlobalVirtualGroupFamilyResponse:
type: object
properties:
global_virtual_group_family_id:
type: integer
format: int64
greenfield.virtualgroup.QuerySwapInInfoResponse:
type: object
properties:
Expand Down
28 changes: 14 additions & 14 deletions x/storage/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,6 @@ func (k Keeper) CreateBucket(
return sdkmath.ZeroUint(), errors.Wrap(types.ErrNoSuchStorageProvider, "the storage provider is not in service")
}

// check primary sp approval
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, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig, ownerAcc)
if err != nil {
return sdkmath.ZeroUint(), err
}
gvgFamily, err := k.virtualGroupKeeper.GetAndCheckGVGFamilyAvailableForNewBucket(ctx, opts.PrimarySpApproval.GlobalVirtualGroupFamilyId)
if err != nil {
return sdkmath.ZeroUint(), err
Expand Down Expand Up @@ -567,6 +559,12 @@ func (k Keeper) CreateObject(
return sdkmath.ZeroUint(), err
}

// check object
_, found = k.GetObjectInfo(ctx, bucketName, objectName)
if found {
return sdkmath.ZeroUint(), types.ErrObjectAlreadyExists
}

// primary sp
sp := k.MustGetPrimarySPForBucket(ctx, bucketInfo)

Expand All @@ -585,12 +583,7 @@ func (k Keeper) CreateObject(
creator = operator
}

// check approval
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, opts.ApprovalMsgBytes, opts.PrimarySpApproval.Sig, operator)
err = k.VerifySP(ctx, sp, operator)
if err != nil {
return sdkmath.ZeroUint(), err
}
Expand Down Expand Up @@ -1618,6 +1611,13 @@ func (k Keeper) VerifySPAndSignature(_ sdk.Context, sp *sptypes.StorageProvider,
return nil
}

func (k Keeper) VerifySP(_ sdk.Context, sp *sptypes.StorageProvider, operator sdk.AccAddress) error {
if sp.Status != sptypes.STATUS_IN_SERVICE && !k.fromSpMaintenanceAcct(sp, operator) {
return sptypes.ErrStorageProviderNotInService
}
return nil
}

func (k Keeper) GenNextBucketId(ctx sdk.Context) sdkmath.Uint {
store := ctx.KVStore(k.storeKey)

Expand Down
76 changes: 18 additions & 58 deletions x/storage/keeper/keeper_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,31 @@ func (s *TestSuite) TestCreateObject() {
})
})

// case 5: approval expired
// case 5: object exist
s.storageKeeper.StoreObjectInfo(s.ctx, &types.ObjectInfo{
Id: sdk.NewUint(1),
BucketName: bucketInfo.BucketName,
ObjectName: objectName,
})
_, err = s.storageKeeper.CreateObject(s.ctx, operatorAddress, bucketInfo.BucketName,
objectName, 100, types.CreateObjectOptions{
Visibility: 0,
ContentType: "",
SourceType: 0,
RedundancyType: 0,
Checksums: nil,
})
s.Require().ErrorContains(err, "Object already exists")

// case 6: valid case
s.virtualGroupKeeper.EXPECT().GetGVGFamily(gomock.Any(), gomock.Any()).Return(&types2.GlobalVirtualGroupFamily{
Id: 0,
PrimarySpId: 0,
GlobalVirtualGroupIds: nil,
VirtualPaymentAddress: "",
}, true).AnyTimes()

spAddress, signBytes, sig := sample.RandSignBytes()
spAddress, _, _ := sample.RandSignBytes()
s.spKeeper.EXPECT().MustGetStorageProvider(gomock.Any(), gomock.Any()).Return(&types3.StorageProvider{
Id: 0,
OperatorAddress: spAddress.String(),
Expand All @@ -122,60 +138,6 @@ func (s *TestSuite) TestCreateObject() {
BlsKey: nil,
}).AnyTimes()
s.ctx = s.ctx.WithBlockHeight(100)
_, err = s.storageKeeper.CreateObject(s.ctx, operatorAddress, bucketInfo.BucketName,
objectName, 100, types.CreateObjectOptions{
Visibility: 0,
ContentType: "",
SourceType: 0,
RedundancyType: 0,
Checksums: nil,
PrimarySpApproval: &common.Approval{
ExpiredHeight: uint64(s.ctx.BlockHeight() - 1),
Sig: sig,
},
ApprovalMsgBytes: signBytes,
})

s.Require().ErrorContains(err, "The approval of sp is expired")

// case 6: invalid approval sig
_, err = s.storageKeeper.CreateObject(s.ctx, operatorAddress, bucketInfo.BucketName,
objectName, 100, types.CreateObjectOptions{
Visibility: 0,
ContentType: "",
SourceType: 0,
RedundancyType: 0,
Checksums: nil,
PrimarySpApproval: &common.Approval{
ExpiredHeight: uint64(s.ctx.BlockHeight() + 1),
Sig: []byte("invalid sig"),
},
ApprovalMsgBytes: signBytes,
})
s.Require().ErrorContains(err, "verify signature error")

// case 7: object exist
s.storageKeeper.StoreObjectInfo(s.ctx, &types.ObjectInfo{
Id: sdk.NewUint(1),
BucketName: bucketInfo.BucketName,
ObjectName: objectName,
})
_, err = s.storageKeeper.CreateObject(s.ctx, operatorAddress, bucketInfo.BucketName,
objectName, 100, types.CreateObjectOptions{
Visibility: 0,
ContentType: "",
SourceType: 0,
RedundancyType: 0,
Checksums: nil,
PrimarySpApproval: &common.Approval{
ExpiredHeight: uint64(s.ctx.BlockHeight() + 1),
Sig: sig,
},
ApprovalMsgBytes: signBytes,
})
s.Require().ErrorContains(err, "Object already exists")

// case 8: valid case
s.storageKeeper.DeleteObjectInfo(s.ctx, &types.ObjectInfo{
Id: sdk.NewUint(1),
BucketName: bucketInfo.BucketName,
Expand Down Expand Up @@ -211,9 +173,7 @@ func (s *TestSuite) TestCreateObject() {
Checksums: nil,
PrimarySpApproval: &common.Approval{
ExpiredHeight: uint64(s.ctx.BlockHeight() + 1),
Sig: sig,
},
ApprovalMsgBytes: signBytes,
})

s.Require().NoError(err)
Expand Down
Loading

0 comments on commit 3815ffd

Please sign in to comment.