Skip to content

Create an Active Participation and Engagement incentive module #627

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

Closed
43 of 50 tasks
iramiller opened this issue Jan 28, 2022 · 1 comment · Fixed by #930
Closed
43 of 50 tasks

Create an Active Participation and Engagement incentive module #627

iramiller opened this issue Jan 28, 2022 · 1 comment · Fixed by #930
Assignees
Labels
enhancement New feature or request incentive Incentive distribution module
Milestone

Comments

@iramiller
Copy link
Member

iramiller commented Jan 28, 2022

Summary

Create a new blockchain module that performs epoch based rewards distribution using a configurable share from the community pool to an eligible pool of addresses based on their on-chain activities during the period.

Problem Definition

One of the major challenges for a growing blockchain is the distribution of incentives to the right collection of accounts to drive interest and engagement in the platform. While a proof of stake blockchain typically has a comprehensive distribution system based on delegations, this rewards system primarily benefits passive participation. The Incentive module design targets active network participants for reward distribution by monitoring their activities and allocating distribution shares accordingly.

Proposal

Create an Incentive module that supports distribution of rewards per epoch using shares. The module should be built in a way that is extensible and flexible for different distribution strategies.

Any account can create a new incentive program by providing funding and a set of configuration that includes the epochs to fund over, eligibility criteria, and a list of activity detectors and their weights.

In addition to direct funding through creation of incentive programs a community funding program can be configured via governance control which uses the community funding pool as a source of funds to distribute.

End Block Processing

