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

Turnpike/f1 fee distribution #543

Closed
Closed
Show file tree
Hide file tree
Changes from 86 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
a67285d
prototype AfterEpoch
xedonman Sep 23, 2021
dbc93c9
Map gauge to current_reward
nonvis Sep 24, 2021
8ec039f
refactor: Modify TempAfterEpochEnd to F1Distribute which is invoked b…
nonvis Sep 24, 2021
bc45a60
add unlocking accumulation store to get total stake amount
xedonman Sep 24, 2021
fc9f946
Update F1Distribute
lazka33 Sep 27, 2021
90269c8
Change F1Distribute param
lazka33 Sep 27, 2021
eccfe6a
Fix F1Distribute
lazka33 Sep 27, 2021
9d2455b
add reward calculation for locks
xedonman Sep 24, 2021
c1fc823
fix bug in sum total stake
xedonman Sep 28, 2021
30a4673
create periodLockReward in incentive module and replace lock.reward
xedonman Sep 28, 2021
7b5b361
Update params, returns
lazka33 Sep 28, 2021
20a57ae
Implement get/set of CurrentReward
lazka33 Sep 28, 2021
ac50ef2
Implement get/set of HistoricalReward
lazka33 Sep 29, 2021
d748513
fix bug in calculation after epoch
xedonman Sep 29, 2021
52db9e0
Update CalculateHistoricalRewards
lazka33 Sep 29, 2021
5b2df12
Implement get/set of PeriodLockReward
xedonman Sep 29, 2021
7544095
Fix bug iterator getter
lazka33 Oct 1, 2021
62ba4bb
Fix some bugs
lazka33 Oct 1, 2021
a637140
Add a test case for f1_distribution
nonvis Oct 1, 2021
6b6202c
debugging historical reward is not set on locking
xedonman Oct 1, 2021
dc0e878
remove duplicated F1Distrubute test
xedonman Oct 1, 2021
89695bf
add token to lock
xedonman Oct 5, 2021
620d799
move finding iterator for duration to iterator.go
xedonman Oct 5, 2021
4db3b5d
skip gauge reward distribute if locked amount is 0
xedonman Oct 6, 2021
c601bf1
add debug purpose query to show internal
xedonman Oct 5, 2021
1357edd
Add a query to return estimated rewards
nonvis Oct 6, 2021
a99f483
Add a cli query
nonvis Oct 6, 2021
c98a0fb
Automatically find locks associated with an address if they are not g…
nonvis Oct 7, 2021
78b79a3
Implement get reward()
nonvis Oct 7, 2021
df484ee
change PeriodLockReward Period key name
xedonman Oct 6, 2021
f7ac06f
fix total unbonding stake counting
xedonman Oct 6, 2021
2d20556
add debug log for F1 Distribution
xedonman Oct 5, 2021
3a8b103
fix skipping historical reward without initialize
xedonman Oct 7, 2021
0dd2f70
convert reward to dec coin to support large stake
xedonman Oct 8, 2021
271e6d7
Change calculating total locksum
lazka33 Oct 8, 2021
4e46cca
Add GetLocksLongerThanTargetTime test
lazka33 Oct 9, 2021
d2d92f6
Update GetLocksLongerThanTargetTime test
lazka33 Oct 12, 2021
11e00dd
Remove GetLocksLongerThanTargetTime
lazka33 Oct 12, 2021
6fc12ca
add unit test for f1 distribution
xedonman Oct 8, 2021
739d795
Add a test case to trigger new epoch
nonvis Oct 12, 2021
d49d92a
add tx to claim lock reward
xedonman Oct 12, 2021
c2a311e
Use days not weeks to trigger a new epoch for testing
nonvis Oct 13, 2021
4d201fe
Add more test cases
nonvis Oct 13, 2021
15a61a6
Manually call WithdrawAllMaturedLocks for tests
nonvis Oct 13, 2021
9939ea9
fix calculating total stakes for unlocking and notUnlocking
xedonman Oct 13, 2021
13a52f8
Add Unit test
lazka33 Oct 14, 2021
13a553a
Update spec to include f1 distribution
nonvis Oct 14, 2021
d8ebdcc
Add a new spec for f1 distribution
nonvis Oct 14, 2021
011b044
refactor calculate historical reward
xedonman Oct 13, 2021
0cdf7c4
fix wrong reward is calculated when token is locked to existing locks
xedonman Oct 14, 2021
e412d43
include current reward when estimate lock reward
xedonman Oct 14, 2021
a059244
remove unused unlocking period lock accumulation strore
xedonman Oct 15, 2021
96a028a
add partial unlock by lockID and according tx
xedonman Oct 15, 2021
011efeb
Add a test case to lock and unlock using two accounts
nonvis Oct 19, 2021
384e738
revert add tokens to lock function
xedonman Oct 19, 2021
cbe1af6
fix when multiple coins are locked in single lock
xedonman Oct 19, 2021
68477ec
fix bug when unlock is done in epoch end block
xedonman Oct 19, 2021
1529650
Skip calculating historical reward if it does not exist
nonvis Oct 20, 2021
4616d8d
cleanup redundant log and code
xedonman Oct 20, 2021
0bc6dc3
Add panics when hooked function returns error
lazka33 Oct 20, 2021
5a7c406
add coin amount range check in partial unlock
xedonman Oct 20, 2021
d5ded84
rename f1 distribution functions name
xedonman Oct 20, 2021
7b0459a
add spec document for beginPartialUnlockingwq
xedonman Oct 20, 2021
621d0c2
Remove useless log
lazka33 Oct 20, 2021
ce22345
Update spec for f1 distribution
lazka33 Oct 21, 2021
f0457c7
revert change of cosmos sdk version in f1dist
xedonman Oct 21, 2021
f5ec2eb
add error check in f1 distribute
xedonman Oct 21, 2021
08a0256
fix panic in lock on period 0
xedonman Oct 25, 2021
29fec51
fix lint error: unchecked return and format
xedonman Oct 25, 2021
bb36586
divide keys for historicalReward and historicalRewardRef
xedonman Oct 25, 2021
ca8fba4
fix bug in test case
xedonman Oct 25, 2021
d0a10bf
make deterministic map protobuf
xedonman Oct 26, 2021
60e052c
remove redundant set of current reward when not calculated
xedonman Oct 26, 2021
60f5254
fix wrong key was given to period lock reward
xedonman Oct 26, 2021
74c8857
Implement init and export genesis
nonvis Oct 27, 2021
2798ebd
Add more fields to historical_reward and remove unnecessary fields
nonvis Oct 27, 2021
911b3f9
Add examples to estimate and claim rewards
nonvis Oct 27, 2021
218ec85
Add more examples to estimate and claim rewards
nonvis Oct 28, 2021
9df7007
Remove log prints and replaced them with add checkers
nonvis Oct 28, 2021
0b23ba2
add query usage
lazka33 Oct 28, 2021
5c18832
fix period skip issue
lazka33 Oct 28, 2021
f21c894
update BeginPartialUnlocking test
lazka33 Oct 28, 2021
b0aaa0d
add grpc query test for new incentives query
xedonman Oct 28, 2021
6db80ec
remove redundant debug log
xedonman Oct 28, 2021
85f2615
add historical reward for next epoch when gauge is finished
xedonman Oct 29, 2021
0155e64
Add a test case to distribute rewards for an inactive non-perpetual g…
nonvis Oct 29, 2021
a7a907e
fix name and small code from review
xedonman Nov 1, 2021
c2a5e66
refactor: Improve readability
nonvis Nov 1, 2021
7b4b8b8
remove comments for confirmed key names
xedonman Nov 3, 2021
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
13 changes: 7 additions & 6 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,18 +401,19 @@ func NewOsmosisApp(
),
)

