Skip to content

Commit

Permalink
Merge pull request #4477 from yangby-cryptape/feature/integrated-fee-…
Browse files Browse the repository at this point in the history
…estimator

feat: (experimental) optional fee estimator with different algorithms
  • Loading branch information
yangby-cryptape authored Oct 24, 2024
2 parents 0404654 + 95c27e1 commit 7f24e60
Show file tree
Hide file tree
Showing 33 changed files with 1,658 additions and 18 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ members = [
"util/dao/utils",
"traits",
"spec",
"util/fee-estimator",
"util/proposal-table",
"script",
"util/app-config",
Expand Down
8 changes: 8 additions & 0 deletions chain/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ impl ConsumeUnverifiedBlockProcessor {
db_txn.insert_epoch_ext(&epoch.last_block_hash_in_previous_epoch(), &epoch)?;
}

let in_ibd = self.shared.is_initial_block_download();

if new_best_block {
info!(
"[verify block] new best block found: {} => {:#x}, difficulty diff = {:#x}, unverified_tip: {}",
Expand Down Expand Up @@ -368,6 +370,9 @@ impl ConsumeUnverifiedBlockProcessor {
) {
error!("[verify block] notify update_tx_pool_for_reorg error {}", e);
}
if let Err(e) = tx_pool_controller.update_ibd_state(in_ibd) {
error!("Notify update_ibd_state error {}", e);
}
}

self.shared
Expand Down Expand Up @@ -395,6 +400,9 @@ impl ConsumeUnverifiedBlockProcessor {
if let Err(e) = tx_pool_controller.notify_new_uncle(block.as_uncle()) {
error!("[verify block] notify new_uncle error {}", e);
}
if let Err(e) = tx_pool_controller.update_ibd_state(in_ibd) {
error!("Notify update_ibd_state error {}", e);
}
}
}
Ok(true)
Expand Down
4 changes: 4 additions & 0 deletions resource/ckb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,7 @@ block_uncles_cache_size = 30
# db_port = 5432
# db_user = "postgres"
# db_password = "123456"
#
# # [fee_estimator]
# # Specifies the fee estimates algorithm. Current algorithms: ConfirmationFraction, WeightUnitsFlow.
# # algorithm = "WeightUnitsFlow"
67 changes: 67 additions & 0 deletions rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ The crate `ckb-rpc`'s minimum supported rustc version is 1.71.1.

* [Method `dry_run_transaction`](#experiment-dry_run_transaction)
* [Method `calculate_dao_maximum_withdraw`](#experiment-calculate_dao_maximum_withdraw)
* [Method `estimate_fee_rate`](#experiment-estimate_fee_rate)
* [Module Indexer](#module-indexer) [👉 OpenRPC spec](http://playground.open-rpc.org/?uiSchema[appBar][ui:title]=CKB-Indexer&uiSchema[appBar][ui:splitView]=false&uiSchema[appBar][ui:examplesDropdown]=false&uiSchema[appBar][ui:logoUrl]=https://raw.githubusercontent.com/nervosnetwork/ckb-rpc-resources/develop/ckb-logo.jpg&schemaUrl=https://raw.githubusercontent.com/nervosnetwork/ckb-rpc-resources/develop/json/indexer_rpc_doc.json)

* [Method `get_indexer_tip`](#indexer-get_indexer_tip)
Expand Down Expand Up @@ -171,6 +172,7 @@ The crate `ckb-rpc`'s minimum supported rustc version is 1.71.1.
* [Type `EpochNumberWithFraction`](#type-epochnumberwithfraction)
* [Type `EpochView`](#type-epochview)
* [Type `EstimateCycles`](#type-estimatecycles)
* [Type `EstimateMode`](#type-estimatemode)
* [Type `ExtraLoggerConfig`](#type-extraloggerconfig)
* [Type `FeeRateStatistics`](#type-feeratestatistics)
* [Type `H256`](#type-h256)
Expand Down Expand Up @@ -2168,6 +2170,62 @@ Response
}
```

<a id="experiment-estimate_fee_rate"></a>
#### Method `estimate_fee_rate`
* `estimate_fee_rate(estimate_mode, enable_fallback)`
* `estimate_mode`: [`EstimateMode`](#type-estimatemode) `|` `null`
* `enable_fallback`: `boolean` `|` `null`
* result: [`Uint64`](#type-uint64)

Get fee estimates.

###### Params

* `estimate_mode` - The fee estimate mode.

Default: `no_priority`.

* `enable_fallback` - True to enable a simple fallback algorithm, when lack of historical empirical data to estimate fee rates with configured algorithm.

Default: `true`.

####### The fallback algorithm

Since CKB transaction confirmation involves a two-step process—1) propose and 2) commit, it is complex to
predict the transaction fee accurately with the expectation that it will be included within a certain block height.

This algorithm relies on two assumptions and uses a simple strategy to estimate the transaction fee: 1) all transactions
in the pool are waiting to be proposed, and 2) no new transactions will be added to the pool.

In practice, this simple algorithm should achieve good accuracy fee rate and running performance.

###### Returns

The estimated fee rate in shannons per kilobyte.

###### Examples

Request

```json
{
"id": 42,
"jsonrpc": "2.0",
"method": "estimate_fee_rate",
"params": []
}
```

Response

```json
{
"id": 42,
"jsonrpc": "2.0",
"result": "0x3e8"
}
```

### Module `Indexer`
- [👉 OpenRPC spec](http://playground.open-rpc.org/?uiSchema[appBar][ui:title]=CKB-Indexer&uiSchema[appBar][ui:splitView]=false&uiSchema[appBar][ui:examplesDropdown]=false&uiSchema[appBar][ui:logoUrl]=https://raw.githubusercontent.com/nervosnetwork/ckb-rpc-resources/develop/ckb-logo.jpg&schemaUrl=https://raw.githubusercontent.com/nervosnetwork/ckb-rpc-resources/develop/json/indexer_rpc_doc.json)

Expand Down Expand Up @@ -6064,6 +6122,15 @@ Response result of the RPC method `estimate_cycles`.

* `cycles`: [`Uint64`](#type-uint64) - The count of cycles that the VM has consumed to verify this transaction.

### Type `EstimateMode`
The fee estimate mode.

It's an enum value from one of:
- no_priority : No priority, expect the transaction to be committed in 1 hour.
- low_priority : Low priority, expect the transaction to be committed in 30 minutes.
- medium_priority : Medium priority, expect the transaction to be committed in 10 minutes.
- high_priority : High priority, expect the transaction to be committed as soon as possible.

### Type `ExtraLoggerConfig`
Runtime logger config for extra loggers.

Expand Down
74 changes: 73 additions & 1 deletion rpc/src/module/experiment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::module::chain::CyclesEstimator;
use async_trait::async_trait;
use ckb_dao::DaoCalculator;
use ckb_jsonrpc_types::{
Capacity, DaoWithdrawingCalculationKind, EstimateCycles, OutPoint, Transaction,
Capacity, DaoWithdrawingCalculationKind, EstimateCycles, EstimateMode, OutPoint, Transaction,
Uint64,
};
use ckb_shared::{shared::Shared, Snapshot};
use ckb_store::ChainStore;
Expand Down Expand Up @@ -162,6 +163,61 @@ pub trait ExperimentRpc {
out_point: OutPoint,
kind: DaoWithdrawingCalculationKind,
) -> Result<Capacity>;

/// Get fee estimates.
///
/// ## Params
///
/// * `estimate_mode` - The fee estimate mode.
///
/// Default: `no_priority`.
///
/// * `enable_fallback` - True to enable a simple fallback algorithm, when lack of historical empirical data to estimate fee rates with configured algorithm.
///
/// Default: `true`.
///
/// ### The fallback algorithm
///
/// Since CKB transaction confirmation involves a two-step process—1) propose and 2) commit, it is complex to
/// predict the transaction fee accurately with the expectation that it will be included within a certain block height.
///
/// This algorithm relies on two assumptions and uses a simple strategy to estimate the transaction fee: 1) all transactions
/// in the pool are waiting to be proposed, and 2) no new transactions will be added to the pool.
///
/// In practice, this simple algorithm should achieve good accuracy fee rate and running performance.
///
/// ## Returns
///
/// The estimated fee rate in shannons per kilobyte.
///
/// ## Examples
///
/// Request
///
/// ```json
/// {
/// "id": 42,
/// "jsonrpc": "2.0",
/// "method": "estimate_fee_rate",
/// "params": []
/// }
/// ```
///
/// Response
///
/// ```json
/// {
/// "id": 42,
/// "jsonrpc": "2.0",
/// "result": "0x3e8"
/// }
/// ```
#[rpc(name = "estimate_fee_rate")]
fn estimate_fee_rate(
&self,
estimate_mode: Option<EstimateMode>,
enable_fallback: Option<bool>,
) -> Result<Uint64>;
}

#[derive(Clone)]
Expand Down Expand Up @@ -241,4 +297,20 @@ impl ExperimentRpc for ExperimentRpcImpl {
}
}
}

fn estimate_fee_rate(
&self,
estimate_mode: Option<EstimateMode>,
enable_fallback: Option<bool>,
) -> Result<Uint64> {
let estimate_mode = estimate_mode.unwrap_or_default();
let enable_fallback = enable_fallback.unwrap_or(true);
self.shared
.tx_pool_controller()
.estimate_fee_rate(estimate_mode.into(), enable_fallback)
.map_err(|err| RPCError::custom(RPCError::CKBInternalError, err.to_string()))?
.map_err(RPCError::from_any_error)
.map(core::FeeRate::as_u64)
.map(Into::into)
}
}
1 change: 1 addition & 0 deletions rpc/src/tests/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ fn mock_rpc_response(example: &RpcTestExample, response: &mut RpcTestResponse) {
"get_pool_tx_detail_info" => {
response.result["timestamp"] = example.response.result["timestamp"].clone()
}
"estimate_fee_rate" => replace_rpc_response::<Uint64>(example, response),
_ => {}
}
}
Expand Down
1 change: 1 addition & 0 deletions shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ckb-systemtime = { path = "../util/systemtime", version = "= 0.119.0-pre" }
ckb-channel = { path = "../util/channel", version = "= 0.119.0-pre" }
ckb-app-config = { path = "../util/app-config", version = "= 0.119.0-pre" }
ckb-migrate = { path = "../util/migrate", version = "= 0.119.0-pre" }
ckb-fee-estimator = { path = "../util/fee-estimator", version = "= 0.119.0-pre"}
ckb-util = { path = "../util", version = "= 0.119.0-pre" }
ckb-metrics = { path = "../util/metrics", version = "= 0.119.0-pre" }
bitflags = "1.0"
Expand Down
Loading

0 comments on commit 7f24e60

Please sign in to comment.