Merge branch 'network' into verification

This commit is contained in:
arkpar
2016-01-11 12:45:35 +01:00
23 changed files with 345 additions and 209 deletions

View File

@@ -17,13 +17,31 @@ impl Ethash {
impl Engine for Ethash {
fn name(&self) -> &str { "Ethash" }
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
// Two fields - mix
fn seal_fields(&self) -> usize { 2 }
// Two empty data items in RLP.
fn seal_rlp(&self) -> Bytes { encode(&H64::new()) }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
fn spec(&self) -> &Spec { &self.spec }
fn evm_schedule(&self, _env_info: &EnvInfo) -> EvmSchedule { EvmSchedule::new_frontier() }
/// Apply the block reward on finalisation of the block.
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, block: &mut Block) {
let a = block.header().author.clone();
block.state_mut().add_balance(&a, &decode(&self.spec().engine_params.get("blockReward").unwrap()));
let reward = self.spec().engine_params.get("blockReward").map(|a| decode(&a)).unwrap_or(U256::from(0u64));
let fields = block.fields();
// Bestow block reward
fields.state.add_balance(&fields.header.author, &(reward + reward / U256::from(32) * U256::from(fields.uncles.len())));
// Bestow uncle rewards
let current_number = fields.header.number();
for u in fields.uncles.iter() {
fields.state.add_balance(u.author(), &(reward * U256::from((8 + u.number() - current_number) / 8)));
}
}
@@ -37,7 +55,7 @@ impl Engine for Ethash {
return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: min_gas_limit, max: From::from(0), found: header.gas_limit })));
}
let maximum_extra_data_size = self.maximum_extra_data_size();
if header.number != From::from(0) && header.extra_data.len() > maximum_extra_data_size {
if header.number != 0 && header.extra_data.len() > maximum_extra_data_size {
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: 0, max: maximum_extra_data_size, found: header.extra_data.len() })));
}
// TODO: Verify seal (quick)
@@ -70,13 +88,13 @@ impl Engine for Ethash {
impl Ethash {
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000;
if header.number == From::from(0) {
if header.number == 0 {
panic!("Can't calculate genesis block difficulty");
}
let min_difficulty = decode(self.spec().engine_params.get("minimumDifficulty").unwrap());
let difficulty_bound_divisor = decode(self.spec().engine_params.get("difficultyBoundDivisor").unwrap());
let duration_limit = decode(self.spec().engine_params.get("durationLimit").unwrap());
let duration_limit: u64 = decode(self.spec().engine_params.get("durationLimit").unwrap());
let frontier_limit = decode(self.spec().engine_params.get("frontierCompatibilityModeLimit").unwrap());
let mut target = if header.number < frontier_limit {
if header.timestamp >= parent.timestamp + duration_limit {
@@ -87,16 +105,16 @@ impl Ethash {
}
}
else {
let diff_inc = (header.timestamp - parent.timestamp) / From::from(10);
if diff_inc <= From::from(1) {
parent.difficulty + parent.difficulty / From::from(2048) * (U256::from(1) - diff_inc)
let diff_inc = (header.timestamp - parent.timestamp) / 10;
if diff_inc <= 1 {
parent.difficulty + parent.difficulty / From::from(2048) * From::from(1 - diff_inc)
}
else {
parent.difficulty - parent.difficulty / From::from(2048) * max(diff_inc - From::from(1), From::from(99))
parent.difficulty - parent.difficulty / From::from(2048) * From::from(max(diff_inc - 1, 99))
}
};
target = max(min_difficulty, target);
let period = ((parent.number + From::from(1)).as_u64() / EXP_DIFF_PERIOD) as usize;
let period = ((parent.number + 1) / EXP_DIFF_PERIOD) as usize;
if period > 1 {
target = max(min_difficulty, target + (U256::from(1) << (period - 2)));
}
@@ -111,9 +129,10 @@ fn on_close_block() {
let genesis_header = engine.spec().genesis_header();
let mut db = OverlayDB::new_temp();
engine.spec().ensure_db_good(&mut db);
let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), vec![]);
let last_hashes = vec![genesis_header.hash()];
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244F40000").unwrap());
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
}
// TODO: difficulty test

View File

@@ -52,7 +52,7 @@ mod tests {
fn morden() {
let morden = new_morden();
assert_eq!(*morden.state_root(), H256::from_str("f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9").unwrap());
assert_eq!(morden.state_root(), H256::from_str("f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9").unwrap());
let genesis = morden.genesis_block();
assert_eq!(BlockView::new(&genesis).header_view().sha3(), H256::from_str("0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303").unwrap());
@@ -63,10 +63,10 @@ mod tests {
fn frontier() {
let frontier = new_frontier();
assert_eq!(*frontier.state_root(), H256::from_str("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544").unwrap());
assert_eq!(frontier.state_root(), H256::from_str("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544").unwrap());
let genesis = frontier.genesis_block();
assert_eq!(BlockView::new(&genesis).header_view().sha3(), H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap());
let _ = frontier.to_engine();
}
}
}