Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: improve CL KVStore entries #5205

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/ory/dockertest/v3 v3.10.0
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3
github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde069
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230516205127-c213fddde069
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230517204120-4d1778feff33
github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627
github.com/pkg/errors v0.9.1
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,10 @@ github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde06
github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde069/go.mod h1:a7lhiXRpn8QJ21OhFpaEnUNErTSIafaYpp02q6uI/Dk=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230516205127-c213fddde069 h1:9C/n+Nx5rre/AHPMlPsQrk1isgydrCNB68aqer86ygE=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230516205127-c213fddde069/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230517180837-78500ca3f449 h1:2wxCDl2gyE7j2KKa6mlgh74RUT9o435r7wTEnBUJewg=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230517180837-78500ca3f449/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230517204120-4d1778feff33 h1:wYTDdZmyMhAU7bjL6i/YZVj3V15js+4p1Vc5d/jxoj8=
github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230517204120-4d1778feff33/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A=
github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 h1:RIrWLzIiZN5Xd2JOfSOtGZaf6V3qEQYg6EaDTAkMnCo=
github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304/go.mod h1:yPWoJTj5RKrXKUChAicp+G/4Ni/uVEpp27mi/FF/L9c=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627 h1:A0SwZgp4bmJFbivYJc8mmVhMjrr3EdUZluBYFke11+w=
Expand Down
53 changes: 53 additions & 0 deletions osmoutils/store_helper.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package osmoutils

import (
"encoding/binary"
"errors"
"fmt"

Expand Down Expand Up @@ -207,3 +208,55 @@ func Get(store store.KVStore, key []byte, result proto.Message) (found bool, err
}
return true, nil
}

// Uint64SliceToBigEndian marshals a slice of uint64 to a bigendian byte slice
func Uint64SliceToBigEndian(values []uint64) []byte {
b := make([]byte, 8*len(values))
for i, id := range values {
binary.BigEndian.PutUint64(b[i*8:(i+1)*8], id)
}
return b
}

// BigEndianToUint64Slice unmarshals a bigendian byte slice to a slice of uint64
func BigEndianToUint64Slice(b []byte) []uint64 {
ids := make([]uint64, len(b)/8)
for i := 0; i < len(b); i += 8 {
ids[i/8] = binary.BigEndian.Uint64(b[i : i+8])
}
return ids
}

// RemoveFromSlice removes a uint64 value from a slice and returns the new slice.
// It returns an error if the value is not found in the slice.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// It returns an error if the value is not found in the slice.
// It returns an error if the value is not found in the slice.
// The computation cost of this method is O(n) as we linearly iterate over given slice

func RemoveFromSlice(slice []uint64, value uint64) ([]uint64, error) {
index := -1

// Find the index of the value.
for i, v := range slice {
if v == value {
index = i
break
}
}

// If value is not found, return an error.
if index == -1 {
return nil, fmt.Errorf("Value %d not found in slice", value)
}

// Remove the value from the slice.
slice = append(slice[:index], slice[index+1:]...)

return slice, nil
}

// SliceContains returns true if the slice contains the value.
func SliceContains(slice []uint64, value uint64) bool {
for _, v := range slice {
if v == value {
return true
}
}
return false
}
117 changes: 117 additions & 0 deletions osmoutils/store_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package osmoutils_test
import (
"errors"
"fmt"
"reflect"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -1309,3 +1310,119 @@ func (s *TestSuite) TestGetDec() {

}
}

func TestUint64SliceToBigEndianAndBigEndianToUint64Slice(t *testing.T) {
tests := []struct {
name string
in []uint64
}{
{
name: "Test with empty slice",
in: []uint64{},
},
{
name: "Test with one element",
in: []uint64{1},
},
{
name: "Test with multiple elements",
in: []uint64{1, 2, 3, 4},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Convert the []uint64 to []byte
b := osmoutils.Uint64SliceToBigEndian(tt.in)

// Convert the []byte back to []uint64
out := osmoutils.BigEndianToUint64Slice(b)

// Check if the original []uint64 is recovered
if !reflect.DeepEqual(out, tt.in) {
t.Errorf("Uint64SliceToBigEndian and BigEndianToUint64Slice = %v, want %v", out, tt.in)
}
})
}
}

func TestRemoveFromSlice(t *testing.T) {
tests := []struct {
name string
slice []uint64
value uint64
want []uint64
wantErr bool
}{
{
name: "Test with empty slice",
slice: []uint64{},
value: 1,
want: nil,
wantErr: true,
},
{
name: "Test with slice that contains the value",
slice: []uint64{1, 2, 3, 4},
value: 1,
want: []uint64{2, 3, 4},
wantErr: false,
},
{
name: "Test with slice that does not contain the value",
slice: []uint64{1, 2, 3, 4},
value: 5,
want: nil,
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := osmoutils.RemoveFromSlice(tt.slice, tt.value)
if (err != nil) != tt.wantErr {
t.Errorf("RemoveFromSlice() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("RemoveFromSlice() = %v, want %v", got, tt.want)
}
})
}
}

