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

fix: get_fee_rate_statics compatibility #3746

Merged
merged 2 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

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

2 changes: 0 additions & 2 deletions devtools/doc/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ def handle_starttag(self, tag, attrs):
self.ty = '`null`'
if self.ty == RUST_DOC_PREFIX + '/std/primitive.bool.html':
self.ty = '`boolean`'
if self.ty == RUST_DOC_PREFIX + '/std/primitive.f64.html':
self.ty = '`64-bit floating point`'
if self.ty == RUST_DOC_PREFIX + '/alloc/string/struct.String.html':
self.ty = '`string`'
elif self.ty == RUST_DOC_PREFIX + '/core/option/enum.Option.html':
Expand Down
12 changes: 6 additions & 6 deletions rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,7 @@ Returns the fee_rate statistics of confirmed blocks on the chain

###### Returns

If the query has data records, it returns statistics, if not, it returns null.
If the query finds the corresponding historical data, the corresponding statistics are returned, containing the mean and median, in shannons per kilo-weight. If not, it returns null.

###### Examples

Expand All @@ -1852,8 +1852,8 @@ Response
"id": 42,
"jsonrpc": "2.0",
"result": {
"mean":59.29387293275573,
"median":5.288207297726071
"mean": "0xe79d",
"median": "0x14a8"
}
}
```
Expand Down Expand Up @@ -5779,15 +5779,15 @@ Response result of the RPC method `estimate_cycles`.

### Type `FeeRateStatics`

The fee_rate statistics information, includes mean and median
The fee_rate statistics information, includes mean and median, unit: shannons per kilo-weight

#### Fields

`FeeRateStatics` is a JSON object with the following fields.

* `mean`: `64-bit floating point` - mean
* `mean`: [`Uint64`](#type-uint64) - mean

* `median`: `64-bit floating point` - median
* `median`: [`Uint64`](#type-uint64) - median


### Type `H256`
Expand Down
9 changes: 6 additions & 3 deletions rpc/src/module/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,10 @@ pub trait ChainRpc {
///
/// ## Returns
///
/// If the query has data records, it returns statistics, if not, it returns null.
/// If the query finds the corresponding historical data,
/// the corresponding statistics are returned,
/// containing the mean and median, in shannons per kilo-weight.
/// If not, it returns null.
///
/// ## Examples
///
Expand All @@ -1520,8 +1523,8 @@ pub trait ChainRpc {
/// "id": 42,
/// "jsonrpc": "2.0",
/// "result": {
/// "mean":59.29387293275573,
/// "median":5.288207297726071
/// "mean": "0xe79d",
/// "median": "0x14a8"
/// }
/// }
/// ```
Expand Down
16 changes: 8 additions & 8 deletions rpc/src/tests/fee_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,35 +54,35 @@ fn test_fee_rate_statics() {
assert_eq!(
statistics,
Some(FeeRateStatics {
mean: 11.0,
median: 11.0
mean: 11_000.into(),
median: 11_000.into(),
})
);

let statistics = FeeRateCollector::new(&provider).statistics(Some(9));
assert_eq!(
statistics,
Some(FeeRateStatics {
mean: 17.0,
median: 17.0
mean: 17_000.into(),
median: 17_000.into()
})
);

let statistics = FeeRateCollector::new(&provider).statistics(Some(30));
assert_eq!(
statistics,
Some(FeeRateStatics {
mean: 11.0,
median: 11.0
mean: 11_000.into(),
median: 11_000.into(),
})
);

let statistics = FeeRateCollector::new(&provider).statistics(Some(0));
assert_eq!(
statistics,
Some(FeeRateStatics {
mean: 21.0,
median: 21.0
mean: 21_000.into(),
median: 21_000.into(),
})
);
}
24 changes: 12 additions & 12 deletions rpc/src/util/fee_rate.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ckb_jsonrpc_types::FeeRateStatics;
use ckb_shared::Snapshot;
use ckb_store::ChainStore;
use ckb_types::core::{tx_pool::get_transaction_weight, BlockExt, BlockNumber};
use ckb_types::core::{tx_pool::get_transaction_weight, BlockExt, BlockNumber, FeeRate};

const DEFAULT_TARGET: u64 = 21;
const MIN_TARGET: u64 = 1;
Expand All @@ -11,16 +11,16 @@ fn is_even(n: u64) -> bool {
n & 1 == 0
}

