Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

simplify BlockReward::reward implementation #10906

Merged
merged 3 commits into from
Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ethcore/src/engines/authority_round/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ impl Engine for AuthorityRound {
Some(ref c) if block.header.number() >= self.block_reward_contract_transition => {
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)?;
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
},
_ => {
Expand Down
32 changes: 7 additions & 25 deletions ethcore/src/engines/block_reward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
//! A module with types for declaring block rewards and a client interface for interacting with a
//! block reward contract.

use ethabi;
use ethabi::ParamType;
use ethereum_types::{H160, Address, U256};
use ethabi::FunctionOutputDecoder;
use ethereum_types::{Address, U256};

use std::sync::Arc;
use hash::keccak;
Expand Down Expand Up @@ -112,44 +111,27 @@ impl BlockRewardContract {
/// `machine.execute_as_system`).
pub fn reward(
&self,
beneficiaries: &[(Address, RewardKind)],
beneficiaries: Vec<(Address, RewardKind)>,
caller: &mut SystemOrCodeCall,
) -> Result<Vec<(Address, U256)>, Error> {
let input = block_reward_contract::functions::reward::encode_input(
beneficiaries.iter().map(|&(address, _)| H160::from(address)),
beneficiaries.iter().map(|&(_, ref reward_kind)| u16::from(*reward_kind)),
);
let (addresses, rewards): (Vec<_>, Vec<_>) = beneficiaries.into_iter().unzip();
let (input, decoder) = block_reward_contract::functions::reward::call(addresses, rewards.into_iter().map(u16::from));

let output = caller(self.kind.clone(), input)
.map_err(Into::into)
.map_err(EngineError::FailedSystemCall)?;

// since this is a non-constant call we can't use ethabi's function output
// deserialization, sadness ensues.
let types = &[
ParamType::Array(Box::new(ParamType::Address)),
ParamType::Array(Box::new(ParamType::Uint(256))),
];

let tokens = ethabi::decode(types, &output)
let (addresses, rewards) = decoder.decode(&output)
.map_err(|err| err.to_string())
.map_err(EngineError::FailedSystemCall)?;

assert!(tokens.len() == 2);

let addresses = tokens[0].clone().to_array().expect("type checked by ethabi::decode; qed");
let rewards = tokens[1].clone().to_array().expect("type checked by ethabi::decode; qed");

if addresses.len() != rewards.len() {
return Err(EngineError::FailedSystemCall(
"invalid data returned by reward contract: both arrays must have the same size".into()
).into());
}

let addresses = addresses.into_iter().map(|t| t.to_address().expect("type checked by ethabi::decode; qed"));
let rewards = rewards.into_iter().map(|t| t.to_uint().expect("type checked by ethabi::decode; qed"));

Ok(addresses.zip(rewards).collect())
Ok(addresses.into_iter().zip(rewards.into_iter()).collect())
}
}

Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/engines/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl Engine for Arc<Ethash> {

let mut call = engines::default_system_or_code_call(&self.machine, block);

let rewards = c.reward(&beneficiaries, &mut call)?;
let rewards = c.reward(beneficiaries, &mut call)?;
rewards.into_iter().map(|(author, amount)| (author, RewardKind::External, amount)).collect()
},
_ => {
Expand Down