Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize a simple module for testing store_block_header and relay_receipt #122

Merged
merged 3 commits into from
Nov 28, 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
Prev Previous commit
Next Next commit
merge from develop and resolve conflicts
  • Loading branch information
hackfisher committed Nov 28, 2019
commit 9bd75739d191c946fbadef96c6ba69b57a090456
5 changes: 3 additions & 2 deletions core/sr-eth-primitives/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ use super::*;
use ethbloom::Bloom;
use pow::EthashSeal;
use rlp::RlpStream;
use sr_primitives::RuntimeDebug;

#[derive(PartialEq, Eq, Clone, Encode, Decode, Copy)]
#[derive(PartialEq, Eq, Clone, Encode, Decode, Copy, RuntimeDebug)]
enum Seal {
/// The seal/signature is included.
With,
/// The seal/signature is not included.
Without,
}

#[derive(Default, PartialEq, Eq, Clone, Encode, Decode)]
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, RlpEncodable, RlpDecodable, RuntimeDebug)]
pub struct EthHeader {
parent_hash: H256,
timestamp: u64,
Expand Down
1 change: 0 additions & 1 deletion core/sr-eth-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use rstd::vec::Vec;

pub mod encoded;
pub mod error;
//pub mod keccak;
pub mod header;
pub mod pow;
pub mod receipt;
Expand Down
194 changes: 136 additions & 58 deletions core/sr-eth-primitives/src/pow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,32 @@ use core::cmp;
use core::convert::{From, Into, TryFrom};
use error::{BlockError, Mismatch, OutOfBounds};
use ethbloom::Bloom;
use keccak_hash::KECCAK_EMPTY_LIST_RLP;
use rstd::collections::btree_map::BTreeMap;
use rstd::mem;
use rstd::result;
use sr_primitives::RuntimeDebug;

use codec::{Decode, Encode};

use ethereum_types::BigEndianHash;
use primitive_types::{H256, U256, U512};

use header::EthHeader;
use keccak_hash::KECCAK_EMPTY_LIST_RLP;
use primitive_types::{H160, H256, U128, U256, U512};
use rlp::*;
use rstd::{collections::btree_map::BTreeMap, mem, result};
use sr_primitives::RuntimeDebug;

//use substrate_primitives::RuntimeDebug;

pub const MINIMUM_DIFFICULTY: u128 = 131072;
// TODO: please keep an eye on this.
// it might change due to ethereum's upgrade
pub const PROGPOW_TRANSITION: u64 = u64::max_value();
//pub const DIFFICULTY_HARDFORK_TRANSITION: u64 = 0x59d9;
pub const DIFFICULTY_HARDFORK_BOUND_DIVISOR: u128 = 0x0200;
pub const DIFFICULTY_BOUND_DIVISOR: u128 = 0x0800;
pub const EXPIP2_TRANSITION: u64 = 0xc3500;
pub const EXPIP2_DURATION_LIMIT: u64 = 0x1e;
pub const DURATION_LIMIT: u64 = 0x3C;
pub const HOMESTEAD_TRANSITION: u64 = 0x30d40;
pub const EIP100B_TRANSITION: u64 = 0xC3500;
pub const DIFFICULTY_INCREMENT_DIVISOR: u64 = 0x3C;
pub const METROPOLIS_DIFFICULTY_INCREMENT_DIVISOR: u64 = 0x1E;

pub const BOMB_DEFUSE_TRANSITION: u64 = 0x30d40;
// 3,000,000
pub const ECIP1010_PAUSE_TRANSITION: u64 = 0x2dc6c0;
// 5,000,000
pub const ECIP1010_CONTINUE_TRANSITION: u64 = 0x4c4b40;

pub const DIFFICULTY_HARDFORK_TRANSITION: u64 = u64::max_value();

#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, RlpDecodable, RlpEncodable, RuntimeDebug)]
pub struct EthHeader {
parent_hash: H256,
timestamp: u64,
number: BlockNumber,
author: Address,
transactions_root: H256,
uncles_hash: H256,
extra_data: Bytes,
state_root: H256,
receipts_root: H256,
log_bloom: Bloom,
gas_used: U256,
gas_limit: U256,
difficulty: U256,
seal: Vec<Bytes>,
hash: Option<H256>,
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode)]
pub struct EthashPartial {
pub minimum_difficulty: U256,
pub difficulty_bound_divisor: U256,
pub difficulty_increment_divisor: u64,
pub metropolis_difficulty_increment_divisor: u64,
pub duration_limit: u64,
pub homestead_transition: u64,
pub difficulty_hardfork_transition: u64,
pub difficulty_hardfork_bound_divisor: U256,
pub bomb_defuse_transition: u64,
pub eip100b_transition: u64,
pub ecip1010_pause_transition: u64,
pub ecip1010_continue_transition: u64,
pub difficulty_bomb_delays: BTreeMap<BlockNumber, BlockNumber>,
pub expip2_transition: u64,
pub expip2_duration_limit: u64,
pub progpow_transition: u64,
}

