Revive parity_setMinGasPrice RPC call (#10294)
* Add function to update minimum gas price * Update TestMinerService to handle min_gas_price changes * Place minimum gas price test behind feature flag * Update check for fixed gas pricer to be more explicit * Use errors::unsupported instead of errors::request_rejected * Add test that fails to set minimum gas price * Fix test that should fail when setting new gas price * Put dev dependencies behind feature flag * Fix deadlock in set_minimal_gas_price() * Update RPC tests with mocked error response * Remove unnecessary cfg flag * Remove duplicate crate imports
This commit is contained in:
parent
6dfc1bd474
commit
8e866ee551
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -707,6 +707,7 @@ dependencies = [
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
"evm 0.1.0",
|
||||
"fetch 0.1.0",
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -728,6 +729,7 @@ dependencies = [
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-machine 0.1.0",
|
||||
"parity-runtime 0.1.0",
|
||||
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -76,7 +76,9 @@ blooms-db = { path = "../util/blooms-db" }
|
||||
criterion = "0.2"
|
||||
env_logger = "0.5"
|
||||
ethcore-accounts = { path = "../accounts" }
|
||||
fetch = { path = "../util/fetch" }
|
||||
kvdb-rocksdb = "0.1.3"
|
||||
parity-runtime = { path = "../util/runtime" }
|
||||
rlp_compress = { path = "../util/rlp-compress" }
|
||||
tempdir = "0.3"
|
||||
trie-standardmap = "0.1"
|
||||
|
@ -143,6 +143,12 @@ extern crate serde_derive;
|
||||
#[cfg_attr(test, macro_use)]
|
||||
extern crate evm;
|
||||
|
||||
#[cfg(all(test, feature = "price-info"))]
|
||||
extern crate fetch;
|
||||
|
||||
#[cfg(all(test, feature = "price-info"))]
|
||||
extern crate parity_runtime;
|
||||
|
||||
pub mod block;
|
||||
pub mod builtin;
|
||||
pub mod client;
|
||||
|
@ -873,6 +873,32 @@ impl miner::MinerService for Miner {
|
||||
self.params.read().gas_range_target.0 / 5
|
||||
}
|
||||
|
||||
fn set_minimal_gas_price(&self, new_price: U256) -> Result<bool, &str> {
|
||||
match *self.gas_pricer.lock() {
|
||||
// Binding the gas pricer to `gp` here to prevent
|
||||
// a deadlock when calling recalibrate()
|
||||
ref mut gp @ GasPricer::Fixed(_) => {
|
||||
trace!(target: "miner", "minimal_gas_price: recalibrating fixed...");
|
||||
*gp = GasPricer::new_fixed(new_price);
|
||||
|
||||
let txq = self.transaction_queue.clone();
|
||||
let mut options = self.options.pool_verification_options.clone();
|
||||
gp.recalibrate(move |gas_price| {
|
||||
debug!(target: "miner", "minimal_gas_price: Got gas price! {}", gas_price);
|
||||
options.minimal_gas_price = gas_price;
|
||||
txq.set_verifier_options(options);
|
||||
});
|
||||
|
||||
Ok(true)
|
||||
},
|
||||
#[cfg(feature = "price-info")]
|
||||
GasPricer::Calibrated(_) => {
|
||||
let error_msg = "Can't update fixed gas price while automatic gas calibration is enabled.";
|
||||
return Err(error_msg);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn import_external_transactions<C: miner::BlockChainClient>(
|
||||
&self,
|
||||
chain: &C,
|
||||
@ -1654,4 +1680,60 @@ mod tests {
|
||||
|
||||
assert!(miner.is_currently_sealing());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_new_minimum_gas_price() {
|
||||
// Creates a new GasPricer::Fixed behind the scenes
|
||||
let miner = Miner::new_for_tests(&Spec::new_test(), None);
|
||||
|
||||
let expected_minimum_gas_price: U256 = 0x1337.into();
|
||||
miner.set_minimal_gas_price(expected_minimum_gas_price).unwrap();
|
||||
|
||||
let txq_options = miner.transaction_queue.status().options;
|
||||
let current_minimum_gas_price = txq_options.minimal_gas_price;
|
||||
|
||||
assert!(current_minimum_gas_price == expected_minimum_gas_price);
|
||||
}
|
||||
|
||||
#[cfg(feature = "price-info")]
|
||||
fn dynamic_gas_pricer() -> GasPricer {
|
||||
use std::time::Duration;
|
||||
use parity_runtime::Executor;
|
||||
use fetch::Client as FetchClient;
|
||||
use ethcore_miner::gas_price_calibrator::{GasPriceCalibrator, GasPriceCalibratorOptions};
|
||||
|
||||
// Don't really care about any of these settings since
|
||||
// the gas pricer is never actually going to be used
|
||||
let fetch = FetchClient::new(1).unwrap();
|
||||
let p = Executor::new_sync();
|
||||
|
||||
GasPricer::new_calibrated(
|
||||
GasPriceCalibrator::new(
|
||||
GasPriceCalibratorOptions {
|
||||
usd_per_tx: 0.0,
|
||||
recalibration_period: Duration::from_secs(0),
|
||||
},
|
||||
fetch,
|
||||
p,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "price-info")]
|
||||
fn should_fail_to_set_new_minimum_gas_price() {
|
||||
// We get a fixed gas pricer by default, need to change that
|
||||
let miner = Miner::new_for_tests(&Spec::new_test(), None);
|
||||
let calibrated_gas_pricer = dynamic_gas_pricer();
|
||||
*miner.gas_pricer.lock() = calibrated_gas_pricer;
|
||||
|
||||
let expected_minimum_gas_price: U256 = 0x1337.into();
|
||||
let result = miner.set_minimal_gas_price(expected_minimum_gas_price);
|
||||
assert!(result.is_err());
|
||||
|
||||
let received_error_msg = result.unwrap_err();
|
||||
let expected_error_msg = "Can't update fixed gas price while automatic gas calibration is enabled.";
|
||||
|
||||
assert!(received_error_msg == expected_error_msg);
|
||||
}
|
||||
}
|
||||
|
@ -205,4 +205,8 @@ pub trait MinerService : Send + Sync {
|
||||
|
||||
/// Suggested gas limit.
|
||||
fn sensible_gas_limit(&self) -> U256;
|
||||
|
||||
/// Set a new minimum gas limit.
|
||||
/// Will not work if dynamic gas calibration is set.
|
||||
fn set_minimal_gas_price(&self, gas_price: U256) -> Result<bool, &str>;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ impl GasPricer {
|
||||
/// Recalibrate current gas price.
|
||||
pub fn recalibrate<F: FnOnce(U256) + Sync + Send + 'static>(&mut self, set_price: F) {
|
||||
match *self {
|
||||
GasPricer::Fixed(ref max) => set_price(max.clone()),
|
||||
GasPricer::Fixed(ref curr) => set_price(curr.clone()),
|
||||
#[cfg(feature = "price-info")]
|
||||
GasPricer::Calibrated(ref mut cal) => cal.recalibrate(set_price),
|
||||
}
|
||||
|
@ -118,9 +118,11 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
||||
F: Fetch + 'static,
|
||||
{
|
||||
|
||||
fn set_min_gas_price(&self, _gas_price: U256) -> Result<bool> {
|
||||
warn!("setMinGasPrice is deprecated. Ignoring request.");
|
||||
Ok(false)
|
||||
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool> {
|
||||
match self.miner.set_minimal_gas_price(gas_price.into()) {
|
||||
Ok(success) => Ok(success),
|
||||
Err(e) => Err(errors::unsupported(e, None)),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_transactions_limit(&self, _limit: usize) -> Result<bool> {
|
||||
|
@ -49,6 +49,8 @@ pub struct TestMinerService {
|
||||
pub pending_receipts: Mutex<Vec<RichReceipt>>,
|
||||
/// Next nonces.
|
||||
pub next_nonces: RwLock<HashMap<Address, U256>>,
|
||||
/// Minimum gas price
|
||||
pub min_gas_price: RwLock<Option<U256>>,
|
||||
/// Signer (if any)
|
||||
pub signer: RwLock<Option<Box<EngineSigner>>>,
|
||||
|
||||
@ -63,6 +65,7 @@ impl Default for TestMinerService {
|
||||
local_transactions: Default::default(),
|
||||
pending_receipts: Default::default(),
|
||||
next_nonces: Default::default(),
|
||||
min_gas_price: RwLock::new(Some(0.into())),
|
||||
authoring_params: RwLock::new(AuthoringParams {
|
||||
author: Address::zero(),
|
||||
gas_range_target: (12345.into(), 54321.into()),
|
||||
@ -279,4 +282,18 @@ impl MinerService for TestMinerService {
|
||||
fn sensible_gas_limit(&self) -> U256 {
|
||||
0x5208.into()
|
||||
}
|
||||
|
||||
fn set_minimal_gas_price(&self, gas_price: U256) -> Result<bool, &str> {
|
||||
let mut new_price = self.min_gas_price.write();
|
||||
match *new_price {
|
||||
Some(ref mut v) => {
|
||||
*v = gas_price;
|
||||
Ok(true)
|
||||
},
|
||||
None => {
|
||||
let error_msg = "Can't update fixed gas price while automatic gas calibration is enabled.";
|
||||
Err(error_msg)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,25 @@ fn rpc_parity_set_min_gas_price() {
|
||||
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_set_min_gas_price_with_automated_calibration_enabled() {
|
||||
let miner = miner_service();
|
||||
*miner.min_gas_price.write() = None;
|
||||
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let updater = updater_service();
|
||||
|
||||
let mut io = IoHandler::new();
|
||||
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xdeadbeef"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Can't update fixed gas price while automatic gas calibration is enabled."},"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user