From 3819c93a266066fe89a81e94cb7944ffab4746c6 Mon Sep 17 00:00:00 2001 From: Roshan <48975233+Pythonberg1997@users.noreply.github.com> Date: Mon, 23 Oct 2023 18:22:53 +0800 Subject: [PATCH] fix: make `handleCreateBucketSynPackage` forward compatible (#509) * fix: make `handleCreateBucketSynPackage` forward compatible * add annotation * fix lint issues --- x/storage/keeper/cross_app_bucket.go | 94 ++++++++- x/storage/types/crosschain.go | 302 ++++++++++++++++++++++----- 2 files changed, 336 insertions(+), 60 deletions(-) diff --git a/x/storage/keeper/cross_app_bucket.go b/x/storage/keeper/cross_app_bucket.go index 6fd06f9ac..b2f510924 100644 --- a/x/storage/keeper/cross_app_bucket.go +++ b/x/storage/keeper/cross_app_bucket.go @@ -4,10 +4,12 @@ import ( "encoding/hex" "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/bnb-chain/greenfield/types/common" "github.com/bnb-chain/greenfield/x/storage/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) var _ sdk.CrossChainApplication = &BucketApp{} @@ -57,7 +59,13 @@ func (app *BucketApp) ExecuteAckPackage(ctx sdk.Context, appCtx *sdk.CrossChainA } func (app *BucketApp) ExecuteFailAckPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult { - pack, err := types.DeserializeCrossChainPackage(payload, types.BucketChannelId, sdk.FailAckCrossChainPackageType) + var pack interface{} + var err error + if ctx.IsUpgraded(upgradetypes.Pampas) { + pack, err = types.DeserializeCrossChainPackageV2(payload, types.BucketChannelId, sdk.FailAckCrossChainPackageType) + } else { + pack, err = types.DeserializeCrossChainPackage(payload, types.BucketChannelId, sdk.FailAckCrossChainPackageType) + } if err != nil { app.storageKeeper.Logger(ctx).Error("deserialize bucket cross chain package error", "payload", hex.EncodeToString(payload), "error", err.Error()) panic("deserialize bucket cross chain package error") @@ -72,6 +80,9 @@ func (app *BucketApp) ExecuteFailAckPackage(ctx sdk.Context, appCtx *sdk.CrossCh case *types.CreateBucketSynPackage: operationType = types.OperationCreateBucket result = app.handleCreateBucketFailAckPackage(ctx, appCtx, p) + case *types.CreateBucketSynPackageV2: + operationType = types.OperationCreateBucket + result = app.handleCreateBucketFailAckPackageV2(ctx, appCtx, p) case *types.DeleteBucketSynPackage: operationType = types.OperationDeleteBucket result = app.handleDeleteBucketFailAckPackage(ctx, appCtx, p) @@ -91,7 +102,13 @@ func (app *BucketApp) ExecuteFailAckPackage(ctx sdk.Context, appCtx *sdk.CrossCh } func (app *BucketApp) ExecuteSynPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult { - pack, err := types.DeserializeCrossChainPackage(payload, types.BucketChannelId, sdk.SynCrossChainPackageType) + var pack interface{} + var err error + if ctx.IsUpgraded(upgradetypes.Pampas) { + pack, err = types.DeserializeCrossChainPackageV2(payload, types.BucketChannelId, sdk.FailAckCrossChainPackageType) + } else { + pack, err = types.DeserializeCrossChainPackage(payload, types.BucketChannelId, sdk.FailAckCrossChainPackageType) + } if err != nil { app.storageKeeper.Logger(ctx).Error("deserialize bucket cross chain package error", "payload", hex.EncodeToString(payload), "error", err.Error()) panic("deserialize bucket cross chain package error") @@ -106,6 +123,9 @@ func (app *BucketApp) ExecuteSynPackage(ctx sdk.Context, appCtx *sdk.CrossChainA case *types.CreateBucketSynPackage: operationType = types.OperationCreateBucket result = app.handleCreateBucketSynPackage(ctx, appCtx, p) + case *types.CreateBucketSynPackageV2: + operationType = types.OperationCreateBucket + result = app.handleCreateBucketSynPackageV2(ctx, appCtx, p) case *types.DeleteBucketSynPackage: operationType = types.OperationDeleteBucket result = app.handleDeleteBucketSynPackage(ctx, appCtx, p) @@ -204,6 +224,12 @@ func (app *BucketApp) handleCreateBucketFailAckPackage(ctx sdk.Context, appCtx * return sdk.ExecuteResult{} } +func (app *BucketApp) handleCreateBucketFailAckPackageV2(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, synPackage *types.CreateBucketSynPackageV2) sdk.ExecuteResult { + app.storageKeeper.Logger(ctx).Error("received create bucket fail ack package ") + + return sdk.ExecuteResult{} +} + func (app *BucketApp) handleCreateBucketSynPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, createBucketPackage *types.CreateBucketSynPackage) sdk.ExecuteResult { err := createBucketPackage.ValidateBasic() if err != nil { @@ -235,9 +261,8 @@ func (app *BucketApp) handleCreateBucketSynPackage(ctx sdk.Context, appCtx *sdk. ChargedReadQuota: createBucketPackage.ChargedReadQuota, PaymentAddress: createBucketPackage.PaymentAddress.String(), PrimarySpApproval: &common.Approval{ - ExpiredHeight: createBucketPackage.PrimarySpApprovalExpiredHeight, - GlobalVirtualGroupFamilyId: createBucketPackage.GlobalVirtualGroupFamilyId, - Sig: createBucketPackage.PrimarySpApprovalSignature, + ExpiredHeight: createBucketPackage.PrimarySpApprovalExpiredHeight, + Sig: createBucketPackage.PrimarySpApprovalSignature, }, ApprovalMsgBytes: createBucketPackage.GetApprovalBytes(), }, @@ -263,6 +288,65 @@ func (app *BucketApp) handleCreateBucketSynPackage(ctx sdk.Context, appCtx *sdk. } } +func (app *BucketApp) handleCreateBucketSynPackageV2(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, createBucketPackageV2 *types.CreateBucketSynPackageV2) sdk.ExecuteResult { + err := createBucketPackageV2.ValidateBasic() + if err != nil { + return sdk.ExecuteResult{ + Payload: types.CreateBucketAckPackage{ + Status: types.StatusFail, + Creator: createBucketPackageV2.Creator, + ExtraData: createBucketPackageV2.ExtraData, + }.MustSerialize(), + Err: err, + } + } + app.storageKeeper.Logger(ctx).Info("process create bucket syn package v2", "bucket name", createBucketPackageV2.BucketName) + + sourceType, err := app.storageKeeper.GetSourceTypeByChainId(ctx, appCtx.SrcChainId) + if err != nil { + return sdk.ExecuteResult{ + Err: err, + } + } + + bucketId, err := app.storageKeeper.CreateBucket(ctx, + createBucketPackageV2.Creator, + createBucketPackageV2.BucketName, + createBucketPackageV2.PrimarySpAddress, + &types.CreateBucketOptions{ + Visibility: types.VisibilityType(createBucketPackageV2.Visibility), + SourceType: sourceType, + ChargedReadQuota: createBucketPackageV2.ChargedReadQuota, + PaymentAddress: createBucketPackageV2.PaymentAddress.String(), + PrimarySpApproval: &common.Approval{ + ExpiredHeight: createBucketPackageV2.PrimarySpApprovalExpiredHeight, + GlobalVirtualGroupFamilyId: createBucketPackageV2.GlobalVirtualGroupFamilyId, + Sig: createBucketPackageV2.PrimarySpApprovalSignature, + }, + ApprovalMsgBytes: createBucketPackageV2.GetApprovalBytes(), + }, + ) + if err != nil { + return sdk.ExecuteResult{ + Payload: types.CreateBucketAckPackage{ + Status: types.StatusFail, + Creator: createBucketPackageV2.Creator, + ExtraData: createBucketPackageV2.ExtraData, + }.MustSerialize(), + Err: err, + } + } + + return sdk.ExecuteResult{ + Payload: types.CreateBucketAckPackage{ + Status: types.StatusSuccess, + Id: bucketId.BigInt(), + Creator: createBucketPackageV2.Creator, + ExtraData: createBucketPackageV2.ExtraData, + }.MustSerialize(), + } +} + func (app *BucketApp) handleDeleteBucketAckPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, ackPackage *types.DeleteBucketAckPackage) sdk.ExecuteResult { app.storageKeeper.Logger(ctx).Error("received delete bucket ack package ") diff --git a/x/storage/types/crosschain.go b/x/storage/types/crosschain.go index 852051887..d36d7473f 100644 --- a/x/storage/types/crosschain.go +++ b/x/storage/types/crosschain.go @@ -68,59 +68,116 @@ func DeserializeRawCrossChainPackage(serializedPackage []byte) (*CrossChainPacka type DeserializeFunc func(serializedPackage []byte) (interface{}, error) -var DeserializeFuncMap = map[sdk.ChannelID]map[uint8][3]DeserializeFunc{ - BucketChannelId: { - OperationMirrorBucket: { - DeserializeMirrorBucketSynPackage, - DeserializeMirrorBucketAckPackage, - DeserializeMirrorBucketSynPackage, - }, - OperationCreateBucket: { - DeserializeCreateBucketSynPackage, - DeserializeCreateBucketAckPackage, - DeserializeCreateBucketSynPackage, - }, - OperationDeleteBucket: { - DeserializeDeleteBucketSynPackage, - DeserializeDeleteBucketAckPackage, - DeserializeDeleteBucketSynPackage, - }, - }, - ObjectChannelId: { - OperationMirrorObject: { - DeserializeMirrorObjectSynPackage, - DeserializeMirrorObjectAckPackage, - DeserializeMirrorObjectSynPackage, +var ( + DeserializeFuncMap = map[sdk.ChannelID]map[uint8][3]DeserializeFunc{ + BucketChannelId: { + OperationMirrorBucket: { + DeserializeMirrorBucketSynPackage, + DeserializeMirrorBucketAckPackage, + DeserializeMirrorBucketSynPackage, + }, + OperationCreateBucket: { + DeserializeCreateBucketSynPackage, + DeserializeCreateBucketAckPackage, + DeserializeCreateBucketSynPackage, + }, + OperationDeleteBucket: { + DeserializeDeleteBucketSynPackage, + DeserializeDeleteBucketAckPackage, + DeserializeDeleteBucketSynPackage, + }, }, - OperationDeleteObject: { - DeserializeDeleteObjectSynPackage, - DeserializeDeleteObjectAckPackage, - DeserializeDeleteObjectSynPackage, + ObjectChannelId: { + OperationMirrorObject: { + DeserializeMirrorObjectSynPackage, + DeserializeMirrorObjectAckPackage, + DeserializeMirrorObjectSynPackage, + }, + OperationDeleteObject: { + DeserializeDeleteObjectSynPackage, + DeserializeDeleteObjectAckPackage, + DeserializeDeleteObjectSynPackage, + }, }, - }, - GroupChannelId: { - OperationMirrorGroup: { - DeserializeMirrorGroupSynPackage, - DeserializeMirrorGroupAckPackage, - DeserializeMirrorGroupSynPackage, + GroupChannelId: { + OperationMirrorGroup: { + DeserializeMirrorGroupSynPackage, + DeserializeMirrorGroupAckPackage, + DeserializeMirrorGroupSynPackage, + }, + OperationCreateGroup: { + DeserializeCreateGroupSynPackage, + DeserializeCreateGroupAckPackage, + DeserializeCreateGroupSynPackage, + }, + OperationDeleteGroup: { + DeserializeDeleteGroupSynPackage, + DeserializeDeleteGroupAckPackage, + DeserializeDeleteGroupSynPackage, + }, + OperationUpdateGroupMember: { + DeserializeUpdateGroupMemberSynPackage, + DeserializeUpdateGroupMemberAckPackage, + DeserializeUpdateGroupMemberSynPackage, + }, }, - OperationCreateGroup: { - DeserializeCreateGroupSynPackage, - DeserializeCreateGroupAckPackage, - DeserializeCreateGroupSynPackage, + } + + // DeserializeFuncMapV2 used after Pampas upgrade + DeserializeFuncMapV2 = map[sdk.ChannelID]map[uint8][3]DeserializeFunc{ + BucketChannelId: { + OperationMirrorBucket: { + DeserializeMirrorBucketSynPackage, + DeserializeMirrorBucketAckPackage, + DeserializeMirrorBucketSynPackage, + }, + OperationCreateBucket: { + DeserializeCreateBucketSynPackageV2, + DeserializeCreateBucketAckPackage, + DeserializeCreateBucketSynPackageV2, + }, + OperationDeleteBucket: { + DeserializeDeleteBucketSynPackage, + DeserializeDeleteBucketAckPackage, + DeserializeDeleteBucketSynPackage, + }, }, - OperationDeleteGroup: { - DeserializeDeleteGroupSynPackage, - DeserializeDeleteGroupAckPackage, - DeserializeDeleteGroupSynPackage, + ObjectChannelId: { + OperationMirrorObject: { + DeserializeMirrorObjectSynPackage, + DeserializeMirrorObjectAckPackage, + DeserializeMirrorObjectSynPackage, + }, + OperationDeleteObject: { + DeserializeDeleteObjectSynPackage, + DeserializeDeleteObjectAckPackage, + DeserializeDeleteObjectSynPackage, + }, }, - OperationUpdateGroupMember: { - DeserializeUpdateGroupMemberSynPackage, - DeserializeUpdateGroupMemberAckPackage, - DeserializeUpdateGroupMemberSynPackage, + GroupChannelId: { + OperationMirrorGroup: { + DeserializeMirrorGroupSynPackage, + DeserializeMirrorGroupAckPackage, + DeserializeMirrorGroupSynPackage, + }, + OperationCreateGroup: { + DeserializeCreateGroupSynPackage, + DeserializeCreateGroupAckPackage, + DeserializeCreateGroupSynPackage, + }, + OperationDeleteGroup: { + DeserializeDeleteGroupSynPackage, + DeserializeDeleteGroupAckPackage, + DeserializeDeleteGroupSynPackage, + }, + OperationUpdateGroupMember: { + DeserializeUpdateGroupMemberSynPackage, + DeserializeUpdateGroupMemberAckPackage, + DeserializeUpdateGroupMemberSynPackage, + }, }, - }, -} + } +) func DeserializeCrossChainPackage(rawPack []byte, channelId sdk.ChannelID, packageType sdk.CrossChainPackageType) (interface{}, error) { if packageType >= 3 { @@ -140,6 +197,24 @@ func DeserializeCrossChainPackage(rawPack []byte, channelId sdk.ChannelID, packa return operationMap[packageType](pack.Package) } +func DeserializeCrossChainPackageV2(rawPack []byte, channelId sdk.ChannelID, packageType sdk.CrossChainPackageType) (interface{}, error) { + if packageType >= 3 { + return nil, ErrInvalidCrossChainPackage + } + + pack, err := DeserializeRawCrossChainPackage(rawPack) + if err != nil { + return nil, err + } + + operationMap, ok := DeserializeFuncMapV2[channelId][pack.OperationType] + if !ok { + return nil, ErrInvalidCrossChainPackage + } + + return operationMap[packageType](pack.Package) +} + const ( StatusSuccess = 0 StatusFail = 1 @@ -341,6 +416,18 @@ func DeserializeMirrorGroupAckPackage(serializedPackage []byte) (interface{}, er } type CreateBucketSynPackage struct { + Creator sdk.AccAddress + BucketName string + Visibility uint32 + PaymentAddress sdk.AccAddress + PrimarySpAddress sdk.AccAddress + PrimarySpApprovalExpiredHeight uint64 + PrimarySpApprovalSignature []byte + ChargedReadQuota uint64 + ExtraData []byte +} + +type CreateBucketSynPackageV2 struct { Creator sdk.AccAddress BucketName string Visibility uint32 @@ -354,6 +441,18 @@ type CreateBucketSynPackage struct { } type CreateBucketSynPackageStruct struct { + Creator common.Address + BucketName string + Visibility uint32 + PaymentAddress common.Address + PrimarySpAddress common.Address + PrimarySpApprovalExpiredHeight uint64 + PrimarySpApprovalSignature []byte + ChargedReadQuota uint64 + ExtraData []byte +} + +type CreateBucketSynPackageV2Struct struct { Creator common.Address BucketName string Visibility uint32 @@ -374,7 +473,6 @@ var ( {Name: "PaymentAddress", Type: "address"}, {Name: "PrimarySpAddress", Type: "address"}, {Name: "PrimarySpApprovalExpiredHeight", Type: "uint64"}, - {Name: "GlobalVirtualGroupFamilyId", Type: "uint32"}, {Name: "PrimarySpApprovalSignature", Type: "bytes"}, {Name: "ChargedReadQuota", Type: "uint64"}, {Name: "ExtraData", Type: "bytes"}, @@ -383,6 +481,23 @@ var ( createBucketSynPackageStructArgs = abi.Arguments{ {Type: createBucketSynPackageStructType}, } + + createBucketSynPackageV2StructType, _ = abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + {Name: "Creator", Type: "address"}, + {Name: "BucketName", Type: "string"}, + {Name: "Visibility", Type: "uint32"}, + {Name: "PaymentAddress", Type: "address"}, + {Name: "PrimarySpAddress", Type: "address"}, + {Name: "PrimarySpApprovalExpiredHeight", Type: "uint64"}, + {Name: "GlobalVirtualGroupFamilyId", Type: "uint32"}, + {Name: "PrimarySpApprovalSignature", Type: "bytes"}, + {Name: "ChargedReadQuota", Type: "uint64"}, + {Name: "ExtraData", Type: "bytes"}, + }) + + createBucketSynPackageV2StructArgs = abi.Arguments{ + {Type: createBucketSynPackageV2StructType}, + } ) func (p CreateBucketSynPackage) MustSerialize() []byte { @@ -393,7 +508,6 @@ func (p CreateBucketSynPackage) MustSerialize() []byte { PaymentAddress: common.BytesToAddress(p.PaymentAddress), PrimarySpAddress: common.BytesToAddress(p.PrimarySpAddress), PrimarySpApprovalExpiredHeight: p.PrimarySpApprovalExpiredHeight, - GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, PrimarySpApprovalSignature: p.PrimarySpApprovalSignature, ChargedReadQuota: p.ChargedReadQuota, ExtraData: p.ExtraData, @@ -412,9 +526,8 @@ func (p CreateBucketSynPackage) ValidateBasic() error { PaymentAddress: p.PaymentAddress.String(), PrimarySpAddress: p.PrimarySpAddress.String(), PrimarySpApproval: &gnfdcommon.Approval{ - ExpiredHeight: p.PrimarySpApprovalExpiredHeight, - GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, - Sig: p.PrimarySpApprovalSignature, + ExpiredHeight: p.PrimarySpApprovalExpiredHeight, + Sig: p.PrimarySpApprovalSignature, }, ChargedReadQuota: p.ChargedReadQuota, } @@ -430,9 +543,8 @@ func (p CreateBucketSynPackage) GetApprovalBytes() []byte { PaymentAddress: p.PaymentAddress.String(), PrimarySpAddress: p.PrimarySpAddress.String(), PrimarySpApproval: &gnfdcommon.Approval{ - ExpiredHeight: p.PrimarySpApprovalExpiredHeight, - GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, - Sig: p.PrimarySpApprovalSignature, + ExpiredHeight: p.PrimarySpApprovalExpiredHeight, + Sig: p.PrimarySpApprovalSignature, }, ChargedReadQuota: p.ChargedReadQuota, } @@ -452,6 +564,86 @@ func DeserializeCreateBucketSynPackage(serializedPackage []byte) (interface{}, e } tp := CreateBucketSynPackage{ + pkgStruct.Creator.Bytes(), + pkgStruct.BucketName, + pkgStruct.Visibility, + pkgStruct.PaymentAddress.Bytes(), + pkgStruct.PrimarySpAddress.Bytes(), + pkgStruct.PrimarySpApprovalExpiredHeight, + pkgStruct.PrimarySpApprovalSignature, + pkgStruct.ChargedReadQuota, + pkgStruct.ExtraData, + } + return &tp, nil +} + +func (p CreateBucketSynPackageV2) MustSerialize() []byte { + encodedBytes, err := createBucketSynPackageStructArgs.Pack(&CreateBucketSynPackageV2Struct{ + Creator: common.BytesToAddress(p.Creator), + BucketName: p.BucketName, + Visibility: p.Visibility, + PaymentAddress: common.BytesToAddress(p.PaymentAddress), + PrimarySpAddress: common.BytesToAddress(p.PrimarySpAddress), + PrimarySpApprovalExpiredHeight: p.PrimarySpApprovalExpiredHeight, + GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, + PrimarySpApprovalSignature: p.PrimarySpApprovalSignature, + ChargedReadQuota: p.ChargedReadQuota, + ExtraData: p.ExtraData, + }) + if err != nil { + panic("encode create bucket syn package v2 error") + } + return encodedBytes +} + +func (p CreateBucketSynPackageV2) ValidateBasic() error { + msg := MsgCreateBucket{ + Creator: p.Creator.String(), + BucketName: p.BucketName, + Visibility: VisibilityType(p.Visibility), + PaymentAddress: p.PaymentAddress.String(), + PrimarySpAddress: p.PrimarySpAddress.String(), + PrimarySpApproval: &gnfdcommon.Approval{ + ExpiredHeight: p.PrimarySpApprovalExpiredHeight, + GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, + Sig: p.PrimarySpApprovalSignature, + }, + ChargedReadQuota: p.ChargedReadQuota, + } + + return msg.ValidateBasic() +} + +func (p CreateBucketSynPackageV2) GetApprovalBytes() []byte { + msg := MsgCreateBucket{ + Creator: p.Creator.String(), + BucketName: p.BucketName, + Visibility: VisibilityType(p.Visibility), + PaymentAddress: p.PaymentAddress.String(), + PrimarySpAddress: p.PrimarySpAddress.String(), + PrimarySpApproval: &gnfdcommon.Approval{ + ExpiredHeight: p.PrimarySpApprovalExpiredHeight, + GlobalVirtualGroupFamilyId: p.GlobalVirtualGroupFamilyId, + Sig: p.PrimarySpApprovalSignature, + }, + ChargedReadQuota: p.ChargedReadQuota, + } + return msg.GetApprovalBytes() +} + +func DeserializeCreateBucketSynPackageV2(serializedPackage []byte) (interface{}, error) { + unpacked, err := createBucketSynPackageV2StructArgs.Unpack(serializedPackage) + if err != nil { + return nil, errors.Wrapf(ErrInvalidCrossChainPackage, "deserialize create bucket syn package v2 failed") + } + + unpackedStruct := abi.ConvertType(unpacked[0], CreateBucketSynPackageV2Struct{}) + pkgStruct, ok := unpackedStruct.(CreateBucketSynPackageV2Struct) + if !ok { + return nil, errors.Wrapf(ErrInvalidCrossChainPackage, "reflect create bucket syn package v2 failed") + } + + tp := CreateBucketSynPackageV2{ pkgStruct.Creator.Bytes(), pkgStruct.BucketName, pkgStruct.Visibility,