From 360ecd37283d3a156f217ab4ae76e3e355c8b2a4 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Sun, 8 Oct 2017 18:17:59 +0200 Subject: [PATCH] Add Musicoin and MCIP-3 UBI hardfork. (#6621) * Add musicoin chain spec. * Add musicoin to parity node * Add musicoin to the wallet * Add i18n for musicoin * Align musicoin chain spec with 1.8, ref #6134 * Update musicoin bootnodes * Prepare MCIP-3 in musicoin chain spec. * Update musicoin chain spec with contract addresses for MCIP-3 * Extend ethash params by MCIP-3 * Fix musicoin chain spec json * Use U256 for block rewards. * Update musicoin registrar * Fix merge leftovers * Update musicoin chain spec for latest master * Bestow MCIP-3 block reward(s). * Update musicoin registry once and for all * Align MCIP-3 block reward with go implementation * Remove mcip3 test chain spec from repository * Update MCIP-3 block rewards * Musicoin homestead transition is at 1_150_000 * Expect mcip3 transtion to be properly defined in chain spec. * Panic handling for mcip to default to regular block rewards if not specified * Giving mcip3 rewards a useful default value. * Fix ethjson tests. * Update musicoin chain spec * Fix tests 0:) * Add musicoin mcip3 era test spec. * Update musicoin chain spec(s) * Add tests for mcip3 era block rewards * Fix tests * Disable byzantium for musicoin * Pass miner reward to the tracer. * Allow modifying blockreward in MCIP-3 transition. --- ethcore/res/ethereum/classic.json | 2 - ethcore/res/ethereum/mcip3_test.json | 167 ++++++++++++++++++ ethcore/res/ethereum/musicoin.json | 167 ++++++++++++++++++ ethcore/src/ethereum/ethash.rs | 62 ++++++- ethcore/src/ethereum/mod.rs | 11 ++ ethcore/src/tests/helpers.rs | 6 + js/src/i18n/_default/settings.js | 1 + js/src/i18n/nl/settings.js | 1 + js/src/i18n/zh-Hant-TW/settings.js | 1 + js/src/i18n/zh/settings.js | 1 + js/src/jsonrpc/interfaces/parity.js | 2 +- .../CurrencySymbol/currencySymbol.example.js | 6 + js/src/ui/CurrencySymbol/currencySymbol.js | 4 + .../ui/CurrencySymbol/currencySymbol.spec.js | 8 + js/src/views/Settings/Parity/parity.js | 8 + json/src/spec/ethash.rs | 32 ++++ parity/cli/mod.rs | 2 +- parity/params.rs | 6 + rpc/src/v1/traits/parity_set.rs | 2 +- 19 files changed, 478 insertions(+), 11 deletions(-) create mode 100644 ethcore/res/ethereum/mcip3_test.json create mode 100644 ethcore/res/ethereum/musicoin.json diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index 5f931cf8b..5f6e3af83 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -14,7 +14,6 @@ "ecip1010PauseTransition": 3000000, "ecip1010ContinueTransition": 5000000, "ecip1017EraRounds": 5000000, - "eip161abcTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff" } @@ -31,7 +30,6 @@ "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", "eip155Transition": 3000000, - "eip98Transition": "0x7fffffffffffff", "eip86Transition": "0x7fffffffffffff" }, diff --git a/ethcore/res/ethereum/mcip3_test.json b/ethcore/res/ethereum/mcip3_test.json new file mode 100644 index 000000000..098e146e3 --- /dev/null +++ b/ethcore/res/ethereum/mcip3_test.json @@ -0,0 +1,167 @@ +{ + "name":"MCIP3 Test", + "dataDir":"mcip3test", + "engine":{ + "Ethash":{ + "params":{ + "minimumDifficulty":"0x020000", + "difficultyBoundDivisor":"0x0800", + "durationLimit":"0x0d", + "homesteadTransition":"0x118c30", + "eip100bTransition":"0x7fffffffffffff", + "eip150Transition":"0x7fffffffffffff", + "eip160Transition":"0x7fffffffffffff", + "eip161abcTransition":"0x7fffffffffffff", + "eip161dTransition":"0x7fffffffffffff", + "eip649Transition":"0x7fffffffffffff", + "blockReward":"0x1105a0185b50a80000", + "mcip3Transition":"0x00", + "mcip3MinerReward":"0xd8d726b7177a80000", + "mcip3UbiReward":"0x2b5e3af16b1880000", + "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", + "mcip3DevReward":"0xc249fdd327780000", + "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" + } + } + }, + "params":{ + "gasLimitBoundDivisor":"0x0400", + "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", + "accountStartNonce":"0x00", + "maximumExtraDataSize":"0x20", + "minGasLimit":"0x1388", + "networkID":"0x76740b", + "forkBlock":"0x5b6", + "forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343", + "eip86Transition":"0x7fffffffffffff", + "eip98Transition":"0x7fffffffffffff", + "eip140Transition":"0x7fffffffffffff", + "eip155Transition":"0x7fffffffffffff", + "eip211Transition":"0x7fffffffffffff", + "eip214Transition":"0x7fffffffffffff", + "eip658Transition":"0x7fffffffffffff", + "maxCodeSize":"0x6000" + }, + "genesis":{ + "seal":{ + "ethereum":{ + "nonce":"0x000000000000002a", + "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty":"0x3d0900", + "author":"0x0000000000000000000000000000000000000000", + "timestamp":"0x00", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"", + "gasLimit":"0x7a1200" + }, + "nodes":[ + "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", + "enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", + "enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", + "enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", + "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", + "enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303", + "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", + "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", + "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" + ], + "accounts":{ + "0000000000000000000000000000000000000001":{ + "balance":"1", + "builtin":{ + "name":"ecrecover", + "pricing":{ + "linear":{ + "base":3000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000002":{ + "balance":"1", + "builtin":{ + "name":"sha256", + "pricing":{ + "linear":{ + "base":60, + "word":12 + } + } + } + }, + "0000000000000000000000000000000000000003":{ + "balance":"1", + "builtin":{ + "name":"ripemd160", + "pricing":{ + "linear":{ + "base":600, + "word":120 + } + } + } + }, + "0000000000000000000000000000000000000004":{ + "balance":"1", + "builtin":{ + "name":"identity", + "pricing":{ + "linear":{ + "base":15, + "word":3 + } + } + } + }, + "0000000000000000000000000000000000000005":{ + "builtin":{ + "name":"modexp", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "modexp":{ + "divisor":20 + } + } + } + }, + "0000000000000000000000000000000000000006":{ + "builtin":{ + "name":"alt_bn128_add", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":500, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000007":{ + "builtin":{ + "name":"alt_bn128_mul", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":40000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000008":{ + "builtin":{ + "name":"alt_bn128_pairing", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "alt_bn128_pairing":{ + "base":100000, + "pair":80000 + } + } + } + } + } +} diff --git a/ethcore/res/ethereum/musicoin.json b/ethcore/res/ethereum/musicoin.json new file mode 100644 index 000000000..cf4d4ffba --- /dev/null +++ b/ethcore/res/ethereum/musicoin.json @@ -0,0 +1,167 @@ +{ + "name":"Musicoin", + "dataDir":"musicoin", + "engine":{ + "Ethash":{ + "params":{ + "minimumDifficulty":"0x020000", + "difficultyBoundDivisor":"0x0800", + "durationLimit":"0x0d", + "homesteadTransition":"0x118c30", + "eip100bTransition":"0x7fffffffffffff", + "eip150Transition":"0x7fffffffffffff", + "eip160Transition":"0x7fffffffffffff", + "eip161abcTransition":"0x7fffffffffffff", + "eip161dTransition":"0x7fffffffffffff", + "eip649Transition":"0x7fffffffffffff", + "blockReward":"0x1105a0185b50a80000", + "mcip3Transition":"0x124f81", + "mcip3MinerReward":"0xd8d726b7177a80000", + "mcip3UbiReward":"0x2b5e3af16b1880000", + "mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310", + "mcip3DevReward":"0xc249fdd327780000", + "mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536" + } + } + }, + "params":{ + "gasLimitBoundDivisor":"0x0400", + "registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D", + "accountStartNonce":"0x00", + "maximumExtraDataSize":"0x20", + "minGasLimit":"0x1388", + "networkID":"0x76740f", + "forkBlock":"0x5b6", + "forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343", + "eip86Transition":"0x7fffffffffffff", + "eip98Transition":"0x7fffffffffffff", + "eip140Transition":"0x7fffffffffffff", + "eip155Transition":"0x7fffffffffffff", + "eip211Transition":"0x7fffffffffffff", + "eip214Transition":"0x7fffffffffffff", + "eip658Transition":"0x7fffffffffffff", + "maxCodeSize":"0x6000" + }, + "genesis":{ + "seal":{ + "ethereum":{ + "nonce":"0x000000000000002a", + "mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty":"0x3d0900", + "author":"0x0000000000000000000000000000000000000000", + "timestamp":"0x00", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"", + "gasLimit":"0x7a1200" + }, + "nodes":[ + "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", + "enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", + "enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", + "enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", + "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", + "enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303", + "enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303", + "enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303", + "enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555" + ], + "accounts":{ + "0000000000000000000000000000000000000001":{ + "balance":"1", + "builtin":{ + "name":"ecrecover", + "pricing":{ + "linear":{ + "base":3000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000002":{ + "balance":"1", + "builtin":{ + "name":"sha256", + "pricing":{ + "linear":{ + "base":60, + "word":12 + } + } + } + }, + "0000000000000000000000000000000000000003":{ + "balance":"1", + "builtin":{ + "name":"ripemd160", + "pricing":{ + "linear":{ + "base":600, + "word":120 + } + } + } + }, + "0000000000000000000000000000000000000004":{ + "balance":"1", + "builtin":{ + "name":"identity", + "pricing":{ + "linear":{ + "base":15, + "word":3 + } + } + } + }, + "0000000000000000000000000000000000000005":{ + "builtin":{ + "name":"modexp", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "modexp":{ + "divisor":20 + } + } + } + }, + "0000000000000000000000000000000000000006":{ + "builtin":{ + "name":"alt_bn128_add", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":500, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000007":{ + "builtin":{ + "name":"alt_bn128_mul", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "linear":{ + "base":40000, + "word":0 + } + } + } + }, + "0000000000000000000000000000000000000008":{ + "builtin":{ + "name":"alt_bn128_pairing", + "activate_at":"0x7fffffffffffff", + "pricing":{ + "alt_bn128_pairing":{ + "base":100000, + "pair":80000 + } + } + } + } + } +} diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index e0a85ab9f..a49ba2e2a 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -22,6 +22,7 @@ use hash::{KECCAK_EMPTY_LIST_RLP}; use ethash::{quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor}; use bigint::prelude::U256; use bigint::hash::{H256, H64}; +use util::Address; use unexpected::{OutOfBounds, Mismatch}; use block::*; use error::{BlockError, Error}; @@ -69,6 +70,18 @@ pub struct EthashParams { pub ecip1010_continue_transition: u64, /// Total block number for one ECIP-1017 era. pub ecip1017_era_rounds: u64, + /// Number of first block where MCIP-3 begins. + pub mcip3_transition: u64, + /// MCIP-3 Block reward coin-base for miners. + pub mcip3_miner_reward: U256, + /// MCIP-3 Block reward ubi-base for basic income. + pub mcip3_ubi_reward: U256, + /// MCIP-3 contract address for universal basic income. + pub mcip3_ubi_contract: Address, + /// MCIP-3 Block reward dev-base for dev funds. + pub mcip3_dev_reward: U256, + /// MCIP-3 contract address for the developer funds. + pub mcip3_dev_contract: Address, /// Block reward in base units. pub block_reward: U256, /// EIP-649 transition block. @@ -95,6 +108,12 @@ impl From for EthashParams { ecip1010_pause_transition: p.ecip1010_pause_transition.map_or(u64::max_value(), Into::into), ecip1010_continue_transition: p.ecip1010_continue_transition.map_or(u64::max_value(), Into::into), ecip1017_era_rounds: p.ecip1017_era_rounds.map_or(u64::max_value(), Into::into), + mcip3_transition: p.mcip3_transition.map_or(u64::max_value(), Into::into), + mcip3_miner_reward: p.mcip3_miner_reward.map_or_else(Default::default, Into::into), + mcip3_ubi_reward: p.mcip3_ubi_reward.map_or(U256::from(0), Into::into), + mcip3_ubi_contract: p.mcip3_ubi_contract.map_or_else(Address::new, Into::into), + mcip3_dev_reward: p.mcip3_dev_reward.map_or(U256::from(0), Into::into), + mcip3_dev_contract: p.mcip3_dev_contract.map_or_else(Address::new, Into::into), block_reward: p.block_reward.map_or_else(Default::default, Into::into), eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into), eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into), @@ -184,24 +203,38 @@ impl Engine for Arc { let author = *LiveBlock::header(&*block).author(); let number = LiveBlock::header(&*block).number(); + // Applies EIP-649 reward. let reward = if number >= self.ethash_params.eip649_transition { self.ethash_params.eip649_reward.unwrap_or(self.ethash_params.block_reward) } else { self.ethash_params.block_reward }; + // Applies ECIP-1017 eras. let eras_rounds = self.ethash_params.ecip1017_era_rounds; let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, number); let n_uncles = LiveBlock::uncles(&*block).len(); - // Bestow block reward - let result_block_reward = reward + reward.shr(5) * U256::from(n_uncles); + // Bestow block rewards. + let mut result_block_reward = reward + reward.shr(5) * U256::from(n_uncles); let mut uncle_rewards = Vec::with_capacity(n_uncles); - self.machine.add_balance(block, &author, &result_block_reward)?; + if number >= self.ethash_params.mcip3_transition { + result_block_reward = self.ethash_params.mcip3_miner_reward; + let ubi_contract = self.ethash_params.mcip3_ubi_contract; + let ubi_reward = self.ethash_params.mcip3_ubi_reward; + let dev_contract = self.ethash_params.mcip3_dev_contract; + let dev_reward = self.ethash_params.mcip3_dev_reward; - // bestow uncle rewards. + self.machine.add_balance(block, &author, &result_block_reward)?; + self.machine.add_balance(block, &ubi_contract, &ubi_reward)?; + self.machine.add_balance(block, &dev_contract, &dev_reward)?; + } else { + self.machine.add_balance(block, &author, &result_block_reward)?; + } + + // Bestow uncle rewards. for u in LiveBlock::uncles(&*block) { let uncle_author = u.author(); let result_uncle_reward = if eras == 0 { @@ -217,7 +250,7 @@ impl Engine for Arc { self.machine.add_balance(block, a, reward)?; } - // note and trace. + // Note and trace. self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards) } @@ -432,7 +465,7 @@ mod tests { use error::{BlockError, Error}; use header::Header; use spec::Spec; - use super::super::{new_morden, new_homestead_test_machine}; + use super::super::{new_morden, new_mcip3_test, new_homestead_test_machine}; use super::{Ethash, EthashParams, ecip1017_eras_block_reward}; use rlp; @@ -502,6 +535,23 @@ mod tests { assert_eq!(b.state().balance(&uncle_author).unwrap(), "3cb71f51fc558000".into()); } + #[test] + fn has_valid_mcip3_era_block_rewards() { + let spec = new_mcip3_test(); + let engine = &*spec.engine; + let genesis_header = spec.genesis_header(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); + let last_hashes = Arc::new(vec![genesis_header.hash()]); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); + let b = b.close(); + + let ubi_contract: Address = "00efdd5883ec628983e9063c7d969fe268bbf310".into(); + let dev_contract: Address = "00756cf8159095948496617f5fb17ed95059f536".into(); + assert_eq!(b.state().balance(&Address::zero()).unwrap(), U256::from_str("d8d726b7177a80000").unwrap()); + assert_eq!(b.state().balance(&ubi_contract).unwrap(), U256::from_str("2b5e3af16b1880000").unwrap()); + assert_eq!(b.state().balance(&dev_contract).unwrap(), U256::from_str("c249fdd327780000").unwrap()); + } + #[test] fn has_valid_metadata() { let engine = test_spec().engine; diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 0b45113d4..75c321ebe 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -70,6 +70,11 @@ 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")) +} + /// Create a new Kovan testnet chain spec. pub fn new_kovan<'a, T: Into>>(params: T) -> Spec { load(params.into(), include_bytes!("../../res/ethereum/kovan.json")) @@ -111,6 +116,9 @@ pub fn new_byzantium_test() -> Spec { load(None, include_bytes!("../../res/ether /// Create a new Foundation Constantinople era spec. pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) } +/// Create a new Musicoin-MCIP3-era spec. +pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) } + // For tests /// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead. @@ -125,6 +133,9 @@ pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_by /// Create a new Foundation Constantinople era spec. pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) } +/// Create a new Musicoin-MCIP3-era spec. +pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) } + #[cfg(test)] mod tests { use bigint::prelude::U256; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index df5e83226..30e74e179 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -377,6 +377,12 @@ pub fn get_default_ethash_params() -> EthashParams { ecip1010_pause_transition: u64::max_value(), ecip1010_continue_transition: u64::max_value(), ecip1017_era_rounds: u64::max_value(), + mcip3_transition: u64::max_value(), + mcip3_miner_reward: 0.into(), + mcip3_ubi_reward: 0.into(), + mcip3_ubi_contract: "0000000000000000000000000000000000000001".into(), + mcip3_dev_reward: 0.into(), + mcip3_dev_contract: "0000000000000000000000000000000000000001".into(), eip649_transition: u64::max_value(), eip649_delay: 3_000_000, eip649_reward: None, diff --git a/js/src/i18n/_default/settings.js b/js/src/i18n/_default/settings.js index aef412b48..29f56badb 100644 --- a/js/src/i18n/_default/settings.js +++ b/js/src/i18n/_default/settings.js @@ -26,6 +26,7 @@ export default { 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_musicoin: `Parity syncs to the Musicoin 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/src/i18n/nl/settings.js b/js/src/i18n/nl/settings.js index f436d39c6..2aedd9d9b 100644 --- a/js/src/i18n/nl/settings.js +++ b/js/src/i18n/nl/settings.js @@ -26,6 +26,7 @@ export default { 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_musicoin: `Parity synchroniseert met het Musicoin 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/src/i18n/zh-Hant-TW/settings.js b/js/src/i18n/zh-Hant-TW/settings.js index 8841279dc..1bcb38758 100644 --- a/js/src/i18n/zh-Hant-TW/settings.js +++ b/js/src/i18n/zh-Hant-TW/settings.js @@ -30,6 +30,7 @@ export default { 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_musicoin: `將Parity同步至Musicoin網路`, // Parity syncs to the Musicoin 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/src/i18n/zh/settings.js b/js/src/i18n/zh/settings.js index 4081a06d6..752d124a1 100644 --- a/js/src/i18n/zh/settings.js +++ b/js/src/i18n/zh/settings.js @@ -30,6 +30,7 @@ export default { 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_musicoin: `将Parity同步至Musicoin网络`, // Parity syncs to the Musicoin 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/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index 997b7d434..2dde67b6f 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -1756,7 +1756,7 @@ export default { params: [ { type: String, - desc: 'Chain spec name, one of: "foundation", "ropsten", "morden", "kovan", "olympic", "classic", "dev", "expanse" or a filename.', + desc: 'Chain spec name, one of: "foundation", "ropsten", "morden", "kovan", "olympic", "classic", "dev", "expanse", "musicoin" or a filename.', example: 'foundation' } ], diff --git a/js/src/ui/CurrencySymbol/currencySymbol.example.js b/js/src/ui/CurrencySymbol/currencySymbol.example.js index c1b56ed5c..1f33dbba8 100644 --- a/js/src/ui/CurrencySymbol/currencySymbol.example.js +++ b/js/src/ui/CurrencySymbol/currencySymbol.example.js @@ -45,6 +45,12 @@ export default class CurrencySymbolExample extends Component { netChain='expanse' /> + + + + ); } diff --git a/js/src/ui/CurrencySymbol/currencySymbol.js b/js/src/ui/CurrencySymbol/currencySymbol.js index 3322b0301..ec7f98458 100644 --- a/js/src/ui/CurrencySymbol/currencySymbol.js +++ b/js/src/ui/CurrencySymbol/currencySymbol.js @@ -20,6 +20,7 @@ import { connect } from 'react-redux'; const SYMBOL_ETC = 'ETC'; const SYMBOL_ETH = 'ETH'; const SYMBOL_EXP = 'EXP'; +const SYMBOL_MUSIC = 'MUSIC'; export class CurrencySymbol extends Component { static propTypes = { @@ -45,6 +46,9 @@ export class CurrencySymbol extends Component { case 'expanse': return SYMBOL_EXP; + case 'musicoin': + return SYMBOL_MUSIC; + default: return SYMBOL_ETH; } diff --git a/js/src/ui/CurrencySymbol/currencySymbol.spec.js b/js/src/ui/CurrencySymbol/currencySymbol.spec.js index e705b5edc..f10557bd2 100644 --- a/js/src/ui/CurrencySymbol/currencySymbol.spec.js +++ b/js/src/ui/CurrencySymbol/currencySymbol.spec.js @@ -74,6 +74,10 @@ describe('ui/CurrencySymbol', () => { expect(render('expanse').text()).equal('EXP'); }); + it('renders MUSIC for musicoin', () => { + expect(render('musicoin').text()).equal('MUSIC'); + }); + it('renders ETH as default', () => { expect(render('somethingElse').text()).equal('ETH'); }); @@ -95,5 +99,9 @@ describe('ui/CurrencySymbol', () => { it('render EXP', () => { expect(render('expanse').instance().renderSymbol()).equal('EXP'); }); + + it('render MUSIC', () => { + expect(render('musicoin').instance().renderSymbol()).equal('MUSIC'); + }); }); }); diff --git a/js/src/views/Settings/Parity/parity.js b/js/src/views/Settings/Parity/parity.js index 9cf2c4f86..853ba3aa1 100644 --- a/js/src/views/Settings/Parity/parity.js +++ b/js/src/views/Settings/Parity/parity.js @@ -263,6 +263,14 @@ export default class Parity extends Component { /> )) } + { + this.renderItem('musicoin', ( + + )) + } { this.renderItem('dev', ( , + + /// See main EthashParams docs. + #[serde(rename="mcip3Transition")] + pub mcip3_transition: Option, + /// See main EthashParams docs. + #[serde(rename="mcip3MinerReward")] + pub mcip3_miner_reward: Option, + /// See main EthashParams docs. + #[serde(rename="mcip3UbiReward")] + pub mcip3_ubi_reward: Option, + /// See main EthashParams docs. + #[serde(rename="mcip3UbiContract")] + pub mcip3_ubi_contract: Option
, + /// See main EthashParams docs. + #[serde(rename="mcip3DevReward")] + pub mcip3_dev_reward: Option, + /// See main EthashParams docs. + #[serde(rename="mcip3DevContract")] + pub mcip3_dev_contract: Option
, + /// EIP-649 transition block. #[serde(rename="eip649Transition")] pub eip649_transition: Option, @@ -212,6 +232,12 @@ mod tests { ecip1010_pause_transition: None, ecip1010_continue_transition: None, ecip1017_era_rounds: None, + mcip3_transition: None, + mcip3_miner_reward: None, + mcip3_ubi_reward: None, + mcip3_ubi_contract: None, + mcip3_dev_reward: None, + mcip3_dev_contract: None, eip649_transition: None, eip649_delay: None, eip649_reward: None, @@ -252,6 +278,12 @@ mod tests { ecip1010_pause_transition: None, ecip1010_continue_transition: None, ecip1017_era_rounds: None, + mcip3_transition: None, + mcip3_miner_reward: None, + mcip3_ubi_reward: None, + mcip3_ubi_contract: None, + mcip3_dev_reward: None, + mcip3_dev_contract: None, eip649_transition: None, eip649_delay: None, eip649_reward: None, diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 7e14eab6d..dc6c2fe7b 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -301,7 +301,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, expanse, 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, 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 2c0e534ba..f508b59f1 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -35,6 +35,7 @@ pub enum SpecType { Olympic, Classic, Expanse, + Musicoin, Dev, Custom(String), } @@ -57,6 +58,7 @@ impl str::FromStr for SpecType { "kovan" | "testnet" => SpecType::Kovan, "olympic" => SpecType::Olympic, "expanse" => SpecType::Expanse, + "musicoin" => SpecType::Musicoin, "dev" => SpecType::Dev, other => SpecType::Custom(other.into()), }; @@ -73,6 +75,7 @@ impl fmt::Display for SpecType { SpecType::Olympic => "olympic", SpecType::Classic => "classic", SpecType::Expanse => "expanse", + SpecType::Musicoin => "musicoin", SpecType::Kovan => "kovan", SpecType::Dev => "dev", SpecType::Custom(ref custom) => custom, @@ -90,6 +93,7 @@ impl SpecType { 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::Kovan => Ok(ethereum::new_kovan(params)), SpecType::Dev => Ok(Spec::new_instant()), SpecType::Custom(ref filename) => { @@ -103,6 +107,7 @@ impl SpecType { match *self { SpecType::Classic => Some("classic".to_owned()), SpecType::Expanse => Some("expanse".to_owned()), + SpecType::Musicoin => Some("musicoin".to_owned()), _ => None, } } @@ -353,6 +358,7 @@ mod tests { 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"); assert_eq!(format!("{}", SpecType::Custom("foo/bar".into())), "foo/bar"); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index cd964daa3..7b3c593dc 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -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", "expanse" 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;