impl EthashPartial {
Expand Down Expand Up @@ -91,12 +61,120 @@ impl EthashPartial {
}
}

#[derive(PartialEq, Eq, Clone, Encode, Decode, Copy, RuntimeDebug)]
enum Seal {
/// The seal/signature is included.
With,
/// The seal/signature is not included.
Without,
impl EthashPartial {
pub fn verify_block_basic(&self, header: &EthHeader) -> result::Result<(), error::BlockError> {
// check the seal fields.
let seal = EthashSeal::parse_seal(header.seal())?;

// TODO: consider removing these lines.
let min_difficulty = self.minimum_difficulty;
if header.difficulty() < &min_difficulty {
return Err(BlockError::DifficultyOutOfBounds(OutOfBounds {
min: Some(min_difficulty),
max: None,
found: header.difficulty().clone(),
}));
}

let difficulty = boundary_to_difficulty(&H256(quick_get_difficulty(
&header.bare_hash().0,
seal.nonce.to_low_u64_be(),
&seal.mix_hash.0,
header.number() >= self.progpow_transition,
)));

if &difficulty < header.difficulty() {
return Err(BlockError::InvalidProofOfWork(OutOfBounds {
min: Some(header.difficulty().clone()),
max: None,
found: difficulty,
}));
}

Ok(())
}

pub fn calculate_difficulty(&self, header: &EthHeader, parent: &EthHeader) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100_000;

if header.number() == 0 {
panic!("Can't calculate genesis block difficulty");
}

let parent_has_uncles = parent.uncles_hash() != &KECCAK_EMPTY_LIST_RLP;

let min_difficulty = self.minimum_difficulty;

let difficulty_hardfork = header.number() >= self.difficulty_hardfork_transition;
let difficulty_bound_divisor = if difficulty_hardfork {
self.difficulty_hardfork_bound_divisor
} else {
self.difficulty_bound_divisor
};

let expip2_hardfork = header.number() >= self.expip2_transition;
let duration_limit = if expip2_hardfork {
self.expip2_duration_limit
} else {
self.duration_limit
};

let frontier_limit = self.homestead_transition;

let mut target = if header.number() < frontier_limit {
if header.timestamp() >= parent.timestamp() + duration_limit {
*parent.difficulty() - (*parent.difficulty() / difficulty_bound_divisor)
} else {
*parent.difficulty() + (*parent.difficulty() / difficulty_bound_divisor)
}
} else {
// trace!(target: "ethash", "Calculating difficulty parent.difficulty={}, header.timestamp={}, parent.timestamp={}", parent.difficulty(), header.timestamp(), parent.timestamp());
//block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)
let (increment_divisor, threshold) = if header.number() < self.eip100b_transition {
(self.difficulty_increment_divisor, 1)
} else if parent_has_uncles {
(self.metropolis_difficulty_increment_divisor, 2)
} else {
(self.metropolis_difficulty_increment_divisor, 1)
};

let diff_inc = (header.timestamp() - parent.timestamp()) / increment_divisor;
if diff_inc <= threshold {
*parent.difficulty()
+ *parent.difficulty() / difficulty_bound_divisor * U256::from(threshold - diff_inc)
} else {
let multiplier: U256 = cmp::min(diff_inc - threshold, 99).into();
parent
.difficulty()
.saturating_sub(*parent.difficulty() / difficulty_bound_divisor * multiplier)
}
};
target = cmp::max(min_difficulty, target);
if header.number() < self.bomb_defuse_transition {
if header.number() < self.ecip1010_pause_transition {
let mut number = header.number();
let original_number = number;
for (block, delay) in &self.difficulty_bomb_delays {
if original_number >= *block {
number = number.saturating_sub(*delay);
}
}
let period = (number / EXP_DIFF_PERIOD) as usize;
if period > 1 {
target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2)));
}
} else if header.number() < self.ecip1010_continue_transition {
let fixed_difficulty = ((self.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize;
target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty));
} else {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
let delay =
((self.ecip1010_continue_transition - self.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize;
target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2)));
}
}
target
}
}

