diff --git a/Cargo.lock b/Cargo.lock index 5f9a38a47..e567bab35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,10 +1317,6 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "fly-client" -version = "0.1.0" - [[package]] name = "fnv" version = "1.0.6" @@ -2715,16 +2711,6 @@ name = "memory_units" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "merkle-mountain-range" -version = "0.1.0" -dependencies = [ - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", - "srml-system 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", -] - [[package]] name = "merkle-patricia-trie" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6f15f00d5..ff3644127 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,8 @@ panic = 'unwind' members = [ "core/cli", "core/ethash", - "core/merkle-mountain-range", - "core/fly-client", +# "core/merkle-mountain-range", +# "core/fly-client", "core/sr-eth-primitives", "core/merkle-patricia-trie", diff --git a/boot-conf/develop/alice.json b/boot-conf/develop/alice.json deleted file mode 100644 index 41a6a28e3..000000000 --- a/boot-conf/develop/alice.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "rpc-external": true, - "rpc-port": 23333, - "ws-external": true, - "ws-port": 23334, - "rpc-cors": "all", - "port": 23335, - "base-path": "/tmp/darwinia-develop/alice" -} diff --git a/boot-conf/develop/bob.json b/boot-conf/develop/bob.json deleted file mode 100644 index d74bf24da..000000000 --- a/boot-conf/develop/bob.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "rpc-external": true, - "rpc-port": 23336, - "ws-external": true, - "ws-port": 23337, - "rpc-cors": "all", - "port": 23338, - "base-path": "/tmp/darwinia-develop/bob" -} diff --git a/boot-conf/testnet/1.json b/boot-conf/testnet/1.json new file mode 100644 index 000000000..6d171952b --- /dev/null +++ b/boot-conf/testnet/1.json @@ -0,0 +1,6 @@ +{ + "base-path": "/tmp/darwinia-testnet/1", + "name": "testnet 1", + "validator": true, + "rpc-port": 6664 +} \ No newline at end of file diff --git a/boot-conf/testnet/2.json b/boot-conf/testnet/2.json new file mode 100644 index 000000000..90b5d02d4 --- /dev/null +++ b/boot-conf/testnet/2.json @@ -0,0 +1,6 @@ +{ + "base-path": "/tmp/darwinia-testnet/2", + "name": "testnet 2", + "validator": true, + "rpc-port": 6665 +} \ No newline at end of file diff --git a/boot-conf/testnet/3.json b/boot-conf/testnet/3.json new file mode 100644 index 000000000..68bf0e428 --- /dev/null +++ b/boot-conf/testnet/3.json @@ -0,0 +1,6 @@ +{ + "base-path": "/tmp/darwinia-testnet/3", + "name": "testnet 3", + "validator": true, + "rpc-port": 6666 +} \ No newline at end of file diff --git a/boot-conf/testnet/4.json b/boot-conf/testnet/4.json new file mode 100644 index 000000000..7a0d57ff3 --- /dev/null +++ b/boot-conf/testnet/4.json @@ -0,0 +1,6 @@ +{ + "base-path": "/tmp/darwinia-testnet/4", + "name": "testnet 4", + "validator": true, + "rpc-port": 6667 +} \ No newline at end of file diff --git a/boot-conf/testnet/5.json b/boot-conf/testnet/5.json new file mode 100644 index 000000000..67e07ab06 --- /dev/null +++ b/boot-conf/testnet/5.json @@ -0,0 +1,6 @@ +{ + "base-path": "/tmp/darwinia-testnet/5", + "name": "testnet 5", + "validator": true, + "rpc-port": 6668 +} \ No newline at end of file diff --git a/boot-conf/testnet/alice.json b/boot-conf/testnet/alice.json new file mode 100644 index 000000000..1b26323e9 --- /dev/null +++ b/boot-conf/testnet/alice.json @@ -0,0 +1,7 @@ +{ + "base-path": "/tmp/darwinia-testnet/alice", + "rpc-external": true, + "ws-external": true, + "ws-port": 23333, + "rpc-cors": "all" +} diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 90ad569cb..d00c95be5 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -247,14 +247,14 @@ pub fn darwinia_genesis( .iter() .cloned() .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), ENDOWMENT))) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect(), vesting: vec![], }), staking: Some(StakingConfig { current_era: 0, - validator_count: initial_authorities.len() as u32 * 2, - minimum_validator_count: initial_authorities.len() as u32, + validator_count: 7, + minimum_validator_count: 1, stakers: initial_authorities .iter() .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)) diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index fd9f97469..a8888a120 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -49,9 +49,9 @@ pub mod time { /// // Develop - // pub const MILLISECS_PER_BLOCK: Moment = 1000; + pub const MILLISECS_PER_BLOCK: Moment = 1000; // Production - pub const MILLISECS_PER_BLOCK: Moment = 3000; + // pub const MILLISECS_PER_BLOCK: Moment = 3000; pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; @@ -60,9 +60,9 @@ pub mod time { pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); // Develop - // pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = MINUTES; + pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = MINUTES; // Production - pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES; + // pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES; pub const EPOCH_DURATION_IN_SLOTS: u64 = { const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64; @@ -76,9 +76,9 @@ pub mod time { pub const SESSION_DURATION: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; // Develop - // pub const SESSION_PER_ERA: sr_staking_primitives::SessionIndex = 1; + pub const SESSION_PER_ERA: sr_staking_primitives::SessionIndex = 3; // Production - pub const SESSION_PER_ERA: sr_staking_primitives::SessionIndex = 5; + // pub const SESSION_PER_ERA: sr_staking_primitives::SessionIndex = 5; } // CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a _ratio_ diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index cfabbe026..1e42bca85 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -68,8 +68,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), impl_name: create_runtime_str!("darwinia-node"), authoring_version: 3, - spec_version: 80, - impl_version: 80, + spec_version: 81, + impl_version: 81, apis: RUNTIME_API_VERSIONS, }; @@ -129,6 +129,16 @@ impl utility::Trait for Runtime { type Call = Call; } +parameter_types! { + pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; +} +impl babe::Trait for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::ExternalTrigger; +} + impl indices::Trait for Runtime { type AccountIndex = AccountIndex; type IsDeadAccount = Balances; @@ -161,16 +171,6 @@ impl transaction_payment::Trait for Runtime { type FeeMultiplierUpdate = TargetedFeeAdjustment; } -parameter_types! { - pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; - pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; -} -impl babe::Trait for Runtime { - type EpochDuration = EpochDuration; - type ExpectedBlockTime = ExpectedBlockTime; - type EpochChangeTrigger = babe::ExternalTrigger; -} - parameter_types! { pub const MinimumPeriod: Moment = SLOT_DURATION / 2; } @@ -224,44 +224,6 @@ impl session::historical::Trait for Runtime { type FullIdentificationOf = staking::ExposureOf; } -impl sudo::Trait for Runtime { - type Event = Event; - type Proposal = Call; -} - -impl offences::Trait for Runtime { - type Event = Event; - type IdentificationTuple = session::historical::IdentificationTuple; - type OnOffenceHandler = Staking; -} - -type SubmitTransaction = TransactionSubmitter; -parameter_types! { - pub const SessionDuration: BlockNumber = SESSION_DURATION; -} -impl im_online::Trait for Runtime { - type AuthorityId = ImOnlineId; - type Event = Event; - type Call = Call; - type SubmitTransaction = SubmitTransaction; - type SessionDuration = SessionDuration; - type ReportUnresponsiveness = Offences; -} - -impl grandpa::Trait for Runtime { - type Event = Event; -} - -parameter_types! { - pub const WindowSize: BlockNumber = 101; - pub const ReportLatency: BlockNumber = 1000; -} -impl finality_tracker::Trait for Runtime { - type OnFinalizationStalled = Grandpa; - type WindowSize = WindowSize; - type ReportLatency = ReportLatency; -} - parameter_types! { // Develop pub const ContractTransferFee: Balance = MICRO; @@ -314,6 +276,44 @@ impl contracts::Trait for Runtime { type BlockGasLimit = contracts::DefaultBlockGasLimit; } +impl sudo::Trait for Runtime { + type Event = Event; + type Proposal = Call; +} + +type SubmitTransaction = TransactionSubmitter; +parameter_types! { + pub const SessionDuration: BlockNumber = SESSION_DURATION; +} +impl im_online::Trait for Runtime { + type AuthorityId = ImOnlineId; + type Event = Event; + type Call = Call; + type SubmitTransaction = SubmitTransaction; + type SessionDuration = SessionDuration; + type ReportUnresponsiveness = Offences; +} + +impl offences::Trait for Runtime { + type Event = Event; + type IdentificationTuple = session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; +} + +impl grandpa::Trait for Runtime { + type Event = Event; +} + +parameter_types! { + pub const WindowSize: BlockNumber = 101; + pub const ReportLatency: BlockNumber = 1000; +} +impl finality_tracker::Trait for Runtime { + type OnFinalizationStalled = Grandpa; + type WindowSize = WindowSize; + type ReportLatency = ReportLatency; +} + impl system::offchain::CreateTransaction for Runtime { type Public = ::Signer; type Signature = Signature; @@ -345,9 +345,9 @@ impl system::offchain::CreateTransaction for Runtim } parameter_types! { - pub const ExistentialDeposit: Balance = 1 * COIN; - pub const TransferFee: Balance = 1 * MICRO; - pub const CreationFee: Balance = 1 * MICRO; + pub const ExistentialDeposit: Balance = COIN; + pub const TransferFee: Balance = MICRO; + pub const CreationFee: Balance = MICRO; } impl balances::Trait for Runtime { type Balance = Balance; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 136a8a0c8..4f3981d61 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -48,7 +48,9 @@ use codec::{Decode, Encode, HasCompact}; use phragmen::{build_support_map, elect, equalize, ExtendedBalance as Power, PhragmenStakedAssignment}; #[cfg(feature = "std")] use regex::bytes::Regex; -use rstd::{borrow::ToOwned, prelude::*, result}; +#[cfg(not(feature = "std"))] +use rstd::borrow::ToOwned; +use rstd::{prelude::*, result}; use session::{historical::OnSessionEnding, SelectInitialValidators}; use sr_primitives::{ traits::{Bounded, CheckedSub, Convert, One, SaturatedConversion, Saturating, StaticLookup, Zero}, @@ -309,6 +311,23 @@ pub struct Exposure { pub others: Vec>, } +// TODO: doc +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ValidatorReward { + who: AccountId, + #[codec(compact)] + amount: Ring, + nominators_reward: Vec>, +} + +// TODO: doc +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct NominatorReward { + who: AccountId, + #[codec(compact)] + amount: Ring, +} + /// A slashing event occurred, slashing a validator for a given amount of balance. #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct SlashJournalEntry { @@ -545,8 +564,8 @@ decl_event!( ::AccountId { /// All validators have been rewarded by the first balance; the second is the remainder - /// from the maximum amount of reward. - Reward(Balance, Balance), + /// from the maximum amount of reward; the third is validator and nominators' reward. + Reward(Balance, Balance, Vec>), // TODO: refactor to Balance later? /// One validator (and its nominators) has been slashed by the given amount. @@ -1440,10 +1459,17 @@ impl Module { /// Reward a given validator by a specific amount. Add the reward to the validator's, and its /// nominators' balance, pro-rata based on their exposure, after having removed the validator's /// pre-payout cut. - fn reward_validator(stash: &T::AccountId, reward: Ring) -> PositiveImbalanceRing { + fn reward_validator( + stash: &T::AccountId, + reward: Ring, + ) -> ( + PositiveImbalanceRing, + (Balance, Vec>), + ) { let off_the_table = Perbill::from_percent(Self::validators(stash).validator_payment_ratio) * reward; let reward = reward - off_the_table; let mut imbalance = >::zero(); + let mut nominators_reward = vec![]; let validator_cut = if reward.is_zero() { Zero::zero() } else { @@ -1452,15 +1478,22 @@ impl Module { for i in &exposures.others { let per_u64 = Perbill::from_rational_approximation(i.value, total); - imbalance.maybe_subsume(Self::make_payout(&i.who, per_u64 * reward)); + let nominator_reward = per_u64 * reward; + + imbalance.maybe_subsume(Self::make_payout(&i.who, nominator_reward)); + nominators_reward.push(NominatorReward { + who: i.who.to_owned(), + amount: nominator_reward.saturated_into(), + }); } let per_u64 = Perbill::from_rational_approximation(exposures.own, total); per_u64 * reward }; - imbalance.maybe_subsume(Self::make_payout(stash, validator_cut + off_the_table)); + let validator_reward = validator_cut + off_the_table; + imbalance.maybe_subsume(Self::make_payout(stash, validator_reward)); - imbalance + (imbalance, (validator_reward.saturated_into(), nominators_reward)) } /// Session has just ended. Provide the validator set for the next session if it's an era-end, along @@ -1517,10 +1550,18 @@ impl Module { ); let mut total_imbalance = >::zero(); + let mut validators_reward = vec![]; for (v, p) in validators.iter().zip(points.individual.into_iter()) { if p != 0 { let reward = Perbill::from_rational_approximation(p, points.total) * total_payout; - total_imbalance.subsume(Self::reward_validator(v, reward)); + let (imbalance, (validator_reward, nominators_reward)) = Self::reward_validator(v, reward); + + total_imbalance.subsume(imbalance); + validators_reward.push(ValidatorReward { + who: v.to_owned(), + amount: validator_reward, + nominators_reward, + }); } } @@ -1528,7 +1569,11 @@ impl Module { let total_payout = total_imbalance.peek(); let rest = max_payout.saturating_sub(total_payout); - Self::deposit_event(RawEvent::Reward(total_payout.saturated_into(), rest.saturated_into())); + Self::deposit_event(RawEvent::Reward( + total_payout.saturated_into(), + rest.saturated_into(), + validators_reward, + )); T::RingReward::on_unbalanced(total_imbalance); T::RingRewardRemainder::on_unbalanced(T::Ring::issue(rest)); diff --git a/types.json b/types.json index e27a3c9de..a6b49a433 100644 --- a/types.json +++ b/types.json @@ -56,6 +56,7 @@ "seal": "Vec", "hash": "Option" }, + "EthTransactionIndex": "(H256, u64)", "H64": { "_struct": "[u8; 8]" }, @@ -87,9 +88,13 @@ "who": "AccountId", "value": "Compact" }, - "Ring": "Balance", - "Power": "Balance", "Kton": "Balance", + "NominatorReward": { + "who": "AccountId", + "amount": "Compact" + }, + "Power": "Balance", + "Ring": "Balance", "SlashJournalEntry": { "who": "AccountId", "amount": "Compact", @@ -118,5 +123,10 @@ "ValidatorPrefs": { "node_name": "Bytes", "validator_payment_ratio": "Compact" + }, + "ValidatorReward": { + "who": "AccountId", + "amount": "Compact", + "nominators_reward": "Vec" } } \ No newline at end of file