AuRa multi block reward (#290)
* Multi block reward for AuRa * Added test * Better error on wrong config
This commit is contained in:
parent
dbc5f94241
commit
6f50061f0c
@ -43,7 +43,7 @@ use engines::{
|
|||||||
};
|
};
|
||||||
use error::{BlockError, Error, ErrorKind};
|
use error::{BlockError, Error, ErrorKind};
|
||||||
use ethereum_types::{Address, H256, H520, U128, U256};
|
use ethereum_types::{Address, H256, H520, U128, U256};
|
||||||
use ethjson;
|
use ethjson::{self, uint::Uint};
|
||||||
use ethkey::{self, Signature};
|
use ethkey::{self, Signature};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use io::{IoContext, IoHandler, IoService, TimerToken};
|
use io::{IoContext, IoHandler, IoService, TimerToken};
|
||||||
@ -80,7 +80,7 @@ pub struct AuthorityRoundParams {
|
|||||||
/// Immediate transitions.
|
/// Immediate transitions.
|
||||||
pub immediate_transitions: bool,
|
pub immediate_transitions: bool,
|
||||||
/// Block reward in base units.
|
/// Block reward in base units.
|
||||||
pub block_reward: U256,
|
pub block_reward: BTreeMap<BlockNumber, U256>,
|
||||||
/// Block reward contract transition block.
|
/// Block reward contract transition block.
|
||||||
pub block_reward_contract_transition: u64,
|
pub block_reward_contract_transition: u64,
|
||||||
/// Block reward contract.
|
/// Block reward contract.
|
||||||
@ -113,7 +113,33 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
|||||||
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
||||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
block_reward: p.block_reward.map_or_else(
|
||||||
|
|| {
|
||||||
|
let mut ret = BTreeMap::new();
|
||||||
|
ret.insert(0, U256::zero());
|
||||||
|
ret
|
||||||
|
},
|
||||||
|
|reward| match reward {
|
||||||
|
ethjson::spec::BlockReward::Single(reward) => {
|
||||||
|
let mut ret = BTreeMap::new();
|
||||||
|
ret.insert(0, reward.into());
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
ethjson::spec::BlockReward::Multi(mut multi) => {
|
||||||
|
if multi.is_empty() {
|
||||||
|
panic!("No block rewards are found in config");
|
||||||
|
}
|
||||||
|
// add block reward from genesis and put reward to zero.
|
||||||
|
multi
|
||||||
|
.entry(Uint(U256::from(0)))
|
||||||
|
.or_insert(Uint(U256::from(0)));
|
||||||
|
multi
|
||||||
|
.into_iter()
|
||||||
|
.map(|(block, reward)| (block.into(), reward.into()))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
block_reward_contract_transition: p
|
block_reward_contract_transition: p
|
||||||
.block_reward_contract_transition
|
.block_reward_contract_transition
|
||||||
.map_or(0, Into::into),
|
.map_or(0, Into::into),
|
||||||
@ -457,7 +483,7 @@ pub struct AuthorityRound {
|
|||||||
empty_steps: Mutex<BTreeSet<EmptyStep>>,
|
empty_steps: Mutex<BTreeSet<EmptyStep>>,
|
||||||
epoch_manager: Mutex<EpochManager>,
|
epoch_manager: Mutex<EpochManager>,
|
||||||
immediate_transitions: bool,
|
immediate_transitions: bool,
|
||||||
block_reward: U256,
|
block_reward: BTreeMap<BlockNumber, U256>,
|
||||||
block_reward_contract_transition: u64,
|
block_reward_contract_transition: u64,
|
||||||
block_reward_contract: Option<BlockRewardContract>,
|
block_reward_contract: Option<BlockRewardContract>,
|
||||||
maximum_uncle_count_transition: u64,
|
maximum_uncle_count_transition: u64,
|
||||||
@ -1374,10 +1400,11 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let author = *block.header.author();
|
let author = *block.header.author();
|
||||||
|
let number = block.header.number();
|
||||||
beneficiaries.push((author, RewardKind::Author));
|
beneficiaries.push((author, RewardKind::Author));
|
||||||
|
|
||||||
let rewards: Vec<_> = match self.block_reward_contract {
|
let rewards: Vec<_> = match self.block_reward_contract {
|
||||||
Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
|
Some(ref c) if number >= self.block_reward_contract_transition => {
|
||||||
let mut call = super::default_system_or_code_call(&self.machine, block);
|
let mut call = super::default_system_or_code_call(&self.machine, block);
|
||||||
|
|
||||||
let rewards = c.reward(&beneficiaries, &mut call)?;
|
let rewards = c.reward(&beneficiaries, &mut call)?;
|
||||||
@ -1386,10 +1413,18 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
.map(|(author, amount)| (author, RewardKind::External, amount))
|
.map(|(author, amount)| (author, RewardKind::External, amount))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
_ => beneficiaries
|
_ => {
|
||||||
|
let (_, reward) = self.block_reward.iter()
|
||||||
|
.rev()
|
||||||
|
.find(|&(block, _)| *block <= number)
|
||||||
|
.expect("Current block's reward is not found; this indicates a chain config error; qed");
|
||||||
|
let reward = *reward;
|
||||||
|
|
||||||
|
beneficiaries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(author, reward_kind)| (author, reward_kind, self.block_reward))
|
.map(|(author, reward_kind)| (author, reward_kind, reward))
|
||||||
.collect(),
|
.collect()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
block_reward::apply_block_rewards(&rewards, block, &self.machine)
|
block_reward::apply_block_rewards(&rewards, block, &self.machine)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use std::{cmp, collections::BTreeMap, path::Path, sync::Arc};
|
use std::{cmp, collections::BTreeMap, path::Path, sync::Arc};
|
||||||
|
|
||||||
use ethereum_types::{H256, H64, U256};
|
use ethereum_types::{H256, H64, U256};
|
||||||
use ethjson;
|
use ethjson::{self, uint::Uint};
|
||||||
use hash::KECCAK_EMPTY_LIST_RLP;
|
use hash::KECCAK_EMPTY_LIST_RLP;
|
||||||
use rlp::Rlp;
|
use rlp::Rlp;
|
||||||
use types::{
|
use types::{
|
||||||
@ -145,10 +145,19 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
|||||||
ret.insert(0, reward.into());
|
ret.insert(0, reward.into());
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ethjson::spec::BlockReward::Multi(multi) => multi
|
ethjson::spec::BlockReward::Multi(mut multi) => {
|
||||||
|
if multi.is_empty() {
|
||||||
|
panic!("No block rewards are found in config");
|
||||||
|
}
|
||||||
|
// add block reward from genesis and put reward to zero.
|
||||||
|
multi
|
||||||
|
.entry(Uint(U256::from(0)))
|
||||||
|
.or_insert(Uint(U256::from(0)));
|
||||||
|
multi
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(block, reward)| (block.into(), reward.into()))
|
.map(|(block, reward)| (block.into(), reward.into()))
|
||||||
.collect(),
|
.collect()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
|
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Authority params deserialization.
|
//! Authority params deserialization.
|
||||||
|
|
||||||
use super::ValidatorSet;
|
use super::{BlockReward, ValidatorSet};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use hash::Address;
|
use hash::Address;
|
||||||
use uint::Uint;
|
use uint::Uint;
|
||||||
@ -40,7 +40,7 @@ pub struct AuthorityRoundParams {
|
|||||||
/// Whether transitions should be immediate.
|
/// Whether transitions should be immediate.
|
||||||
pub immediate_transitions: Option<bool>,
|
pub immediate_transitions: Option<bool>,
|
||||||
/// Reward per block in wei.
|
/// Reward per block in wei.
|
||||||
pub block_reward: Option<Uint>,
|
pub block_reward: Option<BlockReward>,
|
||||||
/// Block at which the block reward contract should start being used.
|
/// Block at which the block reward contract should start being used.
|
||||||
pub block_reward_contract_transition: Option<Uint>,
|
pub block_reward_contract_transition: Option<Uint>,
|
||||||
/// Block reward contract address (setting the block reward contract
|
/// Block reward contract address (setting the block reward contract
|
||||||
@ -70,6 +70,9 @@ pub struct AuthorityRound {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use super::BlockReward;
|
||||||
use ethereum_types::{H160, U256};
|
use ethereum_types::{H160, U256};
|
||||||
use hash::Address;
|
use hash::Address;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
@ -110,5 +113,41 @@ mod tests {
|
|||||||
deserialized.params.maximum_uncle_count,
|
deserialized.params.maximum_uncle_count,
|
||||||
Some(Uint(5.into()))
|
Some(Uint(5.into()))
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
deserialized.params.block_reward,
|
||||||
|
Some(BlockReward::Single(Uint(5000000.into())))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn authority_round_deserialization_multi_block() {
|
||||||
|
let s = r#"{
|
||||||
|
"params": {
|
||||||
|
"stepDuration": "0x02",
|
||||||
|
"validators": {
|
||||||
|
"contract" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||||
|
},
|
||||||
|
"blockReward": {
|
||||||
|
"0": 5000000,
|
||||||
|
"100": 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let deserialized: AuthorityRound = serde_json::from_str(s).unwrap();
|
||||||
|
assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02)));
|
||||||
|
assert_eq!(
|
||||||
|
deserialized.params.validators,
|
||||||
|
ValidatorSet::Contract(Address(H160::from(
|
||||||
|
"0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||||
|
)))
|
||||||
|
);
|
||||||
|
let mut rewards: BTreeMap<Uint, Uint> = BTreeMap::new();
|
||||||
|
rewards.insert(Uint(U256::from(0)), Uint(U256::from(5000000)));
|
||||||
|
rewards.insert(Uint(U256::from(100)), Uint(U256::from(150)));
|
||||||
|
assert_eq!(
|
||||||
|
deserialized.params.block_reward,
|
||||||
|
Some(BlockReward::Multi(rewards))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user