Skip to content

Commit

Permalink
CM-274 Implemented MsgRenewLease
Browse files Browse the repository at this point in the history
  • Loading branch information
rnistuk committed Apr 1, 2020
1 parent 20538d5 commit a681128
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 18 deletions.
47 changes: 39 additions & 8 deletions x/crud/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,20 @@ func GetTxCmd(_ string, cdc *codec.Codec) *cobra.Command {
RunE: client.ValidateCmd,
}
crudTxCmd.AddCommand(flags.PostCommands(
GetCmdCount(cdc),
GetCmdCreate(cdc),
GetCmdRead(cdc),
GetCmdUpdate(cdc),
GetCmdDelete(cdc),
GetCmdKeys(cdc),
GetCmdHas(cdc),
GetCmdRename(cdc),
GetCmdKeyValues(cdc),
GetCmdCount(cdc),
GetCmdDeleteAll(cdc),
GetCmdMultiUpdate(cdc),
GetCmdGetLease(cdc),
GetCmdGetNShortestLease(cdc),
GetCmdHas(cdc),
GetCmdKeyValues(cdc),
GetCmdKeys(cdc),
GetCmdMultiUpdate(cdc),
GetCmdRead(cdc),
GetCmdRename(cdc),
GetCmdRenewLease(cdc),
GetCmdUpdate(cdc),
)...)

return crudTxCmd
Expand Down Expand Up @@ -354,3 +355,33 @@ func GetCmdGetNShortestLease(cdc *codec.Codec) *cobra.Command {
},
}
}

func GetCmdRenewLease(cdc *codec.Codec) *cobra.Command {
cc := cobra.Command{
Use: "renewlease [UUID] [key]",
Short: "renew the lease of an existing entry in the database",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
inBuf := bufio.NewReader(cmd.InOrStdin())
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))

msg := types.MsgRenewLease{
UUID: args[0],
Key: args[1],
Lease: leaseValue,
Owner: cliCtx.GetFromAddress(),
}

err := msg.ValidateBasic()
if err != nil {
return err
}

return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cc.PersistentFlags().Int64Var(&leaseValue, "lease", 0, "lease in blocks (default 172800 (10 days))")
return &cc
}
1 change: 1 addition & 0 deletions x/crud/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string)
r.HandleFunc(fmt.Sprintf("/%s/rename", storeName), BlzRenameHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/update", storeName), BlzUpdateHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/version", storeName), BlzQVersionHandler(cliCtx, storeName)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/renewlease", storeName), BlzRenewLease(cliCtx)).Methods("POST")
}
47 changes: 47 additions & 0 deletions x/crud/client/rest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,50 @@ func BlzGetNShortestLeaseHandler(cliCtx context.CLIContext) http.HandlerFunc {
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}

///////////////////////////////////////////////////////////////////////////////
// Renew Lease
type RenewLeaseReq struct {
BaseReq rest.BaseReq
UUID string
Key string
Lease int64
Owner string
}

func BlzRenewLease(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req RenewLeaseReq

if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}

baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}

addr, err := sdk.AccAddressFromBech32(req.Owner)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

// create the message
msg := types.MsgRenewLease{
UUID: req.UUID,
Key: req.Key,
Lease: req.Lease,
Owner: addr,
}
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
35 changes: 35 additions & 0 deletions x/crud/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ func NewHandler(keeper keeper.IKeeper) sdk.Handler {
return handleMsgGetLease(ctx, keeper, msg)
case types.MsgGetNShortestLease:
return handleMsgGetNShortestLease(ctx, keeper, msg)
case types.MsgRenewLease:
return handleMsgRenewLease(ctx, keeper, msg)

default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, fmt.Sprintf("Unrecognized crud msg type: %v", msg.Type()))
}
Expand Down Expand Up @@ -309,3 +312,35 @@ func handleMsgGetNShortestLease(ctx sdk.Context, keeper keeper.IKeeper, msg type

return &sdk.Result{Data: json_data}, nil
}

func handleMsgRenewLease(ctx sdk.Context, keeper keeper.IKeeper, msg types.MsgRenewLease) (*sdk.Result, error) {
if len(msg.UUID) == 0 || len(msg.Key) == 0 || msg.Owner.Empty() {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid message")
}

owner := keeper.GetOwner(ctx, keeper.GetKVStore(ctx), msg.UUID, msg.Key)
if owner.Empty() {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Key does not exist")
}

if !msg.Owner.Equals(owner) {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Incorrect Owner")
}

if msg.Lease == 0 {
msg.Lease = keeper.GetDefaultLeaseBlocks()
}

blzValue := keeper.GetValue(ctx, keeper.GetKVStore(ctx), msg.UUID, msg.Key)

leaseCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
keeper.DeleteLease(keeper.GetLeaseStore(leaseCtx), msg.UUID, msg.Key, blzValue.Height, blzValue.Lease)

blzValue.Height = ctx.BlockHeight()
blzValue.Lease = msg.Lease

keeper.SetValue(ctx, keeper.GetKVStore(ctx), msg.UUID, msg.Key, blzValue)
keeper.SetLease(keeper.GetLeaseStore(leaseCtx), msg.UUID, msg.Key, blzValue.Height, blzValue.Lease)

return &sdk.Result{}, nil
}
63 changes: 63 additions & 0 deletions x/crud/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,3 +817,66 @@ func Test_handleMsgGetNShortestLease(t *testing.T) {
assert.NotNil(t, err)
}
}