#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
Expand Down
51 changes: 26 additions & 25 deletions srml/ethereum-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
// use blake2::Blake2b;
use codec::{Decode, Encode};
use rstd::vec::Vec;
use sr_eth_primitives::{pow::EthHeader, BestBlock, H160, H256, H64, U128, U256, U512};
use support::{decl_event, decl_module, decl_storage, dispatch::Result};
use sr_eth_primitives::{
header::EthHeader, BestBlock, BlockNumber as EthBlockNumber, H160, H256, H64, U128, U256, U512,
};
use support::{decl_event, decl_module, decl_storage, dispatch::Result, traits::Currency};
use system::ensure_signed;

use sr_primitives::RuntimeDebug;

use rlp::{decode, encode};

//use web3::types::{
// Address, Block, BlockId, BlockNumber, Bytes, CallRequest, Filter, Index, Log, RawHeader, RawReceipt, SyncState,
// Transaction, TransactionId, TransactionReceipt, TransactionRequest, Work, H256, H520, H64, U128, U256,
//};

pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
// type Hash: rstd::hash::Hash;
Expand All @@ -38,17 +35,17 @@ pub struct ActionRecord {

decl_storage! {
trait Store for Module<T: Trait> as EthBridge {
pub BeginNumber get(begin_number): u64;

/// Anchor block that works as genesis block
pub BeginHeader get(begin_header): Option<EthHeader>;

/// Info of the best block header for now
pub BestHeader get(best_header): BestBlock;
///
pub BlockList get(block_list): map EthBlockNumber => EthHeader;

pub HeaderOf get(header_of): map H256 => Option<EthHeader>;

pub BestHashOf get(best_hash_of): map u64 => Option<H256>;

pub HashsOf get(hashs_of): map u64 => Vec<H256>;
// pub BestHashOf get(best_hash_of): map u64 => Option<H256>;
// pub HashsOf get(hashs_of): map u64 => Vec<H256>;

/// Block delay for verify transaction
pub FinalizeNumber get(finalize_number): Option<u64>;
Expand All @@ -59,15 +56,14 @@ decl_storage! {
}
add_extra_genesis {
config(header): Option<Vec<u8>>;
config(number): u64;
build(|config| {
if let Some(h) = &config.header {
let header: EthHeader = rlp::decode(&h).expect("can't deserialize the header");
BeginNumber::put(header.number());
BeginHeader::put(header.clone());

// <Module<T>>::::genesis_header(header);
<Module<T>>::genesis_header(header);
} else {
BeginNumber::put(config.number);
// BeginNumber::put(config.number);
}
});
}
Expand All @@ -78,20 +74,19 @@ decl_module! {
where
origin: T::Origin
{
pub fn genesis_header(origin, header: EthHeader) {
let _relayer = ensure_signed(origin)?;
// BeginHeader::put(header);
}
fn deposit_event() = default;

pub fn store_block_header(origin, header: EthHeader) {
let _relayer = ensure_signed(origin)?;
let _ = Self::verify(&header)?;

<Module<T>>::deposit_event(RawEvent::NewHeader(header));
}

pub fn relay_receipt(origin, proof: ActionRecord) {
// confirm that the block hash is right
// get the MPT from the block header
// Using MPT to verify the proof and index etc.
// get the receipt MPT trie root from the block header
// Using receipt MPT trie root to verify the proof and index etc.
}

pub fn submit_header(origin, header: EthHeader) {
Expand All @@ -106,20 +101,26 @@ decl_event! {
where
<T as system::Trait>::AccountId
{
NewHeader(EthHeader),
TODO(AccountId),
}
}

impl<T: Trait> Module<T> {
pub fn genesis_header(header: EthHeader) {
unimplemented!()
}

pub fn adjust_deposit_value() {
unimplemented!()
}

/// 1. if exists?
/// 2. verify (difficulty + prev_hash + nonce + re-org)
/// 3. challenge
fn verify(_: &EthHeader) -> Result {
unimplemented!()
fn verify(header: &EthHeader) -> Result {
let number = header.number();
Ok(())
}

fn _punish(_who: &T::AccountId) -> Result {
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.