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

feat: Improved Fee Rate Computation #2972

Merged
merged 112 commits into from
Jan 12, 2022
Merged

Conversation

gregorycoppola
Copy link
Contributor

@gregorycoppola gregorycoppola commented Dec 14, 2021

Fixes #2954

#2954 (comment) discusses four proposals for improving fee estimation.

We address these here:

  1. Address outlier block sensitivity by using a median of a window, rather than exponential windowing.
  2. Address impact of STX transfers by using percentiles weighted by the proportion of the block limit consumed rather than 5th, 50th, and 95th percentiles. See weighted percentiles.
  3. Address impact of non-full blocks by treating the non-full proportion of the block as a transaction at the relay fee minimum (a fee of 0 is too low for admission to the mempool).
  4. We should address fee changes in the face of congestion using a strategy of "fuzzing" the estimated fee rate: when queried, nodes will add some random noise to the estimated fee rate. In periods of congestion, clients that used the higher fee would be included in the next block, pushing the fee estimate for the next block up.

Testing

  • There are new unit tests for the two FeeEstimator components, to test the computations.
  • There is an integration in neon_integrations.rs that tests that we can load this new estimator, and use it.

Copy link
Member

@jcnelson jcnelson left a comment

Choose a reason for hiding this comment

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

This mostly LGTM. Just had two comments about the fee math corner cases that must be addressed before merging. Thanks @gregorycoppola!

Copy link
Contributor

@pavitthrap pavitthrap left a comment

Choose a reason for hiding this comment

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

just a few minor comments left!

CHANGELOG.md Outdated Show resolved Hide resolved
src/cost_estimates/fee_medians.rs Outdated Show resolved Hide resolved
})
.expect("SQLite failure");

for result in results {
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 you should verify that you only iterate window_size times (or that results has length window_size)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if it doesn't? panic?

Copy link
Contributor

Choose a reason for hiding this comment

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

seems drastic to panic? maybe only iterate window_size times and print a warn if results is longer than expected. thoughts @kantai ?

Copy link
Member

Choose a reason for hiding this comment

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

I think this would be an appropriate panic/assert, assert!(results.len() <= window_size), because the SQL statement has a LIMIT, there's nothing short of a bug in sqlite or a misunderstanding in our code that should cause that assertion to fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's just forget about this assert as:

  1. we have a limit anyway, so we probably don't need to worry

  2. this structure doesn't have a len:

error[E0599]: no method named `len` found for struct `AndThenRows` in the current scope
   --> src/cost_estimates/fee_medians.rs:130:25
    |
130 |         assert!(results.len() <= window_size);
    |                         ^^^ method not found in `AndThenRows<'_, [closure@src/cost_estimates/fee_medians.rs:122:69: 127:14]>`

Copy link
Member

Choose a reason for hiding this comment

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

That's fine with me.

src/cost_estimates/fee_rate_fuzzer.rs Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
Copy link
Contributor Author

@gregorycoppola gregorycoppola left a comment

Choose a reason for hiding this comment

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

replying to @pavitthrap

testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
})
.expect("SQLite failure");

for result in results {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if it doesn't? panic?

src/cost_estimates/fee_rate_fuzzer.rs Show resolved Hide resolved
Copy link
Contributor

@pavitthrap pavitthrap left a comment

Choose a reason for hiding this comment

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

responded to comments

src/cost_estimates/fee_rate_fuzzer.rs Show resolved Hide resolved
})
.expect("SQLite failure");

for result in results {
Copy link
Contributor

Choose a reason for hiding this comment

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

seems drastic to panic? maybe only iterate window_size times and print a warn if results is longer than expected. thoughts @kantai ?

testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
Copy link
Contributor Author

@gregorycoppola gregorycoppola left a comment

Choose a reason for hiding this comment

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

Two unresolved points.

testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
src/cost_estimates/fee_medians.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/tests/neon_integrations.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/config.rs Outdated Show resolved Hide resolved
MINIMUM_TX_FEE_RATE
};
let fee_rate = fee as f64 / denominator;
if fee_rate >= MINIMUM_TX_FEE_RATE && fee_rate.is_finite() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I chose to panic if the fee_rate is infite, because I think it should never be, unless the user had paid an infinte amount. does that sound ok @kantai

src/cost_estimates/fee_medians.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@pavitthrap pavitthrap left a comment

Choose a reason for hiding this comment

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

lgtm - thanks for addressing my feedback!

@gregorycoppola
Copy link
Contributor Author

Thanks for many rounds of reviews, everyone.

There was a broken that seemed flaky so re-running.

@gregorycoppola
Copy link
Contributor Author

@kantai sorry about the no-op commits. Next time I'll do it the right way but was just tired of this PR and took a short cut.

@blockstack-devops
Copy link
Contributor

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@stacks-network stacks-network locked as resolved and limited conversation to collaborators Nov 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make a separate chainstate directory for fee_estimation constructs
5 participants