func Test_handleMsgRenewLease(t *testing.T) {

mockCtrl, mockKeeper, ctx, owner := initTest(t)
defer mockCtrl.Finish()

mockKeeper.EXPECT().GetDefaultLeaseBlocks().AnyTimes().Return(DefaultLeaseBlockHeight)

// renew the lease to the default and update height
{
renewMsg := types.MsgRenewLease{
UUID: "uuid",
Key: "key",
Lease: 0,
Owner: owner,
}

// always return nil for a store...
ctx := ctx.WithBlockHeight(1100)
mockKeeper.EXPECT().GetKVStore(gomock.Any()).AnyTimes().Return(nil)
mockKeeper.EXPECT().GetLeaseStore(gomock.Any()).AnyTimes()
mockKeeper.EXPECT().GetOwner(ctx, nil, renewMsg.UUID, renewMsg.Key).Return(owner)
mockKeeper.EXPECT().GetValue(ctx, nil, renewMsg.UUID, renewMsg.Key).Return(types.BLZValue{
Value: "value",
Lease: 100,
Owner: owner,
Height: 1000,
})

mockKeeper.EXPECT().DeleteLease(nil, renewMsg.UUID, renewMsg.Key, int64(1000), int64(100))
mockKeeper.EXPECT().SetValue(ctx, nil, renewMsg.UUID, renewMsg.Key, types.BLZValue{
Value: "value",
Lease: DefaultLeaseBlockHeight,
Owner: owner,
Height: 1100,
})

mockKeeper.EXPECT().SetLease(gomock.Any(), renewMsg.UUID, renewMsg.Key, int64(1100), DefaultLeaseBlockHeight)
_, err := NewHandler(mockKeeper)(ctx, renewMsg)
assert.Nil(t, err)

renewMsg.Owner = []byte("BADOWNER1t0helpusuldf6h4wqrnnpyp9wr6law2u5jwa23")
mockKeeper.EXPECT().GetOwner(ctx, nil, renewMsg.UUID, renewMsg.Key).Return(owner)
_, err = NewHandler(mockKeeper)(ctx, renewMsg)
assert.NotNil(t, err)

mockKeeper.EXPECT().GetOwner(ctx, nil, renewMsg.UUID, renewMsg.Key)
_, err = NewHandler(mockKeeper)(ctx, renewMsg)
assert.NotNil(t, err)
}

// Test for empty message parameters
{
_, err := handleMsgRenewLease(ctx, mockKeeper, types.MsgRenewLease{})
assert.NotNil(t, err)

_, err = handleMsgRenewLease(ctx, mockKeeper, types.MsgRenewLease{UUID: "uuid"})
assert.NotNil(t, err)

_, err = handleMsgRenewLease(ctx, mockKeeper, types.MsgRenewLease{UUID: "uuid", Key: "key"})
assert.NotNil(t, err)
}
}
19 changes: 10 additions & 9 deletions x/crud/internal/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@ func init() {
}

