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

Use gas prices from actual blocks to calculate estimate gas prices #2501

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

MitchTurner
Copy link
Member

@MitchTurner MitchTurner commented Dec 16, 2024

Linked Issues/PRs

Description

Because some nodes won't be running the gas price algorithm, or might not be synced properly, we are going to calculate the price based on the latest block gas price. That is a reliable source of truth.

Checklist

  • Breaking changes are clearly marked as such in the PR description and changelog
  • New behavior is reflected in tests
  • The specification matches the implemented behavior (link update PR if changes are needed)

Before requesting review

  • I have reviewed the code myself
  • I have created follow-up issues caused by this PR and linked them here

After merging, notify other teams

[Add or remove entries as needed]

@MitchTurner MitchTurner marked this pull request as ready for review December 16, 2024 04:33
Copy link
Member

@rymnc rymnc left a comment

Choose a reason for hiding this comment

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

left a few questions :)

}

#[async_trait::async_trait]
impl GasPriceEstimate for ArcGasPriceEstimate<u32, u64> {
Copy link
Member

Choose a reason for hiding this comment

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

does this have to be async?

pub(crate) fn update_latest_gas_price(&self, block_info: &BlockInfo) {
match block_info {
BlockInfo::GenesisBlock => {
// do nothing
Copy link
Member

Choose a reason for hiding this comment

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

should we have a test to see what values are stored in the block after genesis? afaiu we test only post genesis transitions

@@ -481,10 +506,12 @@ mod tests {
),
None,
);
let latest_gas_price = Arc::new(parking_lot::RwLock::new((0, 0)));
Copy link
Member

Choose a reason for hiding this comment

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

curious why we need this when perhaps the algo could contain this internally?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah... That works too. It's kinda a separate value so I thought to keep it separate but that would work.

use super::*;
use proptest::proptest;

async fn _worst_case__correctly_calculates_value(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this function is called later on

Suggested change
async fn _worst_case__correctly_calculates_value(
async fn worst_case__correctly_calculates_value(

}

#[allow(dead_code)]
pub struct ArcGasPriceEstimate<Height, GasPrice> {
Copy link
Contributor

@acerone85 acerone85 Dec 16, 2024

Choose a reason for hiding this comment

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

would it be possible to have a bit of documentation here?
In particular, I'd like to understand what the "height" and "price" refer to here, since later they are named as "best_height" and "best_price"


#[async_trait::async_trait]
impl GasPriceEstimate for ArcGasPriceEstimate<u32, u64> {
async fn worst_case_gas_price(&self, height: BlockHeight) -> Option<u64> {
Copy link
Contributor

@acerone85 acerone85 Dec 16, 2024

Choose a reason for hiding this comment

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

so what I get here is that we assume that the price is going to raise by the specified percentage every block until height is reached, is that correct?

best_gas_price: u64,
best_height: u32,
percentage: u64,
target_height: u32,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you can pass directly the difference of target_height and best_height to this function and get rid of one parameter, but I don't have a strong opinion here


#[allow(clippy::cast_possible_truncation)]
pub(crate) fn cumulative_percentage_change(
best_gas_price: u64,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe start_gas_price is better?

let multiple = (1.0f64 + percentage_as_decimal).powf(blocks);
let mut approx = best_gas_price as f64 * multiple;
// account for rounding errors and take a slightly higher value
const ROUNDING_ERROR_CUTOFF: f64 = 16948547188989277.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

can you put a comment about how this value has been obtained?

// account for rounding errors and take a slightly higher value
const ROUNDING_ERROR_CUTOFF: f64 = 16948547188989277.0;
if approx > ROUNDING_ERROR_CUTOFF {
const ROUNDING_ERROR_COMPENSATION: f64 = 2000.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

expected = expected.saturating_add(change_amount);
}

assert!(actual >= expected);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can be more precise here, and place an upper bound on actual, e.g.

Suggested change
assert!(actual >= expected);
assert!(actual >= expected);
assert!(actual <= expected.saturating_add(2000.0))

@acerone85
Copy link
Contributor

I'm not sure I understand what the role of ArcGasPriceEstimate is in this PR, since it seems to be used only in tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants