From 36e230ee165759e2a233e7511070a9c91ab6e106 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Fri, 5 Jan 2018 13:49:07 +0100 Subject: [PATCH] Expanse Byzantium update w/ correct metropolis difficulty increment divisor (#7463) * Byzantium Update for Expanse Here the changes go. Hope I didnt miss anything. * expip2 changes - update duration limit * Fix missing EXPIP-2 fields * Format numbers as hex * Fix compilation errors * Group expanse chain spec fields together * Set metropolisDifficultyIncrementDivisor for Expanse * Revert #7437 * Add Expanse block 900_000 hash checkpoint --- ethcore/res/ethereum/expanse.json | 92 +++++++++++++++++++ ethcore/src/ethereum/ethash.rs | 17 +++- ethcore/src/ethereum/mod.rs | 5 + ethcore/src/tests/helpers.rs | 2 + js-old/src/i18n/_default/settings.js | 3 +- js-old/src/i18n/nl/settings.js | 3 +- js-old/src/i18n/zh-Hant-TW/settings.js | 3 +- js-old/src/i18n/zh/settings.js | 3 +- .../CurrencySymbol/currencySymbol.example.js | 8 +- .../src/ui/CurrencySymbol/currencySymbol.js | 6 +- .../ui/CurrencySymbol/currencySymbol.spec.js | 10 +- js-old/src/views/Settings/Parity/parity.js | 10 +- js/i18n/_default/settings.js | 3 +- js/i18n/nl/settings.js | 3 +- js/i18n/zh-Hant-TW/settings.js | 3 +- js/i18n/zh/settings.js | 3 +- json/src/spec/ethash.rs | 12 +++ parity/cli/mod.rs | 4 +- parity/params.rs | 8 +- rpc/src/v1/traits/parity_set.rs | 4 +- 20 files changed, 182 insertions(+), 20 deletions(-) create mode 100644 ethcore/res/ethereum/expanse.json diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json new file mode 100644 index 000000000..b9b734e31 --- /dev/null +++ b/ethcore/res/ethereum/expanse.json @@ -0,0 +1,92 @@ +{ + "name": "Expanse", + "dataDir": "expanse", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "difficultyIncrementDivisor": "0x3C", + "durationLimit": "0x3C", + "blockReward": "0x6f05b59d3b200000", + "homesteadTransition": "0x30d40", + "difficultyHardforkTransition": "0x59d9", + "difficultyHardforkBoundDivisor": "0x0200", + "bombDefuseTransition": "0x30d40", + "eip150Transition": "0x927C0", + "eip160Transition": "0x927C0", + "eip161abcTransition": "0x927C0", + "eip161dTransition": "0x927C0", + "eip100bTransition": "0xC3500", + "metropolisDifficultyIncrementDivisor": "0x1E", + "eip649Transition": "0xC3500", + "eip649Reward": "0x3782DACE9D900000", + "expip2Transition": "0xC3500", + "expip2DurationLimit": "0x1E" + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21", + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x1", + "chainID": "0x2", + "forkBlock": "0xDBBA0", + "forkCanonHash": "0x8e7bed51e24f5174090408664ac476b90b5e1199a947af7442f1ac88263fc8c7", + "subprotocolName": "exp", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "eip155Transition": "0x927C0", + "eip140Transition": "0xC3500", + "eip211Transition": "0xC3500", + "eip214Transition": "0xC3500", + "eip658Transition": "0xC3500" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x214652414e4b4f21", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x40000000", + "author": "0x93decab0cd745598860f782ac1e8f046cb99e898", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x4672616e6b6f497346726565646f6d", + "gasLimit": "0x1388" + }, + "nodes": [ + "enode://7f335a047654f3e70d6f91312a7cf89c39704011f1a584e2698250db3d63817e74b88e26b7854111e16b2c9d0c7173c05419aeee2d0321850227b126d8b1be3f@46.101.156.249:42786", + "enode://df872f81e25f72356152b44cab662caf1f2e57c3a156ecd20e9ac9246272af68a2031b4239a0bc831f2c6ab34733a041464d46b3ea36dce88d6c11714446e06b@178.62.208.109:42786", + "enode://96d3919b903e7f5ad59ac2f73c43be9172d9d27e2771355db03fd194732b795829a31fe2ea6de109d0804786c39a807e155f065b4b94c6fce167becd0ac02383@45.55.22.34:42786", + "enode://5f6c625bf287e3c08aad568de42d868781e961cbda805c8397cfb7be97e229419bef9a5a25a75f97632787106bba8a7caf9060fab3887ad2cfbeb182ab0f433f@46.101.182.53:42786", + "enode://d33a8d4c2c38a08971ed975b750f21d54c927c0bf7415931e214465a8d01651ecffe4401e1db913f398383381413c78105656d665d83f385244ab302d6138414@128.199.183.48:42786", + "enode://f6f0d6b9b7d02ec9e8e4a16e38675f3621ea5e69860c739a65c1597ca28aefb3cec7a6d84e471ac927d42a1b64c1cbdefad75e7ce8872d57548ddcece20afdd1@159.203.64.95:42786" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0xC3500", "pricing": { "modexp": { "divisor": 20 } } } }, + "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0xC3500", "pricing": { "linear": { "base": 500, "word": 0 } } } }, + "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0xC3500", "pricing": { "linear": { "base": 40000, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xC3500", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, + "bb94f0ceb32257275b2a7a9c094c13e469b4563e": { + "balance": "10000000000000000000000000" + }, + "15656715068ab0dbdf0ab00748a8a19e40f28192": { + "balance": "1000000000000000000000000" + }, + "c075fa11f85bda3aaba67106226aaf086ac16f4e": { + "balance": "100000000000000000000000" + }, + "93decab0cd745598860f782ac1e8f046cb99e898": { + "balance": "10000000000000000000000" + } + } +} diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 70fdcbb82..52b4fc108 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -90,6 +90,10 @@ pub struct EthashParams { pub eip649_delay: u64, /// EIP-649 base reward. pub eip649_reward: Option, + /// EXPIP-2 block height + pub expip2_transition: u64, + /// EXPIP-2 duration limit + pub expip2_duration_limit: u64, } impl From for EthashParams { @@ -118,6 +122,8 @@ impl From for EthashParams { eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into), eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into), eip649_reward: p.eip649_reward.map(Into::into), + expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into), + expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into), } } } @@ -354,7 +360,13 @@ impl Ethash { self.ethash_params.difficulty_bound_divisor }; - let duration_limit = self.ethash_params.duration_limit; + let expip2_hardfork = header.number() >= self.ethash_params.expip2_transition; + let duration_limit = if expip2_hardfork { + self.ethash_params.expip2_duration_limit + } else { + self.ethash_params.duration_limit + }; + let frontier_limit = self.ethash_params.homestead_transition; let mut target = if header.number() < frontier_limit { @@ -363,8 +375,7 @@ impl Ethash { } else { *parent.difficulty() + (*parent.difficulty() / difficulty_bound_divisor) } - } - else { + } else { trace!(target: "ethash", "Calculating difficulty parent.difficulty={}, header.timestamp={}, parent.timestamp={}", parent.difficulty(), header.timestamp(), parent.timestamp()); //block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) let (increment_divisor, threshold) = if header.number() < self.ethash_params.eip100b_transition { diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index d7acabc45..2ecef4941 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -65,6 +65,11 @@ pub fn new_classic<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/classic.json")) } +/// Create a new Expanse mainnet chain spec. +pub fn new_expanse<'a, T: Into>>(params: T) -> Spec { + load(params.into(), include_bytes!("../../res/ethereum/expanse.json")) +} + /// Create a new Musicoin mainnet chain spec. pub fn new_musicoin<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/musicoin.json")) diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 1b286df9a..ead7755e0 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -385,5 +385,7 @@ pub fn get_default_ethash_params() -> EthashParams { eip649_transition: u64::max_value(), eip649_delay: 3_000_000, eip649_reward: None, + expip2_transition: u64::max_value(), + expip2_duration_limit: 30, } } diff --git a/js-old/src/i18n/_default/settings.js b/js-old/src/i18n/_default/settings.js index 44e2a4124..ea447e4a9 100644 --- a/js-old/src/i18n/_default/settings.js +++ b/js-old/src/i18n/_default/settings.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -25,6 +25,7 @@ export default { chains: { chain_classic: `Parity syncs to the Ethereum Classic network`, chain_dev: `Parity uses a local development chain`, + chain_expanse: `Parity syncs to the Expanse network`, chain_foundation: `Parity syncs to the Ethereum network launched by the Ethereum Foundation`, chain_kovan: `Parity syncs to the Kovan test network`, chain_olympic: `Parity syncs to the Olympic test network`, diff --git a/js-old/src/i18n/nl/settings.js b/js-old/src/i18n/nl/settings.js index 412028198..f436d39c6 100644 --- a/js-old/src/i18n/nl/settings.js +++ b/js-old/src/i18n/nl/settings.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -25,6 +25,7 @@ export default { chains: { chain_classic: `Parity synchroniseert met het Ethereum Classic netwerk`, chain_dev: `Parity gebruikt een lokale ontwikkelaars chain`, + chain_expanse: `Parity synchroniseert met het Expanse netwerk`, chain_foundation: `Parity synchroniseert met het Ethereum netwerk wat door de Ethereum Foundation is uitgebracht`, chain_kovan: `Parity synchroniseert met het Kovan test netwerk`, chain_olympic: `Parity synchroniseert met het Olympic test netwerk`, diff --git a/js-old/src/i18n/zh-Hant-TW/settings.js b/js-old/src/i18n/zh-Hant-TW/settings.js index cbae3025f..8841279dc 100644 --- a/js-old/src/i18n/zh-Hant-TW/settings.js +++ b/js-old/src/i18n/zh-Hant-TW/settings.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -29,6 +29,7 @@ export default { chains: { chain_classic: `將Parity同步至以太坊經典網路`, // Parity syncs to the Ethereum Classic network chain_dev: `將Parity使用一條本地開發用區塊鏈`, // Parity uses a local development chain + chain_expanse: `將Parity同步至Expanse網路`, // Parity syncs to the Expanse network chain_foundation: `將Parity同步至以太坊基金會發起的以太坊網路`, // Parity syncs to the Ethereum network launched by the Ethereum Foundation chain_kovan: `將Parity同步至Kovan測試網路`, // Parity syncs to the Kovan test network chain_olympic: `將Parity同步至Olympic測試網路`, // Parity syncs to the Olympic test network diff --git a/js-old/src/i18n/zh/settings.js b/js-old/src/i18n/zh/settings.js index f8a5398fd..4081a06d6 100644 --- a/js-old/src/i18n/zh/settings.js +++ b/js-old/src/i18n/zh/settings.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -29,6 +29,7 @@ export default { chains: { chain_classic: `将Parity同步至以太坊经典网络`, // Parity syncs to the Ethereum Classic network chain_dev: `将Parity使用一条本地开发用区块链`, // Parity uses a local development chain + chain_expanse: `将Parity同步至Expanse网络`, // Parity syncs to the Expanse network chain_foundation: `将Parity同步至以太坊基金会发起的以太坊网络`, // Parity syncs to the Ethereum network launched by the Ethereum Foundation chain_kovan: `将Parity同步至Kovan测试网络`, // Parity syncs to the Kovan test network chain_olympic: `将Parity同步至Olympic测试网络`, // Parity syncs to the Olympic test network diff --git a/js-old/src/ui/CurrencySymbol/currencySymbol.example.js b/js-old/src/ui/CurrencySymbol/currencySymbol.example.js index 9691e4f03..c1b56ed5c 100644 --- a/js-old/src/ui/CurrencySymbol/currencySymbol.example.js +++ b/js-old/src/ui/CurrencySymbol/currencySymbol.example.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -39,6 +39,12 @@ export default class CurrencySymbolExample extends Component { netChain='classic' /> + + + + ); } diff --git a/js-old/src/ui/CurrencySymbol/currencySymbol.js b/js-old/src/ui/CurrencySymbol/currencySymbol.js index b68f3c6f2..3322b0301 100644 --- a/js-old/src/ui/CurrencySymbol/currencySymbol.js +++ b/js-old/src/ui/CurrencySymbol/currencySymbol.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -19,6 +19,7 @@ import { connect } from 'react-redux'; const SYMBOL_ETC = 'ETC'; const SYMBOL_ETH = 'ETH'; +const SYMBOL_EXP = 'EXP'; export class CurrencySymbol extends Component { static propTypes = { @@ -41,6 +42,9 @@ export class CurrencySymbol extends Component { case 'classic': return SYMBOL_ETC; + case 'expanse': + return SYMBOL_EXP; + default: return SYMBOL_ETH; } diff --git a/js-old/src/ui/CurrencySymbol/currencySymbol.spec.js b/js-old/src/ui/CurrencySymbol/currencySymbol.spec.js index b4bca1ab0..e705b5edc 100644 --- a/js-old/src/ui/CurrencySymbol/currencySymbol.spec.js +++ b/js-old/src/ui/CurrencySymbol/currencySymbol.spec.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -70,6 +70,10 @@ describe('ui/CurrencySymbol', () => { expect(render('classic').text()).equal('ETC'); }); + it('renders EXP for expanse', () => { + expect(render('expanse').text()).equal('EXP'); + }); + it('renders ETH as default', () => { expect(render('somethingElse').text()).equal('ETH'); }); @@ -87,5 +91,9 @@ describe('ui/CurrencySymbol', () => { it('render ETC', () => { expect(render('classic').instance().renderSymbol()).equal('ETC'); }); + + it('render EXP', () => { + expect(render('expanse').instance().renderSymbol()).equal('EXP'); + }); }); }); diff --git a/js-old/src/views/Settings/Parity/parity.js b/js-old/src/views/Settings/Parity/parity.js index a670c8d49..7de9b8061 100644 --- a/js-old/src/views/Settings/Parity/parity.js +++ b/js-old/src/views/Settings/Parity/parity.js @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -253,6 +253,14 @@ export default class Parity extends Component { /> )) } + { + this.renderItem('expanse', ( + + )) + } { this.renderItem('dev', ( , + + /// EXPIP-2 block height + #[serde(rename="expip2Transition")] + pub expip2_transition: Option, + + /// EXPIP-2 duration limit + #[serde(rename="expip2DurationLimit")] + pub expip2_duration_limit: Option, } /// Ethash engine deserialization. @@ -241,6 +249,8 @@ mod tests { eip649_transition: None, eip649_delay: None, eip649_reward: None, + expip2_transition: None, + expip2_duration_limit: None, } }); } @@ -287,6 +297,8 @@ mod tests { eip649_transition: None, eip649_delay: None, eip649_reward: None, + expip2_transition: None, + expip2_duration_limit: None, } }); } diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index d40e6844d..a38d36d24 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -290,7 +290,7 @@ usage! { ARG arg_chain: (String) = "foundation", or |c: &Config| otry!(c.parity).chain.clone(), "--chain=[CHAIN]", - "Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, musicoin, ellaism, testnet, kovan or dev.", + "Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, expanse, musicoin, ellaism, testnet, kovan or dev.", ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| otry!(c.parity).keys_path.clone(), "--keys-path=[PATH]", diff --git a/parity/params.rs b/parity/params.rs index 146a511f3..2d5cb8a7d 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -35,6 +35,7 @@ pub enum SpecType { Kovan, Olympic, Classic, + Expanse, Musicoin, Ellaism, Dev, @@ -58,6 +59,7 @@ impl str::FromStr for SpecType { "ropsten" => SpecType::Ropsten, "kovan" | "testnet" => SpecType::Kovan, "olympic" => SpecType::Olympic, + "expanse" => SpecType::Expanse, "musicoin" => SpecType::Musicoin, "ellaism" => SpecType::Ellaism, "dev" => SpecType::Dev, @@ -75,6 +77,7 @@ impl fmt::Display for SpecType { SpecType::Ropsten => "ropsten", SpecType::Olympic => "olympic", SpecType::Classic => "classic", + SpecType::Expanse => "expanse", SpecType::Musicoin => "musicoin", SpecType::Ellaism => "ellaism", SpecType::Kovan => "kovan", @@ -93,6 +96,7 @@ impl SpecType { SpecType::Ropsten => Ok(ethereum::new_ropsten(params)), SpecType::Olympic => Ok(ethereum::new_olympic(params)), SpecType::Classic => Ok(ethereum::new_classic(params)), + SpecType::Expanse => Ok(ethereum::new_expanse(params)), SpecType::Musicoin => Ok(ethereum::new_musicoin(params)), SpecType::Ellaism => Ok(ethereum::new_ellaism(params)), SpecType::Kovan => Ok(ethereum::new_kovan(params)), @@ -107,6 +111,7 @@ impl SpecType { pub fn legacy_fork_name(&self) -> Option { match *self { SpecType::Classic => Some("classic".to_owned()), + SpecType::Expanse => Some("expanse".to_owned()), SpecType::Musicoin => Some("musicoin".to_owned()), _ => None, } @@ -359,6 +364,7 @@ mod tests { assert_eq!(format!("{}", SpecType::Morden), "morden"); assert_eq!(format!("{}", SpecType::Olympic), "olympic"); assert_eq!(format!("{}", SpecType::Classic), "classic"); + assert_eq!(format!("{}", SpecType::Expanse), "expanse"); assert_eq!(format!("{}", SpecType::Musicoin), "musicoin"); assert_eq!(format!("{}", SpecType::Kovan), "kovan"); assert_eq!(format!("{}", SpecType::Dev), "dev"); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index 3bd1ea70b..40aad1a4b 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -87,7 +87,7 @@ build_rpc_trait! { #[rpc(name = "parity_setMode")] fn set_mode(&self, String) -> Result; - /// Set the network spec. Argument must be one of: "foundation", "ropsten", "morden", "kovan", "olympic", "classic", "dev", "musicoin" or a filename. + /// Set the network spec. Argument must be one of: "foundation", "ropsten", "morden", "kovan", "olympic", "classic", "dev", "expanse", "musicoin" or a filename. #[rpc(name = "parity_setChain")] fn set_spec_name(&self, String) -> Result;