app.LockupKeeper = *lockupKeeper.SetHooks(
lockuptypes.NewMultiLockupHooks(
// insert lockup hooks receivers here
),
)

app.IncentivesKeeper = *incentivesKeeper.SetHooks(
incentivestypes.NewMultiIncentiveHooks(
// insert incentive hooks receivers here
),
)

app.LockupKeeper = *lockupKeeper.SetHooks(
lockuptypes.NewMultiLockupHooks(
// insert lockup hooks receivers here
app.IncentivesKeeper.Hooks(),
),
)

app.MintKeeper = *mintKeeper.SetHooks(
minttypes.NewMultiMintHooks(
// insert mint hooks receivers here
Expand Down
40 changes: 39 additions & 1 deletion proto/osmosis/incentives/gauge.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,42 @@ message LockableDurationsInfo {
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"lockable_durations\""
];
}
}

message HistoricalReward {
repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"
];
uint64 period = 2;
uint64 last_eligible_epoch = 3;
}

message CurrentReward {
uint64 period = 1;
int64 last_processed_epoch = 2;
cosmos.base.v1beta1.Coin coin = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"
];
repeated cosmos.base.v1beta1.Coin rewards = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
string denom = 5;
google.protobuf.Duration duration = 6 [
(gogoproto.stdduration) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"duration\""
];
}

