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

Chain-selection from UI #4859

Merged
merged 22 commits into from
Mar 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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