Configuration map of block reward contract addresses (#10875)
* configuration map of block reward contract addresses * Revert test module updates. * re-added block reward transition map tests and docs * review comment
This commit is contained in:
parent
175051bac7
commit
efb390eb60
@ -87,10 +87,8 @@ pub struct AuthorityRoundParams {
|
|||||||
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: U256,
|
||||||
/// Block reward contract transition block.
|
/// Block reward contract addresses with their associated starting block numbers.
|
||||||
pub block_reward_contract_transition: u64,
|
pub block_reward_contract_transitions: BTreeMap<u64, BlockRewardContract>,
|
||||||
/// Block reward contract.
|
|
||||||
pub block_reward_contract: Option<BlockRewardContract>,
|
|
||||||
/// Number of accepted uncles transition block.
|
/// Number of accepted uncles transition block.
|
||||||
pub maximum_uncle_count_transition: u64,
|
pub maximum_uncle_count_transition: u64,
|
||||||
/// Number of accepted uncles.
|
/// Number of accepted uncles.
|
||||||
@ -114,6 +112,30 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
|||||||
step_duration_usize = U16_MAX;
|
step_duration_usize = U16_MAX;
|
||||||
warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX);
|
warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX);
|
||||||
}
|
}
|
||||||
|
let transition_block_num = p.block_reward_contract_transition.map_or(0, Into::into);
|
||||||
|
let mut br_transitions: BTreeMap<_, _> = p.block_reward_contract_transitions
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(block_num, address)|
|
||||||
|
(block_num.into(), BlockRewardContract::new_from_address(address.into())))
|
||||||
|
.collect();
|
||||||
|
if (p.block_reward_contract_code.is_some() || p.block_reward_contract_address.is_some()) &&
|
||||||
|
br_transitions.keys().next().map_or(false, |&block_num| block_num <= transition_block_num)
|
||||||
|
{
|
||||||
|
let s = "blockRewardContractTransition";
|
||||||
|
panic!("{} should be less than any of the keys in {}s", s, s);
|
||||||
|
}
|
||||||
|
if let Some(code) = p.block_reward_contract_code {
|
||||||
|
br_transitions.insert(
|
||||||
|
transition_block_num,
|
||||||
|
BlockRewardContract::new_from_code(Arc::new(code.into()))
|
||||||
|
);
|
||||||
|
} else if let Some(address) = p.block_reward_contract_address {
|
||||||
|
br_transitions.insert(
|
||||||
|
transition_block_num,
|
||||||
|
BlockRewardContract::new_from_address(address.into())
|
||||||
|
);
|
||||||
|
}
|
||||||
AuthorityRoundParams {
|
AuthorityRoundParams {
|
||||||
step_duration: step_duration_usize as u16,
|
step_duration: step_duration_usize as u16,
|
||||||
validators: new_validator_set(p.validators),
|
validators: new_validator_set(p.validators),
|
||||||
@ -122,12 +144,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
|||||||
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(Default::default, Into::into),
|
||||||
block_reward_contract_transition: p.block_reward_contract_transition.map_or(0, Into::into),
|
block_reward_contract_transitions: br_transitions,
|
||||||
block_reward_contract: match (p.block_reward_contract_code, p.block_reward_contract_address) {
|
|
||||||
(Some(code), _) => Some(BlockRewardContract::new_from_code(Arc::new(code.into()))),
|
|
||||||
(_, Some(address)) => Some(BlockRewardContract::new_from_address(address.into())),
|
|
||||||
(None, None) => None,
|
|
||||||
},
|
|
||||||
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
||||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||||
empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)),
|
empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)),
|
||||||
@ -454,8 +471,7 @@ pub struct AuthorityRound {
|
|||||||
epoch_manager: Mutex<EpochManager>,
|
epoch_manager: Mutex<EpochManager>,
|
||||||
immediate_transitions: bool,
|
immediate_transitions: bool,
|
||||||
block_reward: U256,
|
block_reward: U256,
|
||||||
block_reward_contract_transition: u64,
|
block_reward_contract_transitions: BTreeMap<u64, BlockRewardContract>,
|
||||||
block_reward_contract: Option<BlockRewardContract>,
|
|
||||||
maximum_uncle_count_transition: u64,
|
maximum_uncle_count_transition: u64,
|
||||||
maximum_uncle_count: usize,
|
maximum_uncle_count: usize,
|
||||||
empty_steps_transition: u64,
|
empty_steps_transition: u64,
|
||||||
@ -724,8 +740,7 @@ impl AuthorityRound {
|
|||||||
epoch_manager: Mutex::new(EpochManager::blank(our_params.two_thirds_majority_transition)),
|
epoch_manager: Mutex::new(EpochManager::blank(our_params.two_thirds_majority_transition)),
|
||||||
immediate_transitions: our_params.immediate_transitions,
|
immediate_transitions: our_params.immediate_transitions,
|
||||||
block_reward: our_params.block_reward,
|
block_reward: our_params.block_reward,
|
||||||
block_reward_contract_transition: our_params.block_reward_contract_transition,
|
block_reward_contract_transitions: our_params.block_reward_contract_transitions,
|
||||||
block_reward_contract: our_params.block_reward_contract,
|
|
||||||
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
||||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||||
empty_steps_transition: our_params.empty_steps_transition,
|
empty_steps_transition: our_params.empty_steps_transition,
|
||||||
@ -1295,16 +1310,16 @@ impl Engine for AuthorityRound {
|
|||||||
let author = *block.header.author();
|
let author = *block.header.author();
|
||||||
beneficiaries.push((author, RewardKind::Author));
|
beneficiaries.push((author, RewardKind::Author));
|
||||||
|
|
||||||
let rewards: Vec<_> = match self.block_reward_contract {
|
let block_reward_contract_transition = self
|
||||||
Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
|
.block_reward_contract_transitions
|
||||||
|
.range(..=block.header.number())
|
||||||
|
.last();
|
||||||
|
let rewards: Vec<_> = if let Some((_, contract)) = block_reward_contract_transition {
|
||||||
let mut call = engine::default_system_or_code_call(&self.machine, block);
|
let mut call = engine::default_system_or_code_call(&self.machine, block);
|
||||||
|
let rewards = contract.reward(beneficiaries, &mut call)?;
|
||||||
let rewards = c.reward(beneficiaries, &mut call)?;
|
|
||||||
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
|
||||||
},
|
} else {
|
||||||
_ => {
|
|
||||||
beneficiaries.into_iter().map(|(author, reward_kind)| (author, reward_kind, self.block_reward)).collect()
|
beneficiaries.into_iter().map(|(author, reward_kind)| (author, reward_kind, self.block_reward)).collect()
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
block_reward::apply_block_rewards(&rewards, block, &self.machine)
|
block_reward::apply_block_rewards(&rewards, block, &self.machine)
|
||||||
@ -1645,6 +1660,7 @@ impl Engine for AuthorityRound {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
@ -1665,9 +1681,11 @@ mod tests {
|
|||||||
};
|
};
|
||||||
use crate::spec::{Spec, self};
|
use crate::spec::{Spec, self};
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
|
use engines::block_reward::BlockRewardContract;
|
||||||
use engines::validator_set::{TestSet, SimpleList};
|
use engines::validator_set::{TestSet, SimpleList};
|
||||||
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
||||||
use machine::Machine;
|
use machine::Machine;
|
||||||
|
use ethjson;
|
||||||
|
|
||||||
fn build_aura<F>(f: F) -> Arc<AuthorityRound> where
|
fn build_aura<F>(f: F) -> Arc<AuthorityRound> where
|
||||||
F: FnOnce(&mut AuthorityRoundParams),
|
F: FnOnce(&mut AuthorityRoundParams),
|
||||||
@ -1684,8 +1702,7 @@ mod tests {
|
|||||||
empty_steps_transition: u64::max_value(),
|
empty_steps_transition: u64::max_value(),
|
||||||
maximum_empty_steps: 0,
|
maximum_empty_steps: 0,
|
||||||
block_reward: Default::default(),
|
block_reward: Default::default(),
|
||||||
block_reward_contract_transition: 0,
|
block_reward_contract_transitions: Default::default(),
|
||||||
block_reward_contract: Default::default(),
|
|
||||||
strict_empty_steps_transition: 0,
|
strict_empty_steps_transition: 0,
|
||||||
two_thirds_majority_transition: 0,
|
two_thirds_majority_transition: 0,
|
||||||
};
|
};
|
||||||
@ -2452,4 +2469,55 @@ mod tests {
|
|||||||
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
|
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
|
||||||
assert_eq!(engine.verify_block_family(&header, &parent).unwrap(), ());
|
assert_eq!(engine.verify_block_family(&header, &parent).unwrap(), ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_collect_block_reward_transitions() {
|
||||||
|
let config = r#"{
|
||||||
|
"params": {
|
||||||
|
"stepDuration": "5",
|
||||||
|
"validators": {
|
||||||
|
"list" : ["0x1000000000000000000000000000000000000001"]
|
||||||
|
},
|
||||||
|
"blockRewardContractTransition": "0",
|
||||||
|
"blockRewardContractAddress": "0x2000000000000000000000000000000000000002",
|
||||||
|
"blockRewardContractTransitions": {
|
||||||
|
"7": "0x3000000000000000000000000000000000000003",
|
||||||
|
"42": "0x4000000000000000000000000000000000000004"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
let deserialized: ethjson::spec::AuthorityRound = serde_json::from_str(config).unwrap();
|
||||||
|
let params = AuthorityRoundParams::from(deserialized.params);
|
||||||
|
for ((block_num1, address1), (block_num2, address2)) in
|
||||||
|
params.block_reward_contract_transitions.iter().zip(
|
||||||
|
[(0u64, BlockRewardContract::new_from_address(Address::from_str("2000000000000000000000000000000000000002").unwrap())),
|
||||||
|
(7u64, BlockRewardContract::new_from_address(Address::from_str("3000000000000000000000000000000000000003").unwrap())),
|
||||||
|
(42u64, BlockRewardContract::new_from_address(Address::from_str("4000000000000000000000000000000000000004").unwrap())),
|
||||||
|
].iter())
|
||||||
|
{
|
||||||
|
assert_eq!(block_num1, block_num2);
|
||||||
|
assert_eq!(address1, address2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected="blockRewardContractTransition should be less than any of the keys in blockRewardContractTransitions")]
|
||||||
|
fn should_reject_out_of_order_block_reward_transition() {
|
||||||
|
let config = r#"{
|
||||||
|
"params": {
|
||||||
|
"stepDuration": "5",
|
||||||
|
"validators": {
|
||||||
|
"list" : ["0x1000000000000000000000000000000000000001"]
|
||||||
|
},
|
||||||
|
"blockRewardContractTransition": "7",
|
||||||
|
"blockRewardContractAddress": "0x2000000000000000000000000000000000000002",
|
||||||
|
"blockRewardContractTransitions": {
|
||||||
|
"0": "0x3000000000000000000000000000000000000003",
|
||||||
|
"42": "0x4000000000000000000000000000000000000004"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
let deserialized: ethjson::spec::AuthorityRound = serde_json::from_str(config).unwrap();
|
||||||
|
AuthorityRoundParams::from(deserialized.params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Authority params deserialization.
|
//! Authority Round parameter deserialization.
|
||||||
|
//!
|
||||||
|
//! Here is an example of input parameters where the step duration is constant at 5 seconds, the set
|
||||||
|
//! of validators is decided by the contract at address `0x10..01` starting from block 0, and where
|
||||||
|
//! the address of the contract that computes block rewards is set to `0x20..02` for blocks 0
|
||||||
|
//! through 41 and to `0x30.03` for all blocks starting from block 42.
|
||||||
|
//!
|
||||||
|
//! ```ignore
|
||||||
|
//! "params": {
|
||||||
|
//! "stepDuration": "5",
|
||||||
|
//! "validators": {
|
||||||
|
//! "multi": {
|
||||||
|
//! "0": {
|
||||||
|
//! "contract": "0x1000000000000000000000000000000000000001"
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//! },
|
||||||
|
//! "blockRewardContractTransitions": {
|
||||||
|
//! "0": "0x2000000000000000000000000000000000000002",
|
||||||
|
//! "42": "0x3000000000000000000000000000000000000003"
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use hash::Address;
|
use hash::Address;
|
||||||
use uint::Uint;
|
use uint::Uint;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
@ -41,11 +64,24 @@ pub struct AuthorityRoundParams {
|
|||||||
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<Uint>,
|
||||||
/// Block at which the block reward contract should start being used.
|
/// Block at which the block reward contract should start being used. This option allows one to
|
||||||
|
/// add a single block reward contract transition and is compatible with the multiple address
|
||||||
|
/// option `block_reward_contract_transitions` below.
|
||||||
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 which overrides the `block_reward` setting. This option allows
|
||||||
/// overrides the static block reward definition).
|
/// one to add a single block reward contract address and is compatible with the multiple
|
||||||
|
/// address option `block_reward_contract_transitions` below.
|
||||||
pub block_reward_contract_address: Option<Address>,
|
pub block_reward_contract_address: Option<Address>,
|
||||||
|
/// Block reward contract addresses with their associated starting block numbers.
|
||||||
|
///
|
||||||
|
/// Setting the block reward contract overrides `block_reward`. If the single block reward
|
||||||
|
/// contract address is also present then it is added into the map at the block number stored in
|
||||||
|
/// `block_reward_contract_transition` or 0 if that block number is not provided. Therefore both
|
||||||
|
/// a single block reward contract transition and a map of reward contract transitions can be
|
||||||
|
/// used simulataneously in the same configuration. In such a case the code requires that the
|
||||||
|
/// block number of the single transition is strictly less than any of the block numbers in the
|
||||||
|
/// map.
|
||||||
|
pub block_reward_contract_transitions: Option<BTreeMap<Uint, Address>>,
|
||||||
/// Block reward code. This overrides the block reward contract address.
|
/// Block reward code. This overrides the block reward contract address.
|
||||||
pub block_reward_contract_code: Option<Bytes>,
|
pub block_reward_contract_code: Option<Bytes>,
|
||||||
/// Block at which maximum uncle count should be considered.
|
/// Block at which maximum uncle count should be considered.
|
||||||
|
Loading…
Reference in New Issue
Block a user