Chain-selection from UI (#4859)
* First little bits for chain-selection. * Provide RPCs and get settings through to user defaults. * Hasty stash. * Fix updater accidentally redownloading. * Finish up. * Add JS tests. * Hypervisor should never run a binary modified before itself. * Style. * Help tweak. * Fix test compile. * Fix JS test * Build fix for tests. * Revert default chain name * Another test * Use spec name via client. * Fix mock up. * whitespace [ci:skip] * whitespace [ci:skip] * remove exit/restart endpoints.
This commit is contained in:
@@ -151,8 +151,9 @@ pub struct Client {
|
||||
factories: Factories,
|
||||
history: u64,
|
||||
rng: Mutex<OsRng>,
|
||||
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
|
||||
on_user_defaults_change: Mutex<Option<Box<FnMut(Option<Mode>) + 'static + Send>>>,
|
||||
registrar: Mutex<Option<Registry>>,
|
||||
exit_handler: Mutex<Option<Box<Fn(bool, Option<String>) + 'static + Send>>>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
@@ -240,8 +241,9 @@ impl Client {
|
||||
factories: factories,
|
||||
history: history,
|
||||
rng: Mutex::new(OsRng::new().map_err(::util::UtilError::StdIo)?),
|
||||
on_mode_change: Mutex::new(None),
|
||||
on_user_defaults_change: Mutex::new(None),
|
||||
registrar: Mutex::new(None),
|
||||
exit_handler: Mutex::new(None),
|
||||
});
|
||||
|
||||
{
|
||||
@@ -276,6 +278,11 @@ impl Client {
|
||||
self.notify.write().push(Arc::downgrade(&target));
|
||||
}
|
||||
|
||||
/// Set a closure to call when we want to restart the client
|
||||
pub fn set_exit_handler<F>(&self, f: F) where F: Fn(bool, Option<String>) + 'static + Send {
|
||||
*self.exit_handler.lock() = Some(Box::new(f));
|
||||
}
|
||||
|
||||
/// Returns engine reference.
|
||||
pub fn engine(&self) -> &Engine {
|
||||
&*self.engine
|
||||
@@ -294,9 +301,9 @@ impl Client {
|
||||
self.registrar.lock()
|
||||
}
|
||||
|
||||
/// Register an action to be done if a mode change happens.
|
||||
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
|
||||
*self.on_mode_change.lock() = Some(Box::new(f));
|
||||
/// Register an action to be done if a mode/spec_name change happens.
|
||||
pub fn on_user_defaults_change<F>(&self, f: F) where F: 'static + FnMut(Option<Mode>) + Send {
|
||||
*self.on_user_defaults_change.lock() = Some(Box::new(f));
|
||||
}
|
||||
|
||||
/// Flush the block import queue.
|
||||
@@ -651,7 +658,6 @@ impl Client {
|
||||
self.miner.clone()
|
||||
}
|
||||
|
||||
|
||||
/// Replace io channel. Useful for testing.
|
||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
||||
*self.io_channel.lock() = io_channel;
|
||||
@@ -1030,9 +1036,9 @@ impl BlockChainClient for Client {
|
||||
let mut mode = self.mode.lock();
|
||||
*mode = new_mode.clone().into();
|
||||
trace!(target: "mode", "Mode now {:?}", &*mode);
|
||||
if let Some(ref mut f) = *self.on_mode_change.lock() {
|
||||
if let Some(ref mut f) = *self.on_user_defaults_change.lock() {
|
||||
trace!(target: "mode", "Making callback...");
|
||||
f(&*mode)
|
||||
f(Some((&*mode).clone()))
|
||||
}
|
||||
}
|
||||
match new_mode {
|
||||
@@ -1042,6 +1048,22 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn spec_name(&self) -> String {
|
||||
self.config.spec_name.clone()
|
||||
}
|
||||
|
||||
fn set_spec_name(&self, new_spec_name: String) {
|
||||
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
|
||||
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
||||
return;
|
||||
}
|
||||
if let Some(ref h) = *self.exit_handler.lock() {
|
||||
(*h)(true, Some(new_spec_name));
|
||||
} else {
|
||||
warn!("Not hypervised; cannot change chain.");
|
||||
}
|
||||
}
|
||||
|
||||
fn best_block_header(&self) -> encoded::Header {
|
||||
self.chain.read().best_block_header()
|
||||
}
|
||||
|
||||
@@ -123,6 +123,8 @@ pub struct ClientConfig {
|
||||
pub db_wal: bool,
|
||||
/// Operating mode
|
||||
pub mode: Mode,
|
||||
/// The chain spec name
|
||||
pub spec_name: String,
|
||||
/// Type of block verifier used by client.
|
||||
pub verifier_type: VerifierType,
|
||||
/// State db cache-size.
|
||||
|
||||
@@ -721,6 +721,10 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
|
||||
fn set_mode(&self, _: Mode) { unimplemented!(); }
|
||||
|
||||
fn spec_name(&self) -> String { "foundation".into() }
|
||||
|
||||
fn set_spec_name(&self, _: String) { unimplemented!(); }
|
||||
|
||||
fn disable(&self) { unimplemented!(); }
|
||||
|
||||
fn pruning_info(&self) -> PruningInfo {
|
||||
|
||||
@@ -241,6 +241,12 @@ pub trait BlockChainClient : Sync + Send {
|
||||
/// Set the mode.
|
||||
fn set_mode(&self, mode: Mode);
|
||||
|
||||
/// Get the chain spec name.
|
||||
fn spec_name(&self) -> String;
|
||||
|
||||
/// Set the chain via a spec name.
|
||||
fn set_spec_name(&self, spec_name: String);
|
||||
|
||||
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
||||
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
||||
fn disable(&self);
|
||||
|
||||
Reference in New Issue
Block a user