Merge branch 'master' into auth-round
This commit is contained in:
@@ -3,7 +3,7 @@ description = "Ethcore library"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
"eip155Transition": "0x7fffffffffffffff",
|
||||
"eip160Transition": "0x7fffffffffffffff",
|
||||
"eip161abcTransition": "0x7fffffffffffffff",
|
||||
"eip161dTransition": "0x7fffffffffffffff"
|
||||
"eip161dTransition": "0x7fffffffffffffff",
|
||||
"ecip1010PauseTransition": "0x2dc6c0",
|
||||
"ecip1010ContinueTransition": "0x4c4b40"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -65,7 +65,7 @@ use evm::{Factory as EvmFactory, Schedule};
|
||||
use miner::{Miner, MinerService};
|
||||
use snapshot::{self, io as snapshot_io};
|
||||
use factory::Factories;
|
||||
use rlp::{View, UntrustedRlp};
|
||||
use rlp::{decode, View, UntrustedRlp};
|
||||
use state_db::StateDB;
|
||||
use rand::OsRng;
|
||||
|
||||
@@ -147,6 +147,7 @@ pub struct Client {
|
||||
factories: Factories,
|
||||
history: u64,
|
||||
rng: Mutex<OsRng>,
|
||||
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
@@ -211,7 +212,7 @@ impl Client {
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
panic_handler.forward_from(&block_queue);
|
||||
|
||||
let awake = match config.mode { Mode::Dark(..) => false, _ => true };
|
||||
let awake = match config.mode { Mode::Dark(..) | Mode::Off => false, _ => true };
|
||||
|
||||
let factories = Factories {
|
||||
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
|
||||
@@ -243,6 +244,7 @@ impl Client {
|
||||
factories: factories,
|
||||
history: history,
|
||||
rng: Mutex::new(try!(OsRng::new().map_err(::util::UtilError::StdIo))),
|
||||
on_mode_change: Mutex::new(None),
|
||||
};
|
||||
Ok(Arc::new(client))
|
||||
}
|
||||
@@ -260,6 +262,11 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
/// Register an action to be done if a mode change happens.
|
||||
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
|
||||
*self.on_mode_change.lock() = Some(Box::new(f));
|
||||
}
|
||||
|
||||
/// Flush the block import queue.
|
||||
pub fn flush_queue(&self) {
|
||||
self.block_queue.flush();
|
||||
@@ -862,18 +869,37 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn keep_alive(&self) {
|
||||
let mode = self.mode.lock().clone();
|
||||
if mode != Mode::Active {
|
||||
let should_wake = match &*self.mode.lock() {
|
||||
&Mode::Dark(..) | &Mode::Passive(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
if should_wake {
|
||||
self.wake_up();
|
||||
(*self.sleep_state.lock()).last_activity = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
|
||||
fn mode(&self) -> IpcMode { self.mode.lock().clone().into() }
|
||||
fn mode(&self) -> IpcMode {
|
||||
let r = self.mode.lock().clone().into();
|
||||
trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r);
|
||||
r
|
||||
}
|
||||
|
||||
fn set_mode(&self, mode: IpcMode) {
|
||||
*self.mode.lock() = mode.clone().into();
|
||||
match mode {
|
||||
fn set_mode(&self, new_mode: IpcMode) {
|
||||
trace!(target: "mode", "Client::set_mode({:?})", new_mode);
|
||||
{
|
||||
let mut mode = self.mode.lock();
|
||||
*mode = new_mode.clone().into();
|
||||
trace!(target: "mode", "Mode now {:?}", &*mode);
|
||||
match *self.on_mode_change.lock() {
|
||||
Some(ref mut f) => {
|
||||
trace!(target: "mode", "Making callback...");
|
||||
f(&*mode)
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
match new_mode {
|
||||
IpcMode::Active => self.wake_up(),
|
||||
IpcMode::Off => self.sleep(),
|
||||
_ => {(*self.sleep_state.lock()).last_activity = Some(Instant::now()); }
|
||||
@@ -1197,6 +1223,18 @@ impl BlockChainClient for Client {
|
||||
fn signing_network_id(&self) -> Option<u8> {
|
||||
self.engine.signing_network_id(&self.latest_env_info())
|
||||
}
|
||||
|
||||
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>> {
|
||||
self.block_header(id)
|
||||
.map(|block| decode(&block))
|
||||
.map(|header| self.engine.extra_info(&header))
|
||||
}
|
||||
|
||||
fn uncle_extra_info(&self, id: UncleID) -> Option<BTreeMap<String, String>> {
|
||||
self.uncle(id)
|
||||
.map(|block| BlockView::new(&block).header())
|
||||
.map(|header| self.engine.extra_info(&header))
|
||||
}
|
||||
}
|
||||
|
||||
impl MiningBlockChainClient for Client {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::path::Path;
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
pub use std::time::Duration;
|
||||
pub use blockchain::Config as BlockChainConfig;
|
||||
pub use trace::Config as TraceConfig;
|
||||
@@ -86,6 +87,17 @@ impl Default for Mode {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Mode {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match *self {
|
||||
Mode::Active => write!(f, "active"),
|
||||
Mode::Passive(..) => write!(f, "passive"),
|
||||
Mode::Dark(..) => write!(f, "dark"),
|
||||
Mode::Off => write!(f, "offline"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Client configuration. Includes configs for all sub-systems.
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
pub struct ClientConfig {
|
||||
|
||||
@@ -38,6 +38,7 @@ use evm::{Factory as EvmFactory, VMType, Schedule};
|
||||
use miner::{Miner, MinerService, TransactionImportResult};
|
||||
use spec::Spec;
|
||||
use types::mode::Mode;
|
||||
use views::BlockView;
|
||||
|
||||
use verification::queue::QueueInfo;
|
||||
use block::{OpenBlock, SealedBlock};
|
||||
@@ -427,6 +428,10 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
None // Simple default.
|
||||
}
|
||||
|
||||
fn uncle_extra_info(&self, _id: UncleID) -> Option<BTreeMap<String, String>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn transaction_receipt(&self, id: TransactionID) -> Option<LocalizedReceipt> {
|
||||
self.receipts.read().get(&id).cloned()
|
||||
}
|
||||
@@ -469,6 +474,13 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).cloned())
|
||||
}
|
||||
|
||||
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>> {
|
||||
self.block(id)
|
||||
.map(|block| BlockView::new(&block).header())
|
||||
.map(|header| self.spec.engine.extra_info(&header))
|
||||
}
|
||||
|
||||
|
||||
fn block_status(&self, id: BlockID) -> BlockStatus {
|
||||
match id {
|
||||
BlockID::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain,
|
||||
|
||||
@@ -29,13 +29,13 @@ use error::{ImportResult, CallError};
|
||||
use receipt::LocalizedReceipt;
|
||||
use trace::LocalizedTrace;
|
||||
use evm::{Factory as EvmFactory, Schedule};
|
||||
use types::ids::*;
|
||||
use types::trace_filter::Filter as TraceFilter;
|
||||
use executive::Executed;
|
||||
use env_info::LastHashes;
|
||||
use types::call_analytics::CallAnalytics;
|
||||
use block_import_error::BlockImportError;
|
||||
use ipc::IpcConfig;
|
||||
use types::ids::*;
|
||||
use types::trace_filter::Filter as TraceFilter;
|
||||
use types::call_analytics::CallAnalytics;
|
||||
use types::blockchain_info::BlockChainInfo;
|
||||
use types::block_status::BlockStatus;
|
||||
use types::mode::Mode;
|
||||
@@ -235,6 +235,12 @@ pub trait BlockChainClient : Sync + Send {
|
||||
|
||||
/// Set the mode.
|
||||
fn set_mode(&self, mode: Mode);
|
||||
|
||||
/// Returns engine-related extra info for `BlockID`.
|
||||
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>>;
|
||||
|
||||
/// Returns engine-related extra info for `UncleID`.
|
||||
fn uncle_extra_info(&self, id: UncleID) -> Option<BTreeMap<String, String>>;
|
||||
}
|
||||
|
||||
/// Extended client interface used for mining
|
||||
|
||||
@@ -174,7 +174,7 @@ impl Engine for AuthorityRound {
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { hash_map!["signature".to_owned() => "TODO".to_owned()] }
|
||||
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] }
|
||||
|
||||
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
|
||||
Schedule::new_post_eip150(true, true, true)
|
||||
|
||||
@@ -81,7 +81,7 @@ impl Engine for BasicAuthority {
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { hash_map!["signature".to_owned() => "TODO".to_owned()] }
|
||||
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] }
|
||||
|
||||
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
|
||||
Schedule::new_homestead()
|
||||
|
||||
@@ -51,7 +51,7 @@ pub trait Engine : Sync + Send {
|
||||
fn seal_fields(&self) -> usize { 0 }
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||
|
||||
/// Additional information.
|
||||
fn additional_params(&self) -> HashMap<String, String> { HashMap::new() }
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager, H256 as EH256};
|
||||
use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
|
||||
use util::*;
|
||||
use block::*;
|
||||
use builtin::Builtin;
|
||||
@@ -70,6 +70,10 @@ pub struct EthashParams {
|
||||
pub eip161abc_transition: u64,
|
||||
/// Number of first block where EIP-161.d begins.
|
||||
pub eip161d_transition: u64,
|
||||
/// Number of first block where ECIP-1010 begins.
|
||||
pub ecip1010_pause_transition: u64,
|
||||
/// Number of first block where ECIP-1010 ends.
|
||||
pub ecip1010_continue_transition: u64
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
@@ -94,6 +98,8 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
eip160_transition: p.eip160_transition.map_or(0, Into::into),
|
||||
eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into),
|
||||
eip161d_transition: p.eip161d_transition.map_or(0x7fffffffffffffff, Into::into),
|
||||
ecip1010_pause_transition: p.ecip1010_pause_transition.map_or(0x7fffffffffffffff, Into::into),
|
||||
ecip1010_continue_transition: p.ecip1010_continue_transition.map_or(0x7fffffffffffffff, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,8 +139,8 @@ impl Engine for Ethash {
|
||||
}
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, header: &Header) -> HashMap<String, String> {
|
||||
hash_map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())]
|
||||
fn extra_info(&self, header: &Header) -> BTreeMap<String, String> {
|
||||
map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())]
|
||||
}
|
||||
|
||||
fn schedule(&self, env_info: &EnvInfo) -> Schedule {
|
||||
@@ -237,10 +243,10 @@ impl Engine for Ethash {
|
||||
return Err(From::from(BlockError::DifficultyOutOfBounds(OutOfBounds { min: Some(min_difficulty), max: None, found: header.difficulty().clone() })))
|
||||
}
|
||||
|
||||
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(quick_get_difficulty(
|
||||
&Ethash::to_ethash(header.bare_hash()),
|
||||
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
|
||||
&header.bare_hash().0,
|
||||
header.nonce().low_u64(),
|
||||
&Ethash::to_ethash(header.mix_hash())
|
||||
&header.mix_hash().0
|
||||
)));
|
||||
if &difficulty < header.difficulty() {
|
||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
|
||||
@@ -265,10 +271,10 @@ impl Engine for Ethash {
|
||||
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
|
||||
)));
|
||||
}
|
||||
let result = self.pow.compute_light(header.number() as u64, &Ethash::to_ethash(header.bare_hash()), header.nonce().low_u64());
|
||||
let mix = Ethash::from_ethash(result.mix_hash);
|
||||
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(result.value));
|
||||
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, Ethash::from_ethash(slow_get_seedhash(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), Ethash::from_ethash(result.mix_hash), Ethash::from_ethash(result.value));
|
||||
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, header.nonce().low_u64());
|
||||
let mix = H256(result.mix_hash);
|
||||
let difficulty = Ethash::boundary_to_difficulty(&H256(result.value));
|
||||
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, H256(slow_get_seedhash(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), H256(result.mix_hash), H256(result.value));
|
||||
if mix != header.mix_hash() {
|
||||
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: header.mix_hash() })));
|
||||
}
|
||||
@@ -317,7 +323,7 @@ impl Engine for Ethash {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self
|
||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
||||
impl Ethash {
|
||||
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
||||
const EXP_DIFF_PERIOD: u64 = 100000;
|
||||
@@ -353,9 +359,20 @@ impl Ethash {
|
||||
};
|
||||
target = max(min_difficulty, target);
|
||||
if header.number() < self.ethash_params.bomb_defuse_transition {
|
||||
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
|
||||
if period > 1 {
|
||||
target = max(min_difficulty, target + (U256::from(1) << (period - 2)));
|
||||
if header.number() < self.ethash_params.ecip1010_pause_transition {
|
||||
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
|
||||
if period > 1 {
|
||||
target = max(min_difficulty, target + (U256::from(1) << (period - 2)));
|
||||
}
|
||||
}
|
||||
else if header.number() < self.ethash_params.ecip1010_continue_transition {
|
||||
let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize;
|
||||
target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty));
|
||||
}
|
||||
else {
|
||||
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
|
||||
let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize;
|
||||
target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2)));
|
||||
}
|
||||
}
|
||||
target
|
||||
@@ -379,14 +396,6 @@ impl Ethash {
|
||||
(((U256::one() << 255) / *difficulty) << 1).into()
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ethash(hash: H256) -> EH256 {
|
||||
unsafe { mem::transmute(hash) }
|
||||
}
|
||||
|
||||
fn from_ethash(hash: EH256) -> H256 {
|
||||
unsafe { mem::transmute(hash) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Header {
|
||||
@@ -414,8 +423,8 @@ mod tests {
|
||||
use env_info::EnvInfo;
|
||||
use error::{BlockError, Error};
|
||||
use header::Header;
|
||||
use super::super::new_morden;
|
||||
use super::Ethash;
|
||||
use super::super::{new_morden, new_homestead_test};
|
||||
use super::{Ethash, EthashParams};
|
||||
use rlp;
|
||||
|
||||
#[test]
|
||||
@@ -637,5 +646,122 @@ mod tests {
|
||||
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
}
|
||||
|
||||
// TODO: difficulty test
|
||||
#[test]
|
||||
fn difficulty_frontier() {
|
||||
let spec = new_homestead_test();
|
||||
let ethparams = get_default_ethash_params();
|
||||
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
|
||||
|
||||
let mut parent_header = Header::default();
|
||||
parent_header.set_number(1000000);
|
||||
parent_header.set_difficulty(U256::from_str("b69de81a22b").unwrap());
|
||||
parent_header.set_timestamp(1455404053);
|
||||
let mut header = Header::default();
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(1455404058);
|
||||
|
||||
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
|
||||
assert_eq!(U256::from_str("b6b4bbd735f").unwrap(), difficulty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficulty_homestead() {
|
||||
let spec = new_homestead_test();
|
||||
let ethparams = get_default_ethash_params();
|
||||
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
|
||||
|
||||
let mut parent_header = Header::default();
|
||||
parent_header.set_number(1500000);
|
||||
parent_header.set_difficulty(U256::from_str("1fd0fd70792b").unwrap());
|
||||
parent_header.set_timestamp(1463003133);
|
||||
let mut header = Header::default();
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(1463003177);
|
||||
|
||||
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
|
||||
assert_eq!(U256::from_str("1fc50f118efe").unwrap(), difficulty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficulty_classic_bomb_delay() {
|
||||
let spec = new_homestead_test();
|
||||
let ethparams = EthashParams {
|
||||
ecip1010_pause_transition: 3000000,
|
||||
..get_default_ethash_params()
|
||||
};
|
||||
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
|
||||
|
||||
let mut parent_header = Header::default();
|
||||
parent_header.set_number(3500000);
|
||||
parent_header.set_difficulty(U256::from_str("6F62EAF8D3C").unwrap());
|
||||
parent_header.set_timestamp(1452838500);
|
||||
let mut header = Header::default();
|
||||
header.set_number(parent_header.number() + 1);
|
||||
|
||||
header.set_timestamp(parent_header.timestamp() + 20);
|
||||
assert_eq!(
|
||||
U256::from_str("6F55FE9B74B").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
header.set_timestamp(parent_header.timestamp() + 5);
|
||||
assert_eq!(
|
||||
U256::from_str("6F71D75632D").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
header.set_timestamp(parent_header.timestamp() + 80);
|
||||
assert_eq!(
|
||||
U256::from_str("6F02746B3A5").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difficulty_bomb_continue() {
|
||||
let spec = new_homestead_test();
|
||||
let ethparams = EthashParams {
|
||||
ecip1010_pause_transition: 3000000,
|
||||
ecip1010_continue_transition: 5000000,
|
||||
..get_default_ethash_params()
|
||||
};
|
||||
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
|
||||
|
||||
let mut parent_header = Header::default();
|
||||
parent_header.set_number(5000102);
|
||||
parent_header.set_difficulty(U256::from_str("14944397EE8B").unwrap());
|
||||
parent_header.set_timestamp(1513175023);
|
||||
let mut header = Header::default();
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(parent_header.timestamp() + 6);
|
||||
assert_eq!(
|
||||
U256::from_str("1496E6206188").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
parent_header.set_number(5100123);
|
||||
parent_header.set_difficulty(U256::from_str("14D24B39C7CF").unwrap());
|
||||
parent_header.set_timestamp(1514609324);
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(parent_header.timestamp() + 41);
|
||||
assert_eq!(
|
||||
U256::from_str("14CA9C5D9227").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
parent_header.set_number(6150001);
|
||||
parent_header.set_difficulty(U256::from_str("305367B57227").unwrap());
|
||||
parent_header.set_timestamp(1529664575);
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(parent_header.timestamp() + 105);
|
||||
assert_eq!(
|
||||
U256::from_str("309D09E0C609").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
parent_header.set_number(8000000);
|
||||
parent_header.set_difficulty(U256::from_str("1180B36D4CE5B6A").unwrap());
|
||||
parent_header.set_timestamp(1535431724);
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(parent_header.timestamp() + 420);
|
||||
assert_eq!(
|
||||
U256::from_str("5126FFD5BCBB9E7").unwrap(),
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ use evm::Schedule;
|
||||
use engines::Engine;
|
||||
use env_info::EnvInfo;
|
||||
use ethereum;
|
||||
use ethereum::ethash::EthashParams;
|
||||
use devtools::*;
|
||||
use miner::Miner;
|
||||
use header::Header;
|
||||
@@ -422,3 +423,29 @@ pub fn get_bad_state_dummy_block() -> Bytes {
|
||||
|
||||
create_test_block(&block_header)
|
||||
}
|
||||
|
||||
pub fn get_default_ethash_params() -> EthashParams{
|
||||
EthashParams {
|
||||
gas_limit_bound_divisor: U256::from(1024),
|
||||
minimum_difficulty: U256::from(131072),
|
||||
difficulty_bound_divisor: U256::from(2048),
|
||||
difficulty_increment_divisor: 10,
|
||||
duration_limit: 13,
|
||||
block_reward: U256::from(0),
|
||||
registrar: "0000000000000000000000000000000000000001".into(),
|
||||
homestead_transition: 1150000,
|
||||
dao_hardfork_transition: 0x7fffffffffffffff,
|
||||
dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(),
|
||||
dao_hardfork_accounts: vec![],
|
||||
difficulty_hardfork_transition: 0x7fffffffffffffff,
|
||||
difficulty_hardfork_bound_divisor: U256::from(0),
|
||||
bomb_defuse_transition: 0x7fffffffffffffff,
|
||||
eip150_transition: 0x7fffffffffffffff,
|
||||
eip155_transition: 0x7fffffffffffffff,
|
||||
eip160_transition: 0x7fffffffffffffff,
|
||||
eip161abc_transition: 0x7fffffffffffffff,
|
||||
eip161d_transition: 0x7fffffffffffffff,
|
||||
ecip1010_pause_transition: 0x7fffffffffffffff,
|
||||
ecip1010_continue_transition: 0x7fffffffffffffff
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ pub struct TraceId {
|
||||
}
|
||||
|
||||
/// Uniquely identifies Uncle.
|
||||
#[derive(Debug, Binary)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Binary)]
|
||||
pub struct UncleID {
|
||||
/// Block id.
|
||||
pub block: BlockID,
|
||||
|
||||
@@ -20,7 +20,7 @@ pub use std::time::Duration;
|
||||
use client::Mode as ClientMode;
|
||||
|
||||
/// IPC-capable shadow-type for client::config::Mode
|
||||
#[derive(Clone, Binary)]
|
||||
#[derive(Clone, Binary, Debug)]
|
||||
pub enum Mode {
|
||||
/// Same as ClientMode::Off.
|
||||
Off,
|
||||
|
||||
@@ -159,7 +159,7 @@ impl Transaction {
|
||||
unsigned: self,
|
||||
r: sig.r().into(),
|
||||
s: sig.s().into(),
|
||||
v: sig.v() + if let Some(n) = network_id { 1 + n * 2 } else { 27 },
|
||||
v: sig.v() + if let Some(n) = network_id { 35 + n * 2 } else { 27 },
|
||||
hash: Cell::new(None),
|
||||
sender: Cell::new(None),
|
||||
}
|
||||
@@ -302,13 +302,13 @@ impl SignedTransaction {
|
||||
}
|
||||
|
||||
/// 0 if `v` would have been 27 under "Electrum" notation, 1 if 28 or 4 if invalid.
|
||||
pub fn standard_v(&self) -> u8 { match self.v { 0 => 4, v => (v - 1) & 1, } }
|
||||
pub fn standard_v(&self) -> u8 { match self.v { v if v == 27 || v == 28 || v > 36 => (v - 1) % 2, _ => 4 } }
|
||||
|
||||
/// The network ID, or `None` if this is a global transaction.
|
||||
pub fn network_id(&self) -> Option<u8> {
|
||||
match self.v {
|
||||
0 | 27 | 28 => None,
|
||||
v => Some((v - 1) / 2),
|
||||
v if v > 36 => Some((v - 35) / 2),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,21 +456,22 @@ fn should_recover_from_network_specific_signing() {
|
||||
#[test]
|
||||
fn should_agree_with_vitalik() {
|
||||
use rustc_serialize::hex::FromHex;
|
||||
use std::str::FromStr;
|
||||
|
||||
let test_vector = |tx_data: &str, address: &'static str| {
|
||||
let signed: SignedTransaction = decode(&FromHex::from_hex(tx_data).unwrap());
|
||||
assert_eq!(signed.sender().unwrap(), address.into());
|
||||
signed.check_low_s().unwrap();
|
||||
assert_eq!(signed.sender().unwrap(), address.into());
|
||||
flushln!("networkid: {:?}", signed.network_id());
|
||||
};
|
||||
|
||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xda39a520355857fdb37ecb527fe814230fa9962c");
|
||||
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc8a0c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0xd240215f30eafee2aaa5184d8f051ebb41c90b19");
|
||||
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a0ad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a8a0ad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2f2822c55d894df1ba32961c43325dcb3d614ee8");
|
||||
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0xc21df0434ceab6e18a1300d18206e54e807b4456");
|
||||
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf975cee81edae2ab5883f4e2fb2a7f2fd56f4131");
|
||||
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a0ceebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a0ceebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xd477474c9f48dcbfde5d97f30646242ab7a17e06");
|
||||
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a0e455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2da0e455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xb49948deb719ca21e38d29e3360f534b39db0e76");
|
||||
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xbddfc81a8ce87b2360837049a6eda68ab2f58999");
|
||||
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a0e4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c11a0e4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x8f2edcf67f329a146dd4cb1e6b3a072daff85b38");
|
||||
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a0d2f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba0d2f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x4ec38d4782fd4a6ff85c1cde77ccf1ae3c54472c");
|
||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce")
|
||||
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112")
|
||||
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be")
|
||||
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0")
|
||||
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554")
|
||||
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4")
|
||||
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35")
|
||||
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332")
|
||||
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029")
|
||||
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f")
|
||||
}
|
||||
Reference in New Issue
Block a user