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

Predict when the next reward will be farmed #161

Closed
wants to merge 32 commits into from
Closed

Predict when the next reward will be farmed #161

wants to merge 32 commits into from

Conversation

abhi3700
Copy link

@abhi3700 abhi3700 commented Mar 14, 2024

Background

The issue titled "Predict when the next reward will be farmed" discusses the potential to provide users (farmers) with predictions on when they can expect to receive rewards based on on-chain data regarding space pledged and the last farming reward payment timestamp. This prediction could then be displayed to the user as having a high/low probability of receiving a reward with descriptions like "today", "in about an hour", or "any time now".

Description

So, this PR adds the feature to calculate the expected time in getting the next reward (block/vote) as a part of backend.

The calculation is based on the amount of one's space pledged and total space pledged & time elapsed since the last reward timestamp.

If there is no reward payout yet, then we the current timestamp is multiplied with the inverse of contribution ratio, where contribution_ratio = total_space_pledged/space_pledged.

Details on Notion.

image

There are 2 main functions:

Appendix

Here, the challenge is to fetch the current solution range, runtime constants like Slot probability.
Initially, I attempted with graphql, but due to the fact that it always lags behind 10 blocks in realtime data fetching, so switched to RPC approach using subxt crate. And then I finally switched to runtime API call as the former added technical debt.

As of 02c8c7a, the 3rd approach is implemented.

The 4th approach is:

  • to get the total_space_pledged directly as runtime constants without any calculation.

@abhi3700 abhi3700 added the backend Backend logic label Mar 14, 2024
@abhi3700 abhi3700 self-assigned this Mar 14, 2024
@abhi3700 abhi3700 requested a review from nazar-pc March 14, 2024 00:59
@abhi3700 abhi3700 linked an issue Mar 14, 2024 that may be closed by this pull request
Copy link
Member

@nazar-pc nazar-pc left a comment

Choose a reason for hiding this comment

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

Also this seems to be some WIP version of the PR due to #[allow(dead_code)] and no UI changes

Cargo.toml Outdated Show resolved Hide resolved
@abhi3700
Copy link
Author

abhi3700 commented Mar 15, 2024

As of now, removed RPC based code (done previously using subxtcrate). Instead I replaced with runtime API call fetching current solution range value. And then calculated total_space_pledged. Pushed the code in this branch.

In order to get the total_space_pledged value directly, I pushed changes to subspace::add-tsp-runtime-api branch to declare & implement runtime APIs to subspace-runtime.
If the runtime_api implementation is correct, then I can directly access the total_space_pledged without any calculations like this:

client
        .runtime_api()
        .get_total_space_pledged(block_hash)
        .expect("Failed to get total space pledged");

replacing this

@abhi3700 abhi3700 changed the title Predict when the next reward will be farmed Predict when the next reward will be farmed (Backend) Mar 15, 2024
Copy link
Member

@nazar-pc nazar-pc left a comment

Choose a reason for hiding this comment

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

Overall this is closer to what it should be, but there are unrelated changes in the lock file for some reason and frontend is still missing (I see you renamed the PR, but it needs to be shipped together).

In order to get the total_space_pledged value directly, I pushed changes to subspace::add-tsp-runtime-api branch to declare & implement runtime APIs to subspace-runtime.
If the runtime_api implementation is correct, then I can directly access the total_space_pledged without any calculations like this:

That will only work for fully upgraded runtime, not for older runtimes of Gemini 3h. Also as I repeated a few times already, the whole thing is a runtime constant, did you look into a way to query runtime constants are all?

src/backend/node.rs Outdated Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
src/backend/node.rs Outdated Show resolved Hide resolved
src/backend/node.rs Outdated Show resolved Hide resolved
abhi3700 added a commit that referenced this pull request Mar 18, 2024
- Sorted sp-api alphabetically
- Synced '[profile.dev.package]' from 'main' branch
- Reverted 'total_space_pledged' formula to original one
- Added snippet to fetch SLOT_PROBABILITY from runtime api client directly. TODO: uncomment later.
@abhi3700
Copy link
Author

abhi3700 commented Mar 18, 2024

....did you look into a way to query runtime constants are all?

I searched in substrate docs, paritytech docs for sp-api, etc. But couldn't find a way to query the runtime constants.
Everywhere, it was mentioned either to use RPC (via subxt) to get the runtime constant or expose the constant as a function to runtime_api, hence upgrade the runtime.

Copy link
Member

@nazar-pc nazar-pc left a comment

Choose a reason for hiding this comment

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

I searched in substrate docs, paritytech docs for sp-api, etc. But couldn't find a way to query the runtime constants.

Not everything in Substrate is well documented, but since RPC does it, there is a way to query it. Not critical though.

Cargo.toml Outdated Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
src/backend/utils.rs Outdated Show resolved Hide resolved
src/backend/node.rs Outdated Show resolved Hide resolved
src/backend/utils.rs Outdated Show resolved Hide resolved
@abhi3700
Copy link
Author

abhi3700 commented Mar 18, 2024

In terms of frontend, do you think this would look nice here?

The green-colored text.

image

💭 Should we attach the webpage url as well, that shows rewards distributed to all the addresses?..may be block no. or so where the rewards were distributed. I guess that would require querying the synced node 🤔 .

@nazar-pc
Copy link
Member

In terms of frontend, do you think this would look nice here?

Hard to say, but for sure not where the green text for sure. That whole area is for farms and has scrolling. Should be somewhere around tSSC. Something like this would be nice, but it would require rendering manually with plotters library, so probably tiny https://docs.gtk.org/gtk4/class.ProgressBar.html to start is sufficient, which has [pulse-step](https://docs.gtk.org/gtk4/property.ProgressBar.pulse-step.html) property.

