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",
|
"ethjson 0.1.0",
|
||||||
"ethkey 0.3.0",
|
"ethkey 0.3.0",
|
||||||
"evm 0.1.0",
|
"evm 0.1.0",
|
||||||
|
"fetch 0.1.0",
|
||||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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-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-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-machine 0.1.0",
|
"parity-machine 0.1.0",
|
||||||
|
"parity-runtime 0.1.0",
|
||||||
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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"
|
criterion = "0.2"
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
ethcore-accounts = { path = "../accounts" }
|
ethcore-accounts = { path = "../accounts" }
|
||||||
|
fetch = { path = "../util/fetch" }
|
||||||
kvdb-rocksdb = "0.1.3"
|
kvdb-rocksdb = "0.1.3"
|
||||||
|
parity-runtime = { path = "../util/runtime" }
|
||||||
rlp_compress = { path = "../util/rlp-compress" }
|
rlp_compress = { path = "../util/rlp-compress" }
|
||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
trie-standardmap = "0.1"
|
trie-standardmap = "0.1"
|
||||||
|
@ -143,6 +143,12 @@ extern crate serde_derive;
|
|||||||
#[cfg_attr(test, macro_use)]
|
#[cfg_attr(test, macro_use)]
|
||||||
extern crate evm;
|
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 block;
|
||||||
pub mod builtin;
|
pub mod builtin;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
@ -873,6 +873,32 @@ impl miner::MinerService for Miner {
|
|||||||
self.params.read().gas_range_target.0 / 5
|
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>(
|
fn import_external_transactions<C: miner::BlockChainClient>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
@ -1654,4 +1680,60 @@ mod tests {
|
|||||||
|
|
||||||
assert!(miner.is_currently_sealing());
|
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.
|
/// Suggested gas limit.
|
||||||
fn sensible_gas_limit(&self) -> U256;
|
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.
|
/// Recalibrate current gas price.
|
||||||
pub fn recalibrate<F: FnOnce(U256) + Sync + Send + 'static>(&mut self, set_price: F) {
|
pub fn recalibrate<F: FnOnce(U256) + Sync + Send + 'static>(&mut self, set_price: F) {
|
||||||
match *self {
|
match *self {
|
||||||
GasPricer::Fixed(ref max) => set_price(max.clone()),
|
GasPricer::Fixed(ref curr) => set_price(curr.clone()),
|
||||||
#[cfg(feature = "price-info")]
|
#[cfg(feature = "price-info")]
|
||||||
GasPricer::Calibrated(ref mut cal) => cal.recalibrate(set_price),
|
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,
|
F: Fetch + 'static,
|
||||||
{
|
{
|
||||||
|
|
||||||
fn set_min_gas_price(&self, _gas_price: U256) -> Result<bool> {
|
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool> {
|
||||||
warn!("setMinGasPrice is deprecated. Ignoring request.");
|
match self.miner.set_minimal_gas_price(gas_price.into()) {
|
||||||
Ok(false)
|
Ok(success) => Ok(success),
|
||||||
|
Err(e) => Err(errors::unsupported(e, None)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_transactions_limit(&self, _limit: usize) -> Result<bool> {
|
fn set_transactions_limit(&self, _limit: usize) -> Result<bool> {
|
||||||
|
@ -49,6 +49,8 @@ pub struct TestMinerService {
|
|||||||
pub pending_receipts: Mutex<Vec<RichReceipt>>,
|
pub pending_receipts: Mutex<Vec<RichReceipt>>,
|
||||||
/// Next nonces.
|
/// Next nonces.
|
||||||
pub next_nonces: RwLock<HashMap<Address, U256>>,
|
pub next_nonces: RwLock<HashMap<Address, U256>>,
|
||||||
|
/// Minimum gas price
|
||||||
|
pub min_gas_price: RwLock<Option<U256>>,
|
||||||
/// Signer (if any)
|
/// Signer (if any)
|
||||||
pub signer: RwLock<Option<Box<EngineSigner>>>,
|
pub signer: RwLock<Option<Box<EngineSigner>>>,
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ impl Default for TestMinerService {
|
|||||||
local_transactions: Default::default(),
|
local_transactions: Default::default(),
|
||||||
pending_receipts: Default::default(),
|
pending_receipts: Default::default(),
|
||||||
next_nonces: Default::default(),
|
next_nonces: Default::default(),
|
||||||
|
min_gas_price: RwLock::new(Some(0.into())),
|
||||||
authoring_params: RwLock::new(AuthoringParams {
|
authoring_params: RwLock::new(AuthoringParams {
|
||||||
author: Address::zero(),
|
author: Address::zero(),
|
||||||
gas_range_target: (12345.into(), 54321.into()),
|
gas_range_target: (12345.into(), 54321.into()),
|
||||||
@ -279,4 +282,18 @@ impl MinerService for TestMinerService {
|
|||||||
fn sensible_gas_limit(&self) -> U256 {
|
fn sensible_gas_limit(&self) -> U256 {
|
||||||
0x5208.into()
|
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());
|
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 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()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user