message PeriodLockReward {
option (gogoproto.stable_marshaler) = true;
uint64 ID = 1;
map<string, uint64> period = 2;
repeated cosmos.base.v1beta1.Coin rewards = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
9 changes: 9 additions & 0 deletions proto/osmosis/incentives/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ message GenesisState {
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"lockable_durations\""
];
repeated GenesisReward genesis_reward = 4 [ (gogoproto.nullable) = false ];
repeated PeriodLockReward period_lock_reward = 5
[ (gogoproto.nullable) = false ];
}

message GenesisReward {
CurrentReward current_reward = 1 [ (gogoproto.nullable) = false ];
repeated HistoricalReward historical_reward = 2
[ (gogoproto.nullable) = false ];
}
83 changes: 82 additions & 1 deletion proto/osmosis/incentives/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,35 @@ service Query {
option (google.api.http).get =
"/osmosis/incentives/v1beta1/rewards_est/{owner}";
}
// returns current estimate of accumulated rewards
// from both current and historical rewards
rpc Rewards(RewardsRequest) returns (RewardsResponse) {
option (google.api.http).get =
"/osmosis/incentives/v1beta1/rewards/{owner}";
}
// returns lockable durations that are valid to give incentives
rpc LockableDurations(QueryLockableDurationsRequest)
returns (QueryLockableDurationsResponse) {
option (google.api.http).get =
"/osmosis/incentives/v1beta1/lockable_durations";
}

// returns CurrentReward in this epoch
rpc CurrentReward(CurrentRewardRequest) returns (CurrentRewardResponse) {
option (google.api.http).get = "/osmosis/incentives/v1beta1/current_reward";
}
// returns HistoricalReward with given period
rpc HistoricalReward(HistoricalRewardRequest)
returns (HistoricalRewardResponse) {
option (google.api.http).get =
"/osmosis/incentives/v1beta1/historical_reward";
}
// returns PeriodLockReward with given lockID
rpc PeriodLockReward(PeriodLockRewardRequest)
returns (PeriodLockRewardResponse) {
option (google.api.http).get =
"/osmosis/incentives/v1beta1/period_lock_reward";
}
}

message ModuleToDistributeCoinsRequest {}
Expand Down Expand Up @@ -120,11 +143,69 @@ message RewardsEstResponse {
];
}

message RewardsRequest {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
repeated uint64 lock_ids = 2;
}
message RewardsResponse {
repeated cosmos.base.v1beta1.Coin coins = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

message QueryLockableDurationsRequest {}
message QueryLockableDurationsResponse {
repeated google.protobuf.Duration lockable_durations = 1 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"lockable_durations\""
];
}
}

message CurrentRewardRequest {
string denom = 1;
google.protobuf.Duration lockable_durations = 2 [
mattverse marked this conversation as resolved.
Show resolved Hide resolved
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"lockable_durations\""
];
}
message CurrentRewardResponse {
uint64 period = 1;
int64 last_processed_epoch = 2;
cosmos.base.v1beta1.Coin coin = 3 [ (gogoproto.nullable) = false ];
repeated cosmos.base.v1beta1.Coin reward = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

message HistoricalRewardRequest {
string denom = 1;
google.protobuf.Duration lockable_durations = 2 [
mattverse marked this conversation as resolved.
Show resolved Hide resolved
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"lockable_durations\""
];
int64 period = 3;
}
message HistoricalRewardResponse {
repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"
];
uint64 period = 2;
uint64 last_eligible_epoch = 3;
}

