Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Expose default gas price percentile configuration in CLI #7497

Merged
merged 4 commits into from
Jan 9, 2018
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
8 changes: 8 additions & 0 deletions parity/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ usage! {
ARG arg_password: (Vec<String>) = Vec::new(), or |c: &Config| otry!(c.account).password.clone(),
"--password=[FILE]...",
"Provide a file containing a password for unlocking an account. Leading and trailing whitespace is trimmed.",

["UI options"]
FLAG flag_force_ui: (bool) = false, or |c: &Config| otry!(c.ui).force.clone(),
"--force-ui",
Expand Down Expand Up @@ -696,6 +697,10 @@ usage! {
"--min-gas-price=[STRING]",
"Minimum amount of Wei per GAS to be paid for a transaction to be accepted for mining. Overrides --usd-per-tx.",

ARG arg_gas_price_percentile: (usize) = 50usize, or |c: &Config| otry!(c.mining).gas_price_percentile,
"--gas-price-percentile=[PCT]",
"Set PCT percentile gas price value from last 100 blocks as default gas price when sending transactions.",

ARG arg_author: (Option<String>) = None, or |c: &Config| otry!(c.mining).author.clone(),
"--author=[ADDRESS]",
"Specify the block author (aka \"coinbase\") address for sending block rewards from sealed blocks. NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.", // Sealing/Mining Option
Expand Down Expand Up @@ -1142,6 +1147,7 @@ struct Mining {
tx_time_limit: Option<u64>,
relay_set: Option<String>,
min_gas_price: Option<u64>,
gas_price_percentile: Option<usize>,
usd_per_tx: Option<String>,
usd_per_eth: Option<String>,
price_update_period: Option<String>,
Expand Down Expand Up @@ -1546,6 +1552,7 @@ mod tests {
arg_tx_time_limit: Some(100u64),
arg_relay_set: "cheap".into(),
arg_min_gas_price: Some(0u64),
arg_gas_price_percentile: 50usize,
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe override the default for the test in tests/config.full.toml.

arg_usd_per_tx: "0.0025".into(),
arg_usd_per_eth: "auto".into(),
arg_price_update_period: "hourly".into(),
Expand Down Expand Up @@ -1794,6 +1801,7 @@ mod tests {
work_queue_size: None,
relay_set: None,
min_gas_price: None,
gas_price_percentile: None,
usd_per_tx: None,
usd_per_eth: None,
price_update_period: Some("hourly".into()),
Expand Down
2 changes: 2 additions & 0 deletions parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ impl Configuration {
daemon: daemon,
logger_config: logger_config.clone(),
miner_options: self.miner_options()?,
gas_price_percentile: self.args.arg_gas_price_percentile,
ntp_servers: self.ntp_servers(),
ws_conf: ws_conf,
http_conf: http_conf,
Expand Down Expand Up @@ -1357,6 +1358,7 @@ mod tests {
daemon: None,
logger_config: Default::default(),
miner_options: Default::default(),
gas_price_percentile: 50,
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
Expand Down
10 changes: 9 additions & 1 deletion parity/rpc_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ pub struct FullDependencies {
pub fetch: FetchClient,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
pub gas_price_percentile: usize,
}

impl FullDependencies {
Expand All @@ -241,7 +242,7 @@ impl FullDependencies {
($namespace:ident, $handler:expr, $deps:expr, $nonces:expr) => {
{
let deps = &$deps;
let dispatcher = FullDispatcher::new(deps.client.clone(), deps.miner.clone(), $nonces);
let dispatcher = FullDispatcher::new(deps.client.clone(), deps.miner.clone(), $nonces, deps.gas_price_percentile);
if deps.signer_service.is_enabled() {
$handler.extend_with($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, dispatcher, deps.remote.clone(), &deps.secret_store)))
} else {
Expand All @@ -256,6 +257,7 @@ impl FullDependencies {
self.client.clone(),
self.miner.clone(),
nonces.clone(),
self.gas_price_percentile,
);
for api in apis {
match *api {
Expand All @@ -277,6 +279,7 @@ impl FullDependencies {
pending_nonce_from_queue: self.geth_compatibility,
allow_pending_receipt_query: !self.geth_compatibility,
send_block_number_in_get_work: !self.geth_compatibility,
gas_price_percentile: self.gas_price_percentile,
}
);
handler.extend_with(client.to_delegate());
Expand Down Expand Up @@ -422,6 +425,7 @@ pub struct LightDependencies<T> {
pub geth_compatibility: bool,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
pub gas_price_percentile: usize,
}

impl<C: LightChainClient + 'static> LightDependencies<C> {
Expand All @@ -440,6 +444,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.cache.clone(),
self.transaction_queue.clone(),
Arc::new(Mutex::new(dispatch::Reservations::with_pool(self.fetch.pool()))),
self.gas_price_percentile,
);

macro_rules! add_signing_methods {
Expand Down Expand Up @@ -477,6 +482,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.transaction_queue.clone(),
self.secret_store.clone(),
self.cache.clone(),
self.gas_price_percentile,
);
handler.extend_with(Eth::to_delegate(client.clone()));

Expand All @@ -492,6 +498,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.sync.clone(),
self.cache.clone(),
self.remote.clone(),
self.gas_price_percentile,
);
self.client.add_listener(
Arc::downgrade(&client.handler()) as Weak<::light::client::LightChainNotify>
Expand Down Expand Up @@ -521,6 +528,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
signer,
self.dapps_address.clone(),
self.ws_address.clone(),
self.gas_price_percentile,
).to_delegate());

if !for_generic_pubsub {
Expand Down
3 changes: 3 additions & 0 deletions parity/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub struct RunCmd {
pub daemon: Option<String>,
pub logger_config: LogConfig,
pub miner_options: MinerOptions,
pub gas_price_percentile: usize,
pub ntp_servers: Vec<String>,
pub ws_conf: rpc::WsConfiguration,
pub http_conf: rpc::HttpConfiguration,
Expand Down Expand Up @@ -358,6 +359,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
geth_compatibility: cmd.geth_compatibility,
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
gas_price_percentile: cmd.gas_price_percentile,
});

let dependencies = rpc::Dependencies {
Expand Down Expand Up @@ -761,6 +763,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
fetch: fetch.clone(),
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
gas_price_percentile: cmd.gas_price_percentile,
});

let dependencies = rpc::Dependencies {
Expand Down
25 changes: 18 additions & 7 deletions rpc/src/v1/helpers/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct FullDispatcher<C, M> {
client: Arc<C>,
miner: Arc<M>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
}

impl<C, M> FullDispatcher<C, M> {
Expand All @@ -96,11 +97,13 @@ impl<C, M> FullDispatcher<C, M> {
client: Arc<C>,
miner: Arc<M>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
) -> Self {
FullDispatcher {
client,
miner,
nonces,
gas_price_percentile,
}
}
}
Expand All @@ -111,6 +114,7 @@ impl<C, M> Clone for FullDispatcher<C, M> {
client: self.client.clone(),
miner: self.miner.clone(),
nonces: self.nonces.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}
}
Expand Down Expand Up @@ -148,7 +152,9 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
used_default_from: request.from.is_none(),
to: request.to,
nonce,
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*self.client, &*self.miner)),
gas_price: request.gas_price.unwrap_or_else(|| {
default_gas_price(&*self.client, &*self.miner, self.gas_price_percentile)
}),
gas: request.gas.unwrap_or_else(|| self.miner.sensible_gas_limit()),
value: request.value.unwrap_or_else(|| 0.into()),
data: request.data.unwrap_or_else(Vec::new),
Expand Down Expand Up @@ -218,8 +224,8 @@ pub fn fetch_gas_price_corpus(
})
})
.map(move |prices| {
// produce a corpus from the vector, cache it, and return
// the median as the intended gas price.
// produce a corpus from the vector and cache it.
// It's later used to get a percentile for default gas price.
let corpus: ::stats::Corpus<_> = prices.into();
cache.lock().set_gas_price_corpus(corpus.clone());
corpus
Expand Down Expand Up @@ -258,6 +264,8 @@ pub struct LightDispatcher {
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
/// Nonce reservations
pub nonces: Arc<Mutex<nonce::Reservations>>,
/// Gas Price percentile value used as default gas price.
pub gas_price_percentile: usize,
}

impl LightDispatcher {
Expand All @@ -271,6 +279,7 @@ impl LightDispatcher {
cache: Arc<Mutex<LightDataCache>>,
transaction_queue: Arc<RwLock<LightTransactionQueue>>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
) -> Self {
LightDispatcher {
sync,
Expand All @@ -279,6 +288,7 @@ impl LightDispatcher {
cache,
transaction_queue,
nonces,
gas_price_percentile,
}
}

Expand Down Expand Up @@ -345,15 +355,16 @@ impl Dispatcher for LightDispatcher {
};

// fast path for known gas price.
let gas_price_percentile = self.gas_price_percentile;
let gas_price = match request_gas_price {
Some(gas_price) => Either::A(future::ok(with_gas_price(gas_price))),
None => Either::B(fetch_gas_price_corpus(
self.sync.clone(),
self.client.clone(),
self.on_demand.clone(),
self.cache.clone()
).and_then(|corp| match corp.median() {
Some(median) => Ok(*median),
).and_then(move |corp| match corp.percentile(gas_price_percentile) {
Some(percentile) => Ok(*percentile),
None => Ok(DEFAULT_GAS_PRICE), // fall back to default on error.
}).map(with_gas_price))
};
Expand Down Expand Up @@ -738,11 +749,11 @@ fn decrypt(accounts: &AccountProvider, address: Address, msg: Bytes, password: S
}

/// Extract the default gas price from a client and miner.
pub fn default_gas_price<C, M>(client: &C, miner: &M) -> U256 where
pub fn default_gas_price<C, M>(client: &C, miner: &M, percentile: usize) -> U256 where
C: MiningBlockChainClient,
M: MinerService,
{
client.gas_price_corpus(100).median().cloned().unwrap_or_else(|| miner.sensible_gas_price())
client.gas_price_corpus(100).percentile(percentile).cloned().unwrap_or_else(|| miner.sensible_gas_price())
}

/// Convert RPC confirmation payload to signer confirmation payload.
Expand Down
7 changes: 5 additions & 2 deletions rpc/src/v1/helpers/light_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ pub struct LightFetch {
pub sync: Arc<LightSync>,
/// The light data cache.
pub cache: Arc<Mutex<Cache>>,
/// Gas Price percentile
pub gas_price_percentile: usize,
}

/// Extract a transaction at given index.
Expand Down Expand Up @@ -203,15 +205,16 @@ impl LightFetch {
None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))),
};

let gas_price_percentile = self.gas_price_percentile;
let gas_price_fut = match req.gas_price {
Some(price) => Either::A(future::ok(price)),
None => Either::B(dispatch::fetch_gas_price_corpus(
self.sync.clone(),
self.client.clone(),
self.on_demand.clone(),
self.cache.clone(),
).map(|corp| match corp.median() {
Some(median) => *median,
).map(move |corp| match corp.percentile(gas_price_percentile) {
Some(percentile) => *percentile,
None => DEFAULT_GAS_PRICE.into(),
}))
};
Expand Down
5 changes: 4 additions & 1 deletion rpc/src/v1/impls/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub struct EthClientOptions {
pub allow_pending_receipt_query: bool,
/// Send additional block number when asking for work
pub send_block_number_in_get_work: bool,
/// Gas Price Percentile used as default gas price.
pub gas_price_percentile: usize,
}

impl EthClientOptions {
Expand All @@ -84,6 +86,7 @@ impl Default for EthClientOptions {
pending_nonce_from_queue: false,
allow_pending_receipt_query: true,
send_block_number_in_get_work: true,
gas_price_percentile: 50,
}
}
}
Expand Down Expand Up @@ -338,7 +341,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
}

fn gas_price(&self) -> Result<RpcU256> {
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner)))
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
}

fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>> {
Expand Down
4 changes: 3 additions & 1 deletion rpc/src/v1/impls/eth_pubsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ impl EthPubSubClient<LightFetch> {
sync: Arc<LightSync>,
cache: Arc<Mutex<Cache>>,
remote: Remote,
gas_price_percentile: usize,
) -> Self {
let fetch = LightFetch {
client,
on_demand,
sync,
cache
cache,
gas_price_percentile,
};
EthPubSubClient::new(Arc::new(fetch), remote)
}
Expand Down
19 changes: 12 additions & 7 deletions rpc/src/v1/impls/light/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub struct EthClient<T> {
accounts: Arc<AccountProvider>,
cache: Arc<Mutex<LightDataCache>>,
polls: Mutex<PollManager<PollFilter>>,
gas_price_percentile: usize,
}

impl<T> Clone for EthClient<T> {
Expand All @@ -75,6 +76,7 @@ impl<T> Clone for EthClient<T> {
accounts: self.accounts.clone(),
cache: self.cache.clone(),
polls: Mutex::new(PollManager::new()),
gas_price_percentile: self.gas_price_percentile,
}
}
}
Expand All @@ -89,15 +91,17 @@ impl<T: LightChainClient + 'static> EthClient<T> {
transaction_queue: Arc<RwLock<TransactionQueue>>,
accounts: Arc<AccountProvider>,
cache: Arc<Mutex<LightDataCache>>,
gas_price_percentile: usize,
) -> Self {
EthClient {
sync: sync,
client: client,
on_demand: on_demand,
transaction_queue: transaction_queue,
accounts: accounts,
cache: cache,
sync,
client,
on_demand,
transaction_queue,
accounts,
cache,
polls: Mutex::new(PollManager::new()),
gas_price_percentile,
}
}

Expand All @@ -108,6 +112,7 @@ impl<T: LightChainClient + 'static> EthClient<T> {
on_demand: self.on_demand.clone(),
sync: self.sync.clone(),
cache: self.cache.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}

Expand Down Expand Up @@ -239,7 +244,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {

fn gas_price(&self) -> Result<RpcU256> {
Ok(self.cache.lock().gas_price_corpus()
.and_then(|c| c.median().cloned())
.and_then(|c| c.percentile(self.gas_price_percentile).cloned())
.map(RpcU256::from)
.unwrap_or_else(Default::default))
}
Expand Down
Loading