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

Beta backports #7197

Merged
merged 8 commits into from
Dec 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion ethcore/res/ethereum/kovan.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
]
},
"validateScoreTransition": 1000000,
"validateStepTransition": 1500000
"validateStepTransition": 1500000,
"maximumUncleCountTransition": 10000000,
"maximumUncleCount": 2
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion ethcore/res/wasm-tests
9 changes: 7 additions & 2 deletions ethcore/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,13 @@ impl<'x> OpenBlock<'x> {
/// NOTE Will check chain constraints and the uncle number but will NOT check
/// that the header itself is actually valid.
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
if self.block.uncles.len() + 1 > self.engine.maximum_uncle_count() {
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len() + 1}));
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number());
if self.block.uncles.len() + 1 > max_uncles {
return Err(BlockError::TooManyUncles(OutOfBounds{
min: None,
max: Some(max_uncles),
found: self.block.uncles.len() + 1,
}));
}
// TODO: check number
// TODO: check not a direct ancestor (use last_hashes for that)
Expand Down
18 changes: 8 additions & 10 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1230,12 +1230,12 @@ impl BlockChainClient for Client {
}

fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
let (mut upper, env_info) = {
let (mut upper, max_upper, env_info) = {
let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
let initial_upper = env_info.gas_limit;
env_info.gas_limit = UPPER_CEILING.into();
(initial_upper, env_info)
let init = env_info.gas_limit;
let max = init * U256::from(10);
env_info.gas_limit = max;
(init, max, env_info)
};

// that's just a copy of the state.
Expand All @@ -1256,9 +1256,7 @@ impl BlockChainClient for Client {
};

if !cond(upper)? {
// impossible at block gas limit - try `UPPER_CEILING` instead.
// TODO: consider raising limit by powers of two.
upper = UPPER_CEILING.into();
upper = max_upper;
if !cond(upper)? {
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
Expand Down Expand Up @@ -1871,7 +1869,7 @@ impl MiningBlockChainClient for Client {
.find_uncle_headers(&h, engine.maximum_uncle_age())
.unwrap_or_else(Vec::new)
.into_iter()
.take(engine.maximum_uncle_count())
.take(engine.maximum_uncle_count(open_block.header().number()))
.foreach(|h| {
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
open_block was just created;
Expand All @@ -1886,7 +1884,7 @@ impl MiningBlockChainClient for Client {
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
let engine = &*self.engine;
let mut block = block.reopen(engine);
let max_uncles = engine.maximum_uncle_count();
let max_uncles = engine.maximum_uncle_count(block.header().number());
if block.uncles().len() < max_uncles {
let chain = self.chain.read();
let h = chain.best_block_hash();
Expand Down
48 changes: 48 additions & 0 deletions ethcore/src/engines/authority_round/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pub struct AuthorityRoundParams {
pub immediate_transitions: bool,
/// Block reward in base units.
pub block_reward: U256,
/// Number of accepted uncles transition block.
pub maximum_uncle_count_transition: u64,
/// Number of accepted uncles.
pub maximum_uncle_count: usize,
}

impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
Expand All @@ -77,6 +81,8 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
immediate_transitions: p.immediate_transitions.unwrap_or(false),
block_reward: p.block_reward.map_or_else(Default::default, 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),
}
}
}
Expand Down Expand Up @@ -218,6 +224,8 @@ pub struct AuthorityRound {
epoch_manager: Mutex<EpochManager>,
immediate_transitions: bool,
block_reward: U256,
maximum_uncle_count_transition: u64,
maximum_uncle_count: usize,
machine: EthereumMachine,
}

Expand Down Expand Up @@ -365,6 +373,8 @@ impl AuthorityRound {
epoch_manager: Mutex::new(EpochManager::blank()),
immediate_transitions: our_params.immediate_transitions,
block_reward: our_params.block_reward,
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
maximum_uncle_count: our_params.maximum_uncle_count,
machine: machine,
});

Expand Down Expand Up @@ -436,6 +446,15 @@ impl Engine<EthereumMachine> for AuthorityRound {
]
}

fn maximum_uncle_count(&self, block: BlockNumber) -> usize {
if block >= self.maximum_uncle_count_transition {
self.maximum_uncle_count
} else {
// fallback to default value
2
}
}

fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
Expand Down Expand Up @@ -949,6 +968,8 @@ mod tests {
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 0,
maximum_uncle_count: 0,
block_reward: Default::default(),
};

Expand Down Expand Up @@ -976,4 +997,31 @@ mod tests {
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
}

#[test]
fn test_uncles_transition() {
let last_benign = Arc::new(AtomicUsize::new(0));
let params = AuthorityRoundParams {
step_duration: Default::default(),
start_step: Some(1),
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 1,
maximum_uncle_count: 0,
block_reward: Default::default(),
};

let aura = {
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
AuthorityRound::new(params, machine).unwrap()
};

assert_eq!(aura.maximum_uncle_count(0), 2);
assert_eq!(aura.maximum_uncle_count(1), 0);
assert_eq!(aura.maximum_uncle_count(100), 0);
}
}
5 changes: 3 additions & 2 deletions ethcore/src/engines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ pub trait Engine<M: Machine>: Sync + Send {
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }

/// Maximum number of uncles a block is allowed to declare.
fn maximum_uncle_count(&self) -> usize { 2 }
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }

/// The number of generations back that uncles can be.
fn maximum_uncle_age(&self) -> usize { 6 }

Expand Down Expand Up @@ -363,7 +364,7 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> {
}

/// The nonce with which accounts begin at given block.
fn account_start_nonce(&self, block: u64) -> U256 {
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
self.machine().account_start_nonce(block)
}

Expand Down
3 changes: 3 additions & 0 deletions ethcore/src/engines/null_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use bigint::prelude::U256;
use engines::Engine;
use header::BlockNumber;
use parity_machine::{Header, LiveBlock, WithBalances};

/// Params for a null engine.
Expand Down Expand Up @@ -95,6 +96,8 @@ impl<M: WithBalances> Engine<M> for NullEngine<M> {
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
}

fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }

fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/engines/tendermint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ impl Engine<EthereumMachine> for Tendermint {

fn machine(&self) -> &EthereumMachine { &self.machine }

fn maximum_uncle_count(&self) -> usize { 0 }
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }

fn maximum_uncle_age(&self) -> usize { 0 }

Expand Down
14 changes: 12 additions & 2 deletions ethcore/src/ethereum/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use util::Address;
use unexpected::{OutOfBounds, Mismatch};
use block::*;
use error::{BlockError, Error};
use header::Header;
use header::{Header, BlockNumber};
use engines::{self, Engine};
use ethjson;
use rlp::{self, UntrustedRlp};
Expand Down Expand Up @@ -181,6 +181,8 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
}
}

fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }

fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
let difficulty = self.calculate_difficulty(header, parent);
header.set_difficulty(difficulty);
Expand Down Expand Up @@ -447,9 +449,12 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6
} else {
block_number / era_rounds
};
let mut divi = U256::from(1);
for _ in 0..eras {
reward = reward / U256::from(5) * U256::from(4);
reward = reward * U256::from(4);
divi = divi * U256::from(5);
}
reward = reward / divi;
(eras, reward)
}

Expand Down Expand Up @@ -515,6 +520,11 @@ mod tests {
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(15, eras);
assert_eq!(U256::from_str("271000000000000").unwrap(), reward);

let block_number = 250000000;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(49, eras);
assert_eq!(U256::from_str("51212FFBAF0A").unwrap(), reward);
}

#[test]
Expand Down
11 changes: 8 additions & 3 deletions ethcore/src/verification/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,14 @@ pub fn verify_block_family(header: &Header, parent: &Header, engine: &EthEngine,

fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> {
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
let max_uncles = engine.maximum_uncle_count(header.number());
if num_uncles != 0 {
if num_uncles > engine.maximum_uncle_count() {
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
if num_uncles > max_uncles {
return Err(From::from(BlockError::TooManyUncles(OutOfBounds {
min: None,
max: Some(max_uncles),
found: num_uncles,
})));
}

let mut excluded = HashSet::new();
Expand Down Expand Up @@ -653,7 +658,7 @@ mod tests {
let mut bad_uncles = good_uncles.clone();
bad_uncles.push(good_uncle1.clone());
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count()), min: None, found: bad_uncles.len() }));
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count(header.number())), min: None, found: bad_uncles.len() }));

header = good.clone();
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
Expand Down
6 changes: 3 additions & 3 deletions ethcore/wasm/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
Static(
"_storage_read",
&[I32; 2],
Some(I32),
None,
),
Static(
"_storage_write",
&[I32; 2],
Some(I32),
None,
),
Static(
"_balance",
Expand Down Expand Up @@ -115,7 +115,7 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
Static(
"_blockhash",
&[I64, I32],
Some(I32),
None,
),
Static(
"_coinbase",
Expand Down
1 change: 1 addition & 0 deletions ethcore/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod result;
#[cfg(test)]
mod tests;
mod env;
mod panic_payload;

const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;

Expand Down
Loading