message PeriodLockRewardRequest { uint64 id = 1; }
message PeriodLockRewardResponse {
option (gogoproto.stable_marshaler) = true;
uint64 ID = 1;
map<string, uint64> period = 2;
Copy link
Member

Choose a reason for hiding this comment

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

How do these get deserialized into golang? A common problem if its a hashmap is that hashmap iteration is non-deterministic. So typically these get serialized as repeated lists of a (string, uint64) pairs, where that pair is renamed.

Or is the idea that this is a query, not part of the state machine, so its fine? If so, can a comment be added?

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the review. hash map is also used in another data structure. Your point is correct and I will PR with other fixes + queries.

Copy link
Author

Choose a reason for hiding this comment

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

option (gogoproto.stable_marshaler) = true;
above line is added to message using maps to secure iteration order and contiguous memory usage

repeated cosmos.base.v1beta1.Coin rewards = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
14 changes: 14 additions & 0 deletions proto/osmosis/incentives/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ option go_package = "github.com/osmosis-labs/osmosis/x/incentives/types";
service Msg {
rpc CreateGauge(MsgCreateGauge) returns (MsgCreateGaugeResponse);
rpc AddToGauge(MsgAddToGauge) returns (MsgAddToGaugeResponse);
rpc ClaimLockReward(MsgClaimLockReward) returns (MsgClaimLockRewardResponse);
rpc ClaimLockRewardAll(MsgClaimLockRewardAll)
returns (MsgClaimLockRewardResponseAll);
}

message MsgCreateGauge {
Expand Down Expand Up @@ -44,3 +47,14 @@ message MsgAddToGauge {
];
}
message MsgAddToGaugeResponse {}

message MsgClaimLockReward {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
uint64 ID = 2;
}
message MsgClaimLockRewardResponse {}

message MsgClaimLockRewardAll {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
}
message MsgClaimLockRewardResponseAll {}
14 changes: 14 additions & 0 deletions proto/osmosis/lockup/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ service Msg {
returns (MsgBeginUnlockingAllResponse);
// MsgBeginUnlocking begins unlocking tokens by lock ID
rpc BeginUnlocking(MsgBeginUnlocking) returns (MsgBeginUnlockingResponse);
// MsgBeginPartialUnlocking begins unlocking partial amount of tokens by lock
// ID
rpc BeginPartialUnlocking(MsgBeginPartialUnlocking)
returns (MsgBeginPartialUnlockingResponse);
}

message MsgLockTokens {
Expand Down Expand Up @@ -44,3 +48,13 @@ message MsgBeginUnlocking {
uint64 ID = 2;
}
message MsgBeginUnlockingResponse { bool success = 1; }

message MsgBeginPartialUnlocking {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
uint64 ID = 2;
repeated cosmos.base.v1beta1.Coin coins = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
message MsgBeginPartialUnlockingResponse { bool success = 1; }
23 changes: 23 additions & 0 deletions x/incentives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,26 @@ MsgAddToGauge:
```bash
osmosisd tx incentives add-to-gauge $GAUGE_ID 500MyToken
```


## Estimating and Claiming Rewards

The accumulated rewards can be estimated and claimed.

### Examples

```bash
# estimate rewards for validator with a list of lock IDs
osmosisd query incentives rewards $(osmosisd keys show -a validator --keyring-backend=test) \
--lock-ids [lock ids]

# estimate rewards for validator (automatically finds all lock IDs associated with validator)
osmosisd query incentives rewards $(osmosisd keys show -a validator --keyring-backend=test) \

# claim rewards for a specific lock
osmosisd tx incentives claim-lock-reward [lock_id] --from=validator --keyring-backend=test

# claim rewards for all locks
osmosisd tx incentives claim-lock-reward-all --from=validator --keyring-backend=test

```
9 changes: 9 additions & 0 deletions x/incentives/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ func TestNonPerpetualGaugeExpireAfterDistribution(t *testing.T) {
_, err = app.IncentivesKeeper.CreateGauge(ctx, false, addr, coins, distrTo, time.Now(), 1)
require.NoError(t, err)

// lock with balance
addr1 := sdk.AccAddress([]byte("addr1---------------"))
coins = sdk.Coins{sdk.NewInt64Coin(distrTo.Denom, 10)}
lock := lockuptypes.NewPeriodLock(1, addr1, time.Second, time.Time{}, coins)
err = app.BankKeeper.SetBalances(ctx, addr, coins)
require.NoError(t, err)
err = app.LockupKeeper.Lock(ctx, lock)
require.NoError(t, err)

params := app.IncentivesKeeper.GetParams(ctx)
futureCtx := ctx.WithBlockTime(time.Now().Add(time.Minute))
app.EpochsKeeper.BeforeEpochStart(futureCtx, params.DistrEpochIdentifier, 1)
Expand Down
Loading