Merge branch 'network' into verification
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user