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.
This commit is contained in:
Afri Schoedon 2017-10-08 18:17:59 +02:00 committed by Gav Wood
parent 59365b0133
commit 360ecd3728
19 changed files with 478 additions and 11 deletions

View File

@ -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"
},

View File

@ -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
}
}
}
}
}
}

View File

@ -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
}
}
}
}
}
}

View File

@ -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<ethjson::spec::EthashParams> 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<EthereumMachine> for Arc<Ethash> {
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<EthereumMachine> for Arc<Ethash> {
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;

View File

@ -70,6 +70,11 @@ pub fn new_expanse<'a, T: Into<SpecParams<'a>>>(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<SpecParams<'a>>>(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<SpecParams<'a>>>(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;

View File

@ -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,

View File

@ -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`,

View File

@ -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`,

View File

@ -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

View File

@ -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

View File

@ -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'
}
],

View File

@ -45,6 +45,12 @@ export default class CurrencySymbolExample extends Component {
netChain='expanse'
/>
</PlaygroundExample>
<PlaygroundExample name='MUSIC Currency Symbol'>
<CurrencySymbol
netChain='musicoin'
/>
</PlaygroundExample>
</div>
);
}

View File

@ -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;
}

View File

@ -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');
});
});
});

View File

@ -263,6 +263,14 @@ export default class Parity extends Component {
/>
))
}
{
this.renderItem('musicoin', (
<FormattedMessage
id='settings.parity.chains.chain_musicoin'
defaultMessage='Parity syncs to the Musicoin network'
/>
))
}
{
this.renderItem('dev', (
<FormattedMessage

View File

@ -94,6 +94,26 @@ pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="ecip1017EraRounds")]
pub ecip1017_era_rounds: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="mcip3Transition")]
pub mcip3_transition: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="mcip3MinerReward")]
pub mcip3_miner_reward: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="mcip3UbiReward")]
pub mcip3_ubi_reward: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="mcip3UbiContract")]
pub mcip3_ubi_contract: Option<Address>,
/// See main EthashParams docs.
#[serde(rename="mcip3DevReward")]
pub mcip3_dev_reward: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="mcip3DevContract")]
pub mcip3_dev_contract: Option<Address>,
/// EIP-649 transition block.
#[serde(rename="eip649Transition")]
pub eip649_transition: Option<Uint>,
@ -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,

View File

@ -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]",

View File

@ -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");

View File

@ -87,7 +87,7 @@ build_rpc_trait! {
#[rpc(name = "parity_setMode")]
fn set_mode(&self, String) -> Result<bool, Error>;
/// 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<bool, Error>;