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

Commit

Permalink
Chain-selection from UI (#4859)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
gavofyork authored Mar 13, 2017
1 parent 8a67a0a commit 3041c95
Show file tree
Hide file tree
Showing 28 changed files with 372 additions and 50 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
description = "Parity Ethereum client"
name = "parity"
version = "1.6.0"
version = "1.7.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]

Expand Down
38 changes: 30 additions & 8 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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),
});

{
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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()
}
Expand Down
2 changes: 2 additions & 0 deletions ethcore/src/client/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions ethcore/src/client/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 12 additions & 1 deletion js/src/api/rpc/parity/parity.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,15 @@ export default class Parity {
.execute('parity_mode');
}

// DEPRECATED - use chain instead.
netChain () {
return this._transport
.execute('parity_netChain');
.execute('parity_chain');
}

chain () {
return this._transport
.execute('parity_chain');
}

netPeers () {
Expand Down Expand Up @@ -454,6 +460,11 @@ export default class Parity {
.execute('parity_setMode', mode);
}

setChain (specName) {
return this._transport
.execute('parity_setChain', specName);
}

setNewDappsAddresses (addresses) {
return this._transport
.execute('parity_setNewDappsAddresses', addresses ? inAddresses(addresses) : null);
Expand Down
2 changes: 1 addition & 1 deletion js/src/jsonrpc/interfaces/parity.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export default {
'2017-01-20 18:14:19 Configured for DevelopmentChain using InstantSeal engine',
'2017-01-20 18:14:19 Operating mode: active',
'2017-01-20 18:14:19 State DB configuration: fast',
'2017-01-20 18:14:19 Starting Parity/v1.6.0-unstable-2ae8b4c-20170120/x86_64-linux-gnu/rustc1.14.0'
'2017-01-20 18:14:19 Starting Parity/v1.7.0-unstable-2ae8b4c-20170120/x86_64-linux-gnu/rustc1.14.0'
]
}
},
Expand Down
105 changes: 100 additions & 5 deletions js/src/views/Settings/Parity/parity.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default class Parity extends Component {
features = FeaturesStore.get();

componentWillMount () {
this.store.loadChain();
return this.store.loadMode();
}

Expand All @@ -50,11 +51,12 @@ export default class Parity extends Component {
<div>
<FormattedMessage
id='settings.parity.overview_0'
defaultMessage='Control the Parity node settings and mode of operation via this interface.'
defaultMessage='Control the Parity node settings and nature of syncing via this interface.'
/>
</div>
</div>
<div className={ layout.details }>
{ this.renderChains() }
{ this.renderModes() }
<Features />
<LanguageSelector />
Expand All @@ -65,12 +67,12 @@ export default class Parity extends Component {
);
}

renderItem (mode, label) {
renderItem (name, label) {
return (
<MenuItem
key={ mode }
key={ name }
label={ label }
value={ mode }
value={ name }
>
{ label }
</MenuItem>
Expand Down Expand Up @@ -134,7 +136,7 @@ export default class Parity extends Component {
hint={
<FormattedMessage
id='settings.parity.modes.hint'
defaultMessage='the syning mode for the Parity node'
defaultMessage='the syncing mode for the Parity node'
/>
}
label={
Expand Down Expand Up @@ -182,7 +184,100 @@ export default class Parity extends Component {
);
}

renderChains () {
const { chain } = this.store;

return (
<Select
id='parityChainSelect'
hint={
<FormattedMessage
id='settings.parity.chains.hint'
defaultMessage='the chain for the Parity node to sync to'
/>
}
label={
<FormattedMessage
id='settings.parity.chains.label'
defaultMessage='chain/network to sync'
/>
}
onChange={ this.onChangeChain }
value={ chain }
>
{
this.renderItem('foundation', (
<FormattedMessage
id='settings.parity.chains.chain_foundation'
defaultMessage='Parity syncs to the Ethereum network launched by the Ethereum Foundation'
/>
))
}
{
this.renderItem('kovan', (
<FormattedMessage
id='settings.parity.chains.chain_kovan'
defaultMessage='Parity syncs to the Kovan test network'
/>
))
}
{
this.renderItem('olympic', (
<FormattedMessage
id='settings.parity.chains.chain_olympic'
defaultMessage='Parity syncs to the Olympic test network'
/>
))
}
{
this.renderItem('morden', (
<FormattedMessage
id='settings.parity.chains.cmorden_kovan'
defaultMessage='Parity syncs to Morden (Classic) test network'
/>
))
}
{
this.renderItem('ropsten', (
<FormattedMessage
id='settings.parity.chains.chain_ropsten'
defaultMessage='Parity syncs to the Ropsten test network'
/>
))
}
{
this.renderItem('classic', (
<FormattedMessage
id='settings.parity.chains.chain_classic'
defaultMessage='Parity syncs to the Ethereum Classic network'
/>
))
}
{
this.renderItem('expanse', (
<FormattedMessage
id='settings.parity.chains.chain_expanse'
defaultMessage='Parity syncs to the Expanse network'
/>
))
}
{
this.renderItem('dev', (
<FormattedMessage
id='settings.parity.chains.chain_dev'
defaultMessage='Parity uses a local development chain'
/>
))
}
</Select>
);
}

onChangeMode = (event, index, mode) => {
this.store.changeMode(mode || event.target.value);
}

onChangeChain = (event, index, chain) => {
this.store.changeChain(chain || event.target.value);
}
}
28 changes: 28 additions & 0 deletions js/src/views/Settings/Parity/parity.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ describe('views/Settings/Parity', () => {
beforeEach(() => {
render();
sinon.spy(instance.store, 'loadMode');
sinon.spy(instance.store, 'loadChain');
});

afterEach(() => {
instance.store.loadMode.restore();
instance.store.loadChain.restore();
});

it('renders defaults', () => {
Expand All @@ -56,6 +58,10 @@ describe('views/Settings/Parity', () => {
it('loads the mode in the store', () => {
expect(instance.store.loadMode).to.have.been.called;
});

it('loads the chain in the store', () => {
expect(instance.store.loadChain).to.have.been.called;
});
});

describe('components', () => {
Expand Down Expand Up @@ -94,5 +100,27 @@ describe('views/Settings/Parity', () => {
expect(instance.store.changeMode).to.have.been.calledWith('dark');
});
});

describe('chain selector', () => {
let select;

beforeEach(() => {
select = component.find('Select[id="parityChainSelect"]');
sinon.spy(instance.store, 'changeChain');
});

afterEach(() => {
instance.store.changeChain.restore();
});

it('renders a chain selector', () => {
expect(select).to.have.length(1);
});

it('changes the chain on the store when changed', () => {
select.simulate('change', { target: { value: 'dark' } });
expect(instance.store.changeChain).to.have.been.calledWith('dark');
});
});
});
});
4 changes: 3 additions & 1 deletion js/src/views/Settings/Parity/parity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ function createApi () {
return {
parity: {
mode: sinon.stub().resolves('passive'),
setMode: sinon.stub().resolves(true)
setMode: sinon.stub().resolves(true),
chain: sinon.stub().resolves('foundation'),
setChain: sinon.stub().resolves(true)
}
};
}
Expand Down
Loading

0 comments on commit 3041c95

Please sign in to comment.