add a cli flag
This commit is contained in:
parent
01bf483b63
commit
5e7c21ad4a
@ -61,6 +61,7 @@ pass = "test_pass"
|
|||||||
|
|
||||||
[mining]
|
[mining]
|
||||||
author = "0xdeadbeefcafe0000000000000000000000000001"
|
author = "0xdeadbeefcafe0000000000000000000000000001"
|
||||||
|
consensus_signer = "0xdeadbeefcafe0000000000000000000000000001"
|
||||||
force_sealing = true
|
force_sealing = true
|
||||||
reseal_on_txs = "all"
|
reseal_on_txs = "all"
|
||||||
reseal_min_period = 4000
|
reseal_min_period = 4000
|
||||||
|
@ -40,6 +40,7 @@ pass = "password"
|
|||||||
|
|
||||||
[mining]
|
[mining]
|
||||||
author = "0xdeadbeefcafe0000000000000000000000000001"
|
author = "0xdeadbeefcafe0000000000000000000000000001"
|
||||||
|
consensus_signer = "0xdeadbeefcafe0000000000000000000000000001"
|
||||||
force_sealing = true
|
force_sealing = true
|
||||||
reseal_on_txs = "all"
|
reseal_on_txs = "all"
|
||||||
reseal_min_period = 4000
|
reseal_min_period = 4000
|
||||||
|
@ -178,6 +178,8 @@ usage! {
|
|||||||
// -- Sealing/Mining Options
|
// -- Sealing/Mining Options
|
||||||
flag_author: Option<String> = None,
|
flag_author: Option<String> = None,
|
||||||
or |c: &Config| otry!(c.mining).author.clone().map(Some),
|
or |c: &Config| otry!(c.mining).author.clone().map(Some),
|
||||||
|
flag_engine_signer: Option<String> = None,
|
||||||
|
or |c: &Config| otry!(c.mining).consensus_signer.clone().map(Some),
|
||||||
flag_force_sealing: bool = false,
|
flag_force_sealing: bool = false,
|
||||||
or |c: &Config| otry!(c.mining).force_sealing.clone(),
|
or |c: &Config| otry!(c.mining).force_sealing.clone(),
|
||||||
flag_reseal_on_txs: String = "own",
|
flag_reseal_on_txs: String = "own",
|
||||||
@ -367,6 +369,7 @@ struct Dapps {
|
|||||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||||
struct Mining {
|
struct Mining {
|
||||||
author: Option<String>,
|
author: Option<String>,
|
||||||
|
consensus_signer: Option<String>,
|
||||||
force_sealing: Option<bool>,
|
force_sealing: Option<bool>,
|
||||||
reseal_on_txs: Option<String>,
|
reseal_on_txs: Option<String>,
|
||||||
reseal_min_period: Option<u64>,
|
reseal_min_period: Option<u64>,
|
||||||
@ -569,6 +572,7 @@ mod tests {
|
|||||||
|
|
||||||
// -- Sealing/Mining Options
|
// -- Sealing/Mining Options
|
||||||
flag_author: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
flag_author: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
||||||
|
flag_engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
||||||
flag_force_sealing: true,
|
flag_force_sealing: true,
|
||||||
flag_reseal_on_txs: "all".into(),
|
flag_reseal_on_txs: "all".into(),
|
||||||
flag_reseal_min_period: 4000u64,
|
flag_reseal_min_period: 4000u64,
|
||||||
@ -738,6 +742,7 @@ mod tests {
|
|||||||
}),
|
}),
|
||||||
mining: Some(Mining {
|
mining: Some(Mining {
|
||||||
author: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
author: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
||||||
|
consensus_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()),
|
||||||
force_sealing: Some(true),
|
force_sealing: Some(true),
|
||||||
reseal_on_txs: Some("all".into()),
|
reseal_on_txs: Some("all".into()),
|
||||||
reseal_min_period: Some(4000),
|
reseal_min_period: Some(4000),
|
||||||
|
@ -149,6 +149,10 @@ Sealing/Mining Options:
|
|||||||
for sending block rewards from sealed blocks.
|
for sending block rewards from sealed blocks.
|
||||||
NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.
|
NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.
|
||||||
(default: {flag_author:?})
|
(default: {flag_author:?})
|
||||||
|
--engine-signer ADDRESS Specify the address which should be used to
|
||||||
|
sign consensus messages and issue blocks.
|
||||||
|
Relevant only to non-PoW chains.
|
||||||
|
(default: {flag_engine_signer:?})
|
||||||
--force-sealing Force the node to author new blocks as if it were
|
--force-sealing Force the node to author new blocks as if it were
|
||||||
always sealing/mining.
|
always sealing/mining.
|
||||||
(default: {flag_force_sealing})
|
(default: {flag_force_sealing})
|
||||||
|
@ -300,6 +300,7 @@ impl Configuration {
|
|||||||
gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)),
|
gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)),
|
||||||
gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)),
|
gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)),
|
||||||
transactions_limit: self.args.flag_tx_queue_size,
|
transactions_limit: self.args.flag_tx_queue_size,
|
||||||
|
consensus_signer: try!(self.consensus_signer()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(extras)
|
Ok(extras)
|
||||||
@ -309,6 +310,10 @@ impl Configuration {
|
|||||||
to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone()))
|
to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn consensus_signer(&self) -> Result<Address, String> {
|
||||||
|
to_address(self.args.flag_engine_signer.clone())
|
||||||
|
}
|
||||||
|
|
||||||
fn format(&self) -> Result<Option<DataFormat>, String> {
|
fn format(&self) -> Result<Option<DataFormat>, String> {
|
||||||
match self.args.flag_format {
|
match self.args.flag_format {
|
||||||
Some(ref f) => Ok(Some(try!(f.parse()))),
|
Some(ref f) => Ok(Some(try!(f.parse()))),
|
||||||
|
@ -300,14 +300,14 @@ pub fn password_prompt() -> Result<String, String> {
|
|||||||
|
|
||||||
/// Read a password from password file.
|
/// Read a password from password file.
|
||||||
pub fn password_from_file(path: String) -> Result<String, String> {
|
pub fn password_from_file(path: String) -> Result<String, String> {
|
||||||
let passwords = try!(passwords_from_files(vec![path]));
|
let passwords = try!(passwords_from_files(&[path]));
|
||||||
// use only first password from the file
|
// use only first password from the file
|
||||||
passwords.get(0).map(String::to_owned)
|
passwords.get(0).map(String::to_owned)
|
||||||
.ok_or_else(|| "Password file seems to be empty.".to_owned())
|
.ok_or_else(|| "Password file seems to be empty.".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads passwords from files. Treats each line as a separate password.
|
/// Reads passwords from files. Treats each line as a separate password.
|
||||||
pub fn passwords_from_files(files: Vec<String>) -> Result<Vec<String>, String> {
|
pub fn passwords_from_files(files: &[String]) -> Result<Vec<String>, String> {
|
||||||
let passwords = files.iter().map(|filename| {
|
let passwords = files.iter().map(|filename| {
|
||||||
let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)));
|
let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)));
|
||||||
let reader = BufReader::new(&file);
|
let reader = BufReader::new(&file);
|
||||||
|
@ -204,6 +204,7 @@ pub struct MinerExtras {
|
|||||||
pub gas_floor_target: U256,
|
pub gas_floor_target: U256,
|
||||||
pub gas_ceil_target: U256,
|
pub gas_ceil_target: U256,
|
||||||
pub transactions_limit: usize,
|
pub transactions_limit: usize,
|
||||||
|
pub consensus_signer: Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MinerExtras {
|
impl Default for MinerExtras {
|
||||||
@ -214,6 +215,7 @@ impl Default for MinerExtras {
|
|||||||
gas_floor_target: U256::from(4_700_000),
|
gas_floor_target: U256::from(4_700_000),
|
||||||
gas_ceil_target: U256::from(6_283_184),
|
gas_ceil_target: U256::from(6_283_184),
|
||||||
transactions_limit: 1024,
|
transactions_limit: 1024,
|
||||||
|
consensus_signer: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,10 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
sync_config.warp_sync = cmd.warp_sync;
|
sync_config.warp_sync = cmd.warp_sync;
|
||||||
sync_config.download_old_blocks = cmd.download_old_blocks;
|
sync_config.download_old_blocks = cmd.download_old_blocks;
|
||||||
|
|
||||||
|
let passwords = try!(passwords_from_files(&cmd.acc_conf.password_files));
|
||||||
|
|
||||||
// prepare account provider
|
// prepare account provider
|
||||||
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf)));
|
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf, &passwords)));
|
||||||
|
|
||||||
// let the Engine access the accounts
|
// let the Engine access the accounts
|
||||||
spec.engine.register_account_provider(account_provider.clone());
|
spec.engine.register_account_provider(account_provider.clone());
|
||||||
@ -218,6 +220,10 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target);
|
miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target);
|
||||||
miner.set_extra_data(cmd.miner_extras.extra_data);
|
miner.set_extra_data(cmd.miner_extras.extra_data);
|
||||||
miner.set_transactions_limit(cmd.miner_extras.transactions_limit);
|
miner.set_transactions_limit(cmd.miner_extras.transactions_limit);
|
||||||
|
let consensus_signer = cmd.miner_extras.consensus_signer;
|
||||||
|
if passwords.into_iter().any(|p| miner.set_consensus_signer(consensus_signer, p).is_ok()) {
|
||||||
|
return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.consensus_signer));
|
||||||
|
}
|
||||||
|
|
||||||
// create client config
|
// create client config
|
||||||
let client_config = to_client_config(
|
let client_config = to_client_config(
|
||||||
@ -424,19 +430,17 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
|
|||||||
Err("daemon is no supported on windows".into())
|
Err("daemon is no supported on windows".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig) -> Result<AccountProvider, String> {
|
fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: &[String]) -> Result<AccountProvider, String> {
|
||||||
use ethcore::ethstore::EthStore;
|
use ethcore::ethstore::EthStore;
|
||||||
use ethcore::ethstore::dir::DiskDirectory;
|
use ethcore::ethstore::dir::DiskDirectory;
|
||||||
|
|
||||||
let passwords = try!(passwords_from_files(cfg.password_files));
|
|
||||||
|
|
||||||
let dir = Box::new(try!(DiskDirectory::create(dirs.keys.clone()).map_err(|e| format!("Could not open keys directory: {}", e))));
|
let dir = Box::new(try!(DiskDirectory::create(dirs.keys.clone()).map_err(|e| format!("Could not open keys directory: {}", e))));
|
||||||
let account_service = AccountProvider::new(Box::new(
|
let account_service = AccountProvider::new(Box::new(
|
||||||
try!(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e)))
|
try!(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e)))
|
||||||
));
|
));
|
||||||
|
|
||||||
for a in cfg.unlocked_accounts {
|
for a in cfg.unlocked_accounts {
|
||||||
if passwords.iter().find(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()).is_none() {
|
if passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) {
|
||||||
return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a));
|
return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user