Skip to content

Commit

Permalink
Dev/sum tree reward apply (osmosis-labs#200)
Browse files Browse the repository at this point in the history
* lock module integration in progress

* add getaccumulation

* Add map from denom to pot IDs

* apply to reward estimation logic

* Fix bugs / clarify logic in FilteredLocksDistributionEst

* Remove pots arg to GetRewardsEst, add expected keeper

* Update query proto

* Correct GetRewardsEst behavior

Co-authored-by: mconcat <[email protected]>
  • Loading branch information
ValarDragon and mconcat authored May 28, 2021
1 parent 1218e92 commit 849592f
Show file tree
Hide file tree
Showing 18 changed files with 245 additions and 191 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/osmosis-labs/osmosis
go 1.15

require (
github.com/cosmos/cosmos-sdk v0.42.4
github.com/cosmos/cosmos-sdk v0.42.5
github.com/cosmos/iavl v0.15.3
github.com/gogo/protobuf v1.3.3
github.com/golang/mock v1.4.4
Expand Down
3 changes: 2 additions & 1 deletion proto/osmosis/gamm/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ service Query {
rpc SpotPrice(QuerySpotPriceRequest) returns (QuerySpotPriceResponse) {
option (google.api.http).get = "/osmosis/gamm/v1beta1/{poolId}/prices";
}
rpc TotalLiquidity(QueryTotalLiquidityRequest) returns (QueryTotalLiquidityResponse) {
rpc TotalLiquidity(QueryTotalLiquidityRequest)
returns (QueryTotalLiquidityResponse) {
option (google.api.http).get = "/osmosis/gamm/v1beta1/total_liquidity";
}

Expand Down
7 changes: 4 additions & 3 deletions proto/osmosis/incentives/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ service Query {
rpc ActivePots(ActivePotsRequest) returns (ActivePotsResponse);
// returns scheduled pots
rpc UpcomingPots(UpcomingPotsRequest) returns (UpcomingPotsResponse);
// returns rewards estimation at a future specific time
// RewardsEst returns an estimate of the rewards at a future specific time.
// The querier either provides an address or a set of locks
// for which they want to find the associated rewards.
rpc RewardsEst(RewardsEstRequest) returns (RewardsEstResponse);
}

Expand Down Expand Up @@ -82,8 +84,7 @@ message UpcomingPotsResponse {
message RewardsEstRequest {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
repeated lockup.PeriodLock locks = 2 [ (gogoproto.nullable) = false ];
repeated Pot pots = 3 [ (gogoproto.nullable) = false ];
int64 end_epoch = 4;
int64 end_epoch = 3;
}
message RewardsEstResponse {
repeated cosmos.base.v1beta1.Coin coins = 1 [
Expand Down
5 changes: 3 additions & 2 deletions proto/osmosis/mint/v1beta1/mint.proto
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ message Params {
DistributionProportions distribution_proportions = 6
[ (gogoproto.nullable) = false ];
// address to receive developer rewards
string developer_rewards_receiver = 7 [ (gogoproto.moretags) = "yaml:\"developer_rewards_receiver\"" ];
string developer_rewards_receiver = 7
[ (gogoproto.moretags) = "yaml:\"developer_rewards_receiver\"" ];
// start time to distribute minting rewards
google.protobuf.Timestamp minting_rewards_distribution_start_time = 8 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"minting_rewards_distribution_start_time\""
(gogoproto.moretags) = "yaml:\"minting_rewards_distribution_start_time\""
];
}
41 changes: 22 additions & 19 deletions store/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/binary"
"encoding/json"

sdk "github.com/cosmos/cosmos-sdk/types"
store "github.com/cosmos/cosmos-sdk/store"
stypes "github.com/cosmos/cosmos-sdk/store/types"
)
Expand All @@ -23,7 +24,7 @@ type Tree struct {

func NewTree(store store.KVStore, m uint8) Tree {
tree := Tree{store, m}
tree.Set(nil, 0)
tree.Set(nil, sdk.ZeroInt())
return tree
}

Expand Down Expand Up @@ -69,7 +70,7 @@ func (node *node) set(children children) {
node.tree.store.Set(node.tree.nodeKey(node.level, node.key), bz)
}

func (node *node) setLeaf(acc uint64) {
func (node *node) setLeaf(acc sdk.Int) {
if node.level != 0 {
panic("setLeaf should not be called on branch node")
}
Expand Down Expand Up @@ -229,7 +230,7 @@ func (node *node) pull(key []byte) {

type child struct {
Index []byte
Acc uint64
Acc sdk.Int
}

type children []child // max length M slice of key bytes, sorted by index
Expand All @@ -238,9 +239,10 @@ func (children children) key() []byte {
return children[0].Index
}

func (children children) accumulate() (res uint64) {
func (children children) accumulate() (res sdk.Int) {
res = sdk.ZeroInt()
for _, child := range children {
res += child.Acc
res = res.Add(child.Acc)
}
return
}
Expand All @@ -267,7 +269,7 @@ func (children children) set(idx int, child child) children {
return children
}

func (children children) setAcc(idx int, acc uint64) children {
func (children children) setAcc(idx int, acc sdk.Int) children {
children[idx] = child{children[idx].Index, acc}
return children
}
Expand Down Expand Up @@ -318,10 +320,10 @@ func (t Tree) root() *node {
}
}

func (t Tree) Get(key []byte) (res uint64) {
func (t Tree) Get(key []byte) (res sdk.Int) {
keybz := t.leafKey(key)
if !t.store.Has(keybz) {
return 0
return sdk.ZeroInt()
}
err := json.Unmarshal(t.store.Get(keybz), &res)
if err != nil {
Expand Down Expand Up @@ -384,7 +386,7 @@ func (t Tree) ReverseIterator(begin, end []byte) store.Iterator {
return t.nodeReverseIterator(0, begin, end)
}

func (t Tree) Set(key []byte, acc uint64) {
func (t Tree) Set(key []byte, acc sdk.Int) {
node := t.nodeGet(0, key)
node.setLeaf(acc)

Expand All @@ -401,7 +403,8 @@ func (t Tree) Remove(key []byte) {
parent.pull(key)
}

func (node *node) accSplit(key []byte) (left uint64, exact uint64, right uint64) {
func (node *node) accSplit(key []byte) (left sdk.Int, exact sdk.Int, right sdk.Int) {
left, exact, right = sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt()
if node.level == 0 {
var err error
bz := node.tree.store.Get(node.tree.leafKey(node.key))
Expand All @@ -425,30 +428,30 @@ func (node *node) accSplit(key []byte) (left uint64, exact uint64, right uint64)
idx--
}
left, exact, right = node.tree.nodeGet(node.level-1, children[idx].Index).accSplit(key)
left += children[:idx].accumulate()
right += children[idx+1:].accumulate()
left = left.Add(children[:idx].accumulate())
right = right.Add(children[idx+1:].accumulate())
return
}

func (t Tree) SplitAcc(key []byte) (uint64, uint64, uint64) {
func (t Tree) SplitAcc(key []byte) (sdk.Int, sdk.Int, sdk.Int) {
return t.root().accSplit(key)
}

func (t Tree) SliceAcc(start []byte, end []byte) uint64 {
func (t Tree) SliceAcc(start []byte, end []byte) sdk.Int {
if start == nil {
left, exact, _ := t.root().accSplit(end)
return left + exact
return left.Add(exact)
}
if end == nil {
_, exact, right := t.root().accSplit(start)
return exact + right
return exact.Add(right)
}
_, leftexact, leftrest := t.root().accSplit(start)
_, _, rightest := t.root().accSplit(end)
return leftexact + leftrest - rightest
return leftexact.Add(leftrest).Sub(rightest)
}

func (node *node) visualize(depth int, acc uint64) {
func (node *node) visualize(depth int, acc sdk.Int) {
if !node.exists() {
return
}
Expand All @@ -464,5 +467,5 @@ func (node *node) visualize(depth int, acc uint64) {
}

func (t Tree) DebugVisualize() {
t.root().visualize(0, 0)
t.root().visualize(0, sdk.ZeroInt())
}
19 changes: 10 additions & 9 deletions store/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

dbm "github.com/tendermint/tm-db"

sdk "github.com/cosmos/cosmos-sdk/types"
iavlstore "github.com/cosmos/cosmos-sdk/store/iavl"

"github.com/osmosis-labs/osmosis/store"
Expand Down Expand Up @@ -71,7 +72,7 @@ func (suite *TreeTestSuite) TestTreeInvariants() {
suite.SetupTest()

pairs := pairs{pair{[]byte("hello"), 100}}
suite.tree.Set([]byte("hello"), 100)
suite.tree.Set([]byte("hello"), sdk.NewIntFromUint64(100))

// tested up to 2000
for i := 0; i < 500; i++ {
Expand All @@ -91,21 +92,21 @@ func (suite *TreeTestSuite) TestTreeInvariants() {
pairs = append(pairs, pair{key, value})
}

suite.tree.Set(key, value)
suite.tree.Set(key, sdk.NewIntFromUint64(value))

// check all is right
for _, pair := range pairs {
suite.Require().Equal(suite.tree.Get(pair.key), pair.value)
suite.Require().Equal(suite.tree.Get(pair.key).Uint64(), pair.value)
// XXX: check all branch nodes
}

// check accumulation calc is alright
left, exact, right := uint64(0), pairs[0].value, pairs[1:].sum()
for idx, pair := range pairs {
tleft, texact, tright := suite.tree.SplitAcc(pair.key)
suite.Require().Equal(left, tleft)
suite.Require().Equal(exact, texact)
suite.Require().Equal(right, tright)
suite.Require().Equal(left, tleft.Uint64())
suite.Require().Equal(exact, texact.Uint64())
suite.Require().Equal(right, tright.Uint64())

key := append(pair.key, 0x00)
if idx == len(pairs)-1 {
Expand All @@ -116,9 +117,9 @@ func (suite *TreeTestSuite) TestTreeInvariants() {
}

tleft, texact, tright = suite.tree.SplitAcc(key)
suite.Require().Equal(left+exact, tleft)
suite.Require().Equal(uint64(0), texact)
suite.Require().Equal(right, tright)
suite.Require().Equal(left+exact, tleft.Uint64())
suite.Require().Equal(uint64(0), texact.Uint64())
suite.Require().Equal(right, tright.Uint64())

left += exact
exact = pairs[idx+1].value
Expand Down
2 changes: 1 addition & 1 deletion x/incentives/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,5 @@ func (k Keeper) RewardsEst(goCtx context.Context, req *types.RewardsEstRequest)
if err != nil {
return nil, err
}
return &types.RewardsEstResponse{Coins: k.GetRewardsEst(ctx, owner, req.Locks, req.Pots, req.EndEpoch)}, nil
return &types.RewardsEstResponse{Coins: k.GetRewardsEst(ctx, owner, req.Locks, req.EndEpoch)}, nil
}
Loading

0 comments on commit 849592f

Please sign in to comment.