💭 Should we attach the webpage url as well, that shows rewards distributed to all the addresses?..may be block no. or so where the rewards were distributed. I guess that would require querying the synced node 🤔 .

Don't think I understood what you wanted to say here.

@abhi3700
Copy link
Author

abhi3700 commented Mar 20, 2024

Okay, I will look into it.

Don't think I understood what you wanted to say here.

I was basically suggesting a feature where a farmer could query for all an address in the rewards list. May be putting a link to the rewards page in block explorer would work. Not sure. Need to think on this.

@nazar-pc
Copy link
Member

I was basically suggesting a feature where a farmer could query for all an address in the rewards list. May be putting a link to the rewards page in block explorer would work. Not sure. Need to think on this.

Still didn't understand what you meant. Did you try to click on the balance yet, is that what you meant?

@abhi3700
Copy link
Author

I was basically suggesting a feature where a farmer could query for all an address in the rewards list. May be putting a link to the rewards page in block explorer would work. Not sure. Need to think on this.

Still didn't understand what you meant. Did you try to click on the balance yet, is that what you meant?

Nevermind, I get it.

abhi3700 added 14 commits May 8, 2024 19:40
To calculate total_space_pledged, get:
  a. solution_ranges currrent value
  b. chain constants like slot_probability
Removed chrono crate, instead used the current timestamp using std. lib
- Sorted sp-api alphabetically
- Synced '[profile.dev.package]' from 'main' branch
- Reverted 'total_space_pledged' formula to original one
- Added snippet to fetch SLOT_PROBABILITY from runtime api client directly. TODO: uncomment later.
Previously used the formula as defined in subspace-test-runtime. Now, changed as defined in subspace-runtime.
- max_pieces_in_sector, slot_probability are fetched using runtime_api rather than defining separately in space-acres.
- 'sp-api' crate modified as git dependency
@nazar-pc
Copy link
Member

I'm closing this PR since we can't merge it as is. We can reopen it later once both frontend and backend parts are implemented, tested and organized cleanly in a state that is ready for review.

@nazar-pc nazar-pc closed this May 16, 2024
@nazar-pc nazar-pc deleted the issue-86 branch May 16, 2024 15:09
@abhi3700 abhi3700 changed the title Predict when the next reward will be farmed (Backend) Predict when the next reward will be farmed May 24, 2024
abhi3700 added 8 commits May 25, 2024 04:40
1. Error Handling in `calculate_expected_reward_duration_from_now` Function:
    - Added `anyhow::Result<u64>` as the return type.
    - Utilized `checked_sub`, `checked_div`, and `checked_mul` methods to prevent overflows.
    - Included explicit error handling for division by zero.

2. Frontend Updates:
    - Introduced a new `utils` module.
    - Added `CmdOut` enum for command output related to reward ETA progress.

3. Running View Enhancements:
    - Added new fields in `RunningView` for space pledged and progress bar tracking.
    - Implemented `update_cmd` to handle progress update commands.
    - Calculated total space pledged and initialized corresponding state in `RunningView`.
    - Provided the function `move_progress_bar` to manage progress bar updates based on ETA.
    - Defined the helper function `calculate_progress_params` for progress calculation.

4. Progress Bar Drawing Updates:
    - Enhanced drawing logic to handle different themes (dark/light) properly.
    - Updated the `create_circular_progress_bar` function to set up the progress bar correctly.

5. Cleanup and Refactoring:
    - Removed the `allocated_space` method from `FarmWidget` as it is no longer needed.
    - Updated comments and improved function headers for better clarity.

Overall, the changes enhance the reward time estimation process and provide a seamless visual representation of progress towards reward payments.
- The reward ETA progress bar variable name was changed from  to  to better reflect its purpose.
- Additionally the status change was done before moving the progress bar
Backend notification sent to the frontend with chain_constants inside 'Initialize' enum param of RunningInput enum
Previously, progress bar was available as a function returning DrawingArea type. Now, it is available as ELM state with fields: progress, tooltip, diameter
…ssue-86

# Conflicts:
#	Cargo.lock
#	Cargo.toml
@abhi3700 abhi3700 reopened this May 29, 2024
Details:
```
warning: large size difference between variants
  --> src/frontend/running.rs:35:1
   |
35 | /  pub enum RunningInput {
36 | |/     Initialize {
37 | ||         best_block_number: BlockNumber,
38 | ||         reward_address_balance: Balance,
39 | ||         initial_farm_states: Vec<InitialFarmState>,
...  ||
42 | ||         chain_constants: ChainConstants,
43 | ||     },
   | ||_____- the largest variant contains at least 268 bytes
44 | |      NodeNotification(NodeNotification),
   | |      ---------------------------------- the second-largest variant contains at least 48 bytes
...  |
47 | |      TogglePausePlotting,
48 | |  }
   | |__^ the entire enum is at least 0 bytes
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
   = note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
   |
40 |         raw_config: Box<RawConfig>,
   |                     ~~~~~~~~~~~~~~
```
@nazar-pc
Copy link
Member

There are 32 commits here, may I ask you to reorganize PR according to https://github.com/subspace/subspace/blob/main/CONTRIBUTING.md?
It should have at most a few cleanly organized commits that can be reviewed individually, no way I'll be going through 32 commits worth of changes for so few lines of code.

@abhi3700
Copy link
Author

There are 32 commits here, may I ask you to reorganize PR according to https://github.com/subspace/subspace/blob/main/CONTRIBUTING.md? It should have at most a few cleanly organized commits that can be reviewed individually, no way I'll be going through 32 commits worth of changes for so few lines of code.

Reorganized the whole work in few commits here: #206

@abhi3700 abhi3700 closed this May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Backend logic
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Predict when the next reward will be farmed
2 participants