Skip to content

Commit

Permalink
Add query and cli for lock reward receiver (#5373)
Browse files Browse the repository at this point in the history
* Add query and cli

* Add stargate whitelist
  • Loading branch information
mattverse authored and pysel committed Jun 6, 2023
1 parent 5a97d25 commit c454fc2
Show file tree
Hide file tree
Showing 8 changed files with 664 additions and 117 deletions.
10 changes: 10 additions & 0 deletions proto/osmosis/lockup/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ service Query {
"/osmosis/lockup/v1beta1/locked_by_id/{lock_id}";
}

// Returns lock record by id
rpc LockRewardReceiver(LockRewardReceiverRequest)
returns (LockRewardReceiverResponse) {
option (google.api.http).get =
"/osmosis/lockup/v1beta1/lock_reward_receiver/{lock_id}";
}

// Returns next lock ID
rpc NextLockID(NextLockIDRequest) returns (NextLockIDResponse) {
option (google.api.http).get = "/osmosis/lockup/v1beta1/next_lock_id";
Expand Down Expand Up @@ -253,6 +260,9 @@ message LockedDenomResponse {
message LockedRequest { uint64 lock_id = 1; };
message LockedResponse { PeriodLock lock = 1; };

message LockRewardReceiverRequest { uint64 lock_id = 1; };
message LockRewardReceiverResponse { string reward_receiver = 1; };

message NextLockIDRequest {};
message NextLockIDResponse { uint64 lock_id = 1; };

Expand Down
1 change: 1 addition & 0 deletions wasmbinding/stargate_whitelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func init() {
setWhitelistedQuery("/osmosis.lockup.Query/LockedDenom", &lockuptypes.LockedDenomResponse{})
setWhitelistedQuery("/osmosis.lockup.Query/LockedByID", &lockuptypes.LockedResponse{})
setWhitelistedQuery("/osmosis.lockup.Query/NextLockID", &lockuptypes.NextLockIDResponse{})
setWhitelistedQuery("/osmosis.lockup.Query/LockRewardReceiver", &lockuptypes.LockRewardReceiverResponse{})

// mint
setWhitelistedQuery("/osmosis.mint.v1beta1.Query/EpochProvisions", &minttypes.QueryEpochProvisionsResponse{})
Expand Down
14 changes: 14 additions & 0 deletions x/lockup/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func GetQueryCmd() *cobra.Command {
GetCmdAccountUnlockedBeforeTime(),
GetCmdAccountLockedPastTimeDenom(),
GetCmdLockedByID(),
GetCmdLockRewardReceiver(),
GetCmdAccountLockedLongerDuration(),
GetCmdAccountLockedLongerDurationNotUnlockingOnly(),
GetCmdAccountLockedLongerDurationDenom(),
Expand Down Expand Up @@ -192,6 +193,19 @@ func GetCmdLockedByID() *cobra.Command {
return osmocli.BuildQueryCli[*types.LockedRequest](&q, types.NewQueryClient)
}

// GetCmdLockRewardReceiver returns reward receiver for the given lock id
func GetCmdLockRewardReceiver() *cobra.Command {
q := osmocli.QueryDescriptor{
Use: "lock-reward-receiver <id>",
Short: "Query lock's reward receiver",
Long: `{{.Short}}{{.ExampleHeader}}
{{.CommandPrefix}} lock-reward-receiver 1`,
QueryFnName: "LockedByID",
}
q.Long = osmocli.FormatLongDesc(q.Long, osmocli.NewLongMetadata(types.ModuleName).WithShort(q.Short))
return osmocli.BuildQueryCli[*types.LockRewardReceiverRequest](&q, types.NewQueryClient)
}

// GetCmdNextLockID returns next lock id to be created.
func GetCmdNextLockID() *cobra.Command {
return osmocli.SimpleQueryCmd[*types.NextLockIDRequest](
Expand Down
11 changes: 11 additions & 0 deletions x/lockup/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ func (q Querier) LockedByID(goCtx context.Context, req *types.LockedRequest) (*t
return &types.LockedResponse{Lock: lock}, err
}

// LockRewardReceiver returns lock reward receiver of the lock.
func (q Querier) LockRewardReceiver(goCtx context.Context, req *types.LockRewardReceiverRequest) (*types.LockRewardReceiverResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(goCtx)
rewardReceiver, err := q.Keeper.GetLockRewardReceiver(ctx, req.LockId)
return &types.LockRewardReceiverResponse{RewardReceiver: rewardReceiver}, err
}

// NextLockID returns next lock ID to be created.
func (q Querier) NextLockID(goCtx context.Context, req *types.NextLockIDRequest) (*types.NextLockIDResponse, error) {
if req == nil {
Expand Down
25 changes: 25 additions & 0 deletions x/lockup/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,31 @@ func (s *KeeperTestSuite) TestLockedByID() {
s.Require().Equal(res.Lock.IsUnlocking(), false)
}

func (s *KeeperTestSuite) TestLockRewardReceiver() {
s.SetupTest()
addr1 := sdk.AccAddress([]byte("addr1---------------"))
addr2 := sdk.AccAddress([]byte("addr2---------------"))

// lock coins
coins := sdk.Coins{sdk.NewInt64Coin("stake", 10)}
s.LockTokens(addr1, coins, time.Second)

res, err := s.querier.LockRewardReceiver(sdk.WrapSDKContext(s.Ctx), &types.LockRewardReceiverRequest{LockId: 1})
s.Require().NoError(err)
s.Require().Equal(res.RewardReceiver, addr1.String())

// now change lock reward receiver and then query again
s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, 1, addr1, addr2.String())
res, err = s.querier.LockRewardReceiver(sdk.WrapSDKContext(s.Ctx), &types.LockRewardReceiverRequest{LockId: 1})
s.Require().NoError(err)
s.Require().Equal(res.RewardReceiver, addr2.String())

// try getting lock reward receiver for invalid lock id, this should error
res, err = s.querier.LockRewardReceiver(sdk.WrapSDKContext(s.Ctx), &types.LockRewardReceiverRequest{LockId: 10})
s.Require().Error(err)
s.Require().Equal(res.RewardReceiver, "")
}

func (s *KeeperTestSuite) TestNextLockID() {
s.SetupTest()
addr1 := sdk.AccAddress([]byte("addr1---------------"))
Expand Down
18 changes: 18 additions & 0 deletions x/lockup/keeper/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,24 @@ func (k Keeper) GetLockByID(ctx sdk.Context, lockID uint64) (*types.PeriodLock,
return &lock, err
}

// GetLockRewardReceiver returns the reward receiver stored in state.
// Note that if the lock reward receiver address in state is an empty string literal,
// it indicates that the lock reward receiver is the owner of the lock, thus
// returns the lock owner address.
func (k Keeper) GetLockRewardReceiver(ctx sdk.Context, lockID uint64) (string, error) {
lock, err := k.GetLockByID(ctx, lockID)
if err != nil {
return "", err
}

rewardReceiverAddress := lock.RewardReceiverAddress
if rewardReceiverAddress == "" {
rewardReceiverAddress = lock.Owner
}

return rewardReceiverAddress, nil
}

// GetPeriodLocks Returns the period locks on pool.
func (k Keeper) GetPeriodLocks(ctx sdk.Context) ([]types.PeriodLock, error) {
unlockings := k.getLocksFromIterator(ctx, k.LockIterator(ctx, true))
Expand Down
Loading

0 comments on commit c454fc2

Please sign in to comment.