fn mean(numbers: &[f64]) -> f64 {
let sum: f64 = numbers.iter().sum();
sum / numbers.len() as f64
fn mean(numbers: &[u64]) -> u64 {
let sum: u64 = numbers.iter().sum();
sum / numbers.len() as u64
}

fn median(numbers: &mut [f64]) -> f64 {
numbers.sort_unstable_by(|a, b| a.partial_cmp(b).expect("slice does not contain NaN"));
fn median(numbers: &mut [u64]) -> u64 {
numbers.sort_unstable();
let mid = numbers.len() / 2;
if numbers.len() % 2 == 0 {
mean(&[numbers[mid - 1], numbers[mid]]) as f64
mean(&[numbers[mid - 1], numbers[mid]])
} else {
numbers[mid]
}
Expand All @@ -30,9 +30,9 @@ pub(crate) trait FeeRateProvider {
fn get_tip_number(&self) -> BlockNumber;
fn get_block_ext_by_number(&self, number: BlockNumber) -> Option<BlockExt>;

fn collect<F>(&self, target: u64, f: F) -> Vec<f64>
fn collect<F>(&self, target: u64, f: F) -> Vec<u64>
where
F: FnMut(Vec<f64>, BlockExt) -> Vec<f64>,
F: FnMut(Vec<u64>, BlockExt) -> Vec<u64>,
{
let tip_number = self.get_tip_number();
let start = std::cmp::max(
Expand Down Expand Up @@ -88,7 +88,7 @@ where
) {
let weight = get_transaction_weight(size as usize, cycles);
if weight > 0 {
fee_rates.push(fee.as_u64() as f64 / weight as f64);
fee_rates.push(FeeRate::calculate(fee, weight).as_u64());
}
}
}
Expand All @@ -99,8 +99,8 @@ where
None
} else {
Some(FeeRateStatics {
mean: mean(&fee_rates),
median: median(&mut fee_rates),
mean: mean(&fee_rates).into(),
median: median(&mut fee_rates).into(),
})
}
}
Expand Down
5 changes: 4 additions & 1 deletion tx-pool/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ pub(crate) fn check_tx_fee(
let fee = DaoCalculator::new(snapshot.consensus(), &snapshot.as_data_provider())
.transaction_fee(rtx)
.map_err(|err| Reject::Malformed(format!("{}", err)))?;
let min_fee = tx_pool.config.min_fee_rate.fee(tx_size);
// Theoretically we cannot use size as weight directly to calculate fee_rate,
// here min fee rate is used as a cheap check,
// so we will use size to calculate fee_rate directly
let min_fee = tx_pool.config.min_fee_rate.fee(tx_size as u64);
// reject txs which fee lower than min fee rate
if fee < min_fee {
let reject =
Expand Down
6 changes: 3 additions & 3 deletions util/jsonrpc-types/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1398,11 +1398,11 @@ impl HardForkFeature {
}
}

/// The fee_rate statistics information, includes mean and median
/// The fee_rate statistics information, includes mean and median, unit: shannons per kilo-weight
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct FeeRateStatics {
/// mean
pub mean: f64,
pub mean: Uint64,
/// median
pub median: f64,
pub median: Uint64,
}
16 changes: 8 additions & 8 deletions util/types/src/core/fee_rate.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use crate::core::Capacity;

/// shannons per kilobytes
/// shannons per kilo-weight
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct FeeRate(pub u64);

const KB: u64 = 1000;
const KW: u64 = 1000;

impl FeeRate {
/// TODO(doc): @doitian
pub fn calculate(fee: Capacity, weight: usize) -> Self {
pub fn calculate(fee: Capacity, weight: u64) -> Self {
if weight == 0 {
return FeeRate::zero();
}
FeeRate::from_u64(fee.as_u64().saturating_mul(KB) / (weight as u64))
FeeRate::from_u64(fee.as_u64().saturating_mul(KW) / weight)
}

/// TODO(doc): @doitian
pub const fn from_u64(fee_per_kb: u64) -> Self {
FeeRate(fee_per_kb)
pub const fn from_u64(fee_per_kw: u64) -> Self {
FeeRate(fee_per_kw)
}

/// TODO(doc): @doitian
Expand All @@ -31,8 +31,8 @@ impl FeeRate {
}

/// TODO(doc): @doitian
pub fn fee(self, size: usize) -> Capacity {
let fee = self.0.saturating_mul(size as u64) / KB;
pub fn fee(self, weight: u64) -> Capacity {
let fee = self.0.saturating_mul(weight) / KW;
Capacity::shannons(fee)
}
}
Expand Down