The processing pipeline of the module end block should be based on 4 stages:

  1. Determine the incentive opportunity detectors to use for the current epoch
  2. Identify events within the event manager history (Add support for event data injection into end block handlers #626) that represent incentive opportunities for an address, include a distribution weight factor and a source pool
  3. For each incentive opportunity, filter based on eligibility criteria required for the incentive.
  4. Update the epoch shares distribution for each address

At the end of a given epoch the module should determine the total funds to distribute from each funding source and split these amounts across the total number of shares allocated in the period (share-value). Using this share-value the module should send a payment to each address in the amount of ( shares-accrued * share-value ). When this is complete the epoch records should be cleared in preparation for the next period.

Basic Parameters (Governance Control)

  • Epoch duration (blocks) - This is the length of the repeating epoch period measured in blocks
  • Community pool accrual tax rate - This is the share of the accrued community funds to collected during the epoch to distribution (as a percentage)

Incentives

Governance proposals should be used to configure the incentive opportunities available for a given epoch. Incentive opportunities have a defined period, eligibility criteria, and funding source.

Eligibility criteria examples

  • Account has transactions during period
  • Account has active delegations (threshold?)
  • Account maintains a balance of funds

Example 1.

The community pool funds are allocated for a perpetual incentive program. At the start of a given epoch the amount of funds within the community pool are recorded. At the end of the epoch the accrued funds during the period are computed, this amount is split based on the community pool tax rate to result in a funding amount for distribution.

  • During the course of the epoch at the end of each block the events of the block are processed against a list of incentive-opportunity detectors. The list of these detectors is kept in the configuration for the community distribution (`opp1, opp2, opp5, etc).
  • The results of these detections are a pairs of address, shares. These pairs are filtered by processing against a list of eligibility criteria functions, again by name min-balance, delegation-amounts, etc.
  • Remaining address, share amounts after the eligibility filters have been applied are recorded, any existing share amounts are summed with the new share
  • At the end of the epoch the funding will be distributed the funding equally across each share with each address being paid out according to the number of shares accrued.

Example 2.

A user with 100M in token decides to create an incentive for relaying IBC transactions. They submit a new incentive program request with their funding and include eligibility criteria of "records IBC tx". During the course of the epoch each time an address records a transaction relay they will accrue a share of the incentive pool. At the end of the epoch the total funding divided by the number of epochs the program runs will result in an allocation that is distributed to each eligible address based on their share.

In this way 100M token could be split across 100 epochs such that the relayers are paid a portion of the 1M per epoch according to their contribution as a share of the relayed transactions they recorded.

Example 3.

A validator incentive program is defined as a validator being online during a period with a minimal amount of downtime allowed. If the epoch is 1000 blocks long then a simple incentive-opportunity detector can be defined with a negative weight greater than 1000 that occurs if the downtime fault is detected. At the end of the epoch if the share count for an address is greater than zero the validator address gets paid, otherwise their reward is forfeit.

Sub-tasks


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@iramiller iramiller added enhancement New feature or request incentive Incentive distribution module labels Jan 28, 2022
@iramiller iramiller added this to the v1.9.0 milestone Jan 28, 2022
@iramiller iramiller changed the title Create an active participation incentive distribution module (draft) Create an Active Participation and Engagement incentive module (draft) Feb 3, 2022
@iramiller
Copy link
Member Author

Given the Epoch duration will need to be adjustable to optimize the processing time and data accrued it is reasonable to presume that reward shares will need to have a lifecycle independent of the epochs...

For example if an address earn a share that share may have a lifespan of 100,000 blocks while the epochs may have a duration of 1000 blocks for performance purposes.

As a related constraint the number of shares or the total benefit rewards might be subject to limits to prevent a few addresses from claiming an outsized amount of the reward pool due to limited participation (for example early in the program) or an outsized amount of activity that might result from spamming the network with transactions.

@iramiller iramiller changed the title Create an Active Participation and Engagement incentive module (draft) Create an Active Participation and Engagement incentive module Mar 15, 2022
@iramiller iramiller moved this from Todo to In Progress in Provenance Core Protocol Team Apr 11, 2022
@nullpointer0x00 nullpointer0x00 self-assigned this Jul 22, 2022
iramiller added a commit that referenced this issue Sep 15, 2022
* big fix to iterator for IterateAllRewardAccountStates for QueryRewardDistributionsByAddress.

* Finished concepts for spec documents.

* Updated and fixed documentation for state transitions.

* Adding msg_service_router_test test for fecthing QueryRewardDistributionsByAddress query.

* Updated the events document for the module.

* Removed params.md

* MOAR tests.

* Updated messages.md

* Updated the documentation for state transitions to more closely match what happens in code.

* fix tests to output json

* refactor tests

* adding action map to New metod for RewardAccount, linter fixes.

* adding cli_test for QueryRewardsByAddress.

* Finished the queries portion part of the spec.

* Updated links in messages.

* Added TOC to messages and updated some names.

* Added TOC to queries.

* Fixed ordering header.

* Added responses for transactions.

* Removed useless parens.

* Added genesis documentation.

* change from little endian to big

* remove unused key functions

* adding query_server tests and adding error to GetRewardsProgram for rewards program not found.

* linter fixes.

* change keys to bigendian, refactor names, remove unused, add test

* Updated state documentation for the module.

* Updated README.

* Clarified a few points.

* tests which pass but can be made to fail.

* Fixed some linting issues on the protofiles.

* Pointing to new tag that is based off of pio-2-ape-rewards-3. It's just renamed.

* Adding the AccountStateAddressLookupKey and associated tests.

* change error message text, remove old epoch error message

* Updated swagger documentation.

* Added comments to fields to document them.

* Updated documentation for all proto files so swagger can detect the comments. Updated non swagger protos to make it all consistent.

* Forogt to update file.

* added index to fetch reward accounts by said index, changed query methos added tests.

* linter fixes.

* add new module store on upgrade

* Moving Claim All rewards to a more efficient address lookup index.

* set of proto-lint fixes

* add missing change

* fixing missing object from rename.

* finish proto lint, updated enum names, added comments

* fix a few go lint issues

* prealloc arrays, fix variable naming

* linter fix.

* Revert "Update metadata module to properly manage authz grants. (#911)"

This reverts commit a9da07d.

* revert merge from main

* add compile time sdk.msg to msgs

* Add unit tests for IsEndingClaimPeriod (#980)

Co-authored-by: Jazz <>

* adding operations tests for simulations of rewards.

* fixing outdated enum in tests.

* Fixed cli args for GetRewardByAddress. It must have 2 args and the documentation was improved.

* Removed linting errors.

* Test commit for coverage. Want to verify coverage is updated.

* Fix error logs and remove NOTICE

* remove notices, remove logging in end/begin blocker

* Added test for additional code coverage.

* Added tests for invalid id formats for QueryClaimPeriodRewardDistributionAll

* remove more notices

* Added test for query claim period reward distributions to test invalid program id and claim period id.

* Added additional coverage tests for QueryAllRewards. Found and fixed a bug that didn't compare claim state correctly.

* Fixed another bug with GetRewardsByAddress. The default case for query type was all, meaning invalid query types would give back all rewards instead of throwing an error.

* fixing decoder for sim tests.

* add reward program id to genesis

* reward program key now not using strconv.

* update protos, fix spelling error, utc times in create reward program

* Removed duplicate enum and just use the one on the RewardAccountState.

* add genesis validate tests, update program id key test

* passing test for sim-nondeterminism

* Added more coverage for add reward program.

* adding operation sim tests and more clean up of module.go

* Added tests for EndRewardProgram. Also added error types.

* Added tests for claim reward distribution keeper methods.

* added end program operation for simulation tests.

* add a few tests and update comments

* fix lint errors

* fix test

* fixing linter on sim tests.

* Updated simtests so they pass. Need a second pair of eyes to verify that this is how the test should be handled.

* minor fixes from the ide.

* golang 1.18 linter fixes.

* fix linter for 1.18

* change key addresses from string to sdk.AccAddress, remove unused method, update tests, remove printlns

* updating documentation for protos.

* Added tests for EndRewardProgramRequest.

* Removed logging of events.

* Added test for invalid address on Query Rewards for Address.

* Updated test to better test output.

* more refined tests.

* Added tests for GetRewardProgramID and GetNextRewardProgramID

* Added error test for iterate abci events.

* Added tests for GetDistributionKeeper and GetAccountKeeper.

* reducing sleep on some claim period tests and adding additional checks.

* updating branch to pio cosmos release fork

* more test documentation.

* more test changes.

* updating third proto so that the proto check passes and more test

* correcting some comments in the protos.

* add constraint for maximum actions must be greater than 0

* proto docs.

* refactor validatebasic to validate for non msg types, add tests

* simple test renames

* minor documentation changes and fixing use of deprecated methods in tests.

* removing migrator and cleaning up un necessary code.

* added small comment on keeper struct mixing value and pointers reciever, pointer receiver is only used is tests, so shuld be fine.

* removing some dead code.

* Adding test for ClaimAllRewards, fixed bug 1. ClaimAllRewardTx should return an error, else there maybe incomplete commit to the state store bug 2. Expired rewward programs should be excluded from all claims, becuase they are essentially non claimable.

* Moving rewarid program id length  and claim period id to constants so that when used for deriving keys, they are all consistent, adding test for parsing lookup keys.

* reevrting messed up merge from main.

* updating comments based on code review.

* adding checks to parse  and make sure return object is correct.

* adding test so that the accountkeeper actually see's account balances beign credited.

* allowing all denoms, and removing all hard coded values for assuming all rewards pool would be in nhash only.

* fixing more tests.

* fixing more tests.

* fixing more tests.

* Removed SetRewardProgramEvent.

* test for rewards running in different denoms and being claimed.. changed doc for minimum_rollover_amount

* updating doc link.

* making min rollover amount to be 10% of claim distribution amount.

* Updated documentation to mention the new minimum rollover amount.

* Renamed tt to tc.

* Removed IsValid check and just use the Validate method on ClaimPeriodRewardDistribution.

* Removed mixing of numbered and non-numbered identifiers.

* Updated tests to make use of Len, Greater, GreaterOrEqual.

* removing alias for provenancconfig and removing wasmKeeper from SimulationManager.

* add pagination to reward program query

* add pagination flags to cli for reward program

* Added test helpers for containsEvent and containsEventWithAttributes.

* moving import to other provenance imports.

* fix cli example

* remove an indent

* change test check to error equals

* more change test check to error equals

* refactor test case struct

* refactor expected id checks

* test refactor from True to Contains

* import clean up

* Fixed comments to be consistent with rest of module.

* Removed the yaml tags and jsontags. By default protobuf serializes to snake case.

* use proto stringer instead of yaml

* Removing unnecessary keys, and changing the decoder based on code review comments.

* Update x/reward/types/reward.go

Co-authored-by: Daniel Wedul <[email protected]>

* code review comments changes,

* Added static compile check for ActionBuilder interface.

* Updated the TOC in genesis spec.

* Renamed suite to s in test functions.

* Removed the SetupTest in reward claim tests.

* Grouped imports in rules.go

* Removed logging of events.

* Changed for loop to for each loop with range events.

* Changed True assert to Equal assert. Equal prints out more information and already does a deepEquals.

* remove custom pagination and follow sdk pattern

* fix lint issue of if to switch

* Adding code comments to the keeper methods as per code review comments.

* fixing broken linter.

* Adding code comments to the keeper methods as per code review comments.

* Update x/reward/keeper/time_management.go

Co-authored-by: Daniel Wedul <[email protected]>

* Added store keys to the documentation.

* On iterating through reward programs, logging error and continuing rather than returning error, as per code review suggestion.

* fix accumulate statement

* removing deprectaed sdkerrors.Wrap from reward module.

* removing unnecessary s.SetupTest()

* moving acculuate to only where append is used for FilteredPaginate.

* Fixing spec for AccountStateAddressLookupKeyPrefix to specify address lenght is stored as first byte.

* I suck fixing unreachable return.

* fixing another place where address size was mentioned as 8

* Fixed accumulate issue.

* Minor fix to accumulate so it always returns true on matches and doesn't depend on accumulate.

* Fixed typo in get reward program command.

* Fixed 'there' typo.

* Fixed Note in wrong location.

* Fixed TOC on state transitions.

* Ran make-toc and updated 02_state overview.

* Updated and organized imports.

* Updated proto to remove last yaml.

* Removed all SetupTest calls from tests.

* Renamed suite to s in keeper_test.

* Renamed suite to s in msg_server_test.

* Renamed suite to s in msg_server_test.

* Renamed suite to s in reward_account_state.

* Renamed suite to s in reward_program_test.

* Renamed suite to s in rules_test.go

* Renamed suite to s in time_management.

* Renamed suite to s in operations_test.

* Removed duplicate suite runner.

* Rewrote ClaimAllRewards to not write while using the iterator.

* Fixed linting issues.

* Changed the order of reward program id and claim period reward distribution in the key. It makes more sense to have the reward program first.

* Changed the order of append in ClaimPeriodRewardDistribution. Previously changed variable definition and not append.

* Fixed tests for key ordering.

* Fixed tests to have name params.

* Added missing function comments in msg_server

* Added missing function comments in query_server.

* Added missing function comments in reward_account_state.

* Add some function comments.

* Moved cosmos imports to be near each other.

* Grouped misc imports.

* Renamed GetOutstandingRewardPrograms to GetAllOutstandingRewardPrograms.

* Returning error on canBuild impl for TransferAction.

* Changing map in proto to a message array, since map ser/deser determinism is questionable.

* Updated proto and swagger documentation to be consistent with the rest of the project.

* Updated documentation for state spec.

* Updated links in specs.

Co-authored-by: Matthew Witkowski <[email protected]>
Co-authored-by: Carlton N Hanna <[email protected]>
Co-authored-by: llama-del-rey <[email protected]>
Co-authored-by: Daniel Wedul <[email protected]>
Co-authored-by: Ira Miller <[email protected]>
Repository owner moved this from In Progress to Done in Provenance Core Protocol Team Sep 15, 2022
@iramiller iramiller moved this from Done to Archive in Provenance Core Protocol Team Sep 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request incentive Incentive distribution module
Projects
Development

Successfully merging a pull request may close this issue.

5 participants