func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(MsgCreate{}, "crud/create", nil)
cdc.RegisterConcrete(MsgRead{}, "crud/read", nil)
cdc.RegisterConcrete(MsgUpdate{}, "crud/update", nil)
cdc.RegisterConcrete(MsgDelete{}, "crud/delete", nil)
cdc.RegisterConcrete(MsgKeys{}, "crud/keys", nil)
cdc.RegisterConcrete(MsgKeyValues{}, "crud/keyvalues", nil)
cdc.RegisterConcrete(MsgHas{}, "crud/has", nil)
cdc.RegisterConcrete(MsgRename{}, "crud/rename", nil)
cdc.RegisterConcrete(MsgCount{}, "crud/count", nil)
cdc.RegisterConcrete(MsgCreate{}, "crud/create", nil)
cdc.RegisterConcrete(MsgDeleteAll{}, "crud/deleteall", nil)
cdc.RegisterConcrete(MsgMultiUpdate{}, "crud/multiupdate", nil)
cdc.RegisterConcrete(MsgDelete{}, "crud/delete", nil)
cdc.RegisterConcrete(MsgGetLease{}, "crud/getlease", nil)
cdc.RegisterConcrete(MsgGetNShortestLease{}, "crud/getnshortestlease", nil)
cdc.RegisterConcrete(MsgHas{}, "crud/has", nil)
cdc.RegisterConcrete(MsgKeyValues{}, "crud/keyvalues", nil)
cdc.RegisterConcrete(MsgKeys{}, "crud/keys", nil)
cdc.RegisterConcrete(MsgMultiUpdate{}, "crud/multiupdate", nil)
cdc.RegisterConcrete(MsgRead{}, "crud/read", nil)
cdc.RegisterConcrete(MsgRename{}, "crud/rename", nil)
cdc.RegisterConcrete(MsgRenewLease{}, "crud/renewlease", nil)
cdc.RegisterConcrete(MsgUpdate{}, "crud/update", nil)
}
37 changes: 37 additions & 0 deletions x/crud/internal/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,3 +536,40 @@ func (msg MsgGetNShortestLease) GetSignBytes() []byte {
func (msg MsgGetNShortestLease) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.Owner}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RenewLease
type MsgRenewLease struct {
UUID string
Key string
Lease int64
Owner sdk.AccAddress
}

func (msg MsgRenewLease) Route() string { return RouterKey }

func (msg MsgRenewLease) Type() string { return "renewlease" }

func (msg MsgRenewLease) ValidateBasic() error {
if msg.Owner.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Owner.String())
}

if len(msg.UUID) == 0 || len(msg.Key) == 0 {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "UUID or Key empty")
}

if msg.Lease < 0 {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Lease negative")
}

return nil
}

func (msg MsgRenewLease) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg))
}

func (msg MsgRenewLease) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.Owner}
}
45 changes: 45 additions & 0 deletions x/crud/internal/types/msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,3 +661,48 @@ func TestMsgGetNShortestLease_GetSigners(t *testing.T) {
}
Equal(t, sut.GetSigners(), []sdk.AccAddress{sut.Owner})
}

/////////////////////////////////////////////////////////////////////////////////
func TestMsgRenewLease_Route(t *testing.T) {
Equal(t, "crud", MsgRenewLease{}.Route())
}

func TestMsgRenewLease_Type(t *testing.T) {
Equal(t, "renewlease", MsgRenewLease{}.Type())
}

func TestMsgRenewLease_ValidateBasic(t *testing.T) {
owner := []byte("bluzelle1t0ywtmrduldf6h4wqrnnpyp9wr6law2u5jwa23")
sut := MsgRenewLease{UUID: "uuid", Key: "key", Lease: int64(100), Owner: owner}

Nil(t, sut.ValidateBasic())

sut.Owner = nil
NotNil(t, sut.ValidateBasic())

sut.Owner = owner
sut.UUID = ""
Equal(t, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "UUID or Key empty").Error(), sut.ValidateBasic().Error())

sut.UUID = "uuid"
sut.Key = ""
Equal(t, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "UUID or Key empty").Error(), sut.ValidateBasic().Error())

sut.Key = "key"
sut.Lease = -5
Equal(t, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Lease negative").Error(), sut.ValidateBasic().Error())
}

func TestMsgRenewLease_GetSignBytes(t *testing.T) {
owner := []byte("bluzelle1t0ywtmrduldf6h4wqrnnpyp9wr6law2u5jwa23")
sut := MsgRenewLease{UUID: "uuid", Key: "key", Lease: int64(100), Owner: owner}
Equal(t,
"{\"type\":\"crud/renewlease\",\"value\":{\"Key\":\"key\",\"Lease\":\"100\",\"Owner\":\"cosmos1vfk827n9d3kx2vt5xpuhwardwfj82mryvcmxsdrhw9exumns09crjamjxekxzaejw56k5ampxgeslhg4h3\",\"UUID\":\"uuid\"}}",
string(sut.GetSignBytes()))
}

func TestMsgRenewLease_GetSigners(t *testing.T) {
owner := []byte("bluzelle1t0ywtmrduldf6h4wqrnnpyp9wr6law2u5jwa23")
sut := MsgRenewLease{UUID: "uuid", Key: "key", Lease: int64(100), Owner: owner}
Equal(t, sut.GetSigners(), []sdk.AccAddress{sut.Owner})
}
2 changes: 1 addition & 1 deletion x/crud/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestAppModuleBasic_GetTxCmd(t *testing.T) {
assert.Equal(t, 2, cmd.SuggestionsMinimumDistance)

commands := cmd.Commands()
assert.Len(t, commands, 13)
assert.Len(t, commands, 14)
}
}

Expand Down

0 comments on commit a681128

Please sign in to comment.