-
Notifications
You must be signed in to change notification settings - Fork 228
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: (experimental) optional fee estimator with different algorithms #4477
base: develop
Are you sure you want to change the base?
feat: (experimental) optional fee estimator with different algorithms #4477
Conversation
impl Algorithm { | ||
pub fn update_ibd_state(&mut self, in_ibd: bool) { | ||
if self.is_ready { | ||
if in_ibd { | ||
self.clear(); | ||
self.is_ready = false; | ||
} | ||
} else if !in_ibd { | ||
self.clear(); | ||
self.is_ready = true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update_ibd_state
is executed every time ckb-chain finishes processing a block, is this the expected behavior?
Or should update_ibd_state
only be executed when the ibd_state
of ckb changes from true
to false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I was correct, the IBD state could change to true
from false
, when a CKB node lost Internet connections for a long time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that when CKB leaves IBD mode, self.ibd_finished
is set to true
only once. If CKB loses internet connection after 24 hours, self.ibd_finished
will always remain true
.
/// Return whether chain is in initial block download
pub fn is_initial_block_download(&self) -> bool {
// Once this function has returned false, it must remain false.
if self.ibd_finished.load(Ordering::Acquire) {
false
} else if unix_time_as_millis().saturating_sub(self.snapshot().tip_header().timestamp())
> MAX_TIP_AGE
{
true
} else {
self.ibd_finished.store(true, Ordering::Release);
false
}
}
f7f60e0
to
1172d2d
Compare
use ckb_types::core::{BlockNumber, FeeRate}; | ||
|
||
/// Average block interval. | ||
pub(crate) const AVG_BLOCK_INTERVAL: u64 = (MAX_BLOCK_INTERVAL + MIN_BLOCK_INTERVAL) / 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AVG_BLOCK_INTERVAL
is calculated as (48 + 8) / 2
, which equals 28 seconds. However, according to https://explorer.nervos.org/charts/block-time-distribution, most block intervals are less than 10 seconds.
pub(crate) const MIN_TARGET: BlockNumber = TX_PROPOSAL_WINDOW.closest() + 1; | ||
|
||
/// Lowest fee rate. | ||
pub(crate) const LOWEST_FEE_RATE: FeeRate = FeeRate::from_u64(1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we reuse DEFAULT_MIN_FEE_RATE
from ckb-app-config
?
#[error("dummy fee estimator is used")] | ||
Dummy, | ||
/// Not ready for do estimate. | ||
#[error("not ready")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about giving a more verbose errro: #[error("not ready, node is in IBD mode")]
/// confirm_blocks => bucket index => confirmed txs count | ||
confirm_blocks_to_confirmed_txs: Vec<Vec<f64>>, | ||
/// confirm_blocks => bucket index => failed txs count | ||
confirm_blocks_to_failed_txs: Vec<Vec<f64>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that confirm_blocks_to_failed_txs
's length is always 1
?
I didn't find which method append/insert Vec<f64>
to confirm_blocks_to_failed_txs
after initialization.
What problem does this PR solve?
Warning
This feature is experimental.
I have done lots of manual tests before submit this PR, but more production environment tests are still required.
Add an optional fee estimator with different algorithms and a RPC method for it.
Description
I do lots manual tests for several day, I don't sure which algorithm is better, so I just submit both of them.
Let's make choice after collect more data in production environment (both mainnet and testnet).
Only 4 levels of priorities for the fee estimator.
Different algorithms have different APIs, I just use some constants as default parameters to avoid specialized parameters, to make the public API more generic.
Current, there are 2 built-in algorithms:
Confirmation Fraction
Migrated from this CKB PR.
👉🏼 Sometimes, it returns unreasonable result, I haven't figured it out yet, since I couldn't reproduce it manually.
Weight-Units Flow
A variant of the Weight-Units Flow Fee Estimator for Bitcoin.
The main difference is I use the block interval to replace the time interval, to avoid unit conversion with random distributions, since our APIs require blocks as the target unit for estimation.
The details of this algorithm are written in the head section of that source code file.
Merged fallback fee estimates algorithm from #4465.
Usage
Append the following content to
ckb.toml
:And enable JSON-RPC API module
Experiment
.After the CKB node started, try the following command:
An example of result is:
What is changed and how it works?
What's Changed:
Related changes
owner/repo
:Check List
Tests
Release note