func TestSliceContains(t *testing.T) {
tests := []struct {
name string
slice []uint64
value uint64
want bool
}{
{
name: "Test with empty slice",
slice: []uint64{},
value: 1,
want: false,
},
{
name: "Test with slice that contains the value",
slice: []uint64{1, 2, 3, 4},
value: 1,
want: true,
},
{
name: "Test with slice that does not contain the value",
slice: []uint64{1, 2, 3, 4},
value: 5,
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := osmoutils.SliceContains(tt.slice, tt.value); got != tt.want {
t.Errorf("SliceContains() = %v, want %v", got, tt.want)
}
})
}
}
2 changes: 1 addition & 1 deletion x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (k Keeper) CollectFees(ctx sdk.Context, owner sdk.AccAddress, positionId ui
return k.collectFees(ctx, owner, positionId)
}

func (k Keeper) IsPositionOwner(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, positionId uint64) (bool, error) {
func (k Keeper) IsPositionOwner(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, positionId uint64) bool {
return k.isPositionOwner(ctx, sender, poolId, positionId)
}

Expand Down
5 changes: 1 addition & 4 deletions x/concentrated-liquidity/fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,7 @@ func (k Keeper) collectFees(ctx sdk.Context, sender sdk.AccAddress, positionId u
}

// Fee collector must be the owner of the position.
isOwner, err := k.isPositionOwner(ctx, sender, position.PoolId, positionId)
if err != nil {
return sdk.Coins{}, err
}
isOwner := k.isPositionOwner(ctx, sender, position.PoolId, positionId)
if !isOwner {
return sdk.Coins{}, types.NotPositionOwnerError{Address: sender.String(), PositionId: positionId}
}
Expand Down
6 changes: 1 addition & 5 deletions x/concentrated-liquidity/incentives.go
Original file line number Diff line number Diff line change
Expand Up @@ -898,11 +898,7 @@ func (k Keeper) collectIncentives(ctx sdk.Context, sender sdk.AccAddress, positi
return sdk.Coins{}, sdk.Coins{}, err
}

isOwner, err := k.isPositionOwner(ctx, sender, position.PoolId, positionId)
if err != nil {
return sdk.Coins{}, sdk.Coins{}, err
}

isOwner := k.isPositionOwner(ctx, sender, position.PoolId, positionId)
if !isOwner {
return sdk.Coins{}, sdk.Coins{}, types.NotPositionOwnerError{Address: sender.String(), PositionId: positionId}
}
Expand Down
7 changes: 3 additions & 4 deletions x/concentrated-liquidity/lp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,7 @@ func (s *KeeperTestSuite) TestWithdrawPosition() {
s.Require().ErrorAs(err, &types.PositionIdNotFoundError{PositionId: config.positionId})
s.Require().Equal(clmodel.Position{}, position)

isPositionOwner, err := concentratedLiquidityKeeper.IsPositionOwner(s.Ctx, owner, config.poolId, config.positionId)
s.Require().NoError(err)
isPositionOwner := concentratedLiquidityKeeper.IsPositionOwner(s.Ctx, owner, config.poolId, config.positionId)
s.Require().False(isPositionOwner)

// Since the positionLiquidity is deleted, retrieving it should return an error.
Expand All @@ -664,12 +663,12 @@ func (s *KeeperTestSuite) TestWithdrawPosition() {
s.Require().Equal(model.Position{}, emptyPositionStruct)

// Retrieve the position ID from the store via owner/poolId key and compare to expected values.
ownerPoolIdToPositionIdKey := types.KeyAddressPoolIdPositionId(s.TestAccs[0], defaultPoolId, DefaultPositionId)
ownerPoolIdToPositionIdKey := types.KeyAddressAndPoolId(s.TestAccs[0], defaultPoolId)
positionIdBytes := store.Get(ownerPoolIdToPositionIdKey)
s.Require().Nil(positionIdBytes)

// Retrieve the position ID from the store via poolId key and compare to expected values.
poolIdtoPositionIdKey := types.KeyPoolPositionPositionId(defaultPoolId, DefaultPositionId)
poolIdtoPositionIdKey := types.KeyPoolPosition(defaultPoolId)
positionIdBytes = store.Get(poolIdtoPositionIdKey)
s.Require().Nil(positionIdBytes)